mcp-remote is a small bridge for MCP clients that can start local programs but cannot connect to a remote MCP server themselves. Your client launches mcp-remote as if it were a local server, and mcp-remote connects to the remote URL, handles OAuth sign-in if the server asks for it, and passes messages both ways. On 28 September 2026 we ran it against four public remote servers from an isolated container. All four connected and listed their tools in under 12 seconds.
What mcp-remote does
A remote MCP server is an HTTPS endpoint. A client that only knows how to start a command, with command and args in its config, has nowhere to put that URL. mcp-remote fills the gap: the client talks to it over standard input and output, and it talks to the endpoint over HTTP.
It is not a server and it does not host anything. It connects to a remote server that already exists. If your client and the provider document a native remote connection, use that instead: it is one less process to debug. mcp-remote is for the cases where that path is missing, which is still common with OAuth-protected servers.
The package is maintained at punkpeye/mcp-remote on GitHub; its MCPVault listing shows the repository, license and grade.
We tested it against four public servers
We ran npx -y mcp-remote@0.14.3 <url> in MCPVault's isolated test environment, completed the MCP handshake and requested the tool list. No tools were called. None of these endpoints needs an account.
| Endpoint | Server reported | Tools | Protocol | Time |
|---|---|---|---|---|
https://mcp.deepwiki.com/mcp |
DeepWiki 2.14.3 | 3 | 2025-06-18 | 11.8 s |
https://docs.mcp.cloudflare.com/mcp |
docs-ai-search 0.4.13 | 2 | 2025-06-18 | 6.4 s |
https://gitmcp.io/modelcontextprotocol/typescript-sdk |
GitMCP 1.1.0 | 4 | 2025-03-26 | 8.1 s |
https://mcp.context7.com/mcp |
Context7 4.1.1 | 2 | 2025-06-18 | 7.4 s |
Tool counts are what each server reported that day and will change. GitMCP answered with an older protocol version than we asked for, and mcp-remote accepted it. Every run started from an empty package cache, so a second start on your machine should be quicker.
To check an endpoint yourself, paste npx -y mcp-remote <url> into the MCPVault tester. It runs the same check and shows the stage that failed, if any.
Add mcp-remote to Claude Desktop, Cursor and Windsurf
All three clients use the same shape. Replace the URL with the one your provider publishes:
{
"mcpServers": {
"deepwiki": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.deepwiki.com/mcp"]
}
}
}
The file lives in a different place for each client:
- Claude Desktop:
~/Library/Application Support/Claude/claude_desktop_config.jsonon macOS,%APPDATA%\Claude\claude_desktop_config.jsonon Windows. Restart the app after editing. - Cursor:
~/.cursor/mcp.json. - Windsurf:
~/.codeium/windsurf/mcp_config.json.
Pass the URL as a plain argument; mcp-remote has no --url flag. -y stops npx from waiting for an install prompt that the client can never answer.
Sign-in and the callback port
Many remote servers use OAuth. On first connection mcp-remote opens your browser, you approve access, and the provider redirects back to a small listener that mcp-remote runs on your machine. Tokens are stored in ~/.mcp-auth.
The listener needs a local port. By default mcp-remote derives a stable port from the server URL, somewhere between 3335 and 49150, and tries up to 8 ports from there if one is taken. If you pass a port as the argument after the URL, mcp-remote uses exactly that port, because the provider may have that redirect registered, and stops with an error if the port is taken.
That listener is also why OAuth needs a normal desktop. When we pointed mcp-remote at an OAuth-protected endpoint inside our sandbox, which cannot open local ports, it stopped with:
Fatal error: Error: Could not find a free callback port for this server (tried 22227-22234).
On a laptop the same error means another process holds those ports. In a container, CI job or SSH session it usually means the environment forbids listening at all. If the provider supports the OAuth device flow, --device-code lets you finish sign-in on another machine.
Keep tokens out of the arguments
Some servers take a static API key in a header instead of OAuth. --header "Authorization: Bearer ..." works, but anything in args is visible in your process list and easy to commit by accident. Put headers in a file that only you can read:
# ~/.config/mcp/remote-headers.txt
Authorization: Bearer your-token
"args": ["-y", "mcp-remote", "https://remote.example.com/mcp",
"--header-file", "/absolute/path/to/remote-headers.txt"]
One Name: value per line; # starts a comment. The README says an unreadable file is an error, so a wrong path fails loudly instead of connecting without the header.
HTTP, SSE and the new protocol revision
mcp-remote tries the streamable HTTP transport first and falls back to the older SSE transport if the endpoint returns 404. You can force one with --transport http-only or --transport sse-only. The fallback is also why a wrong URL produces two errors instead of one (see below).
The 2026-07-28 revision of MCP retired the initialize handshake. A server built on it will not answer a client that still starts with initialize, and most desktop clients still do. --protocol auto makes mcp-remote probe for a new-style server and translate for your client. It is off by default because, according to the README, every server in use today is still on the older protocol.
Common errors and what they mean
Two 404s in a row
The log shows Received error (status 404): Error POSTing to endpoint: Not Found, then falling-back-to-alternate-transport, then SSE error: Non-200 status code (404). Both transports returned 404, so the path is wrong. Copy it exactly from the provider; /mcp and /sse are not interchangeable.
Could not find a free callback port
On a desktop another process holds the ports; in a container or CI job the environment cannot listen. The sign-in section above covers both.
Token exchange failed: HTTP 400
Stale credentials. Delete ~/.mcp-auth and connect again.
The client shows MCP error -32000
mcp-remote exited before the client got an answer. Its own error line is in the client's log; our guide to fixing MCP error -32000 shows where each client keeps it.
Works in a terminal, fails in Claude Desktop
Claude Desktop uses your system Node.js, not the one your shell may load through a version manager. mcp-remote needs Node 18 or newer.
Behind a corporate VPN
Point NODE_EXTRA_CA_CERTS at your company's CA certificate in the server's env block.
Anything else
Add --debug to args. mcp-remote then writes a timestamped log of every step to ~/.mcp-auth/. To take the client out of the picture, run the full flow from a terminal:
npx -p mcp-remote@latest mcp-remote-client https://mcp.deepwiki.com/mcp
It signs in if needed and tries to list the server's tools and resources.
Frequently Asked Questions
Does mcp-remote host an MCP server for me?
No. It connects a local client to a remote server that someone already runs. You still need the endpoint URL from the service owner or from your own deployment.
Do I need mcp-remote if my client supports remote servers?
Usually not. Use the client's native remote setup when the provider documents one. mcp-remote is for clients that only accept a command, and for OAuth flows the client does not handle.
Should I use the /sse or the /mcp URL?
Use the exact URL the provider documents. mcp-remote will try both transports on the URL you give it, but it cannot guess a different path.
Is it safe to connect a remote server this way?
The bridge does not change what the server can access: it gets whatever access you approve at sign-in. Check its scopes and tool list first; each listing in the MCPVault directory shows the documented tools and whether the server has passed a live handshake.
If you run a remote MCP server, claim its listing and set the endpoint as its verify command. MCPVault's verifier reaches it through mcp-remote for the live handshake.
Sources
- mcp-remote README, version 0.14.3
- mcp-remote on npm
- MCPVault test runs, 28 September 2026
