MCP: persistent port/token + mcp-remote shim recipe for Claude Code

Port (default 47821) and bearer token now persist to mcp.json with
OS-picked fallback if the port is taken; new Regenerate button in the
panel rotates the token and restarts the running server. rmcp's
DNS-rebinding host allowlist is disabled so WSL gateway IPs can
connect (bearer-auth handles the gatekeeping); the auth middleware
only enforces on /mcp paths so OAuth-discovery clients don't see a
Bearer challenge on /.well-known/* probes.

Claude Code's HTTP-MCP client currently tries OAuth and ignores
static `headers` auth (anthropics/claude-code#17152, #46879), so the
panel + README config snippet now uses `npx mcp-remote` as a stdio
shim that proxies the HTTP endpoint with the bearer baked in.
This commit is contained in:
megaproxy 2026-05-26 11:05:13 +01:00
parent 352aa8c281
commit 799f507c3c
8 changed files with 290 additions and 46 deletions

View file

@ -60,19 +60,45 @@ Layout + per-pane settings auto-save to `%APPDATA%\com.megaproxy.tiletopia\works
### MCP server (Claude can drive the workspace)
The titlebar 🤖 button opens a small panel that starts an MCP (Model Context Protocol) server on `127.0.0.1`. A Claude session — running anywhere on the machine, including inside one of tiletopia's own panes — can connect to it, read scrollback, wait for commands to settle, and inspect the layout. v1 is **read-only**: no spawning, no keystroke injection, no host editing.
The titlebar 🤖 button opens a small panel that starts an MCP (Model Context Protocol) server. A Claude session — running anywhere reachable from the host, including inside one of tiletopia's own panes — can connect to it, read scrollback, wait for commands to settle, and inspect the layout. v1 is **read-only**: no spawning, no keystroke injection, no host editing.
- **Off by default.** Click the button, hit **Server: ON** to start. The panel shows the bound URL + a randomly-generated bearer token and a ready-to-paste Claude config snippet.
- **Off by default.** Click the button, hit **Server: ON** to start. The panel shows the URL + bearer token and a ready-to-paste Claude config snippet. Both port and token persist across restarts (saved to `%APPDATA%\com.megaproxy.tiletopia\mcp.json`); use **Regenerate** in the panel if the token leaks.
- **Default-deny per pane.** Toggle the 🤖 chip in any pane's toolbar to allow MCP to see it. Panes without the chip on are invisible to the server.
- **Saved SSH passwords are never exposed** through the MCP surface.
- **WSL connectivity.** For Claude running inside WSL2 to reach the Windows-side server at `127.0.0.1`, set `networkingMode=mirrored` in `%UserProfile%\.wslconfig` (Win 11 22H2+):
- **Bound to all interfaces** (`0.0.0.0`). The bearer token is the only auth — don't enable the server on an untrusted network.
```
[wsl2]
networkingMode=mirrored
```
#### Claude Code setup (via `mcp-remote` stdio shim)
Without mirrored mode you can still connect via the WSL gateway IP (default route).
Claude Code's HTTP-MCP client currently tries OAuth discovery and ignores static `headers` auth (Anthropic [#17152](https://github.com/anthropics/claude-code/issues/17152), [#46879](https://github.com/anthropics/claude-code/issues/46879)). The [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) stdio shim transparently proxies the HTTP endpoint with the bearer header attached, sidestepping the OAuth flow.
The panel's config snippet uses this shim by default — paste it into your project's `.mcp.json`:
```json
{
"mcpServers": {
"tiletopia": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"http://127.0.0.1:47821/mcp",
"--allow-http",
"--header", "Authorization: Bearer <token-from-panel>"
]
}
}
}
```
Requires `npx` (Node 18+) on the client side. Other MCP clients that handle static bearer auth correctly can skip the shim and connect directly to the URL + token shown in the panel.
#### WSL connectivity
When Claude runs inside WSL, swap `127.0.0.1` for the WSL gateway IP (`ip route show default | awk '{print $3}'` inside WSL — note that this changes after each WSL restart) **or** enable mirrored networking (`networkingMode=mirrored` in `%UserProfile%\.wslconfig` then `wsl --shutdown`; Win 11 22H2+). Allow the port through Windows Defender Firewall once — elevated PowerShell:
```powershell
New-NetFirewallRule -DisplayName "tiletopia MCP" -Direction Inbound `
-Action Allow -Protocol TCP -LocalPort 47821 -Profile Any
```
## Stack