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

axis-agent-mcp

v0.1.0

Published

Model Context Protocol server wrapping the AXIS agent-identity protocol: carry & present a credential, and look one up.

Readme

axis-mcp

A Model Context Protocol server that wraps the AXIS agent-identity protocol. It packages both resolution-side motions of the protocol into one install:

  • Carry & Present (operator side) — the agent holds its credential locally, mints AXIS Identity Tokens (AITs), and surfaces a signup link to its operator when it isn't yet registered.
  • Look Up (platform side) — resolve any inbound agent to its operator and authority, and verify a presented token. Free, account-less, read-only.

Beyond resolution, it is a self-hosted operator tool: the human operator manages the agent's identity and permissions entirely on their own machine — local operator-key custody, a local permission policy, and local enforcement — so you run an agent's identity and authorization with no hosted Governor and no Kipple infra beyond the public registry. See the Operator CLI and Operator-key local custody below.

It wraps the existing axis-protocol-sdk (signing, local verification) and the live AXIS Prime registry's public read endpoints (https://registry.axisprime.ai). No new backend. (Hosted, recoverable, multi-device custody + managed policy remain a separate explicit upgrade — the Governor — not required here.)

MCP is a surface, not the identity layer. AXIS agent identity lives in the protocol and axis-protocol-sdk; this MCP server is the surface that lets an MCP-speaking agent (Claude, etc.) use it as tools. An agent on any other stack — a plain HTTP client, a Python agent, the next protocol — uses axis-protocol-sdk directly and gets the same identity. AXIS isn't tied to MCP; MCP is simply the most ergonomic surface for LLM agents today.

Tools

Motion B — Look Up (zero local state, read-only)

| Tool | What it does | |---|---| | axis_verify(token, expected_audience?) | Verify an AIT via the registry; optionally check its aud claim. | | axis_resolve_agent(agent_id, presenting_ait?) | Resolve an agent's public identity record. | | axis_resolve_operator(operator_id) | Resolve an operator's public record. |

Motion A — Carry & Present (local custody)

| Tool | What it does | |---|---| | axis_status() | Report the local credential + the mandatory custody disclosure (or a signup affordance). | | axis_requirements(platform_url) | Read a platform's /.well-known/axis-access (+ axis-scopes): audience, tier, required scopes, registration URL. | | axis_present(audience_or_platform_url, scope?, ttl?=300, dlg?) | Mint an AIT and return it + the Authorization: Bearer <ait> header. Refuses any scope not granted in local policy. When a scope is asserted and no dlg is passed, auto-attaches the newest registered delegation covering that scope (dlg_source: "auto") — so a gate can resolve it without the caller knowing to pass dlg. | | axis_delegate(scope, ttl?) | Sign a delegation (operator → agent) with the local operator key and register it via the registrar path so a platform gate can resolve it. Refuses any scope not granted in local policy. | | post_comment(url, text, scope?) | One-call engage: post a comment on an AXIS-gated platform. Discovers requirements, ensures a registered delegation for the comment scope, mints the token, and POSTs it — hiding the endpoint, header, and payload. Returns the exact axis grant … to run (never self-grants) if the operator hasn't granted the scope. | | axis_request_onboarding(platform_url?) | Generate the agent keypair locally and return a one-click device-code operator signup link. Platform URL optional — omit to onboard platformless at the default (email) tier and engage specific platforms later. The link also carries the operator public signing key + a registration proof so the registrar registers it (POST /operators/:id/key), making operator-signed grants registry-verifiable. | | axis_complete_onboarding(device_code?) | Poll the registrar device-token endpoint once for a pending onboarding: pending (re-invoke), complete (binds the returned agent_id to the local key), or denied/expired. | | axis_dashboard(activity_limit?=20) | The operator dashboard in one call: agents, per-agent permissions (scope/expiry/approval), and recent signed activity, with a render hint. The in-chat equivalent of the axis dashboard localhost page — read-only, never returns key material. |

Prompts

| Prompt | What it does | |---|---| | my_agents | Discoverable entry in the client's prompt menu; drives the model to call axis_dashboard and render the operator dashboard inline — so you find it in the UI instead of learning a CLI command. |

Operator CLI (axis)

The MCP server serves your agent's LLM. The axis CLI is for you, the human operator: it manages your agent's identity and permissions entirely locally — no hosted Governor, no Kipple infra beyond the public registry. Both share the ~/.axis-mcp store.

npm run build              # builds dist/cli.js (bin: `axis`)
axis status                # held credential(s): ids, tier, granted scopes, custody, op-key
axis agents                # list local agents
axis operator-key init     # generate the operator key + register the public key
axis grant content:comment --ttl 30   # grant a scope (policy + operator-signed delegation)
axis approve content:publish           # approve a requires-approval scope
axis require-approval content:publish  # flag a scope deny-by-default
axis revoke content:comment            # revoke one scope
axis revoke --all                      # revoke the whole agent
axis audit --tail 20                   # show the signed local audit log
axis dashboard                         # open the localhost click-instead-of-type dashboard
axis help

Run without installing the bin via npm run axis -- <cmd> (e.g. npm run axis -- status).

Local operator dashboard (axis dashboard)

For operators who'd rather click than type, axis dashboard starts a tiny localhost-only web page that does what the CLI does — list agents, grant / revoke / approve scopes, flag requires-approval, and tail the audit log — backed by small JSON endpoints on the same Node server. It reuses the exact same policy / store / scope / delegation logic as the CLI (policy.ts, tools/delegate.ts), so a grant from the page mints the same operator-signed delegation that axis grant does.

axis dashboard               # http://127.0.0.1:7878/?token=…  (auto-opens the browser)
axis dashboard --port 9000   # pick a port
axis dashboard --no-open     # don't auto-open the browser

Security: the server binds 127.0.0.1 only (never 0.0.0.0), so it is not reachable from other machines. A random per-session token is minted at start and embedded in the printed URL; every control endpoint requires it (header x-axis-token or ?token=), and mutating endpoints additionally reject cross-site requests (same-origin / Sec-Fetch-Site guard) — so a random web page open in the same browser can't drive your local permission state. The dashboard is for the human operator; it's distinct from the stdio MCP server (which serves the agent's LLM), and both share ~/.axis-mcp.

Permission model. axis grant <scope> writes the scope into ~/.axis-mcp/policy.json and mints/refreshes an operator-signed delegation covering the agent's full granted set. axis_present and axis_delegate then refuse to mint or sign for any scope that isn't granted (clear error pointing at axis grant). Scopes flagged axis require-approval are deny-by-default until axis approve. The scope grammar is AXIS v0.3 (resource:action, with resource:* and * wildcards); malformed scopes are rejected with a did-you-mean hint.

Operator-key local custody

axis operator-key init generates an operator Ed25519 keypair (distinct from the agent identity key, in a separate keychain account). Registering the public key with the registry via POST /operators/:id/key is registrar-authenticated and proof-bearing, so it follows whichever registry the MCP points at — cloud or your own (see Self-hosting). Either way grants are operator-signed locally regardless of registration; registration only enables third parties to verify the delegation proof against a registry-held key.

One-click onboarding registers the operator key too. You don't have to run axis operator-key init separately: axis_request_onboarding ensures the operator key exists and carries its public key + a registration proof (operator_pubkey, operator_proof) into the activation link. When the operator signs in, the registrar registers it via POST /operators/:id/key — so the operator key is registry-verifiable from the same one-click flow. The proof is an Ed25519 signature over the RFC 8785 JCS canonicalization of { publicKey } (proofType jcs-eddsa-2026), the same regime the registry uses for POST /register. This path is live — the registrar reads those params from the link and registers the operator key during onboarding. The registrar's outcome (registered / conflict / pending) is surfaced as operator_key_status by axis_complete_onboarding and in axis_status.

Self-hosting against your own registry

Self-host mode behaves exactly like cloud: you run your own axis-registry instance (your own ledger) and register operator keys through a registrar credential in that instance — the same code path as registry.axisprime.ai.

  1. Deploy axis-registry and seed a registrar row (the shipped seed-key.sql gives you a one-time registrar API key).
  2. Point the MCP at it, supply that key, then provision the operator key:
    export AXIS_REGISTRY_URL=https://registry.example.com   # or http://localhost:8787
    export AXIS_REGISTRAR_API_KEY=<your registrar key>
    axis operator-key init

The MCP registers your operator public key directly (registrar Bearer + JCS-EdDSA proof of ownership). Without AXIS_REGISTRAR_API_KEY the command still provisions and holds the key locally but skips registry registration — a no-registrar write to the central registry is correctly refused, so use the cloud one-click onboarding for that path.

Key custody (LOCAL mode)

The agent's Ed25519 identity key is generated on this machine and stored in the OS keychain (via keytar). If the keychain is unavailable, it falls back to an AES-256-GCM-encrypted file under ~/.axis-mcp/. The private key is never returned by any tool and never leaves the machine.

Disclosure (always surfaced by axis_status and onboarding): Your agent's identity key is stored on this computer. Anyone who can use this computer can act as your agent.

Every present/sign action is recorded to a local append-only signed audit log at ~/.axis-mcp/audit.jsonl (default-on).

Run

npm install
npm run build      # tsc → dist/
npm start          # node dist/server.js  (stdio transport)
# or, no build step:
npm run dev        # tsx src/server.ts

Register with an MCP client

claude_desktop_config.json (or any MCP client config):

{
  "mcpServers": {
    "axis": {
      "command": "node",
      "args": ["C:/Users/josha/dev/axis-mcp/dist/server.js"]
    }
  }
}

Environment overrides

| Var | Default | Purpose | |---|---|---| | AXIS_REGISTRY_URL | https://registry.axisprime.ai | Registry base URL. | | AXIS_REGISTRAR_URL | https://signup.axisprime.ai | Registrar base for onboarding links (live). | | AXIS_REGISTRAR_API_KEY | (unset) | Self-host only. A registrar key seeded in your own registry so the MCP can register the operator key and delegations directly against AXIS_REGISTRY_URL (Bearer + proof). Unset on the cloud path. (AXIS_REGISTRAR_KEY is accepted as an alias.) | | AXIS_DELEGATION_REGISTRAR_URL | (unset) | Product path for delegation registration. A cloud registrar mint endpoint that holds the registrar key server-side; the MCP POSTs the operator-signed delegation to it, so no registrar credential lives on the operator's machine. Preferred over AXIS_REGISTRAR_API_KEY when set. | | AXIS_COMMENTS_GATE_URL | https://axis-comments.editor-9a4.workers.dev | Comment gate base for post_comment on the axis-comments-ghost audience (until AXIS discovery advertises an actions manifest). | | AXIS_MCP_HOME | ~/.axis-mcp | Local data home (audit log, key fallback, metadata, policy). | | AXIS_MCP_DISABLE_KEYCHAIN | (unset) | Set to 1 to force the encrypted-file key fallback (never the OS keychain). Used by the test suite; available where the keychain is undesirable. | | AXIS_HTTP_TIMEOUT_MS | 30000 | Registry / well-known fetch timeout. |

Tests

npm test           # all (unit + live registry + server smoke)
npm run test:unit  # offline: present/delegate signing round-trips
npm run test:live  # hits registry.axisprime.ai public read endpoints

See BUILD-STATUS.md for what's verified and the registrar onboarding contract.

License

TBD. No license is set yet (this repo is private). Likely Apache 2.0 to match the open AXIS stack (protocol, registry, SDK); but MUST be MIT / MIT-0 if this is published as a ClawHub skill (ClawHub external mandate). Decide before the repo goes public or is published (GitHub / npm / ClawHub). Tracked in the Cross-Project Coordination DB (Notion).