Skip to main content
Glama
README.md
# mcp-proxy-bridge

> An MCP server + Claude Code hook that makes a target host (e.g. **github.com**) reachable through your **local proxy** — launching the proxy client if needed and configuring your tools to route through it.

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Node](https://img.shields.io/badge/node-%3E%3D18-green)](https://nodejs.org)
[![Zero dependencies](https://img.shields.io/badge/dependencies-0-blue)](#)

If you're behind a network where GitHub (or another host) only works through a local proxy like **Clash / Clash Verge / v2rayN / sing-box**, this bridge makes it *just work* for your AI coding assistant:

- **MCP server** — tools to check reachability, start/stop the proxy, and orchestrate the whole flow.
- **PreToolUse hook** — fires automatically on Bash commands that touch a configured host, brings the proxy up, and points git at it.

Zero dependencies (Node stdlib only) — deliberately, because a tool that fixes network problems must not need a network install.

---

## How it works

Most local proxies run with **system proxy and TUN off**, so simply starting the proxy client doesn't route your traffic. The bridge:

1. Probes whether the target is reachable directly.
2. If not, checks the local proxy port; if closed, launches your proxy client and waits for the port.
3. Verifies the target through the proxy (HTTP CONNECT or SOCKS5 → TLS HEAD).
4. Sets a **URL-scoped** git proxy so only the configured host routes through the proxy — every other repo host is untouched. Idempotent and reversible.

> Note: this is a **local** tool. It launches *your* proxy client and configures *your* machine. Each user runs their own copy next to their own proxy — it is **not** a shared hosted service.

## Install

### Use without installing (npx)
```bash
# MCP server (spawned once by your client at startup — npx is fine here)
claude mcp add proxy-bridge -- npx -y mcp-proxy-bridge
```

### Install globally (recommended for the hook, which runs on every Bash call)
```bash
npm install -g mcp-proxy-bridge
```

### From source / GitHub
```bash
git clone https://github.com/xiaolaifeng/mcp-proxy-bridge.git
cd mcp-proxy-bridge
node src/server.mjs --print-config   # sanity check
```

## Quick start (Claude Code)

1. **Create a config** (edit the result to match your proxy client):
   ```bash
   mcp-proxy-bridge --init            # writes ~/.mcp-proxy-bridge.json
   $EDITOR ~/.mcp-proxy-bridge.json   # set launch.command, ports, process.names
   mcp-proxy-bridge --print-config    # verify
   ```
   See [`examples/`](examples) for Clash Verge, v2rayN, sing-box, and SOCKS5.

2. **Register the MCP server** (user scope = all projects):
   ```bash
   claude mcp add proxy-bridge --scope user -- npx -y mcp-proxy-bridge
   # or, if installed globally:
   claude mcp add proxy-bridge --scope user -- mcp-proxy-bridge
   ```

3. **Register the hook** in `~/.claude/settings.json`:
   ```jsonc
   {
     "hooks": {
       "PreToolUse": [
         {
           "matcher": "Bash",
           "hooks": [
             { "type": "command", "command": "mcp-proxy-bridge-hook" }
           ]
         }
       ]
     }
   }
   ```
   (Use `npx -y mcp-proxy-bridge-hook` instead if not installed globally, but global install is faster for a per-command hook.)

4. Restart Claude Code. Run a `git pull` that touches GitHub — the proxy comes up automatically.

## Configuration

Config is layered, later wins: **defaults < JSON file < environment variables**.

- **File**: `~/.mcp-proxy-bridge.json` (override path with `PROXY_BRIDGE_CONFIG`).
- **Env**: see table below.
- **CLI**: `--print-config`, `--init [path]`.

```jsonc
{
  "targets": ["github.com", "api.github.com", "raw.githubusercontent.com"],
  "checkPort": 443,
  "proxy": { "host": "127.0.0.1", "port": 7897, "scheme": "http" },
  "launch": { "command": "clash-verge", "args": [], "cwd": null, "waitPortMs": 40000 },
  "process": { "names": ["clash-verge", "verge-mihomo", "mihomo"] },
  "gitProxy": { "enable": true, "scope": null },
  "hook": { "matchTargets": true, "extraPatterns": ["\\bgit\\s+[^|;&\\n]*\\b(clone|fetch|pull|push|ls-remote|submodule)\\b"] }
}
```

| Field | Meaning |
|-------|---------|
| `targets` | Hosts to verify. |
| `checkPort` | Port probed on each target (443 = HTTPS). |
| `proxy.host` / `proxy.port` | Your local proxy address. |
| `proxy.scheme` | `http` (HTTP CONNECT) or `socks5`. |
| `launch.command` / `launch.args` | Command to start your proxy client. `null` = you start it manually. |
| `launch.waitPortMs` | How long to wait for the port after launching. |
| `process.names` | Best-effort process names for `status` / `stop` (Windows auto-appends `.exe`). |
| `gitProxy.enable` | Hook sets URL-scoped git proxy for the targets. |
| `gitProxy.scope` | Override git URL prefixes (defaults to `https://<target>/` per target). |
| `hook.matchTargets` | Hook fires when a command mentions any target host. |
| `hook.extraPatterns` | Extra regexes that trigger the hook (default: git network verbs). |

### Environment variables
| Var | Maps to |
|-----|---------|
| `PROXY_BRIDGE_CONFIG` | Config file path. |
| `PROXY_BRIDGE_TARGETS` | Comma-separated targets. |
| `PROXY_BRIDGE_CHECK_PORT` | Target port. |
| `PROXY_BRIDGE_PROXY_HOST` / `PROXY_BRIDGE_PROXY_PORT` / `PROXY_BRIDGE_PROXY_SCHEME` | Proxy endpoint. |
| `PROXY_BRIDGE_LAUNCH_CMD` / `PROXY_BRIDGE_LAUNCH_ARGS` | Launch command (args: JSON array or space-split). |
| `PROXY_BRIDGE_PROCESS_NAMES` | Comma-separated process names. |
| `PROXY_BRIDGE_SET_GIT_PROXY` | `0` disables git proxy. |
| `PROXY_BRIDGE_GIT_SCOPE` | Comma-separated git URL prefixes. |
| `PROXY_BRIDGE_HOOK_EXTRA` | Comma-separated extra trigger regexes. |

## MCP tools
| Tool | Description |
|------|-------------|
| `ensure_access` | Check direct; if down, start proxy, wait for port, verify via proxy. |
| `check` | `useProxy` true/false reachability of a target. |
| `status` | Proxy process running? Port open? Targets? |
| `start_proxy` / `stop_proxy` | Launch / best-effort kill. |
| `proxy_info` | Proxy URL + env/git-config hints (and unset). |
| `set_git_proxy` | Apply the URL-scoped git proxy. |
| `show_config` | Resolved config + config path. |

## Platform notes
- **Windows**: process detection via `tasklist`, stop via `taskkill`. Append `.exe` automatically.
- **macOS / Linux**: process detection via `pgrep`, stop via `pkill`. Set `launch.command` to the app binary or `open -a "Clash Verge"` on macOS.
- Port readiness is the primary "proxy is up" signal on all platforms.

## Other MCP clients
Works with any MCP-capable client that speaks stdio (Claude Desktop, etc.). Point the client at:
```
npx -y mcp-proxy-bridge
```
The hook is Claude-Code-specific (PreToolUse). For other clients, call the `ensure_access` tool before GitHub operations, or use the git-proxy hint from `proxy_info`.

## Troubleshooting
- **`status` shows `proxyPortOpen: false`**: your proxy client isn't running or the port differs — check `proxy.port` and `launch.command`.
- **Proxy up but target still unreachable**: the selected node/subscription in your proxy client can't reach the target — switch nodes, then retry.
- **`processRunning: false` even when running**: add the right `process.names` (this field is best-effort; the port probe is authoritative).
- **Don't want the persistent git proxy**: run `git config --global --unset http.<scope>.proxy`, or set `PROXY_BRIDGE_SET_GIT_PROXY=0`.
- If you enable **TUN** or **system proxy** in your client, the explicit git proxy becomes unnecessary but stays harmless.

## Manual testing
```bash
mcp-proxy-bridge --print-config
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'$'\n''{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | node src/server.mjs
echo '{"tool_input":{"command":"git pull origin main"}}' | node src/hook.mjs   # should emit context
echo '{"tool_input":{"command":"docker ps"}}' | node src/hook.mjs             # should be silent
```

## Security & notes
- The bridge only ever talks to `127.0.0.1` (your proxy) and the configured target hosts over TLS. No telemetry, no remote calls.
- `set_git_proxy` / the hook modify **global git config** (`http.<scope>.proxy`) — reversible via the `--unset` commands in `proxy_info`.
- MIT licensed.

---

## For maintainers — publishing

**npm:**
```bash
npm version patch         # or minor / major
npm pack                  # inspect the tarball contents
npm publish               # publishes the files listed in package.json "files"
```
Before publishing, fill in `package.json` `author`, `repository`, `homepage`, `bugs` (already set: author Robin Lee, repo xiaolaifeng/mcp-proxy-bridge).

**GitHub:** push the repo, then users can `npx github:xiaolaifeng/mcp-proxy-bridge`.

**MCP directories** (for discovery): submit to [mcp.so](https://mcp.so), [Glama](https://glama.ai/mcp/servers), [Smithery](https://smithery.ai), and the [Anthropic MCP server list](https://github.com/modelcontextprotocol/servers).

## License
[MIT](LICENSE)

TDQS

A3.7/5.0

Scored across 8 tools

Disambiguation4/5

Most tools have distinct purposes, but 'check' and 'ensure_access' both test reachability; 'ensure_access' is a higher-level operation that may also launch the proxy, causing slight ambiguity.

Naming Consistency3/5

Tool names use a mix of conventions: some are verbs only ('check'), some are verb_noun ('start_proxy'), and some are noun_only ('status') or noun_info ('proxy_info'), lacking a consistent pattern.

Tool Count5/5

With 8 tools, the set is well-scoped for managing a proxy bridge, covering essential operations without unnecessary bloat.

Completeness4/5

The tool set covers core proxy lifecycle (start/stop/status), reachability testing, configuration access, and git proxy setup. Missing direct tool for managing proxy targets, but config editing may be external.

Maintenance

ActivityInactive
ResponsivenessNo issues