modelcontextprotocol / modelcontextprotocol/python-sdk

Server.call_tool()'s input-validation error result discards jsonschema.ValidationError's structured fields, leaving only free-text prose

Ouverte
#3,351 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

v1 v2
Langage dominant
Python
Étoiles
24.3k
Forks
4k
Merge moyen
1 j 1 h
PR mergées (30 j)
31

Description

Summary

Server.call_tool()'s low-level dispatch validates tool arguments against tool.inputSchema and, on failure, builds the error result like this:

try:
    jsonschema.validate(instance=arguments, schema=tool.inputSchema)
except jsonschema.ValidationError as e:
    return self._make_error_result(f"Input validation error: {e.message}")

_make_error_result produces CallToolResult(content=[TextContent(text=error_message)], isError=True) — no code, no structured data, nothing beyond the interpolated message string. jsonschema.ValidationError carries several structured attributes that would make a good stable identifier — e.validator (e.g. "type", "required", "enum", "additionalProperties"), e.schema_path, e.json_path — but all of them are discarded before the text crosses the transport (stdio, in our case).

Why this matters

A client that wants to programmatically distinguish why a tool call was rejected (missing required field vs. wrong type vs. enum mismatch, etc.) currently has no option but to regex e.message. That's brittle by construction: jsonschema's message wording already varies per validator keyword ("'X' is not of type 'Y'", "'X' is a required property", "'X' is not one of [...]", ...) with no shared machine-readable code across them, and nothing upstream commits to keeping that wording stable across jsonschema versions.

We hit this trying to classify tool-call failures from an MCP server (google-analytics-mcp, built on this SDK's low-level Server class) into "agent-fixable bad input" vs. "genuine server fault" for log-severity purposes, and had to give up — there's no code or structured field anywhere in the CallToolResult to key on, only the interpolated message. Confirmed this isn't something a well-behaved MCP client (or our own client's JSON-RPC handling) is dropping — the schema-validation error result is a normal JSON-RPC success envelope wrapping isError: true, and _make_error_result simply never puts anything but a message string into it.

Suggested fix

Forward e.validator (and ideally e.schema_path/e.json_path) into a structured data field on the error result, alongside the existing human-readable message — e.g. _make_error_result(message, data={"validator": e.validator, "schema_path": list(e.schema_path)}) — so any server built on the low-level Server class gets locale-stable, machine-readable input-validation errors "for free," without every server author having to reimplement schema validation themselves to get one.

Happy to provide a full repro (raw JSON-RPC request/response) if useful.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par Server.call_tool() et _make_error_result(), puis suivez la structure CallToolResult utilisée par le transport JSON-RPC. Vérifiez les tests existants pour la validation de l’input-schema et les résultats d’erreur. Le travail est considéré comme terminé lorsque les échecs de validation conservent le message lisible actuel tout en exposant des champs structurés stables tels que le validateur et le chemin du schéma.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
api, backend
Type d'issue
Fonctionnalité
Difficulté
3/5
Temps estimé
1-2 jours
Activité
Active
Clarté
Plutôt claire
Accessibilité débutants
55/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.