modelcontextprotocol / modelcontextprotocol/python-sdk

FastMCP tool argument models silently ignore unknown/misspelled arguments (extra=ignore default)

Ouverte Adaptée aux débutants
#3,067 1 commentaire 1 réaction 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

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

Description

Description

mcp.server.fastmcp.utilities.func_metadata.ArgModelBase does not set extra in its
model_config, so it inherits Pydantic v2's default, extra="ignore":

class ArgModelBase(BaseModel):
    """A model representing the arguments to a function."""
    ...
    model_config = ConfigDict(
        arbitrary_types_allowed=True,
    )

Every per-tool *Arguments model that FastMCP generates via create_model(..., __base__=ArgModelBase, ...)
inherits this. As a result, when a client calls a tool with an argument name that doesn't
exist on the function (a typo, or a hallucinated parameter name from an LLM), Pydantic
silently drops it instead of raising a validation error. The tool then runs with that
parameter at its default value, and returns a "successful" but semantically wrong result —
with no signal anywhere that anything was off.

Reproduction

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("repro")

@mcp.tool()
def read_doc(topic: str = "") -> str:
    return f"topic={topic!r}"

# Simulate what happens when a client calls with the wrong argument name:
tool = mcp._tool_manager.get_tool("read_doc")
result = tool.fn_metadata.arg_model.model_validate({"path": "something"})
print(result.model_dump_one_level())
# {'topic': ''}  <- no error, no signal that "path" was bogus

Expected behavior

An unknown argument in a tools/call request should fail validation immediately with a
clear error (e.g. Pydantic's own "Extra inputs are not permitted"), the same way a missing
required argument already does. This is especially important for MCP given the primary
caller is frequently an LLM: a wrong parameter name is a common, plausible failure mode, and
a loud, immediate error is far more useful (and self-correcting for the model) than a
silently-wrong "successful" response.

Suggested fix

Set extra="forbid" on ArgModelBase.model_config:

model_config = ConfigDict(
    arbitrary_types_allowed=True,
    extra="forbid",
)

This should be safe: the fields validated by ArgModelBase subclasses are exactly the
arguments dict of a tools/call request (i.e. exactly what's declared in the tool's
inputSchema). Protocol-level fields (_meta, progressToken, etc.) live on the
surrounding params object, not inside arguments, and Context is injected separately
via arguments_to_pass_directly — neither passes through ArgModelBase. The side effect is
that model_json_schema() will now emit "additionalProperties": false on the published
inputSchema, which seems like a feature, not a regression (it lets clients that validate
against the schema catch this class of error before the round-trip).

Scope checked

  • Confirmed present in mcp 1.27.2 and 1.28.1 (latest on PyPI as of 2026-07).
  • Confirmed still present on main (the in-progress v2, where fastmcp is being renamed to
    mcpserver): src/mcp/server/mcpserver/utilities/func_metadata.py has the same
    ArgModelBase without extra set.
  • I didn't find an existing issue about this specific behavior (searched for "extra fields",
    "forbid", "unknown argument", "additionalProperties", "silently ignored").
  • For context: the TypeScript SDK has an equivalent gap for a different underlying reason
    (Zod's default strip behavior on unknown object keys) — see
    https://github.com/modelcontextprotocol/typescript-sdk/issues/147

Happy to open a PR with the one-line change plus a regression test if that's 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 src/mcp/server/mcpserver/utilities/func_metadata.py et examinez ArgModelBase.model_config ainsi que le chemin de validation du arg_model généré. Ajoutez un test de régression utilisant le cas d’argument inconnu de type read_doc-style, puis exécutez les tests FastMCP pertinents ; le travail est terminé lorsque les arguments inconnus de l’outil lèvent des erreurs de validation et que le schéma publié rejette les propriétés supplémentaires.

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

Évaluation

Stack technique
python
Domaine
api, backend-api-design
Type d'issue
Bug
Difficulté
2/5
Temps estimé
1-3 heures
Activité
Calme
Clarté
Clairement spécifiée
Accessibilité débutants
76/100

Recevez les nouvelles issues par e-mail

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