Generated output schema uses Pydantic's validation shape while structured output uses its serialization shape
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 52/100
Línea de trabajo
Comienza en Tool.from_function en la implementación de las herramientas del servidor MCP, usando las rutas de importación mostradas para las versiones del SDK, y sigue cómo se producen output_schema y structured_content. Reproduce los ejemplos alias_output y computed_output con Draft202012Validator. La tarea está terminada cuando el esquema generado acepta ambos resultados estructurados serializados, incluidos wireOut y doubled.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Initial Checks
- I confirm that I'm using the latest version of MCP Python SDK.
- I confirm that I searched existing issues and pull requests before opening this issue.
Description
For a Pydantic return model whose validation and serialization shapes differ, the generated outputSchema describes the validation shape while structuredContent uses the serialization shape. The SDK therefore publishes an output schema that rejects its own generated structured result.
This is related to, but not a duplicate of, #1073 / #1099. That change aligned ordinary field aliases by serializing structured output with aliases. Split validation_alias / serialization_alias values still expose different validation and serialization shapes, and serialization-only fields such as computed_field reveal the same underlying mismatch.
Example Code
from __future__ import annotations
import asyncio
import json
from jsonschema import Draft202012Validator
from pydantic import BaseModel, ConfigDict, Field, computed_field
try:
from mcp.server.mcpserver.tools.base import Tool
except ImportError: # MCP Python SDK 1.x
from mcp.server.fastmcp.tools.base import Tool
class AliasOutput(BaseModel):
model_config = ConfigDict(extra="forbid", populate_by_name=True)
value: int = Field(validation_alias="wireIn", serialization_alias="wireOut")
def alias_output() -> AliasOutput:
return AliasOutput(value=1)
class ComputedOutput(BaseModel):
model_config = ConfigDict(extra="forbid")
value: int
@computed_field
@property
def doubled(self) -> int:
return self.value * 2
def computed_output() -> ComputedOutput:
return ComputedOutput(value=1)
async def check(function: object) -> None:
tool = Tool.from_function(function)
converted = await tool.run({}, None, convert_result=True)
structured = converted[1] if isinstance(converted, tuple) else converted.structured_content
errors = [
error.message
for error in Draft202012Validator(tool.output_schema).iter_errors(structured)
]
print(function.__name__)
print("schema:", json.dumps(tool.output_schema, sort_keys=True))
print("structured:", json.dumps(structured, sort_keys=True))
print("schema_errors:", errors)
async def main() -> None:
await check(alias_output)
await check(computed_output)
asyncio.run(main())
Observed validator messages:
alias_output
schema: ... "wireIn" ...
structured: {"wireOut": 1}
schema_errors: ["Additional properties are not allowed ('wireOut' was unexpected)", "'wireIn' is a required property"]
computed_output
schema: ... "value" ...
structured: {"doubled": 2, "value": 1}
schema_errors: ["Additional properties are not allowed ('doubled' was unexpected)"]
Expected behavior
The generated outputSchema should describe the serialized structured output. Generating the output model schema in Pydantic serialization mode makes both witnesses conform: the alias schema uses wireOut, and the computed-field schema includes doubled.
Python & MCP Python SDK
- Python: 3.13.13
- MCP Python SDK: 1.28.1 (latest stable)
- Also reproduced on current
main:2713b53b127afc094dc97d6067df9f69b647661c(2.0.0b2) - Pydantic: 2.13.4
- Lenguaje dominante
- Python
- Estrellas
- 24.3k
- Forks
- 4k
- Merge medio
- 1 d 1 h
- PR fusionados (30 d)
- 31
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de modelcontextprotocol/python-sdk
-
Streamable HTTP client logs a WARNING for valid 202 Accepted on session termination (DELETE) Abiertov1 v2
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
modelcontextprotocol/python-sdk#3546 · 4 comentarios ·
-
v1 v2
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
modelcontextprotocol/python-sdk#3545 · 1 comentario ·
-
v1 v2
Dificultad 1/5 Menos de una hora Aptitud para principiantes 91/100
modelcontextprotocol/python-sdk#3508 · 2 comentarios ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
modelcontextprotocol/python-sdk#3504 ·
-
v1 v2
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
modelcontextprotocol/python-sdk#3492 · 1 comentario ·
Todos los issues de modelcontextprotocol/python-sdk
Issues similares
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
zostera/django-bootstrap4#894 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
use-agent-os/agent-os#3276 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
zephyrproject-rtos/zephyr#119726 ·
-
area/auth bug comp/agent P3 platform/discord type/security
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
NousResearch/hermes-agent#117848 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
zilliztech/memsearch#759 ·