|
| 1 | +# mcp4openapi - Enterprise MCP Gateway |
| 2 | + |
| 3 | +## What This Is |
| 4 | + |
| 5 | +A centralized, enterprise-grade MCP gateway that acts as the single front door for all AI clients |
| 6 | +inside the company to reach upstream MCP servers. It authenticates clients via SSO/OIDC or API |
| 7 | +keys, enforces team-level tool access policies, and forwards tool calls to upstream remote HTTP MCP |
| 8 | +servers (internal services and third-party SaaS) using credentials supplied by the client at session |
| 9 | +initialization - the gateway itself stores no upstream secrets. |
| 10 | + |
| 11 | +Built on top of the existing mcp4openapi server, extending it from an OpenAPI-to-MCP adapter into a |
| 12 | +full MCP proxy/gate. |
| 13 | + |
| 14 | +## Core Value |
| 15 | + |
| 16 | +A security boundary between internal AI clients and all upstream MCP servers: one place to |
| 17 | +authenticate, authorize, audit, and proxy every tool call in the company. |
| 18 | + |
| 19 | +## Requirements |
| 20 | + |
| 21 | +### Validated |
| 22 | + |
| 23 | +- Existing capabilities already shipped and working: |
| 24 | +- ✓ MCP server over HTTP (SSE, sessions, MCP spec 2025-03-26) - existing |
| 25 | +- ✓ Profile-driven configuration with Zod-validated schemas - existing |
| 26 | +- ✓ OpenAPI-backed tool generation from REST APIs - existing |
| 27 | +- ✓ OAuth 2.0 provider (PKCE, DCR, token exchange) - existing |
| 28 | +- ✓ Multi-auth support (bearer, query, custom header, OAuth) - existing |
| 29 | +- ✓ Multi-tenant HTTP transport with session isolation - existing |
| 30 | +- ✓ Rate limiting, SSRF protection, token redaction - existing |
| 31 | +- ✓ Prometheus metrics emission (prom-client) - existing |
| 32 | +- ✓ Upstream MCP provider config schema (UpstreamMcpProvider type, Zod schemas) - existing (PR #219) |
| 33 | + |
| 34 | +### Validated |
| 35 | + |
| 36 | +- ✓ Upstream session lifecycle (Phase 01) - per-session `UpstreamConnectionManager` with lazy connect, concurrent-safe `getOrConnect`, heartbeat pings, and session-scoped cleanup wired into HTTP transport destruction lifecycle |
| 37 | +- ✓ Pass-through credential forwarding (Phase 01) - client-supplied Bearer token forwarded directly to upstream; profile-per-upstream model; no credential storage on gateway; `validateCredentials` with SSRF-protected `validation_endpoint` for early auth validation |
| 38 | +- ✓ Auth redaction hardening (Phase 01) - `sanitizeAuthErrorMessage` preserves last-4 Bearer suffix for debuggability; `redactString` fully redacts; token never appears in logs or error responses |
| 39 | + |
| 40 | +### Active |
| 41 | +- [ ] Upstream tool discovery and proxy - tools/list and tools/call forwarded to correct upstream |
| 42 | + provider; upstream tools appear in tools/list alongside (or instead of) OpenAPI-backed tools |
| 43 | +- [ ] Tool namespacing - upstream tool names prefixed/namespaced to prevent collisions across |
| 44 | + providers (#215) |
| 45 | +- [ ] Team-level allow/deny policy - each client identity (team/API key/SSO principal) maps to a |
| 46 | + policy that allows or denies specific upstream servers and/or tool names (#216) |
| 47 | +- [ ] Client authentication gate - SSO/OIDC (Entra ID / Okta / Keycloak) for interactive clients; |
| 48 | + API keys for M2M; identity resolved before any tool call is processed |
| 49 | +- [ ] Upstream notification forwarding - tools/list_changed and other server-initiated upstream |
| 50 | + notifications forwarded to downstream SSE clients with replay on reconnect (#214) |
| 51 | +- [ ] Audit log - structured persistent log of every tool call: client identity, team, tool name, |
| 52 | + upstream server, outcome, timestamp |
| 53 | +- [ ] Request tracing - OpenTelemetry trace context propagated through gateway and forwarded to |
| 54 | + upstream where possible |
| 55 | +- [ ] Third-party SaaS MCP proxy - remote HTTP MCP endpoints for services like GitHub, Slack, etc. |
| 56 | + supported through the same upstream provider config model |
| 57 | +- [ ] End-to-end documentation and test coverage for proxy mode (#218) |
| 58 | + |
| 59 | +### Out of Scope |
| 60 | + |
| 61 | +- Stdio upstream MCP processes - execution boundary undefined, risk of process isolation issues; |
| 62 | + deferred to a later phase behind an explicit feature gate (#217) |
| 63 | +- Server-side upstream credential storage - pass-through model replaces the need; vault integration |
| 64 | + adds complexity without benefit given the chosen auth model |
| 65 | +- Attribute-based access control (ABAC) - team-level allow/deny covers v1 needs; ABAC adds |
| 66 | + authoring overhead before any team has adopted the gateway |
| 67 | +- Public internet exposure - on-prem/private cloud deployment only; no multi-cloud SaaS distribution |
| 68 | + in scope |
| 69 | + |
| 70 | +## Context |
| 71 | + |
| 72 | +- **Existing codebase:** mcp4openapi is a TypeScript/Node.js MCP server (Express, MCP SDK 1.26.0, |
| 73 | + jose for JWT, Zod for schema validation). The HTTP transport already handles SSE sessions, |
| 74 | + multi-tenancy, OAuth provider, and interceptor chains (auth -> rate-limit -> retry -> fetch). |
| 75 | +- **Tracking issue:** davidruzicka/mcp4openapi#211 groups the full MCP proxy roadmap. Issues |
| 76 | + #213-#218 map directly to the active requirements above. #212 (upstream config schema) is done. |
| 77 | +- **Deployment target:** On-prem / private cloud. No public internet exposure. Docker/Kubernetes |
| 78 | + packaging assumed. |
| 79 | +- **Client auth model:** SSO/OIDC tokens from the company IdP (Entra ID, Okta, Keycloak) for |
| 80 | + interactive users; API keys for machine-to-machine. Both paths must resolve to a team identity |
| 81 | + before policy is checked. |
| 82 | +- **Upstream auth model:** Pass-through. Clients supply their own upstream credentials at HTTP |
| 83 | + session initialization. The gateway extracts and stores them in the session context, then forwards |
| 84 | + them on each upstream call. No credential storage or rotation responsibility on the gateway. |
| 85 | +- **Security posture:** SSRF protection already in place. Token redaction in logs. Trust boundaries: |
| 86 | + inbound client auth and upstream auth are fully separate layers. |
| 87 | + |
| 88 | +## Constraints |
| 89 | + |
| 90 | +- **Tech stack:** TypeScript 5 / Node.js 22 / ESM - no runtime changes; extend, don't replace |
| 91 | +- **MCP protocol:** MCP spec 2025-03-26 compliance must be preserved end-to-end (client <-> gateway |
| 92 | + <-> upstream) |
| 93 | +- **Security:** Inbound client identity must be verified before any upstream connection is |
| 94 | + established; upstream credentials must never leak into logs or error responses |
| 95 | +- **Compatibility:** Existing OpenAPI-backed tool generation must continue working unchanged; |
| 96 | + proxy mode is additive, not a replacement |
| 97 | + |
| 98 | +## Key Decisions |
| 99 | + |
| 100 | +| Decision | Rationale | Outcome | |
| 101 | +|----------|-----------|---------| |
| 102 | +| Pass-through upstream credentials | Gateway stores no secrets - client owns their own upstream tokens; simpler security model, no vault dependency | Validated in Phase 01 - profile-per-upstream model, `token: string \| undefined` passed directly | |
| 103 | +| Profile-per-upstream (not session-level credential aggregation) | Simpler than per-session credential bag; one profile = one upstream = one token env var | Validated in Phase 01 - dead X-Upstream-Authorization extractor removed | |
| 104 | +| Remote HTTP upstream first, stdio deferred | Stdio adds process isolation complexity; HTTP upstream covers the primary enterprise use case first | - Pending | |
| 105 | +| Build on mcp4openapi transport stack | Existing SSE session management, OAuth provider, multi-tenant HTTP transport are production-grade; extend rather than rewrite | - Pending | |
| 106 | +| Team-level allow/deny (not RBAC/ABAC) | Explicit allow/deny per team is auditable and predictable; ABAC adds authoring overhead before adoption | - Pending | |
| 107 | +| Tool namespacing by upstream provider | Prevents tool name collisions across providers; makes audit logs and policy rules unambiguous | - Pending | |
| 108 | + |
| 109 | +--- |
| 110 | +*Last updated: 2026-03-30 after Phase 01 completion* |
| 111 | + |
| 112 | +## Evolution |
| 113 | + |
| 114 | +This document evolves at phase transitions and milestone boundaries. |
| 115 | + |
| 116 | +**After each phase transition** (via `/gsd:transition`): |
| 117 | +1. Requirements invalidated? -> Move to Out of Scope with reason |
| 118 | +2. Requirements validated? -> Move to Validated with phase reference |
| 119 | +3. New requirements emerged? -> Add to Active |
| 120 | +4. Decisions to log? -> Add to Key Decisions |
| 121 | +5. "What This Is" still accurate? -> Update if drifted |
| 122 | + |
| 123 | +**After each milestone** (via `/gsd:complete-milestone`): |
| 124 | +1. Full review of all sections |
| 125 | +2. Core Value check - still the right priority? |
| 126 | +3. Audit Out of Scope - reasons still valid? |
| 127 | +4. Update Context with current state |
0 commit comments