modelcontextprotocol / modelcontextprotocol/python-sdk
Type the MCPServer handler pipeline: tool/resource/prompt return types
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 24.3k
- Forks
- 4k
- Merge moyen
- 1 j 1 h
- PR mergées (30 j)
- 31
Description
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)
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par FuncMetadata.convert_result(), Tool.run(), ToolManager.call_tool() et MCPServer.call_tool() afin de retracer la chaîne de retour de l’outil et le flag convert_result. Examinez ensuite Prompt.fn, PromptResult et ResourceTemplate.matches() pour détecter les incohérences d’annotations indiquées. Le travail est terminé lorsque le pipeline de handlers possède des types publics exacts, que les chemins de typage obsolètes ou incorrects sont traités et que la gestion des valeurs de retour destinée aux utilisateurs est documentée.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- backend-api-design, documentation
- Type d'issue
- Refactorisation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 48/100