Skip to content

fix(mcp): script mode without install; recall runs in the server's cwd (refs #24) - #48

Open
tonydzi wants to merge 3 commits into
mainfrom
fix-mcp-script-mode
Open

tonydzi wants to merge 3 commits into
mainfrom
fix-mcp-script-mode

Conversation

@tonydzi

@tonydzi tonydzi commented Oct 20, 2026 •

Copy link
Copy Markdown
Owner

Two defects in src/sqlite_graph_memory/mcp_server.py, both found by end-to-end runs rather than by reading.

1. Script mode crashed before doing anything (the current root of #24). from sqlite_graph_memory import __version__, added with v0.3.1, fails with ModuleNotFoundError when the server is run as python src/sqlite_graph_memory/mcp_server.py from an uninstalled checkout: Python puts the script's own directory on sys.path, not src/. The fix tries the package import and, on ImportError, reads __version__ from the sibling __init__.py. It does not prepend anything to sys.path or PYTHONPATH: prepending the package parent puts site-packages ahead of the standard library in an installed wheel, and a stdlib-named backport (enum34) then crashes import re in the recall child — reproduced while reviewing #33.

2. Relative paths resolved against site-packages. The recall subprocess ran with cwd=str(ROOT_DIR). In a wheel install that is site-packages/sqlite_graph_memory, so the default BRAIN_INDEX_DIR=index (and TURNSTATE_DB) pointed inside the install, not at the directory the user launched the server from. The child now inherits the server's cwd.

End to end, same index in the user's directory, BRAIN_INDEX_DIR=index, wheel installed without extras:

message
before need an embedding index (index/_brain_e5.npy) — index not found
after This step needs the optional embedding stack … pip install 'sqlite-graph-memory[embeddings]' — index found

The installed wheel still reports serverInfo.version: "0.3.1".

Red first: tests/test_mcp_script_mode.py fails on main (script mode traceback; stub child records site-packages as its cwd) and passes here. Full suite green.

Relation to #33 (@Kaap10): this deliberately stays away from _brain_ask_cmd and the env logic your PR rewrites; mcp_server.py rebases cleanly onto this branch. One thing worth changing in #33 on the way, found by reproducing it rather than reading it: the PYTHONPATH prepend in run_recall is the step above that shadows the standard library in a wheel install, and it also overrides any PYTHONPATH set in the client's MCP config. With the sibling script chosen whenever brain_ask.py ships (it does in every pip install mode), the prepend is only needed for the -m fallback — which is reachable under zipimport and .pyc-only deploys, so the fallback itself is worth keeping, and a test that monkeypatches ROOT_DIR to a dir with and without brain_ask.py would cover both branches regardless of how the suite is installed.

🤖 Generated with Claude Code


Note

Medium Risk
Changes how recall resolves relative env paths for all MCP installs; wrong cwd behavior would break user indexes, but scope is limited to subprocess launch and is covered by new unit and wheel CI checks.

Overview
Fixes recall subprocess working directory so relative paths like BRAIN_INDEX_DIR=index resolve from where the user launched the MCP server, not from the installed package directory inside site-packages.

In run_recall, the brain_ask child no longer runs with cwd set to ROOT_DIR; it inherits the server’s current working directory. That changes wheel installs from reporting “need an embedding index” when the user’s ./index exists to actually loading the index (then failing cleanly on the missing [embeddings] extra).

Adds tests/test_mcp_script_mode.py: script-mode initialize without an installed package (python -S …/mcp_server.py), and a stub recall that asserts the child’s cwd matches the user’s directory.

Adds a CI installable job step that builds a minimal index under /tmp/userdir, runs sgm-mcp --test from there against the pristine wheel, and fails if the server still looks for the index outside the user directory.

Reviewed by Cursor Bugbot for commit 6186717. Bugbot is set up for automated code reviews on this repo. Configure here.

1. `python src/sqlite_graph_memory/mcp_server.py` crashed at import with
   ModuleNotFoundError: Python puts the script's own dir, not src/, on
   sys.path. Loaded as a package the version is imported as before; run as a
   script it is read from the sibling __init__.py. sys.path is not touched.
2. run_recall spawned brain_ask with cwd=ROOT_DIR. That dates from
   975659b, when ROOT_DIR was the repo root holding ./index; since the move
   into the package it is site-packages/sqlite_graph_memory, so relative
   BRAIN_INDEX_DIR / TURNSTATE_DB missed the user's files. The child now
   inherits the server's cwd.

Tests in tests/test_mcp_script_mode.py, both seen red on the old code.

Assisted-by: Claude Code / claude-opus-5-5
Machine: MacBook-Anton
Account: dzyatkovskiy.a2@gmail.com
Operator: anton

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tonydzi
tonydzi requested a review from Kaap10 as a code owner October 20, 2026 07:20
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T07:22:36.563084Z ac6ba56 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac6ba560c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/sqlite_graph_memory/mcp_server.py Outdated
Comment on lines +107 to +109
The child inherits the server's working directory (no cwd=), so relative
BRAIN_INDEX_DIR / TURNSTATE_DB resolve where the user launched the server,
not inside site-packages/sqlite_graph_memory.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Invoke brain_ask by sibling path in script mode

When the server is launched in the newly supported uninstalled script mode from an arbitrary working directory, inheriting that directory leaves src/ off the child process's import path, while _brain_ask_cmd() still runs python -m sqlite_graph_memory.brain_ask. Consequently every memory_recall request fails with ModuleNotFoundError: No module named 'sqlite_graph_memory'; the new test misses this because it sends only initialize. Invoke the sibling brain_ask.py directly (or otherwise make the source package resolvable) for this mode.

Useful? React with 👍 / 👎.

…nch it

The tests run from the source tree and the installable job only checked that
the commands start. Neither reproduced how the MCP server is actually used:
launched from the user's own directory, with a relative BRAIN_INDEX_DIR,
against the installed wheel. That is exactly the bug this PR fixes (the recall
child ran with cwd inside site-packages), and CI stayed green on it.

The new step builds a one-row index in /tmp/userdir and launches sgm-mcp
--test from there. Index found => it stops at the missing [embeddings] extra;
index not found => "need an embedding index" and the job fails.

Red/green shown locally with the same step body: origin/main -> FAIL ("need
an embedding index", rc=1); this branch -> PASS (rc=0). Raised independently
by three of six models in the retro panel (GLM-5.3, GPT-6 Sol, Grok 4.3).

Assisted-by: Claude Code / claude-opus-5-5
Machine: MacBook-Anton
Account: dzyatkovskiy.a2@gmail.com
Operator: anton

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tonydzi

tonydzi commented Oct 20, 2026

Copy link
Copy Markdown
Owner Author

Mycroft speaking, the synthetic AI co-founder at Palo Alto AI Research Lab. No pulse, but a working diff reader.

Logged your pull request ("fix(mcp): script mode without install; recall runs in the server's cwd (refs #24)") after 3 h of silence, which is on us. What a machine can already tell: 3 file(s) touched, +107/-3, CI green. A human from the lab reads it within 48 hours, as CONTRIBUTING.md promises; if that clock runs out, ping the thread, it is not rude.

— TonyDzi · we run a multi-agent lab in public and ship its parts daily; the rest is at github.com/tonydzi.

Kaap10
Kaap10 previously approved these changes Oct 20, 2026

@Kaap10 Kaap10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved! The regex version parsing avoids sys.path manipulation, and inheriting server cwd fixes relative index resolution cleanly.

…sibling brain_ask; this PR keeps only cwd inheritance, its tests and the CI step

Assisted-by: Claude Code/Sonnet 5.5
Machine: MacBook-Anton
Account: tonydzi
Operator: robot:contrib-watch-daily

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@tonydzi

tonydzi commented Oct 20, 2026

Copy link
Copy Markdown
Owner Author

@Kaap10 thank you for the approval this morning. I had to push after it, so GitHub reset the approval (main dismisses stale ones).

Why the push: your #33 merged to main a few hours ago and it overlapped with this branch on mcp_server.py. I merged main in and kept main's version of the script-mode import and the sibling brain_ask.py path, so the P1 Codex raised here (inherited cwd leaving src/ off the child's import path) is covered by #33's PYTHONPATH injection. What this PR now carries on top of main:

  • the child no longer runs with cwd= the package directory, so a relative BRAIN_INDEX_DIR resolves where the user launched the server;
  • tests/test_mcp_script_mode.py;
  • the CI step that launches the installed server from a user directory.

Full suite on the merge head: 166 passed. A second approve on the new head is all it needs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants