|
1 | 1 | # Cursor Workspace Routing via Global `mcp-remote` Bridge |
2 | 2 |
|
3 | | -**Last Updated:** Jul 20, 2026 |
4 | | -**Status:** Complete (Phases 1–3 on `dev-rebased`) |
| 3 | +**Last Updated:** Jul 24, 2026 |
| 4 | +**Status:** Complete (Phases 1–3) — Agents Window multi-workspace spike **pending** (observability logs shipped) |
5 | 5 | **Branch:** `dev-rebased` |
6 | 6 |
|
7 | 7 | ### Phase 1 spike results (Jul 20, 2026) |
|
10 | 10 | - **Gateway:** `localhost:45818` up (`0.5.0`). |
11 | 11 | - **Auth + connect:** `phase1-spike-bridge` client reached gateway; machine-naming dialog appeared and was approved. |
12 | 12 | - **Remaining manual QA:** two-window `${workspaceFolder}` routing not yet verified in real Cursor; transport/auth path is confirmed. |
| 13 | + |
13 | 14 | **Depends on:** `docs/manual/workspace-header-routing.md` (existing per-repo header fix this supersedes as the recommended path), `upstream-client-mapping-reconciliation.md` Phase 1 (`mcpk_` API-key auth — this feature's auth mechanism) |
14 | 15 | **Unblocks:** Zero-maintenance Cursor workspace routing — no per-repo files, no agent cooperation required |
15 | 16 |
|
| 17 | +### Agents Window multi-workspace spike (Jul 24, 2026) |
| 18 | + |
| 19 | +**Hypothesis:** Cursor Agents Window groups agents by workspace in the UI, but may share one MCP session / mis-resolve `${workspaceFolder}` across workspaces, so mux cannot pin the correct root→FeatureSet binding. Gondor-local + global bridge config is already the intended Editor path; this spike proves what Agents Window actually sends. |
| 20 | + |
| 21 | +**Observability (shipped):** gateway logs now include: |
| 22 | + |
| 23 | +| Signal | Where | Level | |
| 24 | +| ------ | ----- | ----- | |
| 25 | +| `session_id` + `workspace_header` on every MCP POST | `oauth_middleware` `→ MCP` | info | |
| 26 | +| Workspace header without `mcp-session-id` (pin skipped) | `oauth_middleware` | warn | |
| 27 | +| First pin / same-session root clobber | `session_roots.set_pinned` | info / warn | |
| 28 | +| `workspace_root` on resolve | `handler` `[FeatureSetResolver] resolved` | info | |
| 29 | +| `x-mcpmux-workspace` / `x-mcpmux-machine-id` in DEBUG request headers | `logging_middleware` | debug | |
| 30 | + |
| 31 | +**Repro (Gondor):** |
| 32 | + |
| 33 | +1. Rebuild/restart the desktop gateway so the new logs are live. |
| 34 | +2. In Agents Window, start one agent under workspace A and one under workspace B (both already machine-bound on Gondor, e.g. `mcp-mux` vs `sync2hire-platform`). |
| 35 | +3. From each agent, call any `mcpmux_*` tool (e.g. `mcpmux_list_servers` or `mcpmux_search_tools`). |
| 36 | +4. Grep gateway logs: `SessionRoots`, `workspace_header`, `pin clobber`, `→ MCP`, `[FeatureSetResolver] resolved`. |
| 37 | + |
| 38 | +**Pass:** distinct `session_id` values; each `workspace_header` / resolved `workspace_root` matches that agent's workspace; no `pin clobber` warn. |
| 39 | + |
| 40 | +**Fail:** shared `session_id` with `pin clobber` (previous ≠ new), or `workspace_header=<absent>`, or header present without session id. |
| 41 | + |
| 42 | +**Next if fail:** prefer per-repo static `.cursor/mcp.json` header for Agents Window, and/or treat as Cursor Agents Window MCP binding gap (not a new per-agent identity axis). |
| 43 | + |
| 44 | +**Spike results:** _pending manual run_ |
| 45 | + |
16 | 46 | --- |
17 | 47 |
|
18 | 48 | ## Problem |
@@ -161,7 +191,9 @@ Removes the "hand-assemble JSON" friction so the bridge is actually usable by so |
161 | 191 | | File | Note | |
162 | 192 | | ---- | ---- | |
163 | 193 | | [`apps/desktop/src-tauri/src/commands/workspace_install.rs`](../../apps/desktop/src-tauri/src/commands/workspace_install.rs) | The existing per-repo header install this feature supplements, not replaces | |
164 | | -| [`crates/mcpmux-gateway/src/services/session_roots.rs`](../../crates/mcpmux-gateway/src/services/session_roots.rs) | `X-Mcpmux-Workspace` is already authoritative here — no gateway changes needed | |
| 194 | +| [`crates/mcpmux-gateway/src/services/session_roots.rs`](../../crates/mcpmux-gateway/src/services/session_roots.rs) | `X-Mcpmux-Workspace` pin is authoritative; Agents Window spike adds pin/clobber info+warn logs | |
| 195 | +| [`crates/mcpmux-gateway/src/mcp/oauth_middleware.rs`](../../crates/mcpmux-gateway/src/mcp/oauth_middleware.rs) | `→ MCP` logs `session_id` + `workspace_header`; warns when pin skipped | |
| 196 | +| [`crates/mcpmux-gateway/src/mcp/handler.rs`](../../crates/mcpmux-gateway/src/mcp/handler.rs) | Resolver resolved log includes `workspace_root` | |
165 | 197 | | [`docs/manual/workspace-header-routing.md`](../manual/workspace-header-routing.md) | Documents the underlying Cursor `roots`-reporting bug this bridge works around | |
166 | 198 | | [`docs/planning/upstream-client-mapping-reconciliation.md`](./upstream-client-mapping-reconciliation.md) | Phase 1 — `mcpk_` API-key auth, reused here as the bridge's auth mechanism | |
167 | 199 | | [`apps/desktop/src/features/clients/RegisterApiKeyClientModal.tsx`](../../apps/desktop/src/features/clients/RegisterApiKeyClientModal.tsx) | Existing API-key minting UI this feature's Phase 2 panel is modeled on | |
|
0 commit comments