Skip to content

Conversation

@rothnic
Copy link

@rothnic rothnic commented Oct 31, 2025

Fixes issue #5

The MCP server wrote plain text to stdout, corrupting the JSON-RPC protocol stream and causing clients like MCP Inspector to fail on connect with parse errors.

Changes

Redirect logs from stdout to stderr

  • Changed 3 console.log calls to console.error in index.js:
    • Server startup message in main()
    • Component selection logging in select_components tool handler
    • Documentation retrieval logging in getSelectedComponentsDocs()

Add regression test

  • Created test/no-stdout-on-start.test.js that spawns the server process and asserts stdout remains empty while stderr contains expected logs
  • Updated package.json to run tests via node --test

Add CI workflow

  • Created .github/workflows/ci.yml to run tests on Node 18.x, 20.x, 22.x
  • Triggers on push to main and PRs targeting main
  • Status check will be CI / test for branch protection rules

Enabling Branch Protection

After merge, configure main branch to require CI / test status check to prevent future regressions.

Original prompt

Problem
The MCP server writes plain text to stdout (e.g., "Use Gluestack Components MCP Server running on stdio" and other console.log calls), which corrupts the MCP stdio JSON stream and causes clients like the MCP Inspector to throw a JSON parse error on first connect. We need to ensure stdout is reserved exclusively for the protocol and add CI tests to prevent regressions. Also add a GitHub Actions workflow to run tests on PRs and pushes to main so merges are blocked when tests fail (branch protection can then require this check on main).

Tasks

  1. Update index.js so no logging goes to stdout:

    • Replace all console.log calls with console.error to route logs to stderr.
    • Locations to change:
      • After server.connect: console.log("Use Gluestack Components MCP Server running on stdio") -> console.error(...)
      • In getSelectedComponentsDocs: console.log(✅ Getting documentation for components: ...) -> console.error(...)
      • In the select_components tool handler: console.log(✅ Selected components: ...) -> console.error(...)
  2. Add a test to prevent regressions using Node's built-in test runner:

    • File: test/no-stdout-on-start.test.js
    • Behavior: spawn node index.js, capture stdout and stderr for ~500ms, and assert that stdout is empty on startup. Kill the process afterward.
  3. Update package.json scripts to run the tests:

    • Set "test": "node --test"
    • Keep existing fields. Ensure type: module remains.
  4. Add a GitHub Actions workflow to run tests on push to main and on pull requests targeting main:

    • File: .github/workflows/ci.yml
    • Use Ubuntu runner, matrix over Node versions [18.x, 20.x, 22.x].
    • Steps: checkout, setup-node (with cache), npm install, npm test.
    • Name the workflow "CI" and the job "test" so the status check will be visible as CI/test with matrix expansions.

Acceptance

  • npm test passes locally (no stdout emitted on startup).
  • PR includes the new CI workflow; when the PR is opened, CI should run and pass.
  • After merging, repository owners can enforce branch protection on main to require the CI workflow to pass before merging.

Implementation details

  • Do not change server behavior besides redirecting logs from stdout to stderr.
  • Do not introduce new dependencies.
  • Preserve ESM (type: module) setup.

Files to modify/add

  • index.js: change console.log -> console.error in the three locations.
  • package.json: set scripts.test to "node --test".
  • test/no-stdout-on-start.test.js: add the described test.
  • .github/workflows/ci.yml: add the described workflow.

Please create a branch (e.g., chore/mcp-stdout-ci) off main, commit the changes, and open a pull request titled "Fix MCP stdio logging and add CI test workflow" with a concise description of what changed and how to enable branch protection to block merges on failing tests.

This pull request was created as a result of the following prompt from Copilot chat.

Problem
The MCP server writes plain text to stdout (e.g., "Use Gluestack Components MCP Server running on stdio" and other console.log calls), which corrupts the MCP stdio JSON stream and causes clients like the MCP Inspector to throw a JSON parse error on first connect. We need to ensure stdout is reserved exclusively for the protocol and add CI tests to prevent regressions. Also add a GitHub Actions workflow to run tests on PRs and pushes to main so merges are blocked when tests fail (branch protection can then require this check on main).

Tasks

  1. Update index.js so no logging goes to stdout:

    • Replace all console.log calls with console.error to route logs to stderr.
    • Locations to change:
      • After server.connect: console.log("Use Gluestack Components MCP Server running on stdio") -> console.error(...)
      • In getSelectedComponentsDocs: console.log(✅ Getting documentation for components: ...) -> console.error(...)
      • In the select_components tool handler: console.log(✅ Selected components: ...) -> console.error(...)
  2. Add a test to prevent regressions using Node's built-in test runner:

    • File: test/no-stdout-on-start.test.js
    • Behavior: spawn node index.js, capture stdout and stderr for ~500ms, and assert that stdout is empty on startup. Kill the process afterward.
  3. Update package.json scripts to run the tests:

    • Set "test": "node --test"
    • Keep existing fields. Ensure type: module remains.
  4. Add a GitHub Actions workflow to run tests on push to main and on pull requests targeting main:

    • File: .github/workflows/ci.yml
    • Use Ubuntu runner, matrix over Node versions [18.x, 20.x, 22.x].
    • Steps: checkout, setup-node (with cache), npm install, npm test.
    • Name the workflow "CI" and the job "test" so the status check will be visible as CI/test with matrix expansions.

Acceptance

  • npm test passes locally (no stdout emitted on startup).
  • PR includes the new CI workflow; when the PR is opened, CI should run and pass.
  • After merging, repository owners can enforce branch protection on main to require the CI workflow to pass before merging.

Implementation details

  • Do not change server behavior besides redirecting logs from stdout to stderr.
  • Do not introduce new dependencies.
  • Preserve ESM (type: module) setup.

Files to modify/add

  • index.js: change console.log -> console.error in the three locations.
  • package.json: set scripts.test to "node --test".
  • test/no-stdout-on-start.test.js: add the described test.
  • .github/workflows/ci.yml: add the described workflow.

Please create a branch (e.g., chore/mcp-stdout-ci) off main, commit the changes, and open a pull request titled "Fix MCP stdio logging and add CI test workflow" with a concise description of what changed and how to enable branch protection to block merges on failing tests.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant