Open-source proxy for MCP Apps — fixes CSP, handles auth, observes every tool call.
curl -fsSL https://raw.githubusercontent.com/cptrodgers/mcpr/main/scripts/install.sh | sh
mcpr --mcp http://localhost:9000MCP Apps (ChatGPT Apps, Claude connectors) run widgets inside sandboxed iframes. The sandbox blocks everything by default — API calls, images, fonts, scripts — unless you declare exactly the right CSP domains. Get it wrong and your widget silently doesn't render. No error. No hint. Just a blank iframe.
On top of that, your MCP server runs on one port, widgets on another, and AI clients need HTTPS. General proxies like ngrok don't understand MCP protocol, so you're left stitching together tunnels, headers, and CSP rules by hand.
mcpr fixes this. One binary. One command. Zero config.
Fixes CSP automatically. mcpr reads your MCP server's _meta.ui.csp declarations (connectDomains, resourceDomains, frameDomains) and injects the correct Content Security Policy headers. Your widgets render on the first try.
Merges MCP + widgets behind one URL. JSON-RPC requests route to your MCP server. Everything else serves your widgets. One origin, one tunnel, one URL to configure in ChatGPT or Claude.
Observes every tool call. Structured JSON events for every request — tool name, latency, session, status, CSP violations. Pipe to stdout, file, or mcpr.app for dashboards and replay.
Tunnels to production. Public HTTPS URL in one command. Stable across restarts. No ngrok subscription. Works with ChatGPT, Claude, and any MCP client.
mcpr --mcp http://localhost:9000
# → https://abc123.tunnel.mcpr.appmcpr --mcp http://localhost:9000 --widgets http://localhost:4444
# → https://abc123.tunnel.mcpr.app (one URL, two services)mcpr --mcp http://localhost:9000 --eventsEvery MCP request emits a structured JSON event:
{
"ts": "2026-04-03T10:15:30.142Z",
"type": "tool_call",
"method": "tools/call",
"tool": "search_products",
"session": "sess_abc123",
"latency_ms": 142,
"status": "ok",
"csp_applied": true
}For Claude Desktop, VS Code, or Cursor — no public URL needed.
mcpr --mcp http://localhost:9000 --no-tunnel --port 3000
# → http://localhost:3000/mcpYour machine AI client (ChatGPT / Claude)
┌─────────────────┐
│ MCP server :9000│◄──┐
└─────────────────┘ │
│ mcpr tunnel
├─────────────── ◄──────────── https://abc123.tunnel.mcpr.app
┌─────────────────┐ │ (CSP inject,
│ Widgets :4444 │◄──┘ events, auth)
└─────────────────┘
mcpr inspects every incoming request at the protocol level:
- JSON-RPC → routed to your MCP server (tool calls, discovery, sessions)
- Everything else → served as widget assets (HTML, JS, CSS, images)
Widget HTML is rewritten on the fly (lol_html streaming parser) so relative paths work correctly inside sandboxed iframes. CSP headers are injected based on your server's _meta.ui.csp metadata.
| mcpr | ngrok / Cloudflare Tunnel | Raw reverse proxy | |
|---|---|---|---|
| Understands MCP protocol | ✓ | ✗ | ✗ |
| Auto-injects CSP headers | ✓ | ✗ | ✗ |
| Rewrites widget HTML for sandboxed iframes | ✓ | ✗ | ✗ |
| Merges MCP + widgets behind one URL | ✓ | ✗ | Manual config |
| Structured MCP events (tool calls, sessions) | ✓ | ✗ | ✗ |
| Public HTTPS tunnel | ✓ | ✓ | ✗ |
| Free | ✓ | Paid for stable URLs | ✓ |
| Zero config | ✓ | ✓ | ✗ |
Test your MCP tools and preview widgets without an AI client subscription. Studio is available at cloud.mcpr.app:
- Call tools — execute MCP tools with custom input, see raw responses with timing
- Preview widgets — render widgets in ChatGPT and Claude simulation modes
- Inspect CSP — see which CSP rules are applied and what's being blocked
- Test OAuth — visualize and debug MCP OAuth flows end-to-end
mcpr works with zero config. For persistent settings, create mcpr.toml:
# mcpr.toml — minimal
mcp = "http://localhost:9000"
widgets = "http://localhost:4444"# mcpr.toml — production
mcp = "http://localhost:9000"
widgets = "./widgets/dist" # static files from disk
no_tunnel = true
port = 8080
[csp]
default = "default-src 'self'"
[logging]
format = "json"
level = "info"CLI args override everything:
mcpr [OPTIONS]
Options:
--version Print version
--mcp <URL> Upstream MCP server
--widgets <URL|PATH> Widget source (dev server URL or static directory)
--port <PORT> Local proxy port (default: 8080)
--events Emit structured JSON events to stdout
--csp <DOMAIN> Extra CSP domains (repeatable)
--csp-mode <MODE> CSP mode: "extend" (default) or "override"
--no-tunnel Local-only mode, no public URL
--relay-url <URL> Custom relay server
--relay Run as relay server
--relay-domain <DOMAIN> Relay base domain (relay mode)
Config precedence: CLI args > env vars > mcpr.toml > defaults
See config_examples/ for ready-to-use templates.
# Linux / macOS
curl -fsSL https://raw.githubusercontent.com/cptrodgers/mcpr/main/scripts/install.sh | sh
# Docker
docker run ghcr.io/cptrodgers/mcpr --mcp http://host.docker.internal:9000
# From source (Rust)
cargo install mcprservices:
mcpr:
image: ghcr.io/cptrodgers/mcpr:latest
ports:
- "8080:8080"
command: ["--mcp", "http://mcp-server:9000", "--no-tunnel", "--port", "8080", "--events"]Run your own tunnel relay instead of using tunnel.mcpr.app. Requires wildcard DNS and TLS termination.
See docs/DEPLOY_RELAY_SERVER.md for the full guide.
mcpr is under active development. Here's what's shipping next:
- MCP tunnel with stable URLs
- Widget HTML rewriting + CSP injection
- Structured event emitter (
--events) - Protocol-level request classification (MCP vs widget)
- Cloud Studio at mcpr.app
- Cloud event sync (one-line config)
- OAuth at the proxy layer via auth platforms (Supabase Auth, Better Auth, ...) or direct identity providers (Google, GitHub, ...)
- Tool-level ACL
- Production hardening (circuit breaker, retry, Redis sessions)
- Multi-server routing (one URL, many MCP backends)
See ROADMAP.md for details and discussion.
mcpr is a Rust workspace with 7 crates:
| Crate | Purpose |
|---|---|
mcpr-cli |
Binary entry point, TUI, config |
mcpr-core |
Proxy engine, router, forwarding |
mcpr-protocol |
JSON-RPC parser, MCP types |
mcpr-widgets |
CSP handling, HTML rewriting |
mcpr-tunnel |
Tunnel client + self-hosted relay |
mcpr-events |
Structured event system |
mcpr-session |
Session management |
Single binary. No runtime dependencies. Built with Axum + Tower.
Contributions welcome. Please open an issue to discuss before submitting PRs.
Apache 2.0 — see LICENSE for details.
