{"_id":"@ai-agent-ledger/mcp-gateway","name":"@ai-agent-ledger/mcp-gateway","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@ai-agent-ledger/mcp-gateway","version":"0.1.0","description":"Policy enforcement, tamper-evident audit trail, and kill switch for any MCP server — a drop-in governance proxy","repository":{"type":"git","url":"git+https://github.com/Esammy/agentledger-mcp-gateway.git"},"bugs":{"url":"https://github.com/Esammy/agentledger-mcp-gateway/issues"},"homepage":"https://github.com/Esammy/agentledger-mcp-gateway#readme","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"bin":{"agentledger-mcp-gateway":"dist/cli.js"},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","ci:local":"npm run typecheck && npm run build && npm test","prepublishOnly":"node -e \"const d=require('./package.json').dependencies['@ai-agent-ledger/sdk']; if(d.startsWith('file:')){console.error('ERROR: set @ai-agent-ledger/sdk to a published semver range (e.g. ^0.3.0) before publishing.');process.exit(1)}\" && npm run build"},"keywords":["mcp","model-context-protocol","mcp-server","mcp-proxy","ai-agents","governance","guardrails","audit","policy","kill-switch","ai-safety","llm-security"],"license":"MIT","dependencies":{"@ai-agent-ledger/sdk":"0.3.0","@modelcontextprotocol/sdk":"^1.29.0","ws":"^8.18.0"},"devDependencies":{"@types/node":"^20.0.0","@types/ws":"^8.0.0","tsup":"^8.0.0","typescript":"^5.4.0","vitest":"^1.6.0"},"engines":{"node":">=18.0.0"},"_id":"@ai-agent-ledger/mcp-gateway@0.1.0","gitHead":"8377718a0a86ff0f2421f53c23c0610e439a5ffd","_nodeVersion":"21.7.3","_npmVersion":"10.5.0","dist":{"integrity":"sha512-/HKSLHbe244C2mxA06IHRCOYV19XKff6HGCjVvzGmDpBwDSLHXz4WaiSv/ZWpFjGuH0jak7xKKmD+z4bD0KaoA==","shasum":"f8540a2c0ec4dd96392d41ca4f92e09755f7a2f0","tarball":"https://registry.npmjs.org/@ai-agent-ledger/mcp-gateway/-/mcp-gateway-0.1.0.tgz","fileCount":9,"unpackedSize":71375,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIH7AKLV5WHGUpz83SYr9EX22ZGFxfn3oiZ7H1NcETf/UAiBCR2I1bipd9ra0YVfQLJCajoMjP4aBxOKK1iC2Lc5gXA=="}]},"_npmUser":{"name":"esammy","email":"egwusamuel2015@gmail.com"},"directories":{},"maintainers":[{"name":"esammy","email":"egwusamuel2015@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-gateway_0.1.0_1783789857632_0.045069140118632056"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-11T17:10:57.492Z","0.1.0":"2026-07-11T17:10:57.762Z","modified":"2026-07-11T17:10:57.967Z"},"maintainers":[{"name":"esammy","email":"egwusamuel2015@gmail.com"}],"description":"Policy enforcement, tamper-evident audit trail, and kill switch for any MCP server — a drop-in governance proxy","homepage":"https://github.com/Esammy/agentledger-mcp-gateway#readme","keywords":["mcp","model-context-protocol","mcp-server","mcp-proxy","ai-agents","governance","guardrails","audit","policy","kill-switch","ai-safety","llm-security"],"repository":{"type":"git","url":"git+https://github.com/Esammy/agentledger-mcp-gateway.git"},"bugs":{"url":"https://github.com/Esammy/agentledger-mcp-gateway/issues"},"license":"MIT","readme":"# AgentLedger MCP Gateway 🛡️⛓️\n\n**Policy enforcement, tamper-evident audit trail, and kill switch for any MCP server. One line in your config.**\n\nPut the gateway in front of any [Model Context Protocol](https://modelcontextprotocol.io) server and every tool call is policy-checked *before* it executes, recorded in a SHA-256 hash chain you can verify later, and stoppable mid-session with an HTTP kill switch. The wrapped server needs zero changes — the agent doesn't even know the gateway is there.\n\n```\nMCP client (Claude Desktop / Claude Code / Cursor / your agent)\n        │  stdio\n        ▼\n  agentledger-mcp-gateway      ← policies · audit chain · kill switch · risk scoring\n        │  stdio\n        ▼\n  any MCP server (filesystem, github, postgres, stripe, your own…)\n```\n\n## Quick start (Claude Desktop / Claude Code / Cursor)\n\nWrap the server you already use. Before:\n\n```json\n{\n  \"mcpServers\": {\n    \"filesystem\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"C:/work\"]\n    }\n  }\n}\n```\n\nAfter — same server, now governed:\n\n```json\n{\n  \"mcpServers\": {\n    \"filesystem\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\", \"@ai-agent-ledger/mcp-gateway\",\n        \"--policies\", \"C:/work/policies.json\",\n        \"--ledger\", \"C:/work/audit.ndjson\",\n        \"--dashboard\", \"4000\",\n        \"--\",\n        \"npx\", \"-y\", \"@modelcontextprotocol/server-filesystem\", \"C:/work\"\n      ]\n    }\n  }\n}\n```\n\nEverything after `--` is the original server command, unchanged.\n\n## Write policies three ways\n\n`policies.json` is an array; mix and match:\n\n```json\n[\n  { \"template\": \"no_delete\" },\n  { \"template\": \"no_spend_over\", \"args\": [500] },\n\n  {\n    \"id\": \"no-env-reads\",\n    \"description\": \"Block reads of .env files\",\n    \"action\": \"block\",\n    \"severity\": \"critical\",\n    \"conditions\": [\n      { \"type\": \"tool_match\", \"tools\": [\"read_file\", \"read_text_file\"] },\n      { \"type\": \"arg_contains\", \"path\": \"[0].path\", \"pattern\": \".env\" }\n    ]\n  },\n\n  {\n    \"description\": \"Require human approval before any email to an address outside mycompany.com\",\n    \"action\": \"approve_gate\",\n    \"severity\": \"high\"\n  }\n]\n```\n\n1. **Templates** — built-ins from the SDK: `no_delete`, `no_spend_over(n)`, `external_email_gate(domain)`, `business_hours_only(start, end)`, `pii_write_alert(channels)`.\n2. **Raw rules** — deterministic condition ASTs (`tool_match`, `arg_contains`, `arg_gt`, `time_outside`, `data_classification`, …). No LLM anywhere.\n3. **Natural language** — compiled **once at startup** into a raw rule via whichever key you have set: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GROQ_API_KEY`, or `GEMINI_API_KEY`. Zero LLM calls at enforcement time.\n\nA blocked call returns a normal tool error to the agent (`isError: true` with the policy reason), so the agent adapts instead of crashing.\n\n## Kill switch\n\nStart with `--dashboard 4000` and you get a local REST + WebSocket dashboard server:\n\n```bash\n# Halt this session — the very next tool call throws, mid-conversation\ncurl -X POST http://localhost:4000/runs/<run_id>/kill\n\n# Live-stream every tool call, block, and escalation\nwebsocat ws://localhost:4000/\n\n# Re-verify the hash chain over everything recorded\ncurl http://localhost:4000/runs/<run_id>/verify\n```\n\nThe gateway prints the exact kill-switch `curl` (with the session `run_id`) to stderr at startup. Add `--dashboard-token <secret>` before exposing the port beyond localhost.\n\n## Tamper-evident audit\n\nEvery tool call, policy block, and approval gate is appended to an NDJSON ledger where each entry's id is a SHA-256 over the entry *including* the previous entry's id. Editing, deleting, reordering, or truncating entries breaks verification — and verification tells you where and how:\n\n```ts\nimport { verifyChain } from '@ai-agent-ledger/sdk'\n// { valid: false, broken_at: 3, reason: 'link_broken', runs: [...] }\n```\n\n## All options\n\n```\nagentledger-mcp-gateway [options] -- <child server command> [args...]\n\n--policies <path>         policies.json (templates, raw rules, natural language)\n--ledger <path>           audit NDJSON file (default ./agentledger-audit.ndjson)\n--agent-id <id>           agent id recorded in ledger entries (default mcp-gateway)\n--run-id <id>             session run id (default: generated UUID)\n--dashboard <port>        REST kill switch + WebSocket live feed\n--dashboard-token <tok>   require X-AgentLedger-Token on dashboard requests\n--name <name>             server name advertised to the client\n```\n\n## Programmatic use\n\n```ts\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js'\nimport { AgentLedger, POLICY_TEMPLATES } from '@ai-agent-ledger/sdk'\nimport { createGatewayServer } from '@ai-agent-ledger/mcp-gateway'\n\nconst ledger = new AgentLedger({\n  agent_id: 'my-gateway',\n  storage: { type: 'file', path: './audit.ndjson' },\n  policies: [POLICY_TEMPLATES.no_spend_over(500)],\n})\n\nconst server = await createGatewayServer({ child: connectedClient, ledger, runId: 'session-1' })\n// connect `server` to any transport (stdio, in-memory, …)\n```\n\n## Try it in 60 seconds\n\n```bash\ngit clone https://github.com/Esammy/agentledger-mcp-gateway && cd agentledger-mcp-gateway\nnpm install && npm run build\nnode examples/e2e-smoke.mjs ./sandbox\n# → tools listed, write_file BLOCKED by policy, kill switch fired over HTTP,\n#   hash chain verified — against the real @modelcontextprotocol/server-filesystem\n```\n\n## What this is (and isn't)\n\n- ✅ Enforcement *before* execution — not observability after the fact.\n- ✅ Deterministic rules on the hot path (<2ms) — the only LLM involvement is optional, once, at startup.\n- ✅ Framework-agnostic — governs anything that speaks MCP.\n- ❌ Not a sandbox: the gateway governs the MCP channel. A malicious server binary can still do whatever your OS lets it do. Combine with OS-level sandboxing for untrusted code.\n\nResources and prompts pass through untouched (v0.1 governs `tools/call`).\n\nBuilt on [`@ai-agent-ledger/sdk`](https://github.com/Esammy/AgentLedgerSDK) — the same policies, interceptor, and ledger work directly inside LangChain/OpenAI/Anthropic agents without MCP.\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-df8790fe2e38e2786f3d6895557e2c6c"}