mcp-hop
v1.0.3
Published
Hop your remote MCP servers to localhost — a proxy that makes VPN/internal MCPs work with Claude Desktop
Maintainers
Readme
mcp-hop
Hop your remote MCP servers to localhost.
mcp-hop is a proxy that makes remote Model Context Protocol (MCP) servers available locally. If you have MCP servers behind a VPN, on an internal network, or behind authentication — and you want to use them with Claude Desktop, Cursor, or any tool that expects local MCPs — mcp-hop bridges that gap.
Think of it like a WiFi extender, but for MCP servers.
Your machine Remote network
┌──────────────┐ ┌──────────────────┐
│ Claude │ │ │
│ Desktop │◄── stdio ──► mcp-hop ──── HTTPS ────► │ MCP Server │
│ │ (proxy) │ (behind VPN) │
└──────────────┘ └──────────────────┘Why?
Claude Desktop, Cursor, and similar tools expect MCP servers to be local — either a process they spawn (stdio) or a localhost HTTP endpoint. But many real-world MCP servers live on internal networks, behind VPNs, or require special auth headers.
mcp-hop solves this by:
- Connecting to your remote MCP servers (with auth)
- Exposing each one as a separate local proxy
- Passing through all tools, resources, and prompts transparently
Each remote server gets its own isolated local proxy — no name conflicts, no shared state.
Quick Start
1. Add a remote server
npx mcp-hop config addYou'll be prompted for:
- Server name — a short identifier (e.g.,
work-api) - URL — the remote MCP server endpoint
- Transport — Streamable HTTP (recommended) or SSE
- Auth — Bearer token, custom header, or none
- Local port — auto-assigned, starting at 3101
2. Test the connection
npx mcp-hop inspectThis opens an interactive session where you can:
- List all tools, resources, and prompts
- Call tools with custom arguments and see results
- Verify everything works before setting up Claude Desktop
3. Connect to Claude Desktop
npx mcp-hop setupThis prints the exact JSON to paste into your Claude Desktop config. Copy it into:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Then restart Claude Desktop.
How It Works
When you add two servers — say work-api and data-team — mcp-hop generates this config for Claude Desktop:
{
"mcpServers": {
"work-api": {
"command": "npx",
"args": ["-y", "mcp-hop", "serve", "--name", "work-api"]
},
"data-team": {
"command": "npx",
"args": ["-y", "mcp-hop", "serve", "--name", "data-team"]
}
}
}Claude Desktop launches each as a separate process. Each process:
- Reads the server config from
~/.mcp-hop/config.json - Connects to the remote MCP server (with auth headers)
- Exposes all its tools/resources/prompts over stdio
- Forwards every request transparently — Claude sees the original tool names
Claude Desktop
├─ "work-api" ─► mcp-hop (stdio) ─► https://internal.company.com/mcp
└─ "data-team" ─► mcp-hop (stdio) ─► https://data.internal/sseCommands
mcp-hop serve
Start the proxy.
# Proxy a single server over stdio (what Claude Desktop runs)
npx mcp-hop serve --name work-api --stdio
# Proxy a single server over HTTP
npx mcp-hop serve --name work-api
# Start ALL configured servers, each on its own HTTP port
npx mcp-hop serve
# Override the port
npx mcp-hop serve --name work-api --port 4000| Flag | Description |
|------|-------------|
| -n, --name <name> | Which server to proxy (required for --stdio) |
| --stdio | Use stdio transport (for Claude Desktop) |
| -p, --port <port> | Override the local HTTP port |
| -c, --config <path> | Custom config file path |
mcp-hop inspect
Interactive TUI for testing connections.
# Inspect any configured server (you'll be prompted to choose)
npx mcp-hop inspect
# Inspect a specific server
npx mcp-hop inspect --server work-apiThe inspector lets you:
- List tools — see all tools with their parameters and descriptions
- List resources — browse available resources
- List prompts — see prompt templates and their arguments
- Call a tool — pick a tool, enter JSON arguments, see the response
- Read a resource — fetch and display resource content
- Refresh — re-fetch capabilities from the server
mcp-hop setup
Generate Claude Desktop configuration.
npx mcp-hop setupOutputs a complete mcpServers JSON block ready to paste into claude_desktop_config.json.
mcp-hop config
Manage your server configurations.
# Add a new server (interactive)
npx mcp-hop config add
# List all configured servers
npx mcp-hop config list
# Remove a server
npx mcp-hop config remove work-apiConfiguration
Config lives at ~/.mcp-hop/config.json. You can edit it directly or use the config commands.
{
"version": 1,
"servers": [
{
"name": "work-api",
"url": "https://internal.company.com/mcp",
"transport": "streamable-http",
"auth": {
"type": "bearer",
"token": "your-token-here"
},
"localPort": 3101,
"enabled": true
},
{
"name": "legacy-service",
"url": "https://old.internal/sse",
"transport": "sse",
"auth": {
"type": "custom-header",
"headerName": "X-API-Key",
"headerValue": "sk-abc123"
},
"localPort": 3102,
"enabled": true
}
]
}Server Fields
| Field | Required | Description |
|-------|----------|-------------|
| name | Yes | Unique identifier (alphanumeric, dashes, underscores) |
| url | Yes | Remote MCP server URL |
| transport | Yes | "streamable-http" (recommended) or "sse" (legacy) |
| auth | No | Authentication config (see below) |
| localPort | Yes | Port for the local HTTP proxy |
| enabled | Yes | Set to false to skip this server |
Authentication
Bearer token:
{
"type": "bearer",
"token": "eyJhbGciOiJIUzI1NiIs..."
}Custom header (e.g., API key):
{
"type": "custom-header",
"headerName": "X-API-Key",
"headerValue": "sk-your-key"
}No auth: Omit the auth field entirely.
Transport Modes
mcp-hop supports two ways to expose each proxy locally:
Stdio (for Claude Desktop)
npx mcp-hop serve --name my-server --stdioClaude Desktop spawns mcp-hop as a child process and communicates over stdin/stdout. This is the default mode when used via the generated config.
HTTP (for other clients)
npx mcp-hop serve --name my-serverStarts a local HTTP server on the configured port (e.g., http://localhost:3101/mcp). Useful for:
- Browser-based MCP clients
- Testing with the MCP Inspector
- Any HTTP-based MCP consumer
Each server also exposes a health endpoint at /health:
curl http://localhost:3101/health
# {"status":"ok","sessions":0}Common Scenarios
VPN-only MCP server
You're connected to a corporate VPN. The MCP server at https://tools.internal.corp/mcp is only reachable from your machine.
npx mcp-hop config add
# name: corp-tools
# url: https://tools.internal.corp/mcp
# transport: Streamable HTTP
# auth: Bearer token → paste your token
# port: 3101
npx mcp-hop inspect --server corp-tools
# Verify tools show up
npx mcp-hop setup
# Copy JSON into Claude Desktop configMultiple MCP servers
You have three internal services — each gets its own proxy:
npx mcp-hop config add # → "search-api" on port 3101
npx mcp-hop config add # → "docs-server" on port 3102
npx mcp-hop config add # → "db-tools" on port 3103
npx mcp-hop setup
# Generates config entries for all threeClaude Desktop sees three separate MCP servers, each fully isolated.
Testing with MCP Inspector
# Start the proxy for one server
npx mcp-hop serve --name work-api
# In another terminal, point the MCP Inspector at it
npx @modelcontextprotocol/inspector --url http://localhost:3101/mcpVerbose Logging
Add -v for detailed logs (written to stderr, never interferes with stdio transport):
npx mcp-hop -v serve --name work-api --stdio
npx mcp-hop -v inspectRequirements
- Node.js 18+
- Remote MCP servers must use Streamable HTTP or SSE transport
License
MIT
