Skip to main content

MCP Security

Security hardening profile for Forge MCP (Streamable HTTP).

Baseline

Use MCP with explicit exposure and strict transport settings:

[mcp]
enabled = true
path = "/mcp"
session_ttl_secs = 3600
allowed_origins = ["https://your-app.example"]
require_protocol_version_header = true

Hardening Checklist

  1. Keep MCP disabled by default (enabled = false) in environments that do not need it.
  2. Restrict allowed_origins for browser-based clients.
  3. Require MCP-Protocol-Version header and reject unsupported versions.
  4. Use short session_ttl_secs to limit stale session reuse.
  5. Prefer private tools by default; use public only when necessary.
  6. Add require_role("...") for sensitive tools.
  7. Add rate_limit(...) and timeout to every external-facing tool.

Authentication

Forge MCP tools reuse Forge auth middleware:

  • JWT verification via HMAC or RSA/JWKS
  • tools are private by default unless marked public
  • issuer/audience validation
  • role-based authorization via require_role("...")

Recommended RSA/JWKS setup:

[auth]
jwt_algorithm = "RS256"
jwks_url = "https://your-provider.com/.well-known/jwks.json"
jwt_issuer = "https://your-provider.com"
jwt_audience = "your-app"

OAuth Security

When mcp.oauth = true, Forge adds OAuth 2.1 Authorization Code + PKCE:

  • PKCE (S256 only): prevents authorization code interception. Plain method intentionally unsupported.
  • Authorization codes: 60s TTL, single-use (atomic exchange prevents replay).
  • CSRF protection: server-generated token validated via HttpOnly cookie on the authorize page.
  • Redirect URI validation: exact string match against registered URIs (RFC 8252 localhost port exception).
  • Token audience: OAuth-issued JWTs include aud: "forge:mcp", scoping them to MCP endpoints only.
  • Client-bound refresh tokens: refresh tokens are bound to the OAuth client that created them.
  • Rate limits: client registration (10/min per IP, 1000 client cap), login attempts (5 failures/min per IP).
  • Clickjacking: X-Frame-Options: DENY and CSP frame-ancestors 'none' on the authorize page.
  • Code leakage: Referrer-Policy: no-referrer on authorization redirects.

Error Policy

  • Protocol errors (-32600, -32601, -32602, -32603) for malformed requests and server-side internal failures.
  • Rate limiting returns error code -32029 with a retry-after hint.
  • Tool validation/business failures should return MCP tool results with isError: true.

This separation helps MCP clients and models recover from tool input errors while still treating protocol faults as transport-level failures.

Transport Notes

Forge MCP v1 is Streamable HTTP only.

  • POST handles MCP JSON-RPC request/notification payloads.
  • GET is not used for stream transport in v1 and returns 405.
  • Notification/response payloads accepted by the endpoint return 202.