{"_id":"@admissible-ai/mcp-gateway","name":"@admissible-ai/mcp-gateway","dist-tags":{"experimental":"0.1.0","latest":"0.1.0"},"versions":{"0.1.0":{"name":"@admissible-ai/mcp-gateway","version":"0.1.0","description":"Local Admissible authority gateway for MCP tool execution.","license":"MIT","type":"module","sideEffects":false,"main":"./dist/index.js","types":"./dist/index.d.ts","bin":{"admissible-mcp":"dist/cli.js"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc -p tsconfig.build.json","example:filesystem":"node --import tsx examples/filesystem-server/demo.ts","example:filesystem:direct-bin":"node --import tsx examples/filesystem-server/demo.ts examples/filesystem-server/admissible.direct-bin.mcp.yaml","example:github":"node --import tsx examples/github-disposable/demo.ts","example:github:mocked":"node --import tsx examples/github-disposable/demo.ts --mocked","example:mocked":"node --import tsx examples/mocked-server/demo.ts","prepack":"npm run build","smoke:pack-install":"node scripts/pack-install-smoke.mjs","test":"node --import tsx --test src/*.test.ts"},"publishConfig":{"access":"public"},"engines":{"node":">=18"},"keywords":["admissible","mcp","model-context-protocol","tools","authority"],"dependencies":{"@admissible-ai/sdk":"^0.1.0","@admissible-ai/types":"^0.1.0","js-yaml":"^4.3.0"},"_id":"@admissible-ai/mcp-gateway@0.1.0","gitHead":"dc8406de0a86891b83d87a9f8533aea48e01de82","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-QP0Dal4TuPyIM/XzFX9SZmIZUAzoDgEbGh07lnOj3HF/G9ZZbLk4kTSwct7SnivCKYDY3FnF76+tBByTfYAmqQ==","shasum":"6d3279b38d7cd1e8a1b287620bd5b9c119a151db","tarball":"https://registry.npmjs.org/@admissible-ai/mcp-gateway/-/mcp-gateway-0.1.0.tgz","fileCount":51,"unpackedSize":156807,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIE6muuzBqRQ7bGko9gU0qEqTAD1qRsxX6lWuolsQ7DwdAiEA8VrQpTcHQ5x73wAiHS2InYL2LLNIiuxWuDiMc/vq+uE="}]},"_npmUser":{"name":"tysonjeffreys","email":"tjeffreys@baselinelabs.io"},"directories":{},"maintainers":[{"name":"tysonjeffreys","email":"tjeffreys@baselinelabs.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-gateway_0.1.0_1783364811361_0.086506985639065"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-06T19:06:51.204Z","0.1.0":"2026-07-06T19:06:51.531Z","modified":"2026-07-06T19:06:51.731Z"},"maintainers":[{"name":"tysonjeffreys","email":"tjeffreys@baselinelabs.io"}],"description":"Local Admissible authority gateway for MCP tool execution.","keywords":["admissible","mcp","model-context-protocol","tools","authority"],"license":"MIT","readme":"# @admissible-ai/mcp-gateway\n\nStatus: experimental release candidate.\n\nThe Admissible MCP Gateway is a local authority gateway for MCP tool execution. It lets developers route MCP tool calls through Admissible before tools execute, with commit admission for state-changing Tool Contracts.\n\nMCP connects agents to tools. Admissible governs what those tools are allowed to do before execution.\n\n## What It Is\n\n- A local-first MCP gateway process.\n- A tool authority layer that maps MCP tool calls into Admissible `/v2/execute` operations.\n- A commit admission layer that maps state-changing MCP Tool Contracts into Admissible `/v2/commit` operations before server execution.\n- A Tool Contract resolver that gives every MCP tool an explicit local contract before execution.\n- A command-launched stdio proxy for local MCP servers.\n- A metadata-first adapter that avoids sending secrets or full sensitive payloads by default.\n- A v0 proof that denied MCP tool calls never reach the underlying MCP server.\n\n## What It Is Not\n\n- Not a hosted MCP security platform.\n- Not a dashboard.\n- Not a vulnerability scanner.\n- Not enterprise DLP or SIEM integration.\n- Not a replacement for the Admissible runtime authority layer.\n\n## Install\n\nAfter an explicit publish decision:\n\n```bash\nnpm install -g @admissible-ai/mcp-gateway\n```\n\n## Init\n\n```bash\nadmissible-mcp init\n```\n\n## Minimal Config\n\n```yaml\nadmissible:\n  baseUrl: https://api.admissible.io\n  apiKey: ${ADMISSIBLE_API_KEY}\n\ngateway:\n  mode: local-proxy\n  transport: stdio\n  metadataMode: metadata-first\n  manifestPath: .admissible/mcp-manifest.json\n  auditLogPath: .admissible/mcp-audit.jsonl\n\nservers:\n  filesystem:\n    command: npx\n    requestTimeoutMs: 30000\n    args:\n      - --yes\n      - --package\n      - \"@modelcontextprotocol/server-filesystem\"\n      - mcp-server-filesystem\n      - ./mcp-sandbox\n    authority:\n      scopes:\n        - ./mcp-sandbox/**\n      deny:\n        - ./mcp-sandbox/.env\n        - ./mcp-sandbox/secrets/**\n      approvalRequired:\n        - ./mcp-sandbox/allowed-output/**\n    contracts:\n      read_file:\n        kind: read_only\n        commitClass: none\n        scopes:\n          - ./mcp-sandbox/**\n        deny:\n          - ./mcp-sandbox/.env\n          - ./mcp-sandbox/secrets/**\n        approvalPolicy: never\n        redaction:\n          mode: metadata-first\n          redactKeys:\n            - token\n            - sessionId\n      write_file:\n        kind: local_write\n        commitClass: local\n        scopes:\n          - ./mcp-sandbox/allowed-output/**\n        approvalPolicy: on_yellow\n        budgets:\n          maxCallsPerRun: 5\n```\n\n## MCP Client Configuration\n\nPoint the MCP client at the gateway command:\n\n```json\n{\n  \"mcpServers\": {\n    \"admissible\": {\n      \"command\": \"admissible-mcp\",\n      \"args\": [\"serve\", \"--config\", \"./admissible.mcp.yaml\"]\n    }\n  }\n}\n```\n\nRelative command arguments that start with `./` or `../` are resolved against the config file directory before the gateway launches the MCP server.\n\nCommand-launched stdio servers use newline-delimited JSON-RPC by default, matching the current official MCP TypeScript SDK. Set `stdioFraming: headers` on a server config only for older servers that expect `Content-Length` frames.\n\n## Use With An MCP Client\n\nFirst-use flow:\n\n1. Install `@admissible-ai/mcp-gateway`.\n2. Run `admissible-mcp init`.\n3. Edit `admissible.mcp.yaml`.\n4. Point the MCP client at `admissible-mcp serve`.\n5. Run tools through the gateway.\n\nMinimal MCP client config:\n\n```json\n{\n  \"mcpServers\": {\n    \"admissible\": {\n      \"command\": \"admissible-mcp\",\n      \"args\": [\"serve\", \"--config\", \"./admissible.mcp.yaml\"]\n    }\n  }\n}\n```\n\nFilesystem is the stable local example. GitHub is a disposable-repo pilot only. State-changing tools require commit admission before the underlying MCP server receives the call.\n\nDenied and deferred calls return structured MCP tool results with concise text that is safe to show in a client UI. Local audit logs are JSONL when `gateway.auditLogPath` is configured.\n\nTool names exposed to MCP clients are server-qualified, for example `filesystem.read_file` and `github.list_issues`. This keeps duplicate tool names collision-safe across multiple configured servers. Tool descriptions include a short note that the call is routed through Admissible before execution; detailed contract metadata remains in audit logs.\n\n## Server Launch Modes\n\nThe gateway supports two local launch modes:\n\n- `mockTools`: in-process mock tools for tests and demos.\n- `command`: a child-process MCP server over stdio.\n\nFor command-launched servers, prefer a direct binary path when the MCP server is already installed:\n\n```yaml\nservers:\n  filesystem:\n    command: ${MCP_FILESYSTEM_SERVER_BIN}\n    requestTimeoutMs: 10000\n    args:\n      - ./mcp-sandbox\n```\n\nFor quickstarts, `npx` is supported, but use explicit package mode so npm does not infer the binary name:\n\n```yaml\nservers:\n  filesystem:\n    command: npx\n    requestTimeoutMs: 30000\n    args:\n      - --yes\n      - --package\n      - \"@modelcontextprotocol/server-filesystem\"\n      - mcp-server-filesystem\n      - ./mcp-sandbox\n```\n\n## Tool Contracts\n\nA Tool Contract is the gateway's local declaration of what an MCP tool claims to do before Admissible evaluates execution. Every discovered MCP tool resolves to a contract before it can run.\n\nContract resolution order is:\n\n1. `servers.<name>.contracts.<toolName>` config override.\n2. MCP tool annotations such as read-only or destructive hints.\n3. Tool name, description, and schema heuristics.\n4. Conservative `unknown` fallback.\n\n`contracts` is optional. Existing `authority` config remains the server-level fallback for `scopes`, `deny`, and approval behavior. When both are present, the per-tool contract overrides the server authority defaults for that tool.\n\n```yaml\nservers:\n  filesystem:\n    command: ${MCP_FILESYSTEM_SERVER_BIN}\n    args:\n      - ./mcp-sandbox\n    authority:\n      scopes:\n        - ./mcp-sandbox/**\n      deny:\n        - ./mcp-sandbox/.env\n        - ./mcp-sandbox/secrets/**\n    contracts:\n      read_file:\n        kind: read_only\n        commitClass: none\n        scopes:\n          - ./mcp-sandbox/**\n        deny:\n          - ./mcp-sandbox/.env\n          - ./mcp-sandbox/secrets/**\n        approvalPolicy: never\n        redaction:\n          mode: metadata-first\n          redactKeys:\n            - token\n            - sessionId\n      write_file:\n        kind: local_write\n        commitClass: local\n        scopes:\n          - ./mcp-sandbox/allowed-output/**\n        deny:\n          - ./mcp-sandbox/.env\n          - ./mcp-sandbox/secrets/**\n        approvalPolicy: on_yellow\n        budgets:\n          maxCallsPerRun: 5\n```\n\nSupported `kind` values are `read_only`, `local_write`, `external_write`, `exec`, `network`, `identity`, `financial`, `irreversible`, and `unknown`.\n\nSupported `commitClass` values are `none`, `ephemeral`, `local`, `external`, and `irreversible`.\n\nSupported `approvalPolicy` values are `never`, `on_yellow`, `on_orange`, and `always`. Read-only tools default to `never`; unknown and high-impact tools default cautiously.\n\nBudgets are intentionally lightweight in this phase. `maxCallsPerRun` is enforced locally before Admissible execution and before the MCP server receives the call. `maxCallsPerMinute` and `maxArgumentBytes` are accepted as contract metadata but are not enforced yet.\n\nRedaction is contract-aware. Default sensitive keys are always redacted, and `redaction.redactKeys` extends that list for a specific tool. `metadata-first` remains the default privacy posture.\n\nManifest drift is tied to contracts. If a tool's manifest changes, the gateway marks the contract drift status as `changed` or `new`. High-risk changed tools such as write, exec, network, identity, financial, irreversible, and unknown tools are deferred before execution until the contract is reviewed or refreshed.\n\nAudit events include contract metadata: `contractId`, `contractKind`, `commitClass`, `approvalPolicy`, `contractSource`, `contractVersion`, `contractDriftStatus`, and `budgetDecision`.\n\n## Commit Admission\n\nThe gateway uses `/v2/execute` for every MCP tool call. For Tool Contracts with `commitClass: local`, `commitClass: external`, or `commitClass: irreversible`, the gateway also requires `/v2/commit` admission before the MCP server receives the call.\n\nExecution flow:\n\n1. Resolve the Tool Contract.\n2. Apply local drift and budget gates.\n3. Call `/v2/execute`.\n4. Stop before the MCP server if execute denies or defers.\n5. For `commitClass: none` or `commitClass: ephemeral`, forward the allowed call.\n6. For `commitClass: local`, `external`, or `irreversible`, call `/v2/commit`.\n7. Forward the MCP call only if commit admission allows.\n\nCommit requests are metadata-first. They include server name, tool name, contract id, contract kind, commit class, manifest hash, schema hash, scope summary, and a redacted argument summary linked to the execute operation. Default sensitive-key redaction and contract-specific `redaction.redactKeys` both apply. `redaction.summarizeArgs: false` suppresses safe previews in commit payloads.\n\nIf commit admission denies, defers, requires approval, returns modification, or cannot be reached, the gateway fails closed and does not call the underlying MCP server. Commit modification is treated as defer in this phase.\n\nAudit events add commit metadata: `commitRequired`, `executeTraceId`, `commitTraceId`, `commitDecision`, `commitReason`, `approvalRequired`, and `serverExecuted`.\n\n## Troubleshooting Stdio Launch Hangs\n\nIf `inspect`, `manifest`, or `serve` times out before tool discovery:\n\n- Run the configured command directly and confirm it starts without prompts.\n- Prefer a locally installed server binary over `npx` for repeatable development.\n- Use explicit `npx --yes --package <package> <binary>` when using npm package launch.\n- Increase `requestTimeoutMs` only when the command legitimately has a slow cold start.\n- Set `stdioFraming: headers` only for older servers that require `Content-Length` frames.\n- Ensure the MCP server writes protocol messages to stdout and logs to stderr.\n\n## Example\n\n```bash\nnpm run example:mcp:mocked\nnpm run example:mcp:filesystem\nnpm run example:mcp:github:mocked\nnpm run example:mcp:github\n```\n\nThe filesystem example also includes a direct-binary config:\n\n```bash\nnpm install --save-dev @modelcontextprotocol/server-filesystem\nMCP_FILESYSTEM_SERVER_BIN=\"$(pwd)/node_modules/.bin/mcp-server-filesystem\" npm run example:mcp:filesystem:direct-bin\n```\n\nThe mocked example demonstrates:\n\n- `filesystem.read_file` for `README.md`: allowed and forwarded.\n- `filesystem.read_file` for `.env`: denied before the mocked server is called.\n- `filesystem.write_file` for `allowed-output/commit-deferred.txt`: deferred at commit admission before the mocked server is called.\n\nThe filesystem example launches the official `@modelcontextprotocol/server-filesystem` server and demonstrates:\n\n- `README.md`: allowed and forwarded to the real child-process MCP server.\n- `.env`: denied before the filesystem MCP server receives the tool call.\n- `secrets/hidden.txt`: denied before the filesystem MCP server receives the tool call.\n- `allowed-output/commit-deferred.txt`: deferred at commit admission before the filesystem MCP server receives the write call.\n\n## External MCP Server Pilot: GitHub\n\nThe GitHub pilot is experimental and disposable-repo only. It uses the official local GitHub MCP server as a command-launched stdio server and keeps the same gateway boundary:\n\nMCP tool discovery -> Tool Contracts -> `/v2/execute` -> `/v2/commit` for state-changing tools -> GitHub MCP server execution only after allow.\n\nThe upstream local binary launch shape is:\n\n```yaml\nservers:\n  github:\n    command: ${GITHUB_MCP_SERVER_BIN}\n    args:\n      - stdio\n    env:\n      GITHUB_PERSONAL_ACCESS_TOKEN: ${GITHUB_MCP_TEST_TOKEN}\n      GITHUB_TOOLS: list_issues,issue_write,get_file_contents\n```\n\nThe current upstream issue-create tool is `issue_write` with `method: create`; it is not `create_issue`.\n\nIf you do not have a local `github-mcp-server` binary installed, you can wrap the official Docker image in a local executable and point `GITHUB_MCP_SERVER_BIN` at that wrapper. Docker must be running. The wrapper must stay local and should not be committed.\n\nThe disposable example is in `examples/github-disposable/`:\n\n- `npm run example:mcp:github:mocked` runs without network and proves read allow, issue-write commit defer, and destructive local deny.\n- `npm run example:mcp:github` skips safely unless `GITHUB_MCP_SERVER_BIN`, `GITHUB_MCP_TEST_TOKEN`, `GITHUB_MCP_TEST_OWNER`, and `GITHUB_MCP_TEST_REPO` are set.\n- Live issue creation requires `ADMISSIBLE_MCP_GITHUB_ALLOW_LIVE_WRITE=1`.\n\nUse only a public or throwaway repository owned by a test account or test org. Do not use private repositories, production organizations, customer data, admin tokens, delete scopes, secrets scopes, or Actions/workflow scopes.\n\nGitHub issue writes use `external_write` / `commitClass: external`; the default live path defers at commit admission before the GitHub MCP server receives the write call. Destructive GitHub actions are not enabled in the live config and are contract-denied in the mocked pilot.\n\n## Privacy Posture\n\nThe default mode is `metadata-first`. The gateway sends tool name, server name, manifest hash, schema hash, contract kind, argument shape, safe argument preview, scope markers, and risk markers. It redacts keys such as tokens, passwords, cookies, secrets, credentials, and API keys.\n\nContract-specific `redaction.redactKeys` extends the default redaction set. Full payload forwarding is only enabled when `metadataMode: full-payload` or a contract-level `redaction.mode: full-payload` is configured.\n\n## Current Limitations\n\n- Local-first only.\n- Supports stdio command-launched MCP servers; HTTP/SSE transport is not implemented yet.\n- Filesystem remains the stable real-server target. GitHub is limited to a disposable-repo pilot; Postgres, Slack, Browser, and other external systems are out of scope.\n- Commit admission is wired for state-changing Tool Contracts, but rollback, post-execution commit confirmation, and argument-level commit modification are not implemented yet.\n- No hosted gateway.\n- No enterprise dashboard.\n- No vulnerability scanning.\n- No full DLP.\n- Approval routing depends on existing runtime behavior.\n- Tool classification is conservative and may require config overrides.\n- Metadata-first mode may reduce runtime decision context.\n- Only `maxCallsPerRun` is enforced locally in this phase; other budget fields are contract metadata for future enforcement.\n- The gateway does not include a hosted approval UI.\n","readmeFilename":"README.md","_rev":"1-3e860657b483a824f677082b0e0643c7"}