gabriel / musehub public
Open #210 Bug
filed by gabriel human · 33 days ago

MCP stdio: musehub_set_context's session focus is not honored by the very next musehub_read_context() call

0 Anchors
— Blast radius
— Churn 30d
0 Proposals
No description provided.
◎ Activity1
●
gabriel opened this issue 33 days ago
○
gabriel 33 days ago

Confirmed while building Episode 16 ("Muse + MCP") demo material. Real, reproducible — moderate severity: a documented ergonomic feature (the tool's OWN returned onboarding instructions) doesn't actually work as described, but there's a full working fallback.

Repro (single continuous stdio session, sequential requests):

{"jsonrpc":"2.0","id":1,"method":"initialize", ...}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"musehub_set_context","arguments":{"owner":"gabriel","slug":"build-with-muse"}}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"musehub_read_context","arguments":{}}}

Call 2 succeeds: {"focused": true, "owner": "gabriel", "slug": "build-with-muse", ..., "message": "Session is now focused on gabriel/build-with-muse. Subsequent tool calls that accept owner/slug will use this repo automatically. Pass explicit owner+slug to override."}

Call 3 (the very next call, same process, no args, exactly as the tool's own message says to do) fails: {"error_code": "repo_not_found", "error_message": "Repository '' not found."} — note the empty string, meaning owner/slug resolved to "" rather than falling back to the session-focused repo at all.

Confirmed workaround: passing owner/slug explicitly on every call (musehub_read_context(owner="gabriel", slug="build-with-muse")) works correctly and returns the full real repo context. So the underlying read path is fine — only the session-context fallback resolution is broken.

Why this matters: initialize's own returned instructions field tells every connecting agent to call musehub_set_context once and then omit owner/slug on every subsequent call — that's the documented, intended agent workflow, and it silently fails on the very first follow-up call in the stdio transport.

Suggested starting point: check whether the stdio transport's per-request handling constructs a fresh context/session object per JSON-RPC message instead of reusing one tied to the process/connection — that would explain set_context's write being real but invisible to the next call. Worth checking whether the same session persists correctly over the HTTP Streamable transport (which has an explicit Mcp-Session-Id header) — if HTTP works and only stdio is broken, the bug is specific to how stdio's session state is threaded through dispatcher.py.

Deferred per usual until after the season wraps.