An MCP server for safe API calls from AI agents
corsproxy.dev now runs a remote MCP server. Connect it to Claude Code, Cursor, or your own agent, and the agent can call third-party APIs through your key without ever seeing the API's secret, without reaching internal addresses, and without running up an unbounded bill.
Agents don't have a CORS problem. They have a secrets problem.
An agent runs on a server or your laptop, not in a browser, so the browser's CORS check never applies to it. What goes wrong when an agent calls an API is different:
- The key ends up in the model's context. To call an API that needs a secret, the agent usually has to see the secret. From there it can show up in a transcript or a log, or be talked out of the model by text planted in a web page or document the agent reads (prompt injection).
- The agent can be pointed at internal addresses. Injected text can ask it to "fetch
http://169.254.169.254/…", the address where cloud servers expose their credentials. That's SSRF with a language model as the relay. - Loops cost money. An agent that retries forever calls a paid API forever.
These are the same problems a browser app has with third-party APIs, which is what corsproxy.dev was built for.
What the MCP server does
It lives at https://api.corsproxy.dev/mcp and has three tools:
fetch_urlsends a real request through the proxy (any method, headers, body, optionalttlcaching) and returns the status, CORS and rate-limit headers, and body.check_quotareports today's limit, used, and remaining.explain_errorturns a reason key likeAPI_KEY_ORIGIN_NOT_ALLOWEDinto what it means and how to fix it.
Setup in Claude Code is one command:
claude mcp add --transport http corsproxy https://api.corsproxy.dev/mcp \
--header "X-API-Key: sk_live_..." \
--header "Origin: http://localhost:3000"
It authenticates like any server-side call: your corsproxy.dev key plus an origin that key allows (Free keys always allow localhost). Other clients take the same URL and headers in their mcp.json; see the MCP docs.
The server is also listed on the official MCP Registry as dev.corsproxy/mcp, domain-verified, so clients that support registry discovery can find it without the manual add command above.
Keeping the secret out of the model
fetch_url runs through the same proxy as your browser traffic, so a key's managed upstream headers apply. Store the provider secret on the corsproxy.dev key once:
"upstream_rules": [{
"target_host": "api.openai.com",
"path_prefix": "/v1/chat/completions",
"headers": { "Authorization": "Bearer sk-YOUR_OPENAI_KEY" }
}]
Now the agent calls https://api.openai.com/v1/chat/completions through fetch_url, and the proxy adds the Authorization header on the way out. The agent only ever holds your corsproxy.dev key, which is limited to that host and path, so there's no OpenAI key in its context to leak or be tricked into revealing. We walk through the same pattern for browser apps in keeping API keys out of the browser.
Guardrails you get by default
- Internal addresses are refused. Loopback, private ranges, link-local (including the
169.254.169.254metadata address), carrier-grade NAT, and private IPv6 all returnBLOCKED_HOST. - A hard daily quota. When the account's limit is reached, calls return
RATE_LIMIT_EXCEEDEDuntil midnight UTC. See how the quota works. - Only the APIs you choose. Give the agent's key an allowed-target-hosts list (e.g. just
api.openai.com) and every other host returnsTARGET_NOT_ALLOWED, even if the agent is tricked into trying. - Clear failures. Every rejection carries a stable reason key the agent can read and act on, instead of a vague error.
What it doesn't do yet
- It doesn't expose your logs. API keys can be public browser credentials, so the MCP server only does what a key can already do. Reading logs from an assistant will need a separate private token.
- MCP calls don't appear in the Logs tab yet. They do count against your quota.
- DNS isn't checked. A public hostname that resolves to a private address isn't caught by the address check. On Cloudflare's network, where the proxy runs, private networks aren't reachable anyway.
Try it
Get a free API key, then add the MCP server with the command above. 500 requests/day on Free, 20,000/day on Pro.