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

@framexyz/frame-mcp

v0.4.1

Published

Frame's unified Model Context Protocol server for Claude Desktop and other MCP-capable clients. Exposes the team's Brain (memory, traversal, observability, server-backed PDF), the Frame virtual team (Chief-of-Staff routing + specialist personas), and bran

Readme

@framexyz/frame-mcp

Frame's unified Model Context Protocol server for Claude Desktop and any MCP-capable client. One install line, one config block, three tool surfaces:

  • Brain — the team's shared knowledge store (memory, traversal, observability) plus server-backed PDF rendering. Replaces the previous @iolloyd/brain-mcp package.
  • Brand — vocabulary lint, BRAND.md ↔ brand.css drift check, local Frame-branded HTML preview. Replaces the previous @framexyz/frame-skills-mcp package.
  • Team — Frame's virtual team. Decomposes the single brain agent into specialist persona lenses (Chief of Staff, Head of Operations, Head of Engineering, Head of Compliance) and routes a task across them, then reconciles the answers. frame_team_route + frame_team_persona + frame_team_synthesize.

Brain tools register only when BRAIN_URL is set; brand and team tools are local (prompt assembly) and always available, so brand- or team-only users can install the server with no env vars at all.

Team (virtual team)

The persona prompts are source-of-truth in the brain repo (framexyz/brain, personas/) and vendored here under personas/, pinned by content hash in personas/personas.lock.json. src/personas.mjs fails loud if a vendored copy drifts from its pinned hash — the placement decision (brain 75af9f8a) put the orchestration runtime in frame-skills while keeping personas in brain, and content-hash pinning is how the two stay honest.

Routing flow (the host model is the LLM runtime):

  1. frame_team_route({ task }) → the Chief-of-Staff system prompt, the routable roster, the gate role, and the routing directive. The host adopts the prompt, recalls from brain, and emits OWNER → role with a sub-question per specialist. Compliance is a mandatory gate whenever the task touches the regulated perimeter.
  2. frame_team_persona({ role, task }) → one specialist's assembled prompt; the host answers in that lens. Run per named owner.
  3. frame_team_synthesize({ task, specialist_outputs }) → the Chief-of-Staff synthesis prompt with every specialist output embedded; the host emits one unified recommendation. The Head of Compliance ruling is a binding veto — if present it constrains the result and is never averaged away; if the task touches the regulated perimeter and no Compliance ruling is supplied, the response flags it as unsafe to close (gate_present: false).

To update the vendored personas after editing them in brain:

scripts/sync-personas.sh           # re-vendor + regenerate the lock
scripts/sync-personas.sh --check   # CI: exit 1 if vendored copies drift

Install (Claude Desktop)

Two paths. Pick the one that fits.

Option A — Desktop Extension (.mcpb, recommended)

Download frame-mcp-<version>.mcpb from the latest GitHub release and double-click it. Claude Desktop walks you through the env-var prompts (BRAIN_URL, default domain, optional API key, optional PDF render token) and adds the server to your config. No JSON editing.

Restart Claude Desktop after install. Startup logs land in ~/Library/Logs/Claude/mcp-server-frame.log and include a one-line diagnostic showing tool count, brain auth mode, and which local scripts were located.

Option B — npx from npm

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or your platform's equivalent:

{
  "mcpServers": {
    "frame": {
      "command": "npx",
      "args": ["-y", "@framexyz/frame-mcp"],
      "env": {
        "BRAIN_URL": "https://<project>.supabase.co/functions/v1",
        "BRAIN_API_KEY": "<optional — OAuth used if absent>",
        "FRAME_PDF_RENDER_TOKEN": "<for frame_pdf_preview_html>"
      }
    }
  }
}

Restart Claude Desktop. Same log location and diagnostic as Option A.

Migrating from the predecessor packages

If you currently install both @iolloyd/brain-mcp and @framexyz/frame-skills-mcp, replace both entries with the single frame block above. The three env vars — BRAIN_URL, BRAIN_API_KEY, FRAME_PDF_RENDER_TOKEN — keep the same names and values. No secret rotation needed.

OAuth tokens persist in ~/.brain-mcp/tokens.json (unchanged from @iolloyd/brain-mcp), so users on OAuth don't re-authenticate.

Tools

Brain (registered when BRAIN_URL is set)

Session / auth (no terminal required):

| Tool | What it does | |---|---| | brain_auth | Sign in / re-authenticate from inside Claude Desktop. Opens a Google sign-in window for your @frame.xyz account and stores the session locally. Say "reconnect brain". | | brain_whoami | Report current sign-in status, account, and session validity. | | brain_signout | Clear the locally stored session (for switching accounts / forcing a clean re-auth). |

Memory + traversal:

| Tool | What it does | |---|---| | brain_ask | Natural-language question with synthesised answer + [N] citations. Use this for any "what do we know about X" / "have we discussed Y" query. | | brain_recall | Raw semantic similarity hits (no synthesis). Lower-level than brain_ask. | | brain_remember | Store a fact, decision, or note. Long text is chunked automatically. | | brain_list | Paginated browse over memories in a domain. | | brain_forget | Delete a memory by UUID. | | brain_traverse | Walk cross-reference links from a memory. | | brain_link | Create an explicit link (related / supersedes / contradicts / extends). | | brain_pin | Change a memory's tier (0=identity, 1=critical, 2=topic, 3=deep). | | brain_wake_up | Return the L0+L1 context snapshot for a domain. |

Observability:

| Tool | What it does | |---|---| | brain_health | Status + memory count for a domain. | | brain_stats | Latency / counts / tokens over a time window. |

Knowledge graph (entity triples):

| Tool | What it does | |---|---| | brain_kg_query | Current facts about an entity. | | brain_kg_timeline | Chronological history of triples for an entity. | | brain_kg_invalidate | Mark a triple as no longer true. |

Hierarchical docs (ltree-pathed canonical state):

| Tool | What it does | |---|---| | brain_doc_read | Read a doc by path. | | brain_doc_write | Create or overwrite a doc. | | brain_doc_list | List docs under an ltree prefix. | | brain_doc_search | Hybrid semantic search over docs. | | brain_doc_move | Move a doc (or subtree) to a new path. | | brain_doc_delete | Delete a doc (recursive optional). | | brain_doc_link | Create a typed edge between two docs. | | brain_doc_links | List incoming + outgoing edges for a doc. |

Server-backed PDF:

| Tool | What it does | |---|---| | frame_pdf_generate | Render a Frame-branded PDF (one-pager / brief / addendum / memo) via the backend; returns a 7-day signed download URL. |

Brand (always registered)

| Tool | What it does | |---|---| | frame_brand_lint | Vocabulary + tone lint. Default mode catches tone smells, posturing words, negative-zero phrasing, title-shape. strict mode adds the Annex-B/OSFI forbidden-vocabulary check for customer-facing or regulator disclosure docs. | | frame_brand_tokens_check | BRAND.md § 1 ↔ frame-pdf/assets/brand.css palette drift check. | | frame_pdf_preview_html | Local-iteration HTML preview via frame-pdf-service.fly.dev. For a shareable signed PDF URL, use frame_pdf_generate. |

CLI subcommands

frame-mcp           start MCP server (what Claude Desktop runs)
frame-mcp auth      interactive Google sign-in (writes ~/.brain-mcp/tokens.json)
frame-mcp signout   clear stored tokens
frame-mcp whoami    print currently signed-in identity

These mirror the in-app brain_auth / brain_signout / brain_whoami tools. Prefer the tools inside Claude Desktop — they need no terminal.

Prerequisites

  • Node 18+
  • For frame_brand_tokens_check against the canonical brand authority: a local checkout of framexyz/frame-visuals at ~/code/frame-visuals/ (or pass brand_md_path explicitly).
  • For brain tools: either BRAIN_API_KEY set, or sign in via Google OAuth. You can sign in without a terminal — install the server, open Claude Desktop, and say "reconnect brain" (the brain_auth tool opens a Google window). frame-mcp auth from a shell does the same thing. When a session expires, brain tools return an actionable "sign-in required" message and Claude can re-auth in place via brain_auth — no reinstall, no terminal.
  • For frame_pdf_preview_html: FRAME_PDF_RENDER_TOKEN set (same token brain's /frame-pdf slash command uses).

Development

git clone https://github.com/framexyz/frame-skills.git
cd frame-skills/mcp
npm install
node src/index.mjs   # speaks MCP over stdio

Smoke-test via raw JSON-RPC stdio:

printf '%s\n%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | node src/index.mjs 2>/dev/null

Brain tools are only listed when BRAIN_URL is set; the startup banner on stderr makes this explicit.

Building the Desktop Extension (.mcpb)

The .mcpb bundle for Option-A installs is built from the same source as the npm package, so the two install paths are identical at runtime — only the install gesture differs. The build is driven by @anthropic-ai/mcpb and a small wrapper script that mirrors prepublishOnly's asset staging.

cd mcp
npm run build:mcpb   # produces frame-mcp-<version>.mcpb (gitignored)

The wrapper at scripts/build-mcpb.sh stages source + brand assets into a temp dir, installs production-only deps, validates the manifest, and calls mcpb pack. The artefact stays out of git (*.mcpb in .gitignore); attach it to the matching GitHub Release when cutting a new version.

Cutting a release

One command from the repo root builds the .mcpb, publishes to npm, tags, and creates the GitHub Release with the bundle attached:

task mcp:release

It runs from main with a clean tree, verifies personas are in sync with brain and tests pass, then publishes before tagging so a failed/unauthenticated npm publish leaves no dangling tag. Bump the version in both mcp/package.json and mcp/manifest.json first (task mcp:manifest:check enforces they match). task mcp:publish (npm only) and task mcp:build (.mcpb only) are available for the pieces. See Taskfile.yml.

Publishing the .mcpb to Slack

The release ends by posting the bundle to the #all-frame channel so teammates can install without visiting GitHub Releases. It's a final, non-fatal step — skipped silently unless SLACK_BOT_TOKEN is set, so it never undoes a completed npm + GitHub release:

export SLACK_BOT_TOKEN=xoxb-…          # Slack app invited to the channel,
                                       # with files:write (+ channels:read
                                       # to resolve a channel name)
export SLACK_MCPB_CHANNEL=all-frame    # optional; defaults to all-frame.
                                       # Accepts a name, #name, or an ID.
task mcp:release                       # …or, standalone, after a build:
task mcp:slack

scripts/post-mcpb-to-slack.sh resolves the channel name to an ID (conversations.list), then uploads via Slack's files.getUploadURLExternal → upload → files.completeUploadExternal and attaches a short install note. Pass an ID in SLACK_MCPB_CHANNEL to skip the lookup and the channels:read scope. bash scripts/post-mcpb-to-slack.sh --dry-run prints what it would send without calling Slack.

Token: reuse the brain Slack app's bot token (the same SLACK_BOT_TOKEN stored as a Supabase secret for brain). One-time setup, since that app today only posts (chat:write):

  1. In the brain Slack app config, add the files:write scope (and channels:read if you want name resolution; skip it by passing SLACK_MCPB_CHANNEL=<channel-id>), then reinstall the app.
  2. Invite the bot to #all-frame (/invite @<bot>).

Then export that token before task mcp:release (or task mcp:slack).

License

MIT