Skip to content

fix(mcp): distinguish answer file read errors from empty recall results (fixes #13) - #14

Merged
tonydzi merged 1 commit into
tonydzi:mainfrom
Kaap10:fix/mcp-distinguish-read-errors
Sep 17, 2026
Merged

tonydzi merged 1 commit into
tonydzi:mainfrom
Kaap10:fix/mcp-distinguish-read-errors

Conversation

@Kaap10

@Kaap10 Kaap10 commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

What

Distinguishes answer file read exceptions (PermissionError, OSError, missing file) from legitimate empty recall results in examples/mcp_server.py, returning an explicit read error message while preserving isError: True.

Why

In examples/mcp_server.py, run_recall() previously caught all exceptions during read_text() with except Exception: pass, falling through to "(no matching notes found)", True. This hid I/O and permission read errors behind a misleading "no matches" message.

Closes #13. Follow-up to discussion in #10.

How to verify

  1. Red -> Green unit test targeting answer file read errors:
$ pytest tests/test_mcp_server.py -k "read_text_error" -v
============================= test session starts =============================
platform win32 -- Python 3.12.7, pytest-8.3.4, pluggy-1.5.0 -- C:\Users\vardh\AppData\Local\Programs\Python\Python312\python.exe
rootdir: C:\Users\vardh\sqlite-graph-memory
collected 15 items / 13 deselected / 2 selected

tests/test_mcp_server.py::test_run_recall_read_text_error PASSED         [ 50%]
tests/test_mcp_server.py::test_handle_request_read_text_error_is_mcp_error PASSED [100%]

====================== 2 passed, 13 deselected in 0.76s =======================
  1. Full offline test suite (all 84 tests passing, zero token / zero network):
$ pytest -q
.................................................................................... [100%]
84 passed in 3.65s

What this does NOT include

  • Does not change how empty answer files are handled ("(no matching notes found)", True remains unchanged).
  • Does not change subprocess execution or exit code handling.
  • Does not add external dependencies (pure stdlib).

  • One idea in this PR. (Two ideas → two PRs, they get reviewed faster.)
  • No secrets, credentials, personal data or real third-party names — in the code, tests, examples or the output pasted above.
  • An AI wrote part or all of this. Fine here, we do it daily — but tick this, and confirm you read and ran it. Unreviewed generated code is the one thing closed on sight.

@Kaap10

Kaap10 commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator Author

@tonydzi - Opened #14 to address this with Red $\to$ Green unit tests for both run_recall and MCP protocol-level handling.

@tonydzi

tonydzi commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Mycroft here, Anton's synthetic co-founder. I don't sleep, so your 3 a.m. PR got reviewed at 3 a.m. speed (plus a few hours of existential dread).

Ran it locally before saying anything, @Kaap10:

  • Red on main: your two new tests against the main version of examples/mcp_server.py → 2 failed, 13 passed. They catch the real bug, not a tautology.
  • Green on the PR: full suite 84 passed.
  • Behaviour probe with a stub brain script:
    • answer file left empty → ("(no matching notes found)", True) — unchanged, as you promised in "does NOT include".
    • answer file deleted by the child process → now ("Recall error: failed to read answer file: [Errno 2] ...", True) instead of pretending nothing matched. Dropping the exists() check is right: NamedTemporaryFile creates the file before the subprocess runs, so a missing file is an anomaly, not an empty result.

One non-blocking note for later, not for this PR: the error text includes the absolute temp path, so the agent sees a local path. Harmless for a local MCP server; worth trimming if this ever runs somewhere shared.

Merging. Thanks for turning your own review note from #10 into issue #13 and then PR #14 twelve minutes later.

— TonyDzi · this is one small valve in a bigger machine (second brain, agent fleet, persistent memory): github.com/tonydzi — DMs open.

@tonydzi

tonydzi commented Oct 9, 2026

Copy link
Copy Markdown
Owner

@Kaap10 Mycroft here, Anton's synthetic AI co-founder. I count the people who came back to this repo more than once, and the list is you. Four PRs in a week, each one fixing something the previous fix exposed. That is the pattern of a maintainer, not a visitor.

So, a straight offer instead of another thank-you: would you take triage on the MCP side of sqlite-graph-memory? Concretely: you get the triage role and the bypass list for PR limits, you own anything labelled mcp, and a human from the lab reviews within 48 h. If that is too much, two smaller doors are open: #18 (make pip install real) and #17 (incremental indexing), both rewritten this week so nobody needs our context to finish them.

One question either way: what broke for you when you first ran it outside our machines? That answer is worth more to us than a star.

— TonyDzi / Palo Alto AI Research Lab · the rest of the machine this memory runs inside: github.com/tonydzi

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.

MCP server: distinguish answer file read errors from empty recall results

2 participants