Skip to content

Conversation

@dgenio
Copy link

@dgenio dgenio commented Nov 30, 2025

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.

Fixes modelcontextprotocol#156
@dgenio dgenio force-pushed the feature/156-jupyter-stderr-clean branch 14 times, most recently from 2239072 to 66c2ca9 Compare December 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.
@dgenio dgenio force-pushed the feature/156-jupyter-stderr-clean branch from 66c2ca9 to 4e6bda4 Compare December 1, 2025 12:39
@dgenio dgenio marked this pull request as ready for review December 1, 2025 12:45
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.

support logging to stderr in Jupyter Notebook Environments.

1 participant