npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@homeflare/cloudflare

v0.3.1

Published

Cloudflare Workers helpers: Access identity, MCP OAuth metadata, and structured logging.

Readme

@homeflare/cloudflare

Cloudflare Workers helpers: Access JWT verification and structured logging.

bun add @homeflare/cloudflare

Workers only. This package assumes workerd. For code that must also run on Node or in a script, use @homeflare/kit.

Which auth path?

Three, and they are not alternatives — pick by where your code runs:

| your code | use | why | | ------------------------------ | -------------------------- | ---------------------------------------------------------------------------------- | | a Worker behind Access | accessIdentity(ctx) | the edge already enforced the policy and attached the identity — no token handling | | an origin with no ctx.access | verifyAccessJwt(request) | service-to-service, a non-Worker origin, or a Worker reached by service binding | | an MCP server | serveMcpMetadata() | neither of the above lets a client discover how to authenticate |

accessIdentity — Workers behind Access

import { accessIdentity } from '@homeflare/cloudflare';

export default {
  async fetch(request, env, ctx) {
    const who = await accessIdentity(ctx);
    if (who === undefined) return new Response('Access did not run', { status: 401 });

    return Response.json({ email: who.email, groups: who.groups });
  },
};

Prefer this when it applies. Cloudflare attaches the identity to the execution context (shipped 2026-08-14); verifying the assertion yourself re-checks something the platform already enforced.

⛔ Returns undefined rather than throwing, unlike verifyAccessJwt — a Worker may legitimately serve open routes too, so "no Access here" is a branch you decide, visible at the call site.

⚠️ ctx.access does not propagate through service bindings or RPC. A downstream Worker reached by binding sees undefined even though the caller was authenticated. It needs its own Access application, or to be told.

⚠️ Read groups from here, not from a token. Cloudflare trims the JWT's custom claim at roughly 1 KB — silently — so group membership read from an assertion can be incomplete. That is an authorization bug that only shows up for users in many groups.

serveMcpMetadata — RFC 9728 for MCP servers

import { serveMcpMetadata, unauthorizedResponse } from '@homeflare/cloudflare';

const auth = {
  resource: 'https://mcp.example.com/mcp',
  authorizationServer: 'https://team.cloudflareaccess.com',
};

export default {
  async fetch(request, env, ctx) {
    const discovery = serveMcpMetadata(request, auth);
    if (discovery !== undefined) return discovery;

    const who = await accessIdentity(ctx);
    if (who === undefined) return unauthorizedResponse(auth);
    // …serve MCP
  },
};

Both halves, or neither works. The MCP spec requires a server to publish Protected Resource Metadata and a 401 to carry WWW-Authenticate naming it. Publishing the document while answering a bare 401 leaves clients that follow the header — the common path — with nowhere to go.

⚠️ The well-known URL is derived from the resource URL, not chosen. That derivation is a security property: it stops anyone publishing metadata claiming to describe a resource they have no authority over.

verifyAccessJwt

import { verifyAccessJwt } from '@homeflare/cloudflare';

const who = await verifyAccessJwt(request, {
  teamDomain: env.TEAM_DOMAIN, // https://<team>.cloudflareaccess.com
  audience: env.POLICY_AUD, // the app's AUD tag
});
who.email; // string | undefined
who.sub; // string | undefined
who.claims; // everything else

Never omit audience. Any Access app in the account mints a JWT the team domain will happily verify; the AUD tag is the only thing saying the token was minted for this app.

Throws on a missing header, bad signature, wrong audience, or expiry — deliberately, so a forgotten if (!ok) cannot become an open door. The JWKS is cached per isolate, so it is not refetched per request.

log

import { log } from '@homeflare/cloudflare';

const rlog = log.with({ requestId, path: url.pathname });
rlog.info('handled', { status, ms }); // also .debug .warn .error

Writes one JSON object per line, which Workers Logs indexes field by field. No logging library: console.log of JSON is the integration.

⚠️ One object, never (message, fields) — multiple arguments are stringified and concatenated, which destroys the structure Workers Logs would index.

Never log a credential. There is no redaction layer, by design: a redactor implies it is safe to pass secrets in, then quietly misses one.

Two kinds of auth

This package verifies Cloudflare Access — the edge already authenticated the caller. If you are the identity provider (sessions, accounts, a database), that is @homeflare/auth. Reaching for the wrong one produces a system that looks authenticated and is not.

License

MIT © Timothy Schneider