Atlas / MCP servers / geelen / Mcp Remote

Mcp RemoteCAUTION

mcp/geelen/mcp-remote

Connect an MCP Client that only supports local (stdio) servers to a Remote MCP Server.

Verdict
CAUTION
Grade
B
Trust score
89 /100
Exposed tools
9 5r · 2w · 2d
Transport
stdio · streamable-http
License
MIT
Stars
1,603
01

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://remot
Read from source at commit f63e840981c6OBSERVED · 2026-09-24
02

Connect

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-code
claude mcp add mcp-remote-tests --env TOKEN=${TOKEN} -- npx -y [email protected]
claude-desktop
{
  "mcpServers": {
    "mcp-remote-tests": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]"
      ],
      "env": {
        "TOKEN": "${TOKEN}"
      }
    }
  }
}
03

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.

ToolRiskDescription
createTaskwriteCreate a new task
deleteTaskdestructiveDelete a task
echo_eraread
listTasksreadList all tasks
mcp_searchreadSearch records
needs_inputread
removeUserdestructiveRemove a user
searchreadSearch
updateTaskwriteUpdate a task
04

Trust audit

CAUTIONgrade B · trust 89/100 Install with care. The audit found things worth knowing before you trust its output.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (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)

MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
src/lib/coordination.ts:146
const response = await fetch(`http://127.0.0.1:${port}${MCP_REMOTE_ID_PATH}`, {
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
deleteTask, removeUser
Why it matters. 2 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
.oxfmtrc.json
.oxfmtrc.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.oxlintrc.json
.oxlintrc.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/lib/utils.ts:3262
return crypto.createHash('md5').update(parts.join('|')).digest('hex')
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/lib/node-oauth-client-provider.test.ts:782
provider.useAuthorizationState('../../../../etc/passwd')
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/lib/utils.ts:61
import { version as MCP_REMOTE_VERSION } from '../../package.json'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
test/oauth-simulator/instances.ts:5
import { calculateDefaultPort, getServerUrlHash } from '../../src/lib/utils'
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:265
"HTTPS_PROXY": "http://127.0.0.1:3128",
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
src/lib/coordinate-auth.test.ts:147
await expect(serverIssuesAuthChallenge(`http://127.0.0.1:${port}/mcp`)).resolves.toBe(true)
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
src/lib/coordinate-auth.test.ts:155
await expect(serverIssuesAuthChallenge(`http://127.0.0.1:${port}/mcp`)).resolves.toBe(false)
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
src/lib/coordinate-auth.test.ts:159
await expect(serverIssuesAuthChallenge('http://127.0.0.1:9/mcp')).resolves.toBe(false)
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
express, open, strict-url-sanitise, undici, @modelcontextprotocol/client, @modelcontextprotocol/core, @modelcontextprotocol/server, @types/express
Why it matters. 15 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
test/package.json
@modelcontextprotocol/client, @modelcontextprotocol/server, @types/node, express, vitest, zod
Why it matters. 6 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
README.md:592
npx mcp-remote https://example.remote/server --use-id-token --static-oauth-client-metadata '{ "scope": "openid email" }'
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine

Gates applied: no_behavioural_pass.

Audited 2026-09-24 · audit v0.4.1 · source sha f63e840981c6full audit observations/trust-audit/mcp-server/geelen__mcp-remote.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-09-24f63e840981c6CAUTIONB89first audit
06

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.

Advertisement