GetMCP
Zero Trust for AI agents. Generates and protects MCP servers for both internal copilots and customer-facing agents. Apache 2.0, self-hosted.
Install / Use
claude mcp add Rayenbabdallah -- npx -y github:Rayenbabdallah/GetMCPIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
CommunicationSupported Platforms
Skill content
View source on GitHub<p align="center"> <img src="docs/images/landing-hero.png" alt="GetMCP — Make your API agent-ready, safely. Zero Trust Architecture for AI Agents." width="900" /> </p>TL;DR. Point GetMCP at any OpenAPI spec. It generates two runnable MCP servers (Internal "god mode" and External "customer-safe"), then runs in front of them as a policy proxy with a tamper-evident audit log. Self-hosted, Apache 2.0, no telemetry.
What is GetMCP?
A policy proxy + audit log that sits between AI agents (Claude, ChatGPT, Cursor, your bots) and your existing API.
It does two things:
- Generates Internal + External MCP servers from any OpenAPI spec, so your customers' AI agents can safely call your API.
- Enforces Zero Trust on every call — per-agent identity, 5 policy rule types, Slack-mediated approval for sensitive mutations, and a tamper-evident audit log you can verify with one HTTP request.
┌─────────┐ ┌──────────────────────────────┐ ┌──────────┐
│ AI │ ──► │ GetMCP — auth · policy · │ ──► │ Your API │
│ agent │ │ approval · audit · stream │ │ │
└─────────┘ └──────────────────────────────┘ └──────────┘
Built for: B2B SaaS companies whose customers are starting to wire AI agents into their APIs and need a Zero Trust layer they can self-host.
Not built for: routing internal traffic between microservices (use a service mesh) or rate-limiting public APIs (use a CDN / WAF). GetMCP is specifically the AI-agent → enterprise-API path.
Why not roll your own?
| You'd need to build | What GetMCP gives you on day 1 |
|---|---|
| Auth + per-tenant isolation, with regression tests proving Org A can't read Org B | Apache-2.0, working, tested |
| A streaming proxy with header filtering (no leaking caller Authorization to the upstream) | Real, with 502 / 504 mapped correctly, never 500 |
| A policy engine with deterministic priority order and a dry-run endpoint | 5 rule types, property-tested, POST /policies/simulate |
| A tamper-evident audit log your auditors will accept | sha256 hash chain, one-call GET /audit/verify, NDJSON export |
| A Slack approval flow with HMAC-signed callbacks | Idempotent state machine, replay-on-approve through the proxy |
| All of the above as a Helm chart with rolling deploys | Bundled, pre-install migration hook, no bundled DB |
About 6 months of work for one engineer. GetMCP is one bash command:
./deploy/scripts/bootstrap.sh
Prerequisites
- Docker & Docker Compose
- Node.js 20+ (for local development) — see
.nvmrc - pnpm 9+
- PostgreSQL (if running outside of Docker)
Documentation
Full operator + auditor docs in docs/. Start with docs/quickstart.md — zero to a proxied request in 10 minutes. Live Swagger UI at /docs when the API is running in dev or with ENABLE_DOCS=true.
Quick Start (one command)
git clone https://github.com/Rayenbabdallah/GetMCP
cd GetMCP
./deploy/scripts/bootstrap.sh
The bootstrap script generates .env with fresh POSTGRES_PASSWORD + KEY_ENCRYPTION_KEY, brings up Postgres, runs migrations, starts API + Web, and seeds a demo org. Re-runnable safely. Output prints a working API key (saved exactly once) and curl commands.
Defaults: dashboard at http://localhost:8080, API at http://localhost:3000. Kubernetes deploy via Helm chart in deploy/helm/getmcp/. Full operations runbook in docs/operations.md.
Testing
- Strategy + claim → test mapping:
docs/testing.md - Per-file coverage gates on the 12 correctness-critical files (
apps/api/package.json#jest.coverageThreshold); CI blocks merge on regression - Property tests for the audit chain: 200 random inserts verified end-to-end, 50 random tampers all detected at the right
seq - Cross-rule combination tests for the policy engine — priority interactions, source filters, bypass behavior
Performance
- Targets and tuning knobs:
docs/performance.md - Load tests:
deploy/load/k6-baseline.jsasserts SLA thresholds (p95 < 25ms simulate, p95 < 50ms proxy, < 1% errors). Seedeploy/load/README.mdfor invocation. - Caches: 5s in-memory TTL on policy rules + agent identities. Audit writes are fire-and-forget off the response path.
- Compression enabled for JSON responses, explicitly skipped on
/proxy/executeso the streamed upstream response isn't buffered. - For multi-replica deploys: tune
?connection_limit=inDATABASE_URL(default 3 on a 1-vCPU pod is too low for 1000 RPS).
Security
- Threat model + data-at-rest catalog:
docs/security.md - Vulnerability disclosure:
SECURITY.md(rayenbenabdallah88@gmail.com) - CI gates:
pnpm audit --audit-level=high+ GitHub CodeQL (security-extendedsuite) on every PR - DTO validation:
class-validatordecorators on every body,forbidNonWhitelisted: truerejects extra fields - Secrets at rest: AES-256-GCM (upstream auth, Slack tokens) + scrypt (API keys); the audit chain is sha256-linked and externally verifiable
Production deploy
- Docker Compose:
docker compose -f docker-compose.prod.yml up -dafterbootstrap.sh. Healthchecks, restart policies, log rotation, resource limits, and the migrate-before-start ordering are all wired in. - Kubernetes (Helm):
helm install getmcp deploy/helm/getmcp -n getmcp --set ingress.host=.... Pre-install Helm hook runsprisma migrate deploy; rolling deploy usesmaxSurge:1, maxUnavailable:0. Chart deliberately does NOT bundle Postgres — bring your own (Marketplace Neon, RDS, Cloud SQL). - Backups:
./deploy/scripts/backup-db.sh(compressedpg_dump+ retention prune); restore via./deploy/scripts/restore-db.sh. Always re-runGET /audit/verifyafter a restore — the chain must reportvalid: true.
See docs/operations.md for the full runbook (upgrades, rolling secrets, common incidents, alerting thresholds).
Local development
pnpm install
pnpm dev # runs API and web concurrently
pnpm typecheck # whole monorepo
pnpm lint
pnpm test
Architecture overview
apps/api(NestJS): The core intelligence engine. It parses OpenAPI specs, generates Two-MCP trust boundaries, and runs the Proxy Interceptor to evaluate real-time agent requests against your policies.apps/web(React/Vite): The enterprise dashboard for managing policies, generating infrastructure, and viewing audit logs.docker-compose.yml: Container orchestration for local and beta deployments.
Generator
GetMCP turns an OpenAPI spec into two runnable MCP servers (Internal + External). Endpoints are scored by an LLM classifier on four axes (data sensitivity, mutation impact, tenant scope, reversibility), cached by canonical spec hash, and overridable per endpoint by your security team.
KEY=<your-gmcp_-key>
# Classify (cached on second call for the same spec — no LLM cost)
curl -X POST http://localhost:3000/generator/classify \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"openapiUrl":"https://petstore3.swagger.io/api/v3/openapi.json"}'
# Flip an endpoint manually (or clear with "exposeExternally": null)
curl -X POST http://localhost:3000/generator/override \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"specHash":"...","path":"/admin/users","method":"delete","exposeExternally":true,"reason":"audited"}'
# Generate the Two-MCP split (uses cached classifications + overrides)
curl -X POST http://localhost:3000/generator/generate \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"openapiUrl":"https://petstore3.swagger.io/api/v3/openapi.json"}'
# Download the runnable scaffold (zip)
curl -G "http://localhost:3000/generator/export" \
-H "Authorization: Bearer $KEY" --data-urlencode "openapiUrl=..." -o getmcp.zip
The exported zip contains real, runnable Node MCP servers — pinned @modelcontextprotocol/sdk@1.0.4, one tool per (method, path), reads schema.json at startup, forwards calls to UPSTREAM_BASE_URL via fetch. cd internal-mcp && npm install && UPSTREAM_BASE_URL=... npm start works out of the box.
Set ANTHROPIC_API_KEY to enable the LLM classifier. Without it, the generator falls back to keyword heuristics (deterministic, no network call, lower accuracy).
Operability
- Logs: structured JSON via pino, one line per request. Each line carries
req.id(sourced fromx-request-idheader or generated). Override level withLOG_LEVEL=debug|info|warn|error|silent. - Health:
GET /health/live(process up),GET /health/ready(DB reachable). Both@Public. - Metrics:
GET /metricsexposes Prometheus text. Series:getmcp_proxy_requests_total{action,source,upstream_status}— proxy outcomesgetmcp_proxy_request_duration_ms_bucket{action,source}— controller-entry to response-finish latency histogramgetmcp_policy_decisions_total{kind}— engine outcome distributiongetmcp_audit_writes_total{result}—okvsfailedaudit writes (the headline reliability metric)getmcp_approval_events_total{event}— created / approved / denied / expired- Plus
getmcp_*Node defaults (CPU, heap, event loop lag).
- Migrations:
prisma migrateis the deploy path;db pushis gone. Initial migration committed underapps/api/prisma/migrations/20260515000000_init. - Shutdown:
enableShutdownHooks()on SIGINT/SIGTERM drains in-flight requests, closes Prisma, stops the approval sweeper.
Authentication
Every API endpoint (except /health) requires an Authorization: Bearer <api-key> header scoped to an Organization. Keys are minted by the seed script and via the /orgs endpoints (see apps/api/src/auth). All Prisma queries are filtered by the authenticated organization — see the tenant-isolation tests in apps/api/src/auth/auth.spec.ts.
Configuring an upstream
The proxy forwards requests to a per-organization downstream API. Set it via:
KEY=<your-gmcp_-key>
curl -X PATCH http://localhost:3000/orgs/me \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"upstreamBaseUrl": "https://api.stripe.com",
"upstreamAuthHeader": "Bearer sk_test_...",
"upstreamTimeoutMs": 10000
}'
upstreamAuthHeader is encrypted at rest with KEY_ENCRYPTION_KEY (AES-256-GCM) and never returned by the API. Then call:
curl -X POST http://localhost:3000/proxy/execute \
-H "Authorization: Bearer $KEY" \
-H "x-agent-source: internal_mcp" \
-H "Content-Type: application/json" \
-d '{"method":"GET","path":"/v1/charges"}'
The upstream's status code, headers, and body stream through faithfully. Upstream timeouts return 504, connection errors return 502.
Agents
`POST /proxy/exe
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
84.2kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
73.4kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
ruflo
73.0k🌊 The original agent harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, federation, vector RAG integration, and native Claude Code / Codex / Hermes and many more Integrated
CowAgent
47.1kOpen-source super AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
