"""Muse MCP stdio transport — Claude Desktop / Cursor integration (§KD-5a.E). Entry point:: python -m muse.mcp.stdio_server The process CWD must be the bound Muse repository root (typically ``knowtation-vault-smoke`` for KD-5b tests). """ from __future__ import annotations import json import logging import sys from muse.mcp.server import MuseMCPServer logger = logging.getLogger(__name__) def run_stdio() -> None: """Read newline-delimited JSON-RPC from stdin; write responses to stdout.""" server = MuseMCPServer() logger.info( "Muse MCP stdio started (domain=%s, knowtation=%s)", server.capabilities.get("active_domain"), server.capabilities.get("knowtation_mounted"), ) for line in sys.stdin: line = line.strip() if not line: continue try: raw = json.loads(line) except json.JSONDecodeError as exc: sys.stdout.write( json.dumps( { "jsonrpc": "2.0", "id": None, "error": {"code": -32700, "message": f"Parse error: {exc}"}, } ) + "\n" ) sys.stdout.flush() continue resp = server.handle_request(raw) if resp is not None: sys.stdout.write(json.dumps(resp, default=str) + "\n") sys.stdout.flush() def main() -> None: logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s", stream=sys.stderr, ) run_stdio() if __name__ == "__main__": main()