Skip to content

feat: support stderr logging in Jupyter notebook environments#2020

Open
BabyChrist666 wants to merge 5 commits intomodelcontextprotocol:mainfrom
BabyChrist666:fix/jupyter-stderr-logging-156
Open

feat: support stderr logging in Jupyter notebook environments#2020
BabyChrist666 wants to merge 5 commits intomodelcontextprotocol:mainfrom
BabyChrist666:fix/jupyter-stderr-logging-156

Conversation

@BabyChrist666
Copy link

Summary

Fixes #156

In Jupyter notebook environments, passing sys.stderr directly to subprocess doesn't work as expected - the stderr output is lost and users have no visibility into server errors or crashes. This makes debugging extremely difficult as the notebook cell just hangs with no feedback.

Changes

  • Added _is_jupyter_environment() function to detect Jupyter/IPython notebook environments
  • In Jupyter mode, stderr is captured as a pipe and read asynchronously
  • Stderr output is printed with red ANSI color for visibility in notebooks
  • In non-Jupyter environments, behavior remains completely unchanged (direct stderr passthrough)

How It Works

  1. On client initialization, we detect if running in Jupyter/IPython
  2. If in Jupyter, we set capture_stderr=True which pipes stderr instead of redirecting
  3. An async stderr_reader task reads the pipe and prints to the notebook output
  4. Red ANSI coloring makes errors stand out in the notebook

Technical Details

  • Detection checks for IPKernelApp in config or ZMQInteractiveShell class name
  • Falls back gracefully if IPython is not installed
  • Windows compatibility maintained via FallbackProcess stderr wrapping

Test plan

  • Added TestJupyterStderrSupport test class with 4 tests
  • Test Jupyter detection returns False in normal Python
  • Test graceful handling when IPython not installed
  • Test stderr capture doesn't block the client
  • Test continuous stderr output is handled properly
  • All existing stdio tests pass

🤖 Generated with Claude Code

Fixes modelcontextprotocol#156

In Jupyter notebook environments, passing sys.stderr directly to subprocess
doesn't work as expected - the stderr output is lost and users have no
visibility into server errors or crashes.

This change:
- Adds _is_jupyter_environment() to detect when running in Jupyter/IPython
- In Jupyter mode, captures stderr as a pipe and reads it asynchronously
- Prints stderr output with red ANSI color for visibility in notebooks
- In non-Jupyter environments, behavior remains unchanged (direct stderr)

The fix ensures that MCP server error messages and crash logs are visible
in Jupyter notebooks, making debugging much easier.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@maxisbey maxisbey added bug Something isn't working P3 Nice to haves, rare edge cases labels Feb 10, 2026
@maxisbey
Copy link
Contributor

Please fix CI before we review.

AI Disclaimer

BabyChrist666 and others added 4 commits February 13, 2026 02:17
…pport

- Add missing blank line after _is_jupyter_environment function (ruff E302)
- Change triple-quoted strings from ''' to """ in tests (ruff Q000)
- Remove unused Callable import
- Remove dead code branch in stderr_reader (non-Jupyter path was unreachable)
- Add tests for _is_jupyter_environment with mocked IPython (IPKernelApp, ZMQInteractiveShell)
- Add tests for stderr_reader in Jupyter mode with mocked _is_jupyter_environment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove unused Union import in win32/utilities.py, use | syntax
- Add test for get_ipython() returning None (covers 43->52 branch)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add type: ignore comments for IPython imports (reportMissingImports, etc.)
- Add pragma: no branch for async context manager branches in Jupyter tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working P3 Nice to haves, rare edge cases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support logging to stderr in Jupyter Notebook Environments.

2 participants