Skip to content

Commit 05be5bf

Browse files
Merge pull request #210 from ScriptedAlchemy/codex/cursor-integration-hardening
Harden Cursor MCP integration: degraded serve mode + doctor log diagnostics
2 parents 7158d29 + 8f18092 commit 05be5bf

17 files changed

Lines changed: 1588 additions & 327 deletions

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
- **`serve` no longer exits when project resolution fails at startup** — MCP hosts (Cursor especially) never retry a failed server spawn, so one startup exit over a recoverable config problem (uninitialized project, ambiguous global fallback, bad `--path`) turned every later tool call in the session into "Timed out waiting for connection". `serve` now stays alive in a degraded mode: it completes the MCP handshake, lists the real tools, and answers each tool call with an actionable error naming the failure, the fix, and the `tracedecay tool …` CLI fallback. It rechecks the project on every tool call and recovers in-session once `tracedecay init` (or a corrected path) makes resolution succeed — no server toggle or window reload needed.
1213
- **`serve` now tolerates a literal unexpanded `--path ${workspaceFolder}`** — Cursor's headless agent-session MCP scopes spawn the plugin's serve command without expanding the template variable and never retry the failed scope, which surfaced as "Timed out waiting for connection" on every tool call. `serve` now discards an unexpanded `${...}` template value with a stderr warning and falls back to project discovery where possible, requiring a unique registered project when discovery reaches the global registry in this mode. Rationale and details in `cursor-plugin/README.md`.
1314

15+
### Added
16+
17+
- **`tracedecay doctor --agent cursor` now diagnoses dead Cursor MCP scopes** — best-effort scan of Cursor's recent MCP logs for tracedecay spawn failures (literal unexpanded `${workspaceFolder}` paths, `Connection failed: MCP error -32000`, degraded-mode notices) with concrete remediation ("toggle the MCP server in Cursor Settings → MCP or reload the window"), plus a plugin-bundle-version-vs-binary-version staleness check that points at `tracedecay update-plugin`.
18+
1419
## [0.0.23](https://github.com/ScriptedAlchemy/tracedecay/compare/v0.0.22...v0.0.23) - 2026-07-02
1520

1621
### Other

cursor-plugin/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,34 @@ Notes:
180180
- Entries from per-user and per-repo files are concatenated; allowlists are a
181181
convenience, not a security boundary.
182182

183+
## Troubleshooting a dead MCP scope
184+
185+
Cursor spawns MCP servers with the user home directory as the working
186+
directory, and it **never retries a failed MCP server**: if the `tracedecay
187+
serve` process exits at startup (for example when a headless agent scope
188+
passes a literal, unexpanded `${workspaceFolder}`), every later tool call in
189+
that session reports "Timed out waiting for connection" until you toggle the
190+
server or reload the window.
191+
192+
Two layers of defense ship with this plugin:
193+
194+
- `tracedecay serve` does not exit when project resolution fails at startup.
195+
It completes the MCP handshake and answers tool calls with an actionable
196+
error naming the failure and the fix; it rechecks the project on every tool
197+
call and recovers automatically once `tracedecay init` (or a corrected
198+
`--path`) makes resolution succeed.
199+
- `tracedecay doctor --agent cursor` scans Cursor's recent MCP logs
200+
(`~/.config/Cursor/logs` on Linux, `~/Library/Application Support/Cursor/logs`
201+
on macOS, `%APPDATA%\Cursor\logs` on Windows) for tracedecay spawn failures —
202+
literal `${workspaceFolder}` errors, `Connection failed: MCP error -32000`,
203+
degraded-mode notices — and checks that the installed plugin bundle version
204+
matches the binary.
205+
206+
If a scope has already failed: fix the cause (usually `tracedecay init` in the
207+
project, or upgrading a stale plugin with `tracedecay update-plugin`), then
208+
toggle the tracedecay MCP server in Cursor Settings → MCP or reload the Cursor
209+
window.
210+
183211
## Known limitations
184212

185213
- **Cloud agents:** plugin `sessionStart`, `sessionEnd`, `beforeSubmitPrompt`,

src/agents/cursor.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ impl AgentIntegration for CursorIntegration {
109109
);
110110
}
111111
doctor_check_session_ingest(dc, &ctx.project_path);
112+
super::cursor_diagnostics::report_cursor_mcp_log_findings(dc, &ctx.home);
112113
}
113114

114115
fn is_detected(&self, home: &Path) -> bool {
@@ -828,6 +829,11 @@ fn doctor_check_plugin(dc: &mut DoctorCounters, home: &Path) {
828829
manifest_path.display()
829830
));
830831
}
832+
if let Some(message) =
833+
super::cursor_diagnostics::plugin_version_staleness(&manifest, env!("CARGO_PKG_VERSION"))
834+
{
835+
dc.warn(&message);
836+
}
831837
doctor_check_plugin_mcp(dc, &plugin_dir.join("mcp.json"));
832838
doctor_check_plugin_hooks(dc, &plugin_dir.join("hooks/hooks.json"));
833839
doctor_check_plugin_rule(dc, &plugin_dir.join("rules/tracedecay.mdc"));

0 commit comments

Comments
 (0)