feat(connect): one-click Claude Desktop via mcp-remote stdio bridge (MCP-2479)#682
Conversation
Claude Desktop was marked unsupported in the Connect wizard because it only speaks stdio, even though mcpproxy can be reached from it via an `npx -y mcp-remote <mcpURL>` bridge (already documented in docs/setup.md). - Flip claude-desktop to Supported=true and add a stdio-bridge branch to buildServerEntry that writes `command: npx`, `args: [-y, mcp-remote, <mcpURL>]`. - Add a Note field (ClientDef/ClientStatus) surfacing the bridge requirement; render it in ConnectModal so users know the path uses mcp-remote (needs Node.js). - Connected-state detection already matches the canonical `mcpproxy` entry name, so bridge connections are tracked without a URL field. - Docs: note the one-click wizard path in docs/setup.md; widen connect POST/DELETE client-ID examples. Related MCP-2479
Deploying mcpproxy-docs with
|
| Latest commit: |
77a1b6a
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://559adfcc.mcpproxy-docs.pages.dev |
| Branch Preview URL: | https://fix-mcp-2479-claude-desktop.mcpproxy-docs.pages.dev |
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
On Windows, ConfigPath ignores the homeDir override for claude-desktop and vscode (it reads %APPDATA%), so the no-key and with-key Claude Desktop bridge tests both wrote to the same real APPDATA\Claude path. The no-key test ran first and created the entry; the with-key test then hit `already_exists` (force=false) and never wrote the apikey, failing the assertion on the windows-amd64 runner. Pin %APPDATA% under the per-test temp dir in the test-service helpers, mirroring the existing %LOCALAPPDATA% line, so every client's config path is isolated per-test on Windows. No-op on macOS/Linux. Related MCP-2479
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 27545308743 --repo smart-mcp-proxy/mcpproxy-go
|
|
codex review (gpt-5.5, in-checkout) → REQUEST_CHANGES. The generated bridge entry is valid (
|
…e bridge Addresses Codex REQUEST_CHANGES on PR #682 (MCP-2479): Gap 1 — Connect button hidden on fresh installs. A fresh Claude Desktop has no config file yet (exists=false), so the modal showed "Config not found" instead of a Connect button even though Connect can create the file. Add a `Bridge` flag to ClientDef/ClientStatus (true for claude-desktop) and relax the frontend gate to `supported && (exists || bridge)` for the button and the Connect-All set. Gap 2 — Status detection only matched the `mcpproxy` key. A bridge written under a custom server_name has no URL field and a non-default key, so it showed disconnected. Detect the bridge by inspecting the entry args (mcp-remote + mcpURL) via entryPointsToBridge, regardless of the key. Tests: custom-name bridge detection, bridge flag on ClientDef/status, and a fresh-install (exists=false) Connect-button render. go test ./internal/connect/... green; full vitest + vue-tsc green. Related MCP-2479
Addressed both REQUEST_CHANGES gaps (
|
There was a problem hiding this comment.
codex re-review ACCEPT (gpt-5.5, in-checkout): ConnectModal now shows Connect for bridge clients even when config file absent (connectableClients includes c.bridge); connect.go detects the bridge by args (mcp-remote + mcpURL) so custom server_name entries are recognized; generated entry valid; other clients unaffected. Both round-1 gaps closed.
Summary
The Connect wizard marked Claude Desktop as unsupported even though mcpproxy is reachable from it through an
npx -y mcp-remote <mcpURL>stdio bridge (already documented indocs/setup.md). This made a working, documented path look impossible and cost an adoption win.This PR makes Claude Desktop a real one-click connect target.
Changes
internal/connect/clients.go— flipclaude-desktoptoSupported: true; add a stdio-bridge branch tobuildServerEntrythat writescommand: "npx",args: ["-y", "mcp-remote", <mcpURL>]. NewNotefield onClientDefcarries the bridge caveat.internal/connect/connect.go— addNotetoClientStatus(json:"note,omitempty") and propagate it inGetAllStatus. Connected-state detection already matches the canonicalmcpproxyentry name, so bridge connections are tracked even without a URL field.frontend/src/components/ConnectModal.vue+types/api.ts— render the bridge note under the client row; Claude Desktop now shows a real Connect button.docs/setup.mdnotes the one-click wizard path; connect POST/DELETE client-ID examples widened;make swaggerregenerated.TDD / Acceptance
buildServerEntry("claude-desktop", …)emitsnpx -y mcp-remote <mcpURL>and no URL field —TestBuildServerEntry_ClaudeDesktop_StdioBridge.Connect("claude-desktop", …)writes the bridge entry (with API key in the URL when set) —TestConnect_ClaudeDesktop_WritesStdioBridge,TestConnect_ClaudeDesktop_BridgeIncludesAPIKey.Supportedwith a bridge note —TestClaudeDesktop_SupportedWithBridgeNote, updatedTestGetAllStatus.TestGetAllStatus_ClaudeDesktop_DetectsBridgeConnection.connect-modal.spec.ts.Verification
go test ./internal/connect/... -race— okgo build ./...— okgolangci-lint v2.5.0(CI config) oninternal/connect/...— 0 issuesnpx vitest run— 172 passed;vue-tsc --noEmit— cleanmake swaggerverify — passed (pre-push hook green)Related MCP-2479
🚫 Do not merge — pre-merge gate is human-only (CI green + reviewers + QA first).