fix: SQLAlchemy echo=True floods MCP stdio's stdout with raw SQL, corrupting the JSON-RPC stream (musehub#208)
Root cause confirmed (the reporter's own suspicion was exactly right): musehub/db/database.py::init_db() creates the async engine with echo=settings.debug. SQLAlchemy's InstanceLogger.__init__ (sqlalchemy/log.py) installs its own hardcoded logging.StreamHandler(sys.stdout) directly on the engine's uniquely-named child logger whenever echo is truthy and that logger has no handlers yet. This has nothing to do with stdio_server.py's own logging.basicConfig(stream=sys.stderr) call -- basicConfig only configures the ROOT logger, never the per-engine child logger SQLAlchemy creates and attaches its own stdout handler to directly. Under this project's own default local-dev config (DEBUG=true), every SQL statement got written straight to stdout -- the exact byte stream the stdio MCP transport uses as its JSON-RPC wire protocol.
Reproduced live against the real container (DEBUG=true): a single initialize request produced 2199 lines of raw SQL echo text on stdout before the fix, 1 clean JSON-RPC response line after.
Fix: init_db() gains an echo override parameter (None default = use settings.debug, unchanged for every HTTP/worker caller). The stdio transport now calls init_db(echo=False) unconditionally -- stdio's wire protocol correctness can never depend on a debug flag someone else sets for an unrelated transport.
Semantic Changes
14 symbols
Files Changed
+1
~2
1113 in snapshot
0 comments
muse hub commit comment sha256:71af3895204576a6667c619af9df11ac35f47c40f8a3dbcbde64540cf544f301 --body "your comment"
No comments yet. Be the first to start the discussion.