Overview
MCP exposes tools. Admissible assigns Tool Contracts and gates those tool calls before execution. The gateway stays local: your MCP client connects to admissible-mcp serve, and the gateway launches configured MCP servers behind that boundary.
Boundary
This is a local MCP gateway, not a hosted MCP security platform. It does not provide hosted approvals, hosted policy management, or vulnerability scanning.
Use MCP Gateway when
- your team already uses MCP clients or MCP servers
- you need local pre-execution authority before MCP tools run
- you want read tools and state-changing tools to follow different admission paths
- you need a filesystem-first proof before trying an external server
Do not treat this as
- a hosted MCP security platform
- a full vulnerability scanner
- an approval UI
- a stable private-repo GitHub integration
Package status
@admissible-ai/mcp-gateway
This package is an experimental release candidate. Public install guidance uses @admissible-ai/mcp-gateway@experimentaluntil the gateway is promoted.
# MCP Gateway is an experimental release candidate.# Use the experimental dist tag until the package is promoted.
npm install -g @admissible-ai/mcp-gateway@experimentaladmissible-mcp init --config admissible.mcp.yaml
# Internal RC / local package smoke only.# Use an approved local workspace package or packed RC tarball.admissible-mcp init --config admissible.mcp.yaml
Architecture
The gateway maps MCP calls into the same runtime authority boundary used by the other Admissible integration surfaces.
Flow
- MCP tool discovery
- Tool Contracts
/v2/execute for every MCP tool call/v2/commit for state-changing Tool Contracts- MCP server execution only after allow
MCP client configuration
Point the MCP client at the gateway command instead of connecting directly to the filesystem, GitHub, or other MCP server.
{ "mcpServers": { "admissible": { "command": "admissible-mcp", "args": ["serve", "--config", "./admissible.mcp.yaml"] } }}
Server launch modes
mockTools
In-process tools for tests, examples, and deterministic demos. Use this when you want to prove policy behavior without a real child-process MCP server.
command
A child-process MCP server over stdio. Prefer a direct binary path for repeatable development; explicit npx package mode is acceptable for quickstarts.
npm install --save-dev @modelcontextprotocol/server-filesystemMCP_FILESYSTEM_SERVER_BIN="$(pwd)/node_modules/.bin/mcp-server-filesystem"admissible-mcp inspect --config admissible.mcp.yaml
Commit Admission
Read-only and ephemeral tools stay execute-only. Tools with commitClass: local, external, or irreversible require /v2/commit before server execution.
- deny, defer, approval-required, and failed-commit results stop before the MCP server receives the call
- commit modification is treated as defer in this release candidate
- rollback and post-execution commit confirmation are not implemented yet
Filesystem example
Filesystem is the stable local example. It proves allowed reads, local denies, and commit-deferred writes without involving external services or tokens.
admissible: baseUrl: ${ADMISSIBLE_API_URL} apiKey: ${ADMISSIBLE_API_KEY}gateway: mode: local-proxy transport: stdio metadataMode: metadata-first manifestPath: .admissible/mcp-manifest.json auditLogPath: .admissible/mcp-audit.jsonlservers: 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 read_text_file: kind: read_only commitClass: none scopes: - ./mcp-sandbox/** deny: - ./mcp-sandbox/.env - ./mcp-sandbox/secrets/** approvalPolicy: never write_file: kind: local_write commitClass: local scopes: - ./mcp-sandbox/allowed-output/** deny: - ./mcp-sandbox/.env - ./mcp-sandbox/secrets/** approvalPolicy: on_yellow edit_file: kind: local_write commitClass: local scopes: - ./mcp-sandbox/allowed-output/** deny: - ./mcp-sandbox/.env - ./mcp-sandbox/secrets/** approvalPolicy: on_yellow
README.md read is allowed and forwarded.env read is denied before the filesystem server receives itallowed-output/commit-deferred.txt write is deferred at commit admission
GitHub disposable pilot
GitHub is an external-server pilot, not the first-run path. Use only disposable public or throwaway repositories and least-privilege credentials.
Do not use
- private repositories
- production organizations
- customer data
- broad personal tokens
- admin, delete, secrets, or workflow permissions
The live path reads issues and defers issue creation before GitHub receives the write by default. Live issue creation is opt-in only.
tmp_dir="$(mktemp -d)"wrapper="$tmp_dir/github-mcp-server"cat > "$wrapper" <<'EOF'#!/bin/shexec docker run -i --rm \ -e GITHUB_PERSONAL_ACCESS_TOKEN \ -e GITHUB_TOOLS \ ghcr.io/github/github-mcp-serverEOFchmod 700 "$wrapper"GITHUB_MCP_SERVER_BIN="$wrapper" admissible-mcp inspect --config admissible.github.mcp.yaml
Privacy posture
The gateway defaults to metadata-first. It sends tool name, server name, manifest hash, schema hash, contract kind, argument shape, safe preview, scope markers, and risk markers while redacting sensitive keys.
- tokens, passwords, cookies, secrets, credentials, and API keys are redacted by default
- contract-specific redaction can add more redacted keys
- full-payload mode is explicit and not the default posture
Limitations
- local-first only
- stdio command-launched MCP servers only; HTTP/SSE is not implemented
- no hosted gateway, dashboard, approval UI, vulnerability scanner, full DLP, or SIEM integration
- rollback, post-execution commit confirmation, and argument-level commit modification are not implemented
- only maxCallsPerRun is enforced locally; other budget fields are metadata
- GitHub support is disposable-repo pilot only
Troubleshooting
- run the configured MCP server command directly and confirm it starts without prompts
- prefer a locally installed server binary when npx startup is slow or interactive
- use explicit
npx --yes --package <package> <binary> for package launches - increase requestTimeoutMs only when cold start is legitimately slow
- ensure the MCP server writes JSON-RPC protocol messages to stdout and logs to stderr
- inspect
.admissible/mcp-audit.jsonl for contract and commit decisions