gabriel / musehub public
fix BREAKING fix/210-mcp-stdio-session-focus #1 / 1
AI Agent gabriel · 2 days ago · Oct 22, 2026 · Diff

fix: stdio MCP transport never created a session, breaking musehub_set_context's session focus (musehub#210)

musehub_set_context's own returned message tells every connecting agent to call it once and then omit owner/slug on subsequent calls -- the documented, intended workflow. The dispatcher's session-focus injection (_handle_tools_call, dispatcher.py) was never broken: it correctly writes to session.repo_focus and correctly injects it into the next call's arguments when owner/slug are absent. The bug was entirely in musehub/mcp/stdio_server.py -- every handle_request() call passed session=None (the implicit default), so musehub_set_context's write was a silent no-op (guarded by an is-not-None check on ctx.session), and the next musehub_read_context() call had no session to inject owner/slug from, resolving to an empty-string repository lookup.

The Streamable HTTP transport never had this problem: it creates an MCPSession right after a successful initialize and threads it through every subsequent request via the Mcp-Session-Id header. stdio has no such header, but it IS a single, long-lived connection to exactly one client for the process's lifetime -- so the fix creates one session at the same moment HTTP does (right after a successful initialize) and reuses that same object for every request thereafter, for as long as the process runs.

Extracted the capability-extraction + create_session() logic HTTP already had (_create_session_from_initialize in api/routes/mcp.py) into a shared musehub.mcp.session.create_session_from_initialize_params(), used by both transports now instead of duplicating it.

sha256:64298d820f83e03ad4a1d3dae5a5fe2e57d124c1ebd0d56e99d93e69b595dccc sha
+17 ~9 −2 symbols
4 changed · 1110 in snapshot files
sha256:b89396dc801bb9f3f0fdbd4b1f2776c213c9546233aaa19cefc68e99461c5057 snapshot
+17
symbols added
~9
symbols modified
−2
symbols removed
4
files changed
1110
files in snapshot
0
dead code introduced
Semantic Changes 28 symbols
~ tests/test_mcp_stdio_session.py .py 15 symbols added
+ TestStdioSessionPersistence class class TestStdioSessionPersistence L79–154
+ test_session_is_reused_not_recreated_per_message method async_method test_session_is_reused_not_recreated_per_message L124–154
+ test_set_context_then_read_context_resolves_focused_repo method async_method test_set_context_then_read_context_resolves_focused_repo L80–122
+ _FakeWriteTransport class class _FakeWriteTransport L27–37
+ __init__ method method __init__ L30–31
+ lines method method lines L36–37
+ write method method write L33–34
+ _run_stdio_with_lines function async_function _run_stdio_with_lines L40–75
+ AsyncMock import import AsyncMock L22–22
+ MagicMock import import MagicMock L22–22
+ annotations import import annotations L18–18
+ asyncio import import asyncio L20–20
+ json import import json L21–21
+ patch import import patch L22–22
+ pytest import import pytest L24–24
~ musehub/api/routes/mcp.py .py 1 symbol added, 2 symbols removed, 8 symbols modified
− _create_session_from_initialize function function _create_session_from_initialize L554–565
− create_session import import create_session L47–47
+ create_session_from_initialize_params import import create_session_from_initialize_params L47–47
~ musehub/mcp/session.py .py 1 symbol added
+ create_session_from_initialize_params function function create_session_from_initialize_params L153–169
~ musehub/mcp/stdio_server.py .py 1 symbol modified
~ _run
Files Changed
+1 ~3
1110 in snapshot
← Older Oldest on fix/210-mcp-stdio-session-focus
All commits
Newer → Latest on fix/210-mcp-stdio-session-focus

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:64298d820f83e03ad4a1d3dae5a5fe2e57d124c1ebd0d56e99d93e69b595dccc --body "your comment"