Skip to content

[gitlab-mcp] All startup logs written to stdout, polluting MCP stdio channel #563

Description

@TaylorEnthon

Problem

When @structured-world/gitlab-mcp starts up, it writes all of its informational logs (INFO/WARN/ERROR) to stdout instead of stderr. This breaks the MCP stdio protocol contract: stdout is reserved for JSON-RPC messages, and stderr is where MCP servers should write diagnostic output.

The downstream MCP client (e.g. hermes-agent's mcp client) tries to parse every stdout line as a JSON-RPC message, fails on every log line, and floods the user with ~10 lines of "Failed to parse JSONRPC message from server" before the connection initializes.

Repro

  1. Install @structured-world/gitlab-mcp and configure it in any MCP client with a real GITLAB_TOKEN
  2. Start the MCP client (any TUI/CLI)
  3. Observe startup log spam:
Failed to parse JSONRPC message from server
Traceback (most recent call last):
  File ".../mcp/client/stdio/__init__.py", line 155, in stdout_reader
    message = types.JSONRPCMessage.model_validate_json(line)
pydantic_core._pydantic_core.ValidationError: 1 validation error for JSONRPCMessage
  Invalid JSON: expected value at line 1 column 5 [type=json_invalid,
  input_value='   \x1b[35mversion\x1b[39m: "16.11.10"', input_type=str]
  1. Direct test confirms logs go to stdout, not stderr:
$ GITLAB_TOKEN=*** timeout 8 npx -y @structured-world/gitlab-mcp >out.log 2>err.log
# out.log: 26 lines (all log output)  err.log: 0 lines
  1. Sample log fields observed in stdout (Go log/slog text format with ANSI color):
    • [HH:MM:SS.mmm] \x1b[32mI...\x1b[39m (timestamp + colored INFO prefix)
    • \x1b[35mwidgetTypes\x1b[39m: 15 / \x1b[35mtypeDefinitions\x1b[39m: 77 / \x1b[35mschemaTypes\x1b[39m: 77 — GitLab GraphQL schema introspection metadata
    • \x1b[35mversion\x1b[39m: "16.11.10" / \x1b[35mtier\x1b[39m: "free" — user GitLab instance version + tier

Expected

gitlab-mcp startup logs (WARN about GraphQL fallback, INFO about schema detection, etc.) should go to stderr so they don't get parsed as JSON-RPC protocol messages by the MCP client.

Actual

All logs use Go's default log/slog text format with ANSI colors, written to stdout. The MCP spec requires stdout to be JSON-RPC only.

Workaround

Set enabled: false in the MCP client config to skip this server entirely. This means losing all gitlab-mcp functionality (issues, MRs, repos, etc.) until the bug is fixed.

Suggested fix

Two reasonable paths:

  1. Configure log/slog to write to stderr (or io.Discard for INFO+ unless debug mode is on). This is the spec-compliant fix and likely a one-line change.

  2. Add a --log-file / --log-level flag so users can silence non-error output entirely. More flexible but requires every downstream integration to set the flag.

Either way the change is small — the harder part is just spotting that the default is wrong.

Reported from hermes-agent v0.19.1 on Windows (AMD64). Original diagnosis in hermes-agent issue tracker under known-issues.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions