Skip to main content
Glama
jinyinghua

MCP Secure Relay

by jinyinghua

MCP Secure Relay for Vercel

A separate Vercel project that accepts a standard authenticated MCP connection and relays shell commands and file operations to a lightweight remote executable.

MCP client -- HTTPS --> Vercel /api/mcp -- encrypted HTTP or HTTPS --> relay-agent -- local execution

中文文档见 README.zh-CN.md.

The Vercel-to-agent body is a private protocol: AES-256-GCM encryption plus HMAC-SHA256 authentication, separate request/response keys derived from RELAY_SHARED_SECRET, 60-second timestamp validation, and nonce replay rejection. The remote hop does not need an SSL certificate. Its HTTP headers, endpoint address, timing, and payload size remain visible to the network, so use a private tunnel/firewall where possible. This is application-layer protection, not a replacement for network isolation.

Security model

  • MCP_API_KEYS is mandatory. The relay rejects every MCP request if it is unset.

  • The agent has a separate 32-byte shared secret and rejects tampered, stale, or replayed envelopes.

  • execute_command intentionally accepts arbitrary shell commands, pipelines, redirects, and arguments, running as the agent operating-system user. Issue MCP API keys only to fully trusted clients.

  • read_file and write_file only accept relative paths below root_dir. Absolute paths, .., symbolic links, non-regular files, and missing parent directories are rejected.

  • Writes are disabled by default and use a same-directory temporary file followed by atomic rename when enabled.

  • The agent has independent read/write/output/command-timeout limits. Vercel limits tool responses again.

  • Every attempted operation is written to Redis before dispatch and completed afterward. It stores client key fingerprint, operation, target, byte counts, timing, status, and error code. It never stores API keys, file contents, or command output.

  • Audit storage is required for execution. REDIS_URL takes precedence and supports native Redis/Redis Cloud rediss:// connections; Upstash REST remains available as a fallback. If the selected backend is unavailable before dispatch, no operation is sent to the remote server.

Related MCP server: Remote Coding Runtime

Deploy Vercel

  1. Create a new Vercel project from this directory. Do not import or modify the existing MCP project.

  2. Add every variable in .env.example under Project Settings > Environment Variables. Generate independent values:

openssl rand -base64 48  # MCP_API_KEYS and AUDIT_API_KEY
openssl rand -base64 32  # RELAY_SHARED_SECRET and agent shared_secret
  1. Prefer Redis Cloud by setting its REDIS_URL=rediss://... connection string; the project connects through the native TLS Redis protocol. Alternatively, omit REDIS_URL and configure Upstash Redis REST with UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN.

  2. Deploy with vercel --prod, then set NEXT_PUBLIC_APP_URL to the resulting HTTPS URL and redeploy.

The MCP endpoint is https://YOUR_PROJECT.vercel.app/api/mcp. Configure a standard Streamable HTTP MCP client with Authorization: Bearer YOUR_MCP_KEY.

{
  "mcpServers": {
    "secure-relay": {
      "url": "https://YOUR_PROJECT.vercel.app/api/mcp",
      "headers": { "Authorization": "Bearer YOUR_MCP_KEY" }
    }
  }
}

Build and run the remote executable

The agent uses only the Go standard library and compiles to one static binary. It is not an MCP client and does not install any agent tooling on the remote server.

cd agent
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags='-s -w' -o relay-agent .
install -m 700 relay-agent /usr/local/bin/relay-agent
install -m 600 relay-agent.example.json /etc/relay-agent.json
# Edit /etc/relay-agent.json: shared_secret, root_dir, and command limits.
/usr/local/bin/relay-agent -config /etc/relay-agent.json

The sample binds 127.0.0.1:8787; keep that default and expose it through an existing private tunnel or reverse proxy. If Vercel must call the agent directly, REMOTE_AGENT_URL must be reachable from the public Internet and the host firewall should restrict access where possible. The agent authenticates every request cryptographically, even when reachable through plain HTTP.

Shell commands run with root_dir as their default working directory; root_dir remains the path boundary for read_file and write_file. The example enables writes; set allow_file_write to false if you only need command execution. The agent will not create missing directories for write_file.

Arbitrary command execution and privileges

As of this version, execute_command accepts a command string instead of the former command_id. The agent runs /bin/sh -lc, supporting pipelines, redirects, script fragments, and arbitrary arguments; root_dir is its default working directory.

This makes an MCP API key a high-privilege credential: a connected client can execute any command available to the mcp-relay operating-system user. System package installation additionally requires sudo. Giving mcp-relay NOPASSWD: ALL makes an MCP client effectively root on the server; encryption and auditing do not eliminate that risk.

max_command_seconds is the agent-enforced hard limit, currently capped at 25 seconds to fit Vercel function limits. Clients may request a shorter timeout_seconds, but cannot exceed the remote configuration. Command text is not stored in the 14-day audit database; it records only a SHA-256 fingerprint, status, timing, and byte counts.

Audit access

Retrieve the latest records using the separate audit key:

curl 'https://YOUR_PROJECT.vercel.app/api/audit?limit=100' \
  -H 'Authorization: Bearer YOUR_AUDIT_API_KEY'

Records expire after 14 days. Redis also removes stale index entries on each new audit write.

Verification

npm install
npm run typecheck
npm run build
cd agent && go test ./...

Before production use, test shell execution, command timeouts, ../ paths, symlink paths, oversize files, expired envelopes, and Redis unavailability. Run the agent under a dedicated OS account: every resource that account can access can potentially be accessed by a trusted MCP client through commands.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables remote MCP clients to access local filesystem and shell commands by deploying a Cloudflare Worker relay and a local daemon, providing tools like read/write files, exec commands, git status, etc.
    792 npm
    1
    MIT
  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables MCP clients to safely access user-local filesystems, apply validated patches, inspect git state, and run persistent jobs on outbound-connected local runners through a stateless Cloudflare control plane.
    8
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables agents to connect to remote MCP servers once, access their tools through a compact MCP endpoint, pair a CLI inside sandboxes, and create watches that turn command or tool output into pollable structured events.
    2
    -