Skip to content

Conversation

@dgenio
Copy link

Summary

Fixes#156 - Adds support for displaying stderr output in Jupyter Notebook environments.

Changes

  • Added Jupyter/IPython detection using IPython.get_ipython()
  • Implemented async stderr reader that reads stderr asynchronously (similar to stdout)
  • Added IPython display integration for colored stderr output in Jupyter notebooks
  • Updated process creation to pipe stderr instead of redirecting (enables async reading)
  • Updated Windows process creation and fallback to support piped stderr
  • Updated FallbackProcess to wrap stderr in async-compatible streams

Design Decisions

  • Backward compatibility: errlog parameter is kept but behavior adapts based on environment
  • Error handling: Non-critical errors are logged but don't stop execution
  • Performance: Matches stdout_reader behavior (line-by-line buffering)
  • Platform support: Works on both Unix and Windows (including fallback path)

Testing

  • Added comprehensive tests for stderr capture, Jupyter detection, and display integration
  • All existing tests pass
  • Linting and type checking pass

Behavior

  • In Jupyter: stderr is displayed using IPython's display system with red HTML formatting
  • Outside Jupyter: stderr is printed to the provided errlog stream (defaults to sys.stderr)
  • Fallback: If IPython display fails, falls back to regular print

This enables proper debugging of MCP servers in Jupyter notebook environments, addressing the issue where server crashes or command errors were invisible.

- Add _is_jupyter_notebook() to detect Jupyter/IPython environments - Add _print_stderr() to format stderr with HTML in Jupyter (red color) - Add async _stderr_reader() to capture and display stderr - Pipe stderr (subprocess.PIPE) instead of redirecting to file - Update Windows process creation to support piped stderr - Extract stdout/stdin/stderr readers as module-level functions This enables server stderr output to be visible in Jupyter notebooks, addressing issue modelcontextprotocol#156. Fixesmodelcontextprotocol#156
@dgeniodgenioforce-pushed the feature/156-jupyter-stderr-clean branch 14 times, most recently from 2239072 to 66c2ca9CompareDecember 1, 2025 08:44
- Test Jupyter environment detection (with/without IPython) - Test stderr printing in Jupyter and non-Jupyter environments - Test IPython display fallback when display fails - Test stderr capture and piping - Test stderr reader exception handling - Test empty line filtering and final buffer handling - Test process without stderr stream Achieves 100% code coverage for the new functionality.
@dgeniodgenioforce-pushed the feature/156-jupyter-stderr-clean branch from 66c2ca9 to 4e6bda4CompareDecember 1, 2025 12:39
@dgeniodgenio marked this pull request as ready for review December 1, 2025 12:45
@felixweinbergerfelixweinberger added the enhancement Request for a new feature that's not currently supported label Dec 9, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementRequest for a new feature that's not currently supported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support logging to stderr in Jupyter Notebook Environments.

2 participants

@dgenio@felixweinberger