-
Notifications
You must be signed in to change notification settings - Fork 1.6k
feat: expose errlog on stdio transport #1991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
one of the problems i had when i tried to do this in the past is that if you pass anything apart from a file path you get deadlocks, so you cant actually pass lots of things that would normally be just fine to pass into something that takes a TextIO |
|
@strawgate are you able to replicate the issues you had previously using this PR? |
|
I had tried this exact same thing back during this #978 (comment) I don't think it's a huge deal but I think we should document it so that it's clear that this only supports a file path |
|
Also probably worth noting that the moment you do this you will no longer see server errors in the console |
|
@strawgate I noticed you were using |
The one in that link works just fine, I had attempted to use the textio parameter but couldn't get it not to deadlock with non file destinations Something like modelcontextprotocol/python-sdk#645 |
|
@strawgate docstring updated - let me know your thoughts. Also, it would be great if you could share the code which would allow replicating the issue. |
I can try -- if we don't add a caveat here then we need a test for something other than a file destination anyway as we're now exposing this as part of our API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds the errlog parameter to all STDIO transport classes to allow redirecting subprocess stderr to a specific file handle, addressing issue #1990. The parameter was already supported by the underlying MCP stdio_client but wasn't exposed through the transport layer.
- Added
errlog: TextIO | Noneparameter to all STDIO transport constructors - Updated the internal connection task to pass the errlog parameter to the underlying stdio_client
- Added comprehensive tests to verify errlog functionality works correctly
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/fastmcp/client/transports.py | Added errlog parameter to StdioTransport, PythonStdioTransport, and NodeStdioTransport classes with proper documentation and parameter passing |
| tests/client/test_stdio.py | Added test class TestErrlog with fixtures and test methods to verify errlog parameter acceptance and stderr capture functionality |
tests/client/test_stdio.py
Outdated
| # Need to wait a bit for stderr to flush | ||
| await asyncio.sleep(0.1) | ||
|
|
||
| content = errlog_file.read_text() |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a fixed sleep for synchronization is unreliable and can cause flaky tests. Consider using a more deterministic approach like polling the file size or using proper synchronization mechanisms.
| # Need to wait a bit for stderr to flush | |
| await asyncio.sleep(0.1) | |
| content = errlog_file.read_text() | |
| # Poll for the expected content to appear in the errlog file | |
| expected = "Test error message" | |
| timeout = 1.0 # seconds | |
| interval = 0.01 # seconds | |
| elapsed = 0.0 | |
| while elapsed < timeout: | |
| content = errlog_file.read_text() | |
| if expected in content: | |
| break | |
| await asyncio.sleep(interval) | |
| elapsed += interval | |
| else: | |
| content = errlog_file.read_text() |
|
Were you able to get anything other than a file working with textio? I would love love love to find a way to forward MCP logs to the logger |
|
@strawgate Unfortunately no, I've only tried it with files so far. Forwarding MCP logs to the logger would be awesome though - I agree that would be really useful. Maybe we could explore logger integration in a follow-up PR? Could model it after the python-sdk approach (https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/client/stdio/__init__.py#L138-L167). For this PR, any changes you'd like before merging? |
|
The problem I have in general is that we're exposing textio in our API while we think that it doesn't actually work for the things you might expect it to work for. E.x. In our API maybe we should just expose a log file argument |
|
@strawgate just to confirm - are you suggesting renaming |
|
Or just |
|
@strawgate updated -- let me know your thoughts! |
|
@strawgate just a gentle bump - do you think the current PR version can be released as is? |
|
My thought on Does that make sense to you? Happy to discuss. If that's good with you, I'm good with getting this in for 2.13 |
|
@strawgate sure, that makes sense - I updated the implementation accordingly, with the minor adjustment to keep it |
|
Can you give an example of what custom file handling we're supporting with this? The custom file handling is what I'm nervous about as the issues we are going to get are deadlocks when using textio which go away if we only support a file path |
|
@strawgate One example could be using log_file=tempfile.SpooledTemporaryFile(
mode="w+", max_size=1024 * 1024, encoding="utf-8"
)Anything which follow similar protocol to |
|
@strawgate gentle bump 😊 - let me know your thoughts! |
|
Thanks @mpuhacz and @strawgate ! |
Description
The MCP stdio_client supports an errlog parameter to redirect subprocess stderr to a specific file handle, but StdioTransport didn't expose this capability. This PR provides that missing parameter across all STDIO transport variants.
The errlog parameter is now available on StdioTransport, PythonStdioTransport, NodeStdioTransport, and FastMCPStdioTransport.
Contributors Checklist
errlogto Stdio Transport #1990Review Checklist