Correct Claude Desktop connection: local stdio bridge, not GUI connector

The GUI custom-connector flow validates/calls from Anthropic's cloud and can't reach a localhost server, so a 127.0.0.1 URL fails there. The working path is a local mcp-remote stdio bridge configured in claude_desktop_config.json pointing at http://127.0.0.1:8080/mcp. Updated AGENT.md 8.1/11 and CHANGELOG. HTTPS on :8443 stays available but optional.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-09-20 07:52:31 -04:00
parent f23f2f2b30
commit e3336efc25
2 changed files with 38 additions and 15 deletions
+24 -15
View File
@@ -342,16 +342,25 @@ obeys the safety rules (§1.4).
### 8.1 MCP server — Claude drives the app (`internal/mcp`)
- The app serves an **MCP endpoint over Streamable HTTP at `/mcp`** using
`github.com/modelcontextprotocol/go-sdk`. Claude Desktop connects to it as a
**custom connector**. Like the rest of the app it is **localhostbound and
unauthenticated** (Section 0) — do not expose it offhost without asking.
- **The connector requires `https://`** (Claude Desktop rejects plain `http`).
So `/mcp` is also served over **TLS on localhost** with a **locallytrusted
cert** (mkcertgenerated; the app just reads the cert/key files). Installing the
local CA into the OS trust store is a **host setup step the user performs**, not
something the app or Claude does (it is a securitysettings change). Do **not**
reach for a public tunnel to get HTTPS — that would expose an unauthenticated
repomanagement app to the internet.
`github.com/modelcontextprotocol/go-sdk`. Like the rest of the app it is
**localhostbound and unauthenticated** (Section 0) — do not expose it offhost.
- **How Claude Desktop connects — the local stdio bridge, NOT the GUI connector.**
The "Add custom connector" GUI is for **remote, publiclyreachable** servers:
it probes (and would call tools) **from Anthropic's cloud**, which cannot reach
`127.0.0.1`. So a localhost URL there fails "couldn't reach the server" even
though a local browser reaches it. The working path is a **local stdio bridge**
configured in `claude_desktop_config.json` under `mcpServers`, launched on the
user's machine:
```json
"gitmanager": { "command": "cmd",
"args": ["/c","npx","-y","mcp-remote","http://127.0.0.1:8080/mcp"] }
```
`mcp-remote` runs locally and speaks stdio to Claude Desktop, so it reaches the
local endpoint directly and needs **no public exposure and no HTTPS**. Do **not**
reach for a public tunnel — that would expose an unauthenticated repomanagement
app to the internet.
- **HTTPS is still available** (`:8443`, mkcert cert) for clients that require it,
but is not needed for the stdiobridge path above.
- MCP **tools are thin adapters** over the service layer — no Git/forge logic in
the tool handlers (§1.7). Expected tools (grow as features land):
- Read: `list_repos`, `get_repo`, `get_active_project`, `get_activity`,
@@ -514,11 +523,11 @@ silently guess.)*
- ✅ **RESOLVED 2026-09-19:** **Project handoff is cooperative** — user requests a
switch, Claude finishes to a safe checkpoint, switches, and the user is notified;
pullfirst, not autonomous (Section 8.3).
- ✅ **RESOLVED 2026-09-20:** Claude Desktop's custom connector **requires
`https://`**. Resolved with **local TLS via mkcert** — connect to
`https://localhost:8443/mcp` (HTTP dashboard stays on `:8080`). The user runs
`mkcert -install` + cert generation on the host (§8.1); the stdioshim fallback
is no longer needed.
- ✅ **RESOLVED 2026-09-20:** Claude Desktop's **GUI "custom connector" cannot
reach a localhost server** — it validates/calls from Anthropic's cloud. Solved
with the **local stdio bridge** (`claude_desktop_config.json` → `mcpServers` →
`mcp-remote http://127.0.0.1:8080/mcp`), §8.1. (HTTPS on `:8443` via mkcert was
added earlier and still works, but is not required for this path.)
- **Idletrigger for handoff:** the pull model syncs at Claude's turn boundaries.
If Claude is idle when the user switches, decide the nudge (user's next message,
a heartbeat/poll, or a host push if available) — do not assume instant wake.