| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
…descriptor (modelcontextprotocol#156) When running in Jupyter notebooks, sys.stderr is replaced by ipykernel's OutStream which has no OS file descriptor. Passing it directly to subprocess as the child's stderr fails silently -- the server's diagnostics are lost and crashes produce no visible error. Detect this at spawn time by probing errlog.fileno(). When the probe fails (StringIO, ipykernel stream, or any wrapper without a real fd), spawn the child with stderr=PIPE and forward its output into errlog through an async reader task. The direct fd-inheritance path is unchanged for normal file descriptors. The stderr drain runs before _stop_server_process closes the subprocess transport, so no final bytes from a dying server are lost.
|
This PR has been closed automatically. This repo only keeps pull requests open when they come from a maintainer, or from a contributor a maintainer has assigned to the linked issue, and you aren't currently assigned to #156. If a maintainer assigns you to #156, this PR reopens on its own and there's nothing more you need to do here. Assignment is a maintainer call based on capacity; comments that only ask to be assigned don't factor in. What does help is engaging on the issue itself by confirming the repro, explaining why it matters for your use case, or describing the approach you'd take. You're welcome to keep pushing commits here (just avoid force-pushing, since GitHub can't reopen a rewritten branch), but that on its own won't get the PR reviewed or the issue assigned, and realistically most auto-closed PRs stay closed. There's no need to open a new PR either way. CONTRIBUTING.md has the full reasoning, but in short:
Maintainers: reopen, remove missing-issue-link, or add bypass-issue-check to override. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Summary
Fixes #156.
When running MCP servers from Jupyter notebooks, server stderr output silently vanishes because ipykernel.iostream.OutStream lacks a real OS file descriptor. The SDK tries to pass errlog directly to the subprocess, which silently fails.
How it works
Detection: Added _lacks_file_descriptor(errlog) helper that calls errlog.fileno(). Real stderr returns a number; Jupyter streams and io.StringIO raise an error.
Piping: When errlog has no file descriptor, spawns the server with stderr=subprocess.PIPE instead of inheriting errlog.
Forwarding: An async stderr_reader() task reads chunks from the pipe and writes them to errlog. Handles pipe close and errlog close gracefully.
No-op path: When errlog has a real file descriptor, nothing changes.
Changes
Test plan