Mcp RemoteCAUTION
Connect an MCP Client that only supports local (stdio) servers to a Remote MCP Server.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
Connect an MCP Client that only supports local (stdio) servers to a Remote MCP Server, with auth support:
Why is this necessary?
So far, the majority of MCP servers in the wild are installed locally, using the stdio transport. This has some benefits: both the client and the server can implicitly trust each other as the user has granted them both permission to run. Adding secrets like API keys can be done using environment variables and never leave your machine. And building on npx and uvx has allowed users to avoid explicit install steps, too.
But there's a reason most software that could be moved to the web did get moved to the web: it's so much easier to find and fix bugs & iterate on new features when you can push updates to all your users with a single deploy.
With the latest MCP Authorization specification, we now have a secure way of sharing our MCP servers with the world without running code on user's laptops. Or at least, you would, if all the popular MCP clients supported it yet. Most are stdio-only, and those that do support HTTP+SSE don't yet support the OAuth flows required.
That's where mcp-remote comes in. As soon as your chosen MCP client supports remote, authorized servers, you can remove it. Until that time, drop in this one liner and dress for the MCP clients you want!
Usage
All the most popular MCP clients (Claude Desktop, Cursor & Windsurf) use the following config format:
{
"mcpServers": {
"remote-example": {
"command": "npx",
"args": [
"mcp-remote",
"https://remote.mcp.server/sse"
]
}
}
}Custom Headers
To bypass authentication, or to emit custom headers on all requests to your remote server, pass --header CLI arguments:
{
"mcpServers": {
"remote-example": {
"command": "npx",
"args": [
"mcp-remote",
"https://remotf63e840981c6OBSERVED · 2026-09-24Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add mcp-remote-tests --env TOKEN=${TOKEN} -- npx -y [email protected]{
"mcpServers": {
"mcp-remote-tests": {
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"TOKEN": "${TOKEN}"
}
}
}
}Exposed tools (9)
5 read · 2 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
createTask | write | Create a new task |
deleteTask | destructive | Delete a task |
echo_era | read | |
listTasks | read | List all tasks |
mcp_search | read | Search records |
needs_input | read | |
removeUser | destructive | Remove a user |
search | read | Search |
updateTask | write | Update a task |
Trust audit
CAUTIONgrade B · trust 89/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (2 observation(s))
- Network
- declared (6 observation(s))
- Shell
- none-observed
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (15)
const response = await fetch(`http://127.0.0.1:${port}${MCP_REMOTE_ID_PATH}`, {deleteTask, removeUser
.oxfmtrc.json
.oxlintrc.json
return crypto.createHash('md5').update(parts.join('|')).digest('hex')provider.useAuthorizationState('../../../../etc/passwd')import { version as MCP_REMOTE_VERSION } from '../../package.json'import { calculateDefaultPort, getServerUrlHash } from '../../src/lib/utils'"HTTPS_PROXY": "http://127.0.0.1:3128",
await expect(serverIssuesAuthChallenge(`http://127.0.0.1:${port}/mcp`)).resolves.toBe(true)await expect(serverIssuesAuthChallenge(`http://127.0.0.1:${port}/mcp`)).resolves.toBe(false)await expect(serverIssuesAuthChallenge('http://127.0.0.1:9/mcp')).resolves.toBe(false)express, open, strict-url-sanitise, undici, @modelcontextprotocol/client, @modelcontextprotocol/core, @modelcontextprotocol/server, @types/express
@modelcontextprotocol/client, @modelcontextprotocol/server, @types/node, express, vitest, zod
npx mcp-remote https://example.remote/server --use-id-token --static-oauth-client-metadata '{ "scope": "openid email" }'Gates applied: no_behavioural_pass.
f63e840981c6full audit observations/trust-audit/mcp-server/geelen__mcp-remote.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-09-24 | f63e840981c6 | CAUTION | B | 89 | first audit |
Questions
What is the Mcp Remote MCP server?
Connect an MCP Client that only supports local (stdio) servers to a Remote MCP Server.
What tools does Mcp Remote expose?
9 in total: 5 read-only, 2 that write, and 2 that can delete or overwrite (deleteTask, removeUser). Every one is listed on this page with its risk.
Is Mcp Remote safe to connect to an agent?
With care. The audit graded it B (89/100) and found 15 things worth knowing before you trust this server, listed below with the exact line each was found on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Mcp Remote need?
It reads TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Mcp Remote run?
It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as mcp-remote-tests at 1.0.0.
How current is this page?
The grade is for one exact copy of the source (f63e840981c6), read on 2026-09-24. The repository is watched and re-audited when it changes.