@admissible-ai/mcp-gateway
v0.1.0
Published
Local Admissible authority gateway for MCP tool execution.
Maintainers
Readme
@admissible-ai/mcp-gateway
Status: experimental release candidate.
The 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.
MCP connects agents to tools. Admissible governs what those tools are allowed to do before execution.
What It Is
- A local-first MCP gateway process.
- A tool authority layer that maps MCP tool calls into Admissible
/v2/executeoperations. - A commit admission layer that maps state-changing MCP Tool Contracts into Admissible
/v2/commitoperations before server execution. - A Tool Contract resolver that gives every MCP tool an explicit local contract before execution.
- A command-launched stdio proxy for local MCP servers.
- A metadata-first adapter that avoids sending secrets or full sensitive payloads by default.
- A v0 proof that denied MCP tool calls never reach the underlying MCP server.
What It Is Not
- Not a hosted MCP security platform.
- Not a dashboard.
- Not a vulnerability scanner.
- Not enterprise DLP or SIEM integration.
- Not a replacement for the Admissible runtime authority layer.
Install
After an explicit publish decision:
npm install -g @admissible-ai/mcp-gatewayInit
admissible-mcp initMinimal Config
admissible:
baseUrl: https://api.admissible.io
apiKey: ${ADMISSIBLE_API_KEY}
gateway:
mode: local-proxy
transport: stdio
metadataMode: metadata-first
manifestPath: .admissible/mcp-manifest.json
auditLogPath: .admissible/mcp-audit.jsonl
servers:
filesystem:
command: npx
requestTimeoutMs: 30000
args:
- --yes
- --package
- "@modelcontextprotocol/server-filesystem"
- mcp-server-filesystem
- ./mcp-sandbox
authority:
scopes:
- ./mcp-sandbox/**
deny:
- ./mcp-sandbox/.env
- ./mcp-sandbox/secrets/**
approvalRequired:
- ./mcp-sandbox/allowed-output/**
contracts:
read_file:
kind: read_only
commitClass: none
scopes:
- ./mcp-sandbox/**
deny:
- ./mcp-sandbox/.env
- ./mcp-sandbox/secrets/**
approvalPolicy: never
redaction:
mode: metadata-first
redactKeys:
- token
- sessionId
write_file:
kind: local_write
commitClass: local
scopes:
- ./mcp-sandbox/allowed-output/**
approvalPolicy: on_yellow
budgets:
maxCallsPerRun: 5MCP Client Configuration
Point the MCP client at the gateway command:
{
"mcpServers": {
"admissible": {
"command": "admissible-mcp",
"args": ["serve", "--config", "./admissible.mcp.yaml"]
}
}
}Relative command arguments that start with ./ or ../ are resolved against the config file directory before the gateway launches the MCP server.
Command-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.
Use With An MCP Client
First-use flow:
- Install
@admissible-ai/mcp-gateway. - Run
admissible-mcp init. - Edit
admissible.mcp.yaml. - Point the MCP client at
admissible-mcp serve. - Run tools through the gateway.
Minimal MCP client config:
{
"mcpServers": {
"admissible": {
"command": "admissible-mcp",
"args": ["serve", "--config", "./admissible.mcp.yaml"]
}
}
}Filesystem 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.
Denied 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.
Tool 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.
Server Launch Modes
The gateway supports two local launch modes:
mockTools: in-process mock tools for tests and demos.command: a child-process MCP server over stdio.
For command-launched servers, prefer a direct binary path when the MCP server is already installed:
servers:
filesystem:
command: ${MCP_FILESYSTEM_SERVER_BIN}
requestTimeoutMs: 10000
args:
- ./mcp-sandboxFor quickstarts, npx is supported, but use explicit package mode so npm does not infer the binary name:
servers:
filesystem:
command: npx
requestTimeoutMs: 30000
args:
- --yes
- --package
- "@modelcontextprotocol/server-filesystem"
- mcp-server-filesystem
- ./mcp-sandboxTool Contracts
A 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.
Contract resolution order is:
servers.<name>.contracts.<toolName>config override.- MCP tool annotations such as read-only or destructive hints.
- Tool name, description, and schema heuristics.
- Conservative
unknownfallback.
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.
servers:
filesystem:
command: ${MCP_FILESYSTEM_SERVER_BIN}
args:
- ./mcp-sandbox
authority:
scopes:
- ./mcp-sandbox/**
deny:
- ./mcp-sandbox/.env
- ./mcp-sandbox/secrets/**
contracts:
read_file:
kind: read_only
commitClass: none
scopes:
- ./mcp-sandbox/**
deny:
- ./mcp-sandbox/.env
- ./mcp-sandbox/secrets/**
approvalPolicy: never
redaction:
mode: metadata-first
redactKeys:
- token
- sessionId
write_file:
kind: local_write
commitClass: local
scopes:
- ./mcp-sandbox/allowed-output/**
deny:
- ./mcp-sandbox/.env
- ./mcp-sandbox/secrets/**
approvalPolicy: on_yellow
budgets:
maxCallsPerRun: 5Supported kind values are read_only, local_write, external_write, exec, network, identity, financial, irreversible, and unknown.
Supported commitClass values are none, ephemeral, local, external, and irreversible.
Supported approvalPolicy values are never, on_yellow, on_orange, and always. Read-only tools default to never; unknown and high-impact tools default cautiously.
Budgets 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.
Redaction 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.
Manifest 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.
Audit events include contract metadata: contractId, contractKind, commitClass, approvalPolicy, contractSource, contractVersion, contractDriftStatus, and budgetDecision.
Commit Admission
The 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.
Execution flow:
- Resolve the Tool Contract.
- Apply local drift and budget gates.
- Call
/v2/execute. - Stop before the MCP server if execute denies or defers.
- For
commitClass: noneorcommitClass: ephemeral, forward the allowed call. - For
commitClass: local,external, orirreversible, call/v2/commit. - Forward the MCP call only if commit admission allows.
Commit 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.
If 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.
Audit events add commit metadata: commitRequired, executeTraceId, commitTraceId, commitDecision, commitReason, approvalRequired, and serverExecuted.
Troubleshooting Stdio Launch Hangs
If inspect, manifest, or serve times out before tool discovery:
- Run the configured command directly and confirm it starts without prompts.
- Prefer a locally installed server binary over
npxfor repeatable development. - Use explicit
npx --yes --package <package> <binary>when using npm package launch. - Increase
requestTimeoutMsonly when the command legitimately has a slow cold start. - Set
stdioFraming: headersonly for older servers that requireContent-Lengthframes. - Ensure the MCP server writes protocol messages to stdout and logs to stderr.
Example
npm run example:mcp:mocked
npm run example:mcp:filesystem
npm run example:mcp:github:mocked
npm run example:mcp:githubThe filesystem example also includes a direct-binary config:
npm install --save-dev @modelcontextprotocol/server-filesystem
MCP_FILESYSTEM_SERVER_BIN="$(pwd)/node_modules/.bin/mcp-server-filesystem" npm run example:mcp:filesystem:direct-binThe mocked example demonstrates:
filesystem.read_fileforREADME.md: allowed and forwarded.filesystem.read_filefor.env: denied before the mocked server is called.filesystem.write_fileforallowed-output/commit-deferred.txt: deferred at commit admission before the mocked server is called.
The filesystem example launches the official @modelcontextprotocol/server-filesystem server and demonstrates:
README.md: allowed and forwarded to the real child-process MCP server..env: denied before the filesystem MCP server receives the tool call.secrets/hidden.txt: denied before the filesystem MCP server receives the tool call.allowed-output/commit-deferred.txt: deferred at commit admission before the filesystem MCP server receives the write call.
External MCP Server Pilot: GitHub
The 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:
MCP tool discovery -> Tool Contracts -> /v2/execute -> /v2/commit for state-changing tools -> GitHub MCP server execution only after allow.
The upstream local binary launch shape is:
servers:
github:
command: ${GITHUB_MCP_SERVER_BIN}
args:
- stdio
env:
GITHUB_PERSONAL_ACCESS_TOKEN: ${GITHUB_MCP_TEST_TOKEN}
GITHUB_TOOLS: list_issues,issue_write,get_file_contentsThe current upstream issue-create tool is issue_write with method: create; it is not create_issue.
If 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.
The disposable example is in examples/github-disposable/:
npm run example:mcp:github:mockedruns without network and proves read allow, issue-write commit defer, and destructive local deny.npm run example:mcp:githubskips safely unlessGITHUB_MCP_SERVER_BIN,GITHUB_MCP_TEST_TOKEN,GITHUB_MCP_TEST_OWNER, andGITHUB_MCP_TEST_REPOare set.- Live issue creation requires
ADMISSIBLE_MCP_GITHUB_ALLOW_LIVE_WRITE=1.
Use 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.
GitHub 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.
Privacy Posture
The 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.
Contract-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.
Current Limitations
- Local-first only.
- Supports stdio command-launched MCP servers; HTTP/SSE transport is not implemented yet.
- 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.
- Commit admission is wired for state-changing Tool Contracts, but rollback, post-execution commit confirmation, and argument-level commit modification are not implemented yet.
- No hosted gateway.
- No enterprise dashboard.
- No vulnerability scanning.
- No full DLP.
- Approval routing depends on existing runtime behavior.
- Tool classification is conservative and may require config overrides.
- Metadata-first mode may reduce runtime decision context.
- Only
maxCallsPerRunis enforced locally in this phase; other budget fields are contract metadata for future enforcement. - The gateway does not include a hosted approval UI.
