Skip to content

Commit baf2bd9

Browse files
Vortiagoclaude
andauthored
fix: Fix MCP server STDIO output issues (#38)
* fix: Suppress logging output in stdio mode to prevent MCP protocol interference In stdio mode, the MCP protocol uses stdin/stdout for JSON-RPC communication. Any logging output to stdout/stderr breaks the protocol, causing errors in MCP clients. This fix: - Detects transport mode (stdio/sse/streamable-http) early in startup - Configures Python's logging system based on mode: * stdio mode: Sets level to CRITICAL (suppresses INFO/DEBUG logs) * sse/http modes: Sets level to INFO (enables debugging logs) - Suppresses httpx library HTTP request logging in stdio mode - Suppresses MCP SDK's internal logging in stdio mode Resolves issues where MCP clients see logging output as protocol errors. * chore: Update uv.lock with package metadata Updated lockfile after running uv sync for local testing. Adds revision number and package upload timestamps. * feat: Add pytest to pre-commit hooks for faster feedback Adds pytest to pre-commit hooks to catch test failures before commit. Benefits: - Early bug detection (before pushing to CI) - Fast test suite (195 tests in ~7s) - Total pre-commit time: ~10s (acceptable for workflow) - Same test coverage as CI, but earlier in dev cycle The test suite uses mocking and has no external dependencies, making it fast enough for pre-commit without disrupting flow. * perf: Exclude slow integration tests from pre-commit hooks Optimize pre-commit workflow by skipping 2 integration tests that account for 53% of test execution time (2.5s out of 4.7s). Changes: - Pre-commit: 193 unit tests in 2s (was 195 tests in 4.7s) - Total pre-commit time: 8.8s (was 10.6s) - 17% faster - Integration tests still run in CI for comprehensive coverage Impact: - Faster developer workflow - Maintains test quality (integration tests in CI) - Tests marked with @pytest.mark.integration are skipped --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent f1465ac commit baf2bd9

File tree

3 files changed

+712
-681
lines changed

3 files changed

+712
-681
lines changed

.pre-commit-config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ repos:
2424
types: [python]
2525
pass_filenames: false
2626

27+
# Run test suite (skip slow integration tests)
28+
- id: pytest
29+
name: pytest (fast unit tests)
30+
entry: bash -c 'uv run pytest tests/ -v -m "not integration"'
31+
language: system
32+
types: [python]
33+
pass_filenames: false
34+
2735
# General pre-commit hooks
2836
- repo: https://github.com/pre-commit/pre-commit-hooks
2937
rev: v5.0.0

src/mcp_outline/server.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,28 @@ def main() -> None:
5050
)
5151
transport_mode = "stdio"
5252

53+
# Configure logging based on transport mode
54+
if transport_mode == "stdio":
55+
# In stdio mode, suppress all logging to prevent interference
56+
# with MCP protocol. MCP uses stdio for JSON-RPC communication,
57+
# so any logs to stdout/stderr break the protocol.
58+
logging.basicConfig(
59+
level=logging.CRITICAL, # Only show critical errors
60+
format="%(message)s",
61+
)
62+
# Also suppress httpx logging (HTTP request logs)
63+
logging.getLogger("httpx").setLevel(logging.CRITICAL)
64+
# Suppress MCP SDK's internal logging
65+
logging.getLogger("mcp").setLevel(logging.CRITICAL)
66+
else:
67+
# In SSE/HTTP modes, enable info logging for debugging
68+
logging.basicConfig(
69+
level=logging.INFO,
70+
format="[%(asctime)s] %(levelname)-8s %(message)s",
71+
datefmt="%m/%d/%y %H:%M:%S",
72+
)
73+
logging.getLogger("httpx").setLevel(logging.INFO)
74+
5375
logging.info(
5476
f"Starting MCP Outline server with transport mode: {transport_mode}"
5577
)

0 commit comments

Comments
 (0)