GATE MCP sits between your AI agents and upstream MCP servers.
Every tool call is evaluated against your policies, logged for audit,
and optionally paused for human approval — before it reaches the upstream server.
Quick Start · See It in Action · Admin UI · Policy Engine · CLI · Architecture
AI agents call MCP tools — read files, send messages, run queries, delete resources. Without guardrails, any agent can call any tool with any arguments. No audit trail. No approval workflow. No policy enforcement.
GATE MCP is the gateway that fixes this. It proxies all tool calls and enforces your organization's rules:
- Policy engine — YAML rules that deny, allow, warn, redact, or require approval per tool, role, risk level, or argument value
- Approval workflows — human-in-the-loop for high-risk operations, with durable records and one-time replay tokens
- Audit trail — every invocation logged with tenant, principal, tool, decision, matched rules, and sanitized arguments
- Rate limiting — per-tenant, per-principal, and per-tool quotas
- Tool classification — automatic + manual classification by operation class (read/write/admin) and risk level
- Multi-tenant isolation — tenant-scoped servers, tools, policies, and audit
- Encrypted secrets — AES-256-GCM credential storage with key rotation, KMS/Vault-ready
- Output redaction — post-response content filtering based on policy rules
The Model Context Protocol gives AI agents access to real tools — file systems, databases, APIs, cloud services. Without a control plane:
- Any agent can call any tool with any arguments
- There is no policy layer between the agent and the tool
- There is no audit trail of what was called, by whom, or why it was allowed
- There is no approval workflow for destructive or sensitive operations
- Credentials are passed directly with no mediation or rotation
GATE MCP adds the governance layer that organizations need before deploying MCP in production.
# Prerequisites: Node.js 20+, pnpm 9+, Docker
git clone https://github.com/yogesh895/gate-mcp.git
cd gate-mcp
pnpm install
# Start Postgres + Redis
pnpm docker:up
# Configure environment
cp .env.example .env
# Build all packages
pnpm build
# Run database migrations and seed demo data
pnpm db:migrate
pnpm db:seed
# Start the gateway (port 3100)
pnpm --filter @gate-mcp/gateway dev
# Verify it's running (in a new terminal)
curl http://localhost:3100/health
# => {"status":"healthy","version":"1.0.0",...}
# Start the Admin UI (port 3200) — in another terminal
pnpm --filter @gate-mcp/admin-ui dev
# Open http://localhost:3200Note: All CLI commands below use
pnpm gate-mcp, a root workspace script that invokes the built CLI. Make sure you've runpnpm buildfirst.
The seed script creates one tenant and two principals for local development:
| Resource | Value |
|---|---|
| Tenant slug | default |
| Tenant ID | 00000000-0000-0000-0000-000000000001 |
| Admin principal ID | 00000000-0000-0000-0000-000000000002 |
| Admin role | admin (RBAC: org_admin) |
| Approver principal ID | 00000000-0000-0000-0000-000000000003 |
| Approver role | approver (for approval workflow demos) |
These values are used throughout the demo commands and examples below.
Tenant resolution: In dev mode (
AUTH_MODE=dev), the/mcpendpoint uses theX-Tenant-Slugheader to determine the tenant. If omitted, it falls back to theDEFAULT_TENANT_SLUGfrom.env(default:default). In production (AUTH_MODE=jwt), the tenant is resolved from the JWT token. Always passX-Tenant-Slugexplicitly in multi-tenant setups.
After setup, there are two paths to experience GATE MCP:
| Path | What you see | Requirements |
|---|---|---|
| A: Full runtime demo | Audit trail, approval workflows, all UI pages populated | Gateway + echo server (built in) |
| B: Policy simulation only | Policy decisions in the terminal, policy bundles in the UI | Just the gateway |
Start with Path A for the strongest first experience. Path B is a lighter alternative if you just want to see policy evaluation.
Terminals: For the full demo, you'll have three processes running: the gateway (from Quick Start), the echo server, and the Admin UI. Use separate terminal tabs/windows for each.
The repo includes a built-in mock MCP server with 10 tools. The demo full command registers it, applies a policy, and sends live requests through the gateway — populating every UI page.
# Terminal 2: Start the echo MCP server (port 3300)
pnpm echo-server
# Terminal 3: Run the full demo (gateway must be running)
pnpm gate-mcp demo fullThe demo sends 6 live tool calls and shows the decisions:
✓ ALLOW files.search
✓ ALLOW db.query
⚠ WARN files.write
✗ DENY db.drop_table
✗ DENY repo.delete
⏳ REQUIRE APPROVAL files.share
After running, open http://localhost:3200 and check:
- Overview — 6 invocations with decision breakdown
- Servers — the echo-server you just registered
- Tools — 10 discovered tools with classification
- Policies — the echo-safety policy bundle (active)
- Audit — 6 audit events with decisions and matched rules
- Approvals — pending approval for
files.share
# List pending approvals
pnpm gate-mcp approvals list --status pending
# Approve (use the approver principal — admin can't approve their own request)
pnpm gate-mcp approvals approve <approvalId> 00000000-0000-0000-0000-000000000003
# => Returns a one-time replay token
# Replay the original request with the token
curl -s -X POST http://localhost:3100/mcp \
-H "Content-Type: application/json" \
-H "X-Tenant-Slug: default" \
-d '{"method":"tools/call","params":{"name":"files.share","arguments":{"fileId":"doc-123","email":"[email protected]"}},"_replayToken":"<token>"}' | jq .Both the original request and the approved replay appear in the Audit page, linked together.
Note: Audit events and approval records are created during live
/mcpinvocations (Path A), not during policy simulation (Path B).
If you just want to see how the policy engine evaluates rules without setting up the echo server:
pnpm gate-mcp demo githubThis uploads the GitHub safety policy and simulates 5 scenarios: reads allowed, PR merges require approval, repo deletion denied, contributors restricted to read-only. Or try the Google Drive demo:
pnpm gate-mcp demo driveSimulation is a dry-run — you see decisions in the terminal but no audit events or approvals are created in the database. Use Path A for the full experience.
The Admin UI at http://localhost:3200 is the operator console.
| Page | What It Shows | When It Has Data |
|---|---|---|
| Overview | System health, decision breakdown, recent activity | After live /mcp invocations |
| Servers | Registered upstream MCP servers, discovery status | After server register |
| Tools | Discovered tool catalog with operation/risk class | After server discover |
| Policies | Policy bundles, lifecycle state, diffing, activation history | After policy apply (works with simulation) |
| Approvals | Pending, approved, and rejected requests | After live require_approval decisions |
| Audit | Filterable event log by decision, tool, principal, time | After live /mcp invocations |
| Secrets | Credential inventory, encryption status, health | After configuring server auth |
| Runtime | Circuit breaker state, quota usage, server health | After live traffic |
The UI is tenant-aware — use the tenant selector in the sidebar to switch between tenants.
After running demo full (Path A): All pages will have data. After demo github or demo drive (Path B), only the Policies page is populated.
Note: Each demo activates its own policy bundle for the
defaulttenant. Runningdemo githubafterdemo fullreplaces the echo-safety policy with github-safety as the active bundle. The previous bundle is not deleted — you can reactivate it from the Policy Studio.
Policies are YAML files with rules that match against a normalized execution envelope:
version: "1"
policies:
- name: deny-public-sharing
conditions:
- field: tool.name
operator: equals
value: drive.share_file
- field: args.visibility
operator: equals
value: public
action: deny
reason: "Public file sharing is prohibited"
- name: require-approval-external-share
conditions:
- field: tool.name
operator: equals
value: drive.share_file
- field: args.domain
operator: not_equals
value: ""
action: require_approval
reason: "External sharing requires manager approval"
- name: support-read-only
conditions:
- field: principal.role
operator: in
value: [support, viewer]
- field: tool.operationClass
operator: not_equals
value: read
action: deny
reason: "Support agents are restricted to read-only"Actions: allow · deny · require_approval · warn · redact
Precedence: deny > require_approval > redact > warn > allow (deterministic, no ambiguity)
Condition fields: tool.name, tool.operationClass, tool.riskClass, tool.tags, principal.role, principal.id, args.*
Operators: equals, not_equals, in, not_in, contains
Lifecycle: draft → validated → staged → active → deprecated → archived. Shadow evaluation lets you test new policies against live traffic without affecting decisions.
Ready-to-use policy packs: examples/policy-packs/
Full language reference: docs/policies/language-reference.md
All commands use pnpm gate-mcp:
export GATEWAY_URL=http://localhost:3100 # default
# Server management
pnpm gate-mcp server register <tenant> <name> <endpoint>
pnpm gate-mcp server list <tenant>
pnpm gate-mcp server inspect <serverId>
pnpm gate-mcp server remove <serverId>
pnpm gate-mcp server discover <serverId>
# Tool catalog
pnpm gate-mcp tools list <tenant>
pnpm gate-mcp tools inspect <toolId>
pnpm gate-mcp tools classify <toolId> <operationClass> <riskClass>
# Policy lifecycle
pnpm gate-mcp policy validate <file.yaml>
pnpm gate-mcp policy apply <tenant> <name> <file.yaml>
pnpm gate-mcp policy activate <bundleId> <tenant> [environment]
pnpm gate-mcp policy simulate <file.yaml> [--explain] # see examples/policy-simulations/
pnpm gate-mcp policy transition <bundleId> <targetState>
pnpm gate-mcp policy shadow <bundleId> <tenant>
pnpm gate-mcp policy diff <beforeBundleId> <afterBundleId>
pnpm gate-mcp policy replay <bundleId> <tenant> [--limit N]
# Audit
pnpm gate-mcp audit list [--tenant <t>] [--decision deny] [--limit N]
pnpm gate-mcp audit inspect <eventId>
pnpm gate-mcp audit export [--tenant <t>] [--format csv|json]
pnpm gate-mcp audit preset [<name>] [--tenant <t>]
# Approvals
pnpm gate-mcp approvals list [--status pending]
pnpm gate-mcp approvals inspect <approvalId>
pnpm gate-mcp approvals approve <approvalId> <approverId>
pnpm gate-mcp approvals reject <approvalId> <approverId> [reason]
# Secrets
pnpm gate-mcp secrets list <tenant>
pnpm gate-mcp secrets health <tenant>
pnpm gate-mcp secrets inspect <secretId>
pnpm gate-mcp secrets revoke <secretId>
# Demo
pnpm gate-mcp demo full # Full runtime demo (echo server + live calls)
pnpm gate-mcp demo github # GitHub protection demo (policy simulation)
pnpm gate-mcp demo drive # Google Drive protection demo (policy simulation)Note: All commands that accept
<tenant>work with both slugs (default) and UUIDs.
policy simulatefile format: The simulation YAML file requires asourcefield (inline policy YAML) and anenvelopefield (the request to evaluate). You can also usetenantSlugorbundleIdinstead ofsourceto simulate against an existing active or stored bundle. See examples/policy-simulations/ for ready-to-use examples.
GATE MCP is a modular monolith — a single deployable with strict internal package boundaries. Every live tool call follows the runtime path:
Agent → Ingress → Execution Envelope → Policy → Quotas → Secrets → Router → Output Policy → Audit
The request is normalized into an execution envelope, evaluated against the active policy bundle, checked against quotas, mediated for credentials, proxied to the upstream server, filtered by output policy, and logged to the audit trail.
| Component | Technology |
|---|---|
| Runtime | Node.js 22 / TypeScript (strict mode) |
| HTTP | Fastify 5 |
| Database | PostgreSQL 16 |
| Cache/Queues | Redis 7 |
| Build | pnpm workspaces + Turborepo |
| Testing | Vitest (437 tests) |
Full architecture reference: docs/architecture/overview.md
Four reference integrations show how to protect different types of MCP servers. Each includes a policy pack, tool classifications, and test fixtures:
| Integration | What It Demonstrates |
|---|---|
| Google Drive | File sharing controls, role-based access, approval for external shares |
| GitHub | Repo deletion blocking, protected-branch PR approvals, contributor read-only |
| Slack | Production channel protection, external sharing approval, channel governance |
| SQL | DDL blocking, sensitive table export denial, mutation approvals, analyst read-only |
Use these as templates when protecting your own MCP servers.
GATE MCP supports two deployment modes:
- Docker Compose — single-server deployments and evaluations
- Kubernetes (Helm) — enterprise deployments with scaling and HA
In production, set AUTH_MODE=jwt with your OIDC provider (Auth0, Okta, Keycloak, Azure AD). The gateway validates JWT tokens against your JWKS endpoint for both admin and runtime APIs.
RBAC provides 7 roles (org_admin, tenant_admin, security_admin, policy_author, approver, auditor, readonly_operator) with 19 permissions enforced on every endpoint.
Secrets use AES-256-GCM encryption with key rotation. KMS and Vault provider interfaces are ready for enterprise secret backends.
| Guide | Description |
|---|---|
| Production Deployment | Docker Compose and Helm setup |
| Production Auth | JWT/OIDC configuration for any provider |
| Security Architecture | Trust model, encryption, audit, RBAC |
| Operator Runbook | Day-to-day operations and incident response |
| Evaluation Guide | Structured 2-hour enterprise evaluation |
After your first session with GATE MCP:
| Goal | Where to Go |
|---|---|
| Understand the architecture | docs/architecture/overview.md |
| Connect your own MCP server | See It in Action |
| Write custom policies | docs/policies/language-reference.md |
| Learn the policy lifecycle | docs/policies/lifecycle.md |
| Deploy to production | docs/operations/production-deployment-guide.md |
| Set up JWT/OIDC auth | docs/operations/production-auth.md |
| Run an enterprise evaluation | docs/enterprise/evaluation-guide.md |
| Browse the API | Open http://localhost:3100/documentation (OpenAPI/Swagger) |
- Native YAML policy DSL with simulation, explain, shadow evaluation, and diffing
- Policy lifecycle (draft → validated → staged → active → deprecated → archived)
- Human-in-the-loop approval workflows with replay tokens
- Audit trail with policy bundle linkage and compliance export
- RBAC with 7 roles and 19 permissions
- JWT/OIDC authentication (JWKS validation via jose)
- Output policy with post-response content redaction
- Server registry with auto-discovery
- Tool catalog with classification heuristics
- Per-tenant/principal/tool rate limiting
- AES-256-GCM secret storage with KMS/Vault interfaces
- Circuit breakers and operation-class-aware timeouts
- Admin UI with 8 operational screens
- CLI with 31 commands
- 4 reference integrations (Google Drive, GitHub, Slack, SQL)
- Production Dockerfile and Helm chart
- OpenAPI documentation at
/documentation
- TypeScript client SDK
- Webhook notifications for approval events
- Stdio transport for MCP server discovery
- Shared circuit breaker state via Redis
- Audit event streaming to SIEM
See CONTRIBUTING.md for development setup, repo structure, and guidelines.

