modelcontextprotocol / modelcontextprotocol/python-sdk
Type the MCPServer handler pipeline: tool/resource/prompt return types
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 24.3k
- Fork
- 4k
- Merge medio
- 1g 1h
- PR unite (30g)
- 31
Descrizione
The chain from user @tool()-decorated functions through to CallToolResult is typed as Any end-to-end, hiding a wrong public return type and dead code.
Tool call chain
FuncMetadata.convert_result() returns exactly three shapes:
CallToolResult(when the user returned one directly)Sequence[ContentBlock](unstructured)tuple[Sequence[ContentBlock], dict[str, Any]](unstructured + structured)
But every step of the chain is -> Any:
FuncMetadata.convert_result()—-> AnyTool.run()—-> AnyToolManager.call_tool()—-> AnyMCPServer.call_tool()— declared-> Sequence[ContentBlock] | dict[str, Any], wrong — never returnsdict
Root cause: the convert_result: bool flag on Tool.run() / ToolManager.call_tool() toggles the return type, which is unrepresentable. The False path isn't used in production (only server.py:405, always True).
Symptoms:
- Dead code + TODO acknowledging the wrong type at server.py:317-324
# type: ignore[arg-type]shoving tuple elements intoCallToolResultat server.py:314-315
Prompt / Resource
PromptResultalready includesAwaitable, butPrompt.fnis typedCallable[..., PromptResult | Awaitable[PromptResult]]— doubly wrappedResourceTemplate.matches()returnsdict[str, Any] | Nonebut values are alwaysstr(regex groupdict + unquote)
User-facing return types
What you can return from @tool() is undocumented. A strict bound is impossible (_convert_to_content() ends with pydantic_core.to_json(fallback=str) — everything works), but the docstrings should enumerate what gets first-class handling (str/primitives/BaseModel/ContentBlock/Image/Audio/CallToolResult/list/tuple) vs what gets JSON-dumped.
Related
- #1207 — excessive generics (reason to not introduce
Tool[ReturnT]; aTypeAliasfor the converted result is sufficient) - #2153 — handler error semantics
- #2201 — Tasks support (adds
CreateTaskResultto the converted-result union)
Guida per i contributori
Apri 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.
Direzione di ricerca
Inizia da FuncMetadata.convert_result(), Tool.run(), ToolManager.call_tool() e MCPServer.call_tool() per tracciare la catena di ritorno dello strumento e il flag convert_result. Poi esamina Prompt.fn, PromptResult e ResourceTemplate.matches() per individuare le discrepanze nelle annotazioni indicate. Il lavoro è completato quando la pipeline degli handler ha tipi pubblici accurati, i percorsi di tipizzazione obsoleti o errati sono stati risolti e la gestione dei valori restituiti visibile agli utenti è documentata.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- backend-api-design, documentation
- Tipo di issue
- Refactoring
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 48/100