{"_id":"@braedonsaunders/appkit-mcp","name":"@braedonsaunders/appkit-mcp","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@braedonsaunders/appkit-mcp","version":"0.1.0","description":"Expose an app's governed tool catalogue over the Model Context Protocol — framework-neutral streamable-HTTP handling, request-boundary validation, gated tool registration with audit hooks, and static resources.","license":"AGPL-3.0-or-later","type":"module","exports":{".":{"types":"./index.d.ts","import":"./index.js","default":"./index.js"},"./package.json":"./package.json"},"main":"./index.js","types":"./index.d.ts","dependencies":{"@modelcontextprotocol/sdk":"^1.30.0"},"peerDependencies":{"zod":"^4.0.0"},"author":{"name":"Braedon Saunders"},"repository":{"type":"git","url":"git+https://github.com/braedonsaunders/appkit.git","directory":"packages/mcp"},"homepage":"https://github.com/braedonsaunders/appkit/tree/main/packages/mcp#readme","bugs":{"url":"https://github.com/braedonsaunders/appkit/issues"},"engines":{"node":">=22"},"keywords":["agents","appkit","application-framework","mcp","model-context-protocol","tools","typescript"],"_id":"@braedonsaunders/appkit-mcp@0.1.0","_integrity":"sha512-OV9oe/wBl4S7tC7/4y4mTxH17QQlDn32yGDA22Nmw4QsXjtQid4mG0DLikOe97jMfIA1ghrzJlp5DyBTK1OuYQ==","_resolved":"/tmp/f2e78dabd11d91a9da8376995fc76342/braedonsaunders-appkit-mcp-0.1.0.tgz","_from":"file:braedonsaunders-appkit-mcp-0.1.0.tgz","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-OV9oe/wBl4S7tC7/4y4mTxH17QQlDn32yGDA22Nmw4QsXjtQid4mG0DLikOe97jMfIA1ghrzJlp5DyBTK1OuYQ==","shasum":"72e8a087c8df3c782797adcb37dd49f3e5808660","tarball":"https://registry.npmjs.org/@braedonsaunders/appkit-mcp/-/appkit-mcp-0.1.0.tgz","fileCount":27,"unpackedSize":84962,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@braedonsaunders%2fappkit-mcp@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFGSdQ9caWbUM/5fXArXgwJT9XoGPBq31oGXobF5dk6fAiEAkWRoh2uGlfo27OCnQz1qCxAm9F+Zfotg/9iNbYHqjFA="}]},"_npmUser":{"name":"braedonsaunders","email":"bsaunders@rassaun.com"},"directories":{},"maintainers":[{"name":"braedonsaunders","email":"bsaunders@rassaun.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/appkit-mcp_0.1.0_1787095322387_0.254259399739613"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-18T23:22:02.188Z","0.1.0":"2026-08-18T23:22:02.520Z","modified":"2026-08-18T23:22:02.981Z"},"maintainers":[{"name":"braedonsaunders","email":"bsaunders@rassaun.com"}],"description":"Expose an app's governed tool catalogue over the Model Context Protocol — framework-neutral streamable-HTTP handling, request-boundary validation, gated tool registration with audit hooks, and static resources.","homepage":"https://github.com/braedonsaunders/appkit/tree/main/packages/mcp#readme","keywords":["agents","appkit","application-framework","mcp","model-context-protocol","tools","typescript"],"repository":{"type":"git","url":"git+https://github.com/braedonsaunders/appkit.git","directory":"packages/mcp"},"author":{"name":"Braedon Saunders"},"bugs":{"url":"https://github.com/braedonsaunders/appkit/issues"},"license":"AGPL-3.0-or-later","readme":"# @braedonsaunders/appkit-mcp\n\nExpose an app's governed tool catalogue over the Model Context Protocol.\n\nThe design rule this package enforces: **the agent surface is a thin adapter\nover the same gated engines the app already uses, never a parallel API.** An\napp defines its capabilities once as a catalogue; MCP registration, transport\nhandling, boundary defence, and audit are the reusable part. A tool the caller\nmay not use is never registered — the model cannot see it, so it cannot ask\nfor it. Everything a tool throws passes through one error mapper; anything the\nmapper declines collapses to a generic failure, so stack frames, SQL, and\nsecrets can never reach the model by accident.\n\nFramework-neutral: everything speaks web-standard `Request`/`Response`, so the\nsame handler serves Next.js route handlers, Hono, Bun, or plain Node.\n\n## The pieces\n\n| Module | What it owns |\n| --- | --- |\n| `catalog` | `McpCatalogTool` — one entry in the app's canonical capability catalogue — and `registerToolCatalog`, which registers only the visible ones, wraps execution in the result contract, times it, and reports every call to an audit hook. |\n| `handler` | `handleStreamableHttpRequest` — one stateless streamable-HTTP exchange: fresh transport, auth info forwarded, `X-Request-ID` + `no-store` stamped, transport and server always torn down. `resolveMcpRequestId` accepts a well-formed caller id and replaces anything else. |\n| `boundary` | Host validation (DNS-rebinding defence) and cross-origin allowlisting, plus JSON-RPC error responses, CORS preflight, and 405. |\n| `result` | `mcpSuccess` / `mcpFailure` and the `McpErrorMapper` seam. |\n| `resources` | `registerStaticResources` — ship ground rules, playbooks, and live schemas as readable resources, so an agent learns the app's doctrine from the surface itself. |\n\n## Usage\n\n```ts\nimport {\n  handleStreamableHttpRequest,\n  mcpBoundaryResponse,\n  registerStaticResources,\n  registerToolCatalog,\n  resolveMcpRequestId,\n} from '@braedonsaunders/appkit-mcp'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\n\nexport async function POST(request: Request): Promise<Response> {\n  const rejected = mcpBoundaryResponse(request, { allowedOrigins: TRUSTED_ORIGINS })\n  if (rejected) return rejected\n\n  const auth = await authenticate(request)          // the app's own auth\n  const server = new McpServer({ name: 'my-app', version: VERSION }, { instructions })\n\n  registerToolCatalog(server, TOOL_CATALOG, {\n    context: appContext(auth),                      // tenant + RBAC-bound\n    mapError: (e) => (e instanceof AppError ? { code: e.code, message: e.message } : null),\n    audit: (event) => auditLog(auth, event),\n  })\n  registerStaticResources(server, PLAYBOOKS)\n\n  return handleStreamableHttpRequest(request, {\n    server,\n    requestId: resolveMcpRequestId(request),\n    authInfo: { token: auth.keyId, clientId: auth.clientId, scopes: auth.scopes },\n  })\n}\n```\n\n## What stays in the app\n\nAuthentication, rate limiting, the catalogue itself, and every domain rule.\nTools must terminate in the app's governed services — permissions, validation,\nidempotency, period locks — so the MCP surface can never do something a normal\nAPI caller could not, and the agent acts *as the authenticated user*, never as\nthe platform.\n","readmeFilename":"README.md","_rev":"1-645f0d64b09ccf3577c9025682937c36"}