Skip to main content

Protect an MCP Server

Use Pomerium to expose an internal MCP server to MCP clients (Claude, ChatGPT, VS Code, and others) without adding authentication logic to the server itself.

What you get:

  • External MCP clients authenticate through Pomerium — your server stays auth-free
  • Deny-based policies block destructive tools while allowing everything else
  • Full observability of every tool call via authorize log fields

Architecture

MCP ServerPomeriumMCP ClientMCP ServerPomeriumMCP ClientUserAdds a server URLRegisters client, initiates authSign-in URLRedirect to sign-in URLSign-inRedirect to clientObtain TokenGET https://mcp-server Authorization: Bearer TokenProxy request to MCP ServerUser

Configuration

runtime_flags:
mcp: true

routes:
- from: https://my-mcp-server.your-domain.com
to: http://my-mcp-server.int:8080/mcp
name: My MCP Server
mcp:
server: {} # the brackets are significant, they indicate that this is an MCP server route
policy:
allow:
and:
- domain:
is: company.com
# Block destructive tools (example: any tool prefixed with admin_)
deny:
and:
- mcp_tool:
starts_with: 'admin_'
Experimental Feature

MCP support is currently an experimental feature only available in the main branch or Docker images built from main. To enable MCP functionality, you must set runtime_flags.mcp: true in your Pomerium configuration.

Step-by-step

1. Run your MCP server

Start any MCP server that speaks the HTTP Streamable transport. It does not need to handle authentication — Pomerium takes care of that.

# Example: start one of the sample servers from the pomerium/mcp-servers repo
docker compose up -d

2. Add the route to Pomerium

Add the route configuration shown above to your Pomerium config. Key points:

  • mcp.server: {} tells Pomerium this route fronts an MCP server
  • The policy block controls who can access the server and which tools are allowed
  • See Limit MCP Tool Calling for advanced policy patterns

3. Connect an MCP client

Point any MCP-compatible client at the Pomerium route URL. The client will go through Pomerium's OAuth flow, receive a bearer token, and use it for all subsequent requests.

Server URL: https://my-mcp-server.your-domain.com

4. Verify with the MCP Inspector

Use the MCP Inspector to confirm connectivity:

npx -y @modelcontextprotocol/inspector@latest
  • Transport type: Streamable HTTP
  • URL: https://my-mcp-server.your-domain.com
  • Enable OAuth (Quick OAuth Flow)
  • Click Connect, then Tools → List Tools

Sample repos and next steps

Feedback