{"_id":"@bulwarkauth/mcp-auth","name":"@bulwarkauth/mcp-auth","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@bulwarkauth/mcp-auth","version":"0.1.0","description":"Bulwark authentication provider for MCP servers","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"devDependencies":{"@types/node":"^22.15.21","tsup":"^8.4.0","typescript":"^5.8.3","vitest":"^3.0.0"},"peerDependencies":{"@modelcontextprotocol/sdk":">=1.0.0"},"peerDependenciesMeta":{"@modelcontextprotocol/sdk":{"optional":true}},"license":"Apache-2.0","keywords":["bulwark","auth","authentication","identity","security","mcp","ai-agent","model-context-protocol","credential"],"repository":{"type":"git","url":"git+https://github.com/bulwarkauth/bulwark.git","directory":"sdk/mcp"},"homepage":"https://bulwarkauth.com","bugs":{"url":"https://github.com/bulwarkauth/bulwark/issues"},"publishConfig":{"access":"public"},"scripts":{"build":"tsup","test":"vitest run","typecheck":"tsc --noEmit","dev":"tsup --watch"},"_id":"@bulwarkauth/mcp-auth@0.1.0","_integrity":"sha512-Sp8I5Bx8sqSzWmplEdU+MN5zxMNYKcuaX344tVke8bMJWZ+LgddZrZ3xdZFbWOwz2OH4962v03LPz6jLZ82hJg==","_resolved":"/private/var/folders/bx/h_6976wn2vd66ptqpj1fb_n40000gn/T/72ac890c3c4c9b377ddc957bd591cbf8/bulwarkauth-mcp-auth-0.1.0.tgz","_from":"file:bulwarkauth-mcp-auth-0.1.0.tgz","_nodeVersion":"22.18.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-Sp8I5Bx8sqSzWmplEdU+MN5zxMNYKcuaX344tVke8bMJWZ+LgddZrZ3xdZFbWOwz2OH4962v03LPz6jLZ82hJg==","shasum":"42ce555d2fc4ed18ca92e2783e38bd6ae4b50599","tarball":"https://registry.npmjs.org/@bulwarkauth/mcp-auth/-/mcp-auth-0.1.0.tgz","fileCount":11,"unpackedSize":33473,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDIltUlCSesSTCOt7RELGiVx2brCfv9RXREa2MQ7sCRaAIhAI452vp5GpMiBMdemfElsKpBuqrOdvYMw0cng4OZFsvo"}]},"_npmUser":{"name":"ronai","email":"ron@techtapsolutions.com"},"directories":{},"maintainers":[{"name":"ronai","email":"ron@techtapsolutions.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-auth_0.1.0_1774166198705_0.3585256038535827"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-22T07:56:38.563Z","0.1.0":"2026-03-22T07:56:38.841Z","modified":"2026-03-22T07:56:39.313Z"},"maintainers":[{"name":"ronai","email":"ron@techtapsolutions.com"}],"description":"Bulwark authentication provider for MCP servers","homepage":"https://bulwarkauth.com","keywords":["bulwark","auth","authentication","identity","security","mcp","ai-agent","model-context-protocol","credential"],"repository":{"type":"git","url":"git+https://github.com/bulwarkauth/bulwark.git","directory":"sdk/mcp"},"bugs":{"url":"https://github.com/bulwarkauth/bulwark/issues"},"license":"Apache-2.0","readme":"# @bulwark/mcp-auth\n\nSecure authentication for MCP (Model Context Protocol) servers, powered by [Bulwark](https://bulwarkauth.com).\n\nDrop-in auth for any MCP server — 3 lines to integrate. Agents get scoped, time-limited credentials. Humans approve once. Everything is audited.\n\n## Why\n\nMCP servers connect AI agents to tools and data. But how do you authenticate those connections securely?\n\nMost MCP servers use hardcoded API keys or the developer's own credentials. This means:\n\n- No scoping (the agent has full access to everything the key allows)\n- No time limits (the key works forever)\n- No audit trail (no record of what the agent accessed)\n- No revocation (you can't stop access without rotating the key)\n\n`@bulwark/mcp-auth` fixes all of this.\n\n## Quick Start\n\n### Install\n\n```bash\nnpm install @bulwark/mcp-auth\n```\n\n### Integrate (3 lines)\n\n```typescript\nimport { BulwarkMCP } from \"@bulwark/mcp-auth\";\n\nconst bulwark = new BulwarkMCP();\n\nserver.tool(\n  \"query_database\",\n  bulwark.protect(async (params, context) => {\n    // Your tool logic here — Bulwark handles auth\n    const db = await bulwark.getCredential(\"database\");\n    return await db.query(params.sql);\n  }),\n);\n```\n\n### Configure\n\nSet these environment variables (or pass to constructor):\n\n| Variable            | Description                    | Required |\n| ------------------- | ------------------------------ | -------- |\n| `BULWARK_ENDPOINT`  | Bulwark API URL                | Yes      |\n| `BULWARK_AGENT_KEY` | Agent API key (`bwk_live_...`) | Yes      |\n| `BULWARK_TENANT_ID` | Tenant ID                      | Yes      |\n\n### Claude Desktop Example\n\n```json\n{\n  \"mcpServers\": {\n    \"my-server\": {\n      \"command\": \"npx\",\n      \"args\": [\"my-mcp-server\"],\n      \"env\": {\n        \"BULWARK_ENDPOINT\": \"https://api.bulwarkauth.com\",\n        \"BULWARK_AGENT_KEY\": \"bwk_live_abc123...\",\n        \"BULWARK_TENANT_ID\": \"your-tenant-id\"\n      }\n    }\n  }\n}\n```\n\n## How It Works\n\n1. **Agent registers** with Bulwark — gets an API key\n2. **User authorizes** — Bulwark issues a scoped, time-limited credential\n3. **MCP server uses** `protect()` — Bulwark verifies auth on every tool call\n4. **Credentials are proxied** — the agent never sees raw API keys\n5. **Session ends** — credentials auto-revoke\n\n```\nUser → Approves → Bulwark → Scoped Token → MCP Server → Tool\n                     |                          |\n                  Verifies                   Proxies credentials\n                  Audits                     Returns response\n```\n\n## API Reference\n\n### `BulwarkMCP`\n\nThe main class. Create one instance per MCP server.\n\n```typescript\nconst bulwark = new BulwarkMCP({\n  endpoint: \"https://api.bulwarkauth.com\",\n  agentKey: \"bwk_live_...\",\n  tenantId: \"tenant-uuid\",\n  defaultTTL: 900, // 15 minutes\n  defaultMaxUses: 100,\n});\n```\n\n#### `bulwark.protect(handler, options?)`\n\nWraps a tool handler with Bulwark authentication.\n\n```typescript\nserver.tool(\n  \"my_tool\",\n  bulwark.protect(\n    async (params, context) => {\n      // context.sessionId — current Bulwark session\n      // context.tenantId — tenant ID\n      return result;\n    },\n    {\n      services: [\"my-api\"],\n      operations: [\"read\"],\n      ttl: 600,\n    },\n  ),\n);\n```\n\n#### `bulwark.getCredential(service)`\n\nGets an authenticated credential for a service.\n\n```typescript\nconst cred = await bulwark.getCredential(\"github\");\n// cred.headers — auth headers to pass to the service\n```\n\n#### `bulwark.complete()`\n\nEnds the current session and revokes all credentials.\n\n### `BulwarkMCPClient`\n\nLower-level client for direct API access.\n\n```typescript\nimport { BulwarkMCPClient } from \"@bulwark/mcp-auth\";\n\nconst client = new BulwarkMCPClient({ endpoint, agentKey, tenantId });\nconst session = await client.createSession({ task: \"...\", ttl: 900 });\nconst result = await client.proxyRequest(session.id, {\n  service: \"api\",\n  method: \"GET\",\n  path: \"/data\",\n});\nawait client.completeSession(session.id);\n```\n\n## Security\n\n- Credentials are **never embedded** in tokens — they're injected server-side by Bulwark's credential proxy\n- Sessions are **time-limited** and **usage-limited**\n- All access is **audited** with full trail\n- Tokens support **Biscuit-style attenuation** — sub-agents get narrower permissions automatically\n\n## License\n\nApache 2.0\n\n## Links\n\n- [Bulwark Platform](https://bulwarkauth.com)\n- [Dashboard](https://app.bulwarkauth.com)\n- [Documentation](https://docs.bulwarkauth.com)\n- [API Reference](https://docs.bulwarkauth.com/api)\n","readmeFilename":"README.md","_rev":"1-baf8a3f50e3a47420f05e87d7fc5b757"}