fix(mcp): auto-detect project via roots/list when no rootUri (#196)#214
Merged
Conversation
MCP tools failed with "CodeGraph not initialized" when a client launched the server outside the project and sent no rootUri/workspaceFolders — the server fell back to its own cwd, missed the project's .codegraph/, and returned a misleading "run codegraph init" error on every call. The only workaround was passing projectPath by hand to each tool. When no explicit path is given, the server now asks the client for its workspace root via the standard MCP roots/list request (gated on the client advertising the roots capability) before falling back to cwd. This required teaching the stdio transport to send server->client requests and match their responses by id (previously responses were dropped as invalid). When a project still can't be resolved, the error now names the directory it searched and tells the user to pass projectPath or add --path to the MCP config, instead of pointing at a re-init they don't need. Reported-by: @zhangyu1197 Closes #196 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jorgerobles
pushed a commit
to jorgerobles/codegraph
that referenced
this pull request
Jun 1, 2026
…henry#196) (colbymchenry#214) MCP tools failed with "CodeGraph not initialized" when a client launched the server outside the project and sent no rootUri/workspaceFolders — the server fell back to its own cwd, missed the project's .codegraph/, and returned a misleading "run codegraph init" error on every call. The only workaround was passing projectPath by hand to each tool. When no explicit path is given, the server now asks the client for its workspace root via the standard MCP roots/list request (gated on the client advertising the roots capability) before falling back to cwd. This required teaching the stdio transport to send server->client requests and match their responses by id (previously responses were dropped as invalid). When a project still can't be resolved, the error now names the directory it searched and tells the user to pass projectPath or add --path to the MCP config, instead of pointing at a re-init they don't need. Reported-by: @zhangyu1197 Closes colbymchenry#196 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
MCP tools failed with
CodeGraph not initializedeven when the index existed, reported in #196 by @zhangyu1197.When a client launches the MCP server from a directory other than the project and doesn't pass a
rootUri/workspaceFoldersininitialize(some IDE/JetBrains-family integrations), the server fell back to its ownprocess.cwd(), missed the project's.codegraph/, and returned a misleading "Run 'codegraph init' first" on every call. The only workaround was passingprojectPathto each tool by hand.Root cause:
rootUri/workspaceFoldersare LSP-style fields (non-standard for MCP) — the spec's actual mechanism for a client to expose its workspace root,roots/list, was never implemented.Fix
transport.ts— the stdio transport can now send server→client requests and match their responses by id. Previously aroots/listreply would have been dropped as "Invalid Request" (responses carry nomethod). Includes a timeout so a non-answering client degrades gracefully, and pending requests are rejected on shutdown.index.ts— wheninitializecarries no explicit path, the server no longer commits tocwd. On the first tool call it asks the client viaroots/list(gated on therootscapability), uses the first root, and only falls back tocwdif that yields nothing. One-shot guarded so it never re-issuesroots/listper call. The fast-initialize contract from MCP server fails to connect with Claude Code: Content-Length framing vs newline-delimited JSON transport mismatch #172 is preserved — resolution stays lazy and off the handshake path.tools.ts— the "not initialized" error is now actionable: it names the directory it searched and tells you to passprojectPathor add--path /abs/project, instead of pointing at a re-init you don't need.Tests
New
__tests__/mcp-roots.test.ts(3 tests, real spawned server over stdio):roots/listwhen norootUriis sentrootscapabilityrootUriwithout asking for rootsFull suite green (639 passed), including the #172 handshake-timing regression test.
Credit to @zhangyu1197 for discovering and diagnosing the issue, and for the
projectPathworkaround.Closes #196
🤖 Generated with Claude Code