Why does a local MCP server need a public URL?
MCP (Model Context Protocol) servers speak one of two transports: stdio, where the client starts the server as a local process, and streamable HTTP (and the older HTTP+SSE), which works over the network. Claude Desktop can launch local stdio servers from its config file. Custom connectors in Claude are different: according to Anthropic's help center, Claude connects to your remote MCP server from Anthropic's cloud infrastructure. localhost:8000 means nothing there; the server needs an HTTPS address that is reachable from the internet.
The same need shows up elsewhere: using a tool that runs on your home machine from Claude Code at work, letting a teammate try your server, or giving a CI job access to it.
What is the risk of exposing MCP without authentication?
The authorization section of the MCP specification says it plainly: authorization is OPTIONAL for MCP implementations. Many servers therefore run with no login at all. Two independent studies show how common that is:
- Knostic (July 17, 2025) found 1,862 MCP servers exposed to the internet. All 119 that it verified by hand returned their internal tool list without authentication.
- Trend Micro (TrendAI, April 28, 2026) counted 1,467 exposed MCP servers in its latest scan, up from 492 in its July 2025 report. 1,227 of them use the legacy SSE transport, and an
execute_sqltool showed up on 70 hosts.
If a tool can read files, query a database or run commands, an unauthenticated tunnel URL hands that power to anyone who finds it. A hard-to-guess URL is not access control.
How does Zorven's tunnel MCP mode work?
The tunnel MCP mode turns an HTTP tunnel into a protected MCP endpoint. You find it in the panel under Tunnels > your tunnel > MCP (API: GET/PUT /api/v1/tunnels/{id}/mcp). In short:
| Setting | What it does |
|---|---|
| Authentication: OAuth (recommended, default) | Zorven acts as the authorization server; the tunnel is advertised as an RFC 9728 protected resource and tokens are bound to the tunnel URL. Clients sign in with a Zorven account. |
| Who may connect | Members of the tunnel's organization and/or Zorven accounts with a verified e-mail on your list. *@example.com allows a whole domain. An empty list allows nobody besides the members. |
| Authentication: API key | zmk_... keys sent as Authorization: Bearer or X-API-Key. Keys are shown once and can expire. |
| Authentication: None | Anyone with the URL can call every tool. Requires an explicit acknowledgement; not recommended. |
| Tool allow / deny list | * and ? patterns; deny wins. A blocked call gets a JSON-RPC error and never reaches your server, and tools/list responses are filtered too. |
| Rate limit, streams, timeouts | Tool calls per minute, max open streams, response header and idle stream timeouts. SSE and streamable HTTP pass through unbuffered. |
| Call log and analytics | Method, tool name, status and duration only; arguments and results are never stored. |
In OAuth or API key mode every path of the tunnel requires authentication; unauthenticated requests never reach your server. Zorven does not forward the client's token upstream and strips any X-Zorven-* headers the client sends. It adds the identity it verified as X-Zorven-User, X-Zorven-User-Id, X-Zorven-Scopes and others, plus a signed X-Zorven-Identity header valid for 60 seconds. That matches the MCP spec's rule against token passthrough.
Step 1: Run your MCP server over HTTP locally
Your server has to listen on streamable HTTP (or legacy SSE). A stdio-only server cannot be published through a tunnel; enable the HTTP transport in your MCP library. In this example the server runs at http://localhost:8000/mcp.
Step 2: Install the Zorven client and open a tunnel
Install the client from the Download page, save the client token from the panel and publish the port:
zorven authtoken zrv_live_...
zorven http 8000
The https://<name>--slug.zorven.app address in the output is your tunnel host. Installation details are in the docs.
Step 3: Turn on MCP mode and choose sign-in
- Open the tunnel on the Tunnels page, switch to the MCP tab and enable MCP mode.
- Keep OAuth as the authentication. If only you will use it, organization members is enough; for others, add their Zorven account e-mails, one per line.
- Optionally put write or delete tools on the Tool allow / deny list (for example
delete_*on the blocked list). - Save and press Test connection. The panel checks that the agent is online, that authentication is ready, and that
initializeandtools/listwork. - Copy the Connection URL (the default path is
/mcp).
Step 4: Connect Claude, Claude Code or Cursor
Claude (web and desktop): under Customize > Connectors, choose "Add custom connector" and paste the URL. When you connect, Zorven's consent screen opens; sign in with your Zorven account and approve. On Team and Enterprise plans an organization owner adds the connector.
Claude Code:
claude mcp add --transport http my-server https://<your-tunnel-host>/mcp
Then run /mcp inside Claude Code and finish the sign-in in your browser.
API key mode (CI or any client that can send headers):
claude mcp add --transport http my-server https://<your-tunnel-host>/mcp \
--header "Authorization: Bearer zmk_..."
In Cursor, the same key goes into ~/.cursor/mcp.json with the url and headers fields.
Step 5: Watch usage and revoke access
Tool analytics in the MCP tab show calls, errors and blocked calls per tool. To remove one person, delete their e-mail from the list; to sign everyone out at once, use End all connected sessions. Deleting an API key cuts off clients using it immediately.
How do I manage Zorven itself from an AI client? (zorven mcp)
This is a separate feature: Zorven is also an MCP server. The assistant can read your devices, tunnels, domains and request logs, and create tunnels and domains. Delete tools only appear with the separately granted tunnels:delete / hostnames:delete scopes. It needs API access, so it works on Pro and above.
- Remote:
https://zorven.app/mcp. Add it in Claude as a custom connector (OAuth, no API key needed), or in Claude Code withclaude mcp add --transport http zorven https://zorven.app/mcp --header "Authorization: Bearer zrv_api_...". - Local (stdio):
ZORVEN_API_TOKEN=zrv_api_... zorven mcp. In Claude Desktop's config use"command": "zorven", "args": ["mcp"]; the token never leaves your machine.
Create the API token on the API & Security page of the panel; the *:read scopes are enough for read-only use. Details are in the docs.
When should you choose something else?
- If only Claude Desktop or Claude Code on the same machine uses the server, you don't need a tunnel; stdio is enough.
- If your users cannot create a Zorven account, OAuth mode does not fit; use API key mode. The tunnel MCP mode has no GitHub or Google sign-in, only Zorven accounts.
- A server that browsers must call directly with a CORS preflight is not a fit; OPTIONS requests need authentication too.
- A generic "run command" tool that takes a name as a parameter is not protected by tool name lists; remove dangerous tools on the server side.
Frequently asked questions
Read next
- Zorven for developers: webhooks, demos, APIs and CI/CD.
- Pricing: plan limits and which feature starts on which plan.
- Test webhooks locally and What is CGNAT?
- The ngrok alternative comparison and all guides.
Sources
- Model Context Protocol, Authorization (2025-06-18): modelcontextprotocol.io/specification/2025-06-18/basic/authorization (accessed 2026-11-08)
- Knostic, "Exposing the Unseen: Mapping MCP Servers Across the Internet": knostic.ai/blog/mapping-mcp-servers-study (accessed 2026-11-08)
- Trend Micro (TrendAI), "Update on Exposed MCP Servers: The Threat Widens to the Cloud": trendaisecurity.com (accessed 2026-11-08)
- Claude Help Center, "Get started with custom connectors using remote MCP": support.claude.com/en/articles/11175166 (accessed 2026-11-08)
- Claude Code, "Connect Claude Code to tools via MCP": code.claude.com/docs/en/mcp (accessed 2026-11-08)