Reference Brief / MCP Enterprise Platform
Production deployment of the Model Context Protocol
spec 2025-11-25OAuth 2.1JSON-RPC 2.0 Centralized portal, identity-brokered, audit-centralized, DLP-enforced. Streamable HTTP transport only in production; stdio retired except development.
Components
Architecture path
Centralized portal
Platform team owns deployment via monorepo template. New servers inherit CI/CD, secrets, default-deny writes, audit, rate limits, kill switch. Approval through AI governance.
Federated by team
Each team owns its servers; consumes shared identity + audit + DLP. Risk: low-investment team degrades posture for every consumer.
Vetted marketplace
Servers reviewed, listed, subscribed. Reasonable externally; internally collapses back to portal model unless paired with one.
Local-only (deprecated)
Acceptable for development inner loops, individual experimentation, MCPs requiring developer-machine filesystem. Not in production.
Transport (Streamable HTTP)
| method | path | purpose |
|---|---|---|
POST | /mcp | client → server JSON-RPC; response application/json or text/event-stream |
GET | /mcp | long-lived SSE for server-initiated messages; resume via Last-Event-Id |
DELETE | /mcp | terminate session by Mcp-Session-Id |
| header | direction | purpose |
|---|---|---|
Mcp-Session-Id | both | session id; server issues on initialize, client echoes |
MCP-Protocol-Version | client | protocol revision; e.g. 2025-11-25 |
Last-Event-Id | client | SSE resume cursor on reconnect |
Origin | client | required; server returns 403 on invalid Origin (added 2025-11-25) |
WWW-Authenticate | server | on 401, points to PRM document; carries scope challenges (SEP-835) |
Authorization | client | Bearer token; audience-bound per RFC 8707 |
| aspect | stdio | streamable HTTP |
|---|---|---|
| shape | subprocess per client | long-lived service |
| cache | resets per session | steady state, multi-client share |
| auth | implicit, process boundary | explicit via Authorization |
| audit | fragmented per user | centralized to SIEM |
| updates | user must rebuild | deploy once |
| resume | not supported | Last-Event-Id |
Authorization (OAuth 2.1)
- OAuth 2.1 mandatory for MCP servers as resource servers. Clients implement DCR (RFC 7591) or OAuth Client ID Metadata Documents (SEP-991, added 2025-11-25).
- RFC 9728 (Protected Resource Metadata) mandatory for servers.
401response carriesWWW-Authenticatewithresource_metadataURL pointing to/.well-known/oauth-protected-resource; document declaresauthorization_servers. - RFC 8707 (Resource Indicators) mandatory for clients.
resourceparameter on token requests binds the access token to a specific MCP server URL; without it tokens are ambient and leak across resources. - AS metadata via RFC 8414 at
/.well-known/oauth-authorization-server. OpenID Connect Discovery 1.0 also supported (added 2025-11-25). - Per-tool scopes:
mcp:read,mcp:write,mcp:exec. Validate signature, audience (RFC 8707 §2), expiry every call. - Incremental scope consent via
WWW-Authenticate(SEP-835). Client steps up scope mid-session without full re-auth. - URL Mode Elicitation (2025-11-25): server sends user to external OAuth flow in browser; credentials never transit MCP client. Enables PCI-compliant payment, third-party authorization without token passthrough.
- Token rotation under 24h. Insufficient authentication / authorization is OWASP MCP07; privilege escalation via scope creep is MCP02.
Wire format
Observability
- Per-call audit: caller, tool, params (sensitive fields redacted), outcome, latency, policy decisions (rate limit, deny list, kill switch). Lack of audit and telemetry is OWASP MCP08.
- Real-time ship to SIEM via OpenTelemetry / Vector / fluentd. Append-only on receiver. Cryptographic chaining for high-stakes audit.
- DLP at portal: per-tool rules block PII / PHI / secrets / source-with-keys. Context injection & over-sharing is OWASP MCP10.
- Token-shape regex redaction at log layer; token mismanagement is MCP01. No long-lived tokens in logs.
Multi-tenancy
- Portals are the policy boundary; upstream servers stay group-unaware.
- One upstream MCP behind multiple portals with different scopes, policies, audit streams.
- Cache keys must include tenant identity to prevent cross-tenant leakage.
Code Mode novel
- Code Mode collapses upstream tool catalogs to 2 portal tools:
portal_codemode_search,portal_codemode_execute. - Model writes JS against discovery + execution proxies in sandboxed runtime (Cloudflare Dynamic Workers in their reference implementation).
- Reported: 52 tools / 9,400 tokens to 2 / 600 (94% reduction); cost fixed regardless of MCP count.
- Trade-off: model-written code is itself an injection surface. Command injection & execution is OWASP MCP05.
- Phase 6 optimization. Pilot after base platform stable.
Shadow MCP
- Shadow MCP servers = OWASP MCP09. Unsanctioned servers accessed outside the portal.
- SWG detection:
/mcpand/mcp/ssepaths, JSON-RPC method strings (tools/call,tools/list,initialize,sampling/createMessage),Mcp-Session-Idheader presence. - DLP regex on body:
"method"\s*:\s*"tools/(call|list)";"protocolVersion"\s*:\s*"202[5-6]-[0-9]{2}-[0-9]{2}". - Action: block at egress, log to investigation queue.
First-party policy
- Mandate: every internal service exposed via MCP ships a first-party server. No community packages of unknown provenance.
- Vendors publish official MCPs to prevent customer consumption of third-party packages. Supply chain attacks & dependency tampering is OWASP MCP04.
- SBOM scanned every build. Tool poisoning (MCP03) sub-techniques: rug pulls, schema poisoning, tool shadowing.
Threat model: OWASP MCP Top 10 (2025)
| id | category | primary control surface |
|---|---|---|
MCP01 | token mismanagement & secret exposure | vault-backed creds, log redaction, rotation under 24h |
MCP02 | privilege escalation via scope creep | scope minimization, periodic review, JIT elevation |
MCP03 | tool poisoning | signed manifests, code review of descriptions, no runtime templating |
MCP04 | supply chain attacks & dependency tampering | SBOM, internal mirror, signed releases, first-party only |
MCP05 | command injection & execution | command allowlist at schema, sandbox, syscall filter |
MCP06 | prompt injection via contextual payloads | output sanitization, structured envelopes, instruction-pattern stripping |
MCP07 | insufficient authentication & authorization | OAuth 2.1 + RFC 9728 + RFC 8707, validate every call |
MCP08 | lack of audit and telemetry | per-call SIEM shipping, append-only, chained logs |
MCP09 | shadow MCP servers | SWG detection, egress blocking, audit proxy |
MCP10 | context injection & over-sharing | DLP at portal, classification tagging, flow analysis |
Threat-model deltas (local → shared)
| risk | local | shared |
|---|---|---|
| credential exposure (MCP01) | user shell, kubeconfig, netrc | service account, vault-backed |
| scope creep (MCP02) | drift unmanaged | portal enforces scope on every call |
| tool poisoning (MCP03) | unmanaged updates | signed manifests, version pin |
| supply chain (MCP04) | unvetted public registry | curated, signed releases |
| command injection (MCP05) | user shell as sandbox | isolated runtime + allowlist |
| prompt injection (MCP06) | per-user impact | wider blast radius across users |
| authn/authz (MCP07) | implicit | explicit; OAuth 2.1 must be enforced |
| audit (MCP08) | per-user, opaque | centralized to SIEM |
| shadow MCP (MCP09) | undetectable | SWG detects + blocks |
| over-sharing (MCP10) | no DLP layer | portal-level DLP rules |
Transition phases
- Inventory existing MCP usage. SWG identifies gaps.
- Stand up portal; integrate identity (OAuth 2.1 + RFC 9728 + RFC 8707), audit, DLP.
- Migrate low-risk MCP. Validate per-call authz, session lifecycle, SSE resume.
- Migrate high-traffic MCP with full hardening (rate limits, deny lists, response shaping, circuit breaker, cardinality estimation where applicable).
- Block local at policy + network for migrated upstreams. SWG enforces.
- Roll out remaining servers. High-risk surfaces (shell exec, code exec, fs-write) sit last.
- Pilot Code Mode. Measure token reduction in production traffic. Default-on if sandbox holds under adversarial input.
Decision points
| question | recommendation |
|---|---|
| portal stack | adopt where possible; portal logic is generic |
| identity broker | extend existing IdP; no new identity surface |
| AI Gateway | defer until LLM cost is material |
| DLP engine | integrate existing; do not roll your own |
| Code Mode | phase 6, not first move |
| shell-exec / code-exec MCPs | restrict to dev local; do not place behind shared portal without heavy sandbox |
| first-party policy | mandate for any service exposed via MCP |
| OIDC vs OAuth-only | OIDC Discovery 1.0 supported as of 2025-11-25; use if existing IdP speaks it |