stdio_server: text a tool prints still reaches the client, because sys.stdout is flushed after fd 1 is restored
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 76/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- python
- Ambito
- backend-api-design
Direzione di ricerca
Inizia leggendo l’implementazione di stdio_server() e seguendo dove fd 1 viene reindirizzato e ripristinato; l’issue non indica alcun file né test. Riproduci il caso segnalato con uno strumento che chiama print() mentre stdout è collegato a una pipe, quindi verifica che il testo in sospeso venga inviato a stderr prima del ripristino di fd 1 e non compaia come messaggio JSON-RPC.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
Since #3117, stdio_server() points fd 1 at stderr while it serves, so that stray output from handlers misses the wire. Text written with print() still reaches the client. It goes into sys.stdout's own buffer, which is block-buffered when stdout is a pipe. That buffer is flushed when the interpreter exits, after stdio_server() has given fd 1 back to the client's pipe. The client then reads the text as a JSON-RPC message.
Reproduction
mcp 2.3.0, Python 3.13.16, macOS 26.3.
import asyncio
import sys
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from mcp.server.mcpserver import MCPServer
if sys.argv[1:] == ["server"]:
server = MCPServer("repro")
@server.tool()
def noisy() -> str:
print("stray output from a tool") # e.g. a library that prints
return "done"
server.run("stdio")
else:
async def main():
params = StdioServerParameters(command=sys.executable, args=[__file__, "server"])
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("noisy", {})
print("result:", result.content[0].text)
asyncio.run(main())
Running python repro.py, the call succeeds, and the client also logs:
pydantic_core._pydantic_core.ValidationError: 1 validation error for union[JSONRPCRequest,JSONRPCNotification,JSONRPCResponse,JSONRPCError]
Invalid JSON: expected value at line 1 column 1 [type=json_invalid, input_value='stray output from a tool', input_type=str]
Cause
While fd 1 is diverted, the printed text never reaches it: it sits in sys.stdout's buffer. The buffer is written out at interpreter exit, when fd 1 is the protocol pipe again. Adding sys.stdout.flush() right after the print() in the tool removes the error, and the text appears on stderr, which confirms this.
Suggestion
Flush sys.stdout before restoring fd 1, so that pending text goes to the diversion. Making sys.stdout line-buffered while serving (sys.stdout.reconfigure(line_buffering=True)) would also send printed text to stderr when it is printed, rather than at exit.
As a workaround we call sys.stdout.reconfigure(line_buffering=True) before server.run("stdio") and flush after each tool.
- Lingua principale
- Python
- Stelle
- 24.7k
- Fork
- 4.1k
- Merge medio
- 9h 45m
- PR unite (30g)
- 16
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di modelcontextprotocol/python-sdk
-
bug v2
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
modelcontextprotocol/python-sdk#3811 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug v2
Difficoltà 2/5 1-3 ore Idoneità per principianti 79/100
modelcontextprotocol/python-sdk#3810 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug v1 v2
Difficoltà 2/5 1-3 ore Idoneità per principianti 79/100
modelcontextprotocol/python-sdk#3781 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug]: Inconsistent structured output wrapping and opt-out for typing.Dict and typing sequence generics in func_metadataForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Apertabug v1 v2
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
modelcontextprotocol/python-sdk#3771 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
bug v2
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
modelcontextprotocol/python-sdk#3769 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di modelcontextprotocol/python-sdk
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
FinanceFlash/unvibecode#509 ·
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 82/100
FAIRmat-NFDI/nomad-distro-dev#161 ·
-
bug severity:low
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 2 giorni
-
Log-odds calibration uses upper middle score instead of median for even candidate setsForse già presa @flysheep-ai l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
curriculum documentation quality
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
githubnext/gh-aw-workshop#5367 ·
I maintainer di solito rispondono entro 3 giorni