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

@topolo/mcp

v0.14.31

Published

Model Context Protocol server for the Topolo platform. Exposes scope-gated tools that third-party agents (Claude, Codex, etc.) can call natively.

Readme

TopoloMCP

Model Context Protocol server for the Topolo platform. Lets MCP-capable agents (Claude Desktop, Claude Code, Codex, Cursor, etc.) call Topolo APIs as native tools rather than shelling out.

Why both a CLI and an MCP server?

  • The CLI (@topolo/cli) is for humans, shell scripts, and agents without MCP support.
  • The MCP server (@topolo/mcp) is for agents that speak the protocol natively — it gives them typed tool schemas, scope-filtered tool advertisement, and structured error responses. Both wrap the same @topolo/sdk.

Install and register

npm install -g @topolo/cli
topolo setup
topolo auth login
topolo doctor

Customers install only @topolo/cli; it owns an exact compatible MCP and SDK. topolo setup registers the resolved local Node entry point, so agent startup does not depend on npx, network access, or a separately synchronized package.

Register an accountable agent installation

For Codex, Claude, and other persistent agent hosts, register the host once from an organization context:

topolo installations register \
  --name "Codex on my workstation" \
  --provider openai \
  --host codex \
  --grant app_topolo_agent:actions

The CLI creates an accountable external principal, generates a device-local DPoP key, stores the client secret and private key in the operating system's protected credential store, and configures the host with only TOPOLO_AGENT_INSTALLATION_ID. The MCP exchanges short-lived credentials for the exact service, task, and resource being accessed. No reusable secret is written to Codex or Claude configuration.

Human OAuth contexts and explicit API keys remain supported for interactive and compatibility use, but they are never used as a fallback when an installation ID is configured.

Register with an MCP client

Run topolo setup; it configures Claude Code and Codex with an absolute Node entry point resolved from the installed CLI dependency graph. Advanced hosts may execute the exported @topolo/mcp/stdio entry directly, but customer setup must not use an npx launcher because that makes startup network-dependent.

Hosted HTTP transport

@topolo/mcp/http exports createTopoloMcpHttpHandler, an MCP Streamable HTTP handler over Web-Standard Request/Response. Every request carries its own credential (Authorization: Bearer <access token> or X-Api-Key: <key>); there is no process-wide credential and no fallback. A request without a usable credential answers 401.

import { createTopoloMcpHttpHandler } from '@topolo/mcp/http';

const handler = createTopoloMcpHttpHandler({
  environment: 'production',
  sessionMode: 'stateless',
});
export default { fetch: handler.fetch };

sessionMode chooses how MCP sessions are held:

  • 'stateful' (default) keeps an in-memory Mcp-Session-Id registry bound to the credential that created each session. Every request of a session must reach the same process, so use it only for one long-lived process.
  • 'stateless' serves every POST with a fresh server built from that request's credential, answers with JSON, issues no session id and keeps nothing after the response. Any instance can answer any request, so use it in a Cloudflare Worker or behind a load balancer without session affinity. GET and DELETE answer 405 with Allow: POST.

The hosted Topolo endpoint runs this handler in stateless mode from the Topolo-io/TopoloMCPHost Worker.

Shared local hub (@topolo/mcp/local)

Every stdio registration is its own Node process. A machine with many agent threads and many pinned identities therefore runs threads x identities MCP processes. topolo mcp serve (in @topolo/cli) replaces them with ONE loopback process that mounts each identity at /mcp/<name>; topolo setup --shared registers those URLs with Claude Code and Codex. See the CLI README for setup, security and the exact host configuration.

This package supplies the per-identity handler the hub mounts:

import { createTopoloMcpLocalHandler } from '@topolo/mcp/local';

const handler = createTopoloMcpLocalHandler({
  identity: { environment: 'production', context: 'org:org_topolo' },
  agentName: 'codex',
});
const response = await handler.fetch(request); // Web-standard Request/Response
  • Same credential path as stdio. The identity resolves its credential from the local store exactly as a stdio server pinned with TOPOLO_ENV + TOPOLO_CONTEXT does (omit context only when the environment has a single signed-in context; with several the handler refuses), including refresh before expiry and a forced refresh plus retry on 401. It never reads TOPOLO_API_KEY/TOPOLO_ACCESS_TOKEN, TOPOLO_CONTEXT, TOPOLO_AGENT_INSTALLATION_ID or request headers, so one process can serve many identities without any of them borrowing another's credential.
  • One handler per identity. A handler owns its identity's client, scopes and cache; nothing is shared between handler instances.
  • Stateless Streamable HTTP. Each POST gets a fresh MCP server over the identity's cached ready state (re-resolved every five minutes, or after invalidate()), with JSON responses and no Mcp-Session-Id, so a hub restart never strands a client on a lost session. GET/DELETE answer 405.
  • Ended sign-in. As with stdio, an identity whose saved sign-in needs re-authorization is not an outage: it serves topolo_reauthorization_status and every tool call returns a structured reauth_required result with the verification link, user code and sign-in command (SSE responses). Each request re-checks only that identity's approval. Once approved, requests get the full tool set; a call to the status tool answers reauthorized and carries notifications/tools/list_changed, so the host re-lists without a restart.
  • Failures. A missing or rejected credential, or a public refusal such as an unpinned context with several signed in, answers 503 with its message; anything else answers a generic 500. Neither is cached.
  • No transport security of its own. The hub that mounts the handler owns loopback binding, its bearer token and Host/Origin checks. Do not expose a local handler on a network interface.

Protected action handoff

Local stdio action results return topolo-secret:<id> references instead of bearer credentials. Pass these references unchanged to subsequent published actions; SDK 0.21.4 resolves nonempty string credentials internally using the OS protected store and masks them in plans and diagnostics. Entries are bound to the verified principal, organization, API key identity when present, and environment. References expire after 30 minutes; accessing an expired entry deletes it. Release finished workflow references with topolo_release_action_secret and confirm: true. This deletes local storage only, not the upstream grant. HTTP/Worker hosts remain redacted unless they explicitly configure a protected SDK store; local references cannot be transferred to a different host.

Supported env vars

| Var | Purpose | | ---------------------------- | ----------------------------------------------------- | | TOPOLO_API_KEY | Platform API key (preferred) | | TOPOLO_ACCESS_TOKEN | Short-lived JWT (dev/testing) | | TOPOLO_ENV | Credential environment (production by default) | | TOPOLO_CONTEXT | Pin one stored personal/org context without activating it | | TOPOLO_AGENT_INSTALLATION_ID | Use a protected accountable agent installation | | TOPOLO_AGENT_TASK_ID | Optional stable host task identifier | | TOPOLO_AGENT_NAME | Human-readable agent label for audit logs | | TOPOLO_SERVICE_URL_<ID> | Override a service base URL (e.g. _AUTH, _MAIL) |

An installation ID cannot be combined with a human context, API key, or access token. The MCP rejects ambiguous configuration instead of choosing one.

For concurrent organization or environment operation, run one named MCP server per stored context. TOPOLO_CONTEXT accepts an exact key from topolo context list --json (for example personal or org:org_topolo) or a unique stored organization id, slug, or name. The server reads and refreshes that credential without changing the CLI's active context, so separate agent processes cannot race one shared context pointer.

No implicit default context. Without TOPOLO_CONTEXT, the server uses the environment's stored context only while it is the only one signed in. Once several contexts are signed in for the environment, it refuses to start and asks for a pin, because the stored active context is just whichever sign-in happened last:

{
  "mcpServers": {
    "topolo-topolo": {
      "command": "topolo-mcp",
      "env": { "TOPOLO_ENV": "production", "TOPOLO_CONTEXT": "org:org_topolo" }
    },
    "topolo-personal": {
      "command": "topolo-mcp",
      "env": { "TOPOLO_ENV": "production", "TOPOLO_CONTEXT": "personal" }
    }
  }
}

Do not combine TOPOLO_CONTEXT with an injected API key or access token: those credentials already carry their own immutable context.

Startup sequence

  1. Resolve a protected installation, injected credential, pinned stored context, or the environment's active stored credential. Refuse to start if none is available. Installation mode exchanges a short-lived Auth token bound to the MCP task, organization, and local DPoP key.
  2. Call GET /api/me to load the user's granted scopes + role.
  3. Connect the stdio transport and begin serving MCP requests.
  4. Advertise a fixed, bounded discovery/invocation surface. Agents search one application at a time and call exact action IDs; the server never expands one MCP tool per action or materializes the global catalog.

Startup is synchronous and fast (< 500 ms typical). If the credential is rejected, the process logs the error to stderr and exits non-zero — host clients surface that as a failed server launch.

Data privacy boundary

TopoloMCP is a transport adapter and does not persist customer data. It has no database, KV, R2, Durable Object, filesystem-write, analytics, or log-storage binding. Credentials remain in the caller-owned environment, shared CLI credential store, or operating-system protected installation store. Installation secrets and private keys are never copied into MCP host configuration. Every request is authorized by the target Topolo service.

Only messages raised by TopoloMCP's own input validators are returned verbatim. Authentication, SDK, provider, session-construction, and unexpected runtime errors are replaced with stable non-sensitive messages before they reach MCP responses or stderr. Target services remain responsible for retention, export, deletion, encryption, and audit storage for the data they own.

Tools

| Tool | Required scopes | Destructive hint | | ---------------------------- | --------------------- | ---------------- | | topolo_whoami | (none) | no | | topolo_search_applications | (none) | no | | topolo_get_application | (none) | no | | topolo_get_resource_types | credential-scoped | no | | topolo_list_resources | credential-scoped | no | | topolo_search_actions | (credential-scoped) | no | | topolo_discover_capabilities | credential-scoped | no | | topolo_get_action | (credential-scoped) | no | | topolo_get_action_examples | credential-scoped | no | | topolo_validate_action | credential-scoped | no | | topolo_plan_action | credential-scoped | no | | topolo_prepare_action | credential-scoped | no | | topolo_read_action | catalog or target policy | no | | topolo_call_action | catalog or target policy | yes | | topolo_run_agent | Agent runtime policy | yes | | topolo_upload_action | catalog or target policy | yes | | topolo_list_workspaces | target app runtime policy | no | | topolo_create_workspace | target app runtime policy | yes | | topolo_rename_workspace | target app runtime policy | yes | | topolo_set_default_workspace | target app runtime policy | yes | | topolo_api_call | (service-enforced) | yes |

Applications publish machine-action definitions through Topolo Developers. TopoloAuth projects those into a credential-scoped action catalog using the same service permissions already used for API keys and application access. MCP keeps six stable application/action tools regardless of whether the platform contains ten actions or one billion: search applications, search actions within one app, inspect exact applications/actions, safely invoke automatic reads, and invoke confirmation-gated actions.

Most actions use authorizationMode: static and are filtered by one declared application permission before discovery. Operations whose authority depends on request input (for example, organization admin OR grants:write in the target application) use authorizationMode: runtime: the catalog exposes the typed capability without inventing a global permission, and the target service checks the current database-backed policy for the supplied organization/application on every call.

Workspace lifecycle is first-class so agents do not have to know that Auth is the canonical owner. The tools accept the target application, derive the organization from the credential, and retain Auth's per-app runtime decision. topolo_list_workspaces exposes policy.canCreate and policy.reason; the write tools never infer access from organization ownership.

topolo_api_call is the escape hatch for endpoints without typed MCP tools yet. GET requests work without confirmation; mutating HTTP methods must pass confirm: true or the SDK rejects the call. Backing services still enforce permissions for every request. The tool schema intentionally does not embed a large service enum; agents should call topolo_search_applications first, then pass an app ID/slug from that credential-scoped result. New services become callable without an MCP release once Auth grants the organization and credential the relevant permissions, and new actions become discoverable/callable without an MCP release once the application publishes them.

topolo_read_action and topolo_call_action accept an optional paired resourceType / resourceId context that scopes the call to one workspace (or another cataloged resource alias). Workspaces are platform-owned — the record lives once in TopoloAuth and a workspace belongs to exactly one app — so this only selects which workspace the call is scoped to; it does not create or own one. The SDK sends it as resource headers without changing the credential's personal or organization context. This lets agents address many workspaces independently; providing only one of the pair is rejected before the request is sent.

topolo_run_agent is the bounded external-harness path for Codex, Claude, and other MCP clients. It creates or replays one invocation using the caller's stable idempotencyKey, polls the same invocation, and returns either its terminal result or state: "approval_required" with the exact Topolo verification URL. Calling it again with the same input resumes the durable invocation instead of starting duplicate work.

Safety rails

  • No orgId parameter on any tool. The organization is derived entirely from the credential by each backend app. There is no path for Org A's agent to see Org B's data.
  • Credential-bound context. OAuth tokens and refresh rotation retain their own personal/org context. CLI/MCP context switches do not move the user's web session, and browser switches cannot redirect a running agent credential.
  • Scope-gated tool advertisement. Static actions are removed unless their permission is granted. Input-dependent runtime actions remain discoverable and are authorized by the target service for the concrete request.
  • Credential-scoped catalog discovery. topolo_search_applications uses TopoloAuth's live organization/permission catalog. They do not expose the global generated platform catalog.
  • Credential-scoped action discovery. topolo_search_actions reads only one app partition and returns at most 100 permission-filtered actions per page. Search, capability discovery, validation, and planning return compact agent guidance by default; pass detail: true only when full contracts are needed.
  • Audit headers. Every request sends X-Topolo-Client: topolo-mcp/<ver>, X-Topolo-Agent: <label>, X-Topolo-Request-Id: <uuid>.
  • Write-action confirmation. The SDK refuses mutating HTTP methods unless the call explicitly passes confirm: true. Mutating action tools require the host client to approve before invocation.

Troubleshooting

  • "TOPOLO_API_KEY or TOPOLO_ACCESS_TOKEN must be set" — no credential reached the subprocess. In Claude Desktop, double-check the env block in claude_desktop_config.json. In Claude Code, the server inherits your shell env, so make sure the var is exported in the profile your launcher reads.

  • "credential rejected" — token is expired or revoked. For API keys, mint a fresh one. For access tokens, re-run topolo auth login and copy the new token.

  • Tool missing from the list — the credential doesn't grant the required scope. Check topolo whoami to see the current scopes; either broaden the API key's permissions or switch to one that already has them.

  • Tool call returns Permission denied — the scope check on the backend disagrees with startup introspection (rare, but possible across scope changes). Re-spawn the server to refresh the cached scope set.

  • Optional --provenance on npm publish once the repo is public.