Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

MCPServer completion handler returning more than 100 values fails on 2026-07-28 sessions and violates the 100-item limit on 2025-11-25 sessions

Abierto Apto para principiantes
#3,649 2 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@musi22 ya está trabajando en esto.

Desde el 8/10/2026.

  • #3660 de @musi22 — cerrado sin fusionar

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
88/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python

Línea de trabajo

Empieza por el wrapper MCPServer.completion en mcp/server/mcpserver.py (líneas ~759-766), que pasa el Completion del handler sin modificar; el límite de 100 elementos está en mcp_types/_v2026_07_28 y se aplica en runner.py:381, así que el wrapper debe truncar a 100 valores y establecer total/has_more antes de la validación, conservando los valores definidos por el handler. Compara con createCompletionResult del SDK de TypeScript. Hecho significa una prueba de regresión en tests/server/mcpserver/ que usa un Client en memoria y pasa tanto para mode="auto" (2026-07-28) como para mode="legacy" (2025-11-25), devolviendo 100 valores con has_more=True.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug spec-2026-07-28 v2
Initial Checks
Release line

2.x (current stable)

Description

An @mcp.completion() handler that returns more than 100 values behaves differently depending on the negotiated protocol version, and both behaviours are wrong:

  • 2026-07-28 session: the whole completion/complete request fails with -32603 "Handler returned an invalid result". The user gets no suggestions at all.
  • 2025-11-25 session: all values go out on the wire. The spec says values "Must not exceed 100 items", and total / hasMore are left unset, so the client can't tell the list was too long.

It's easy to hit with the filter-by-prefix pattern from docs/servers/completions.md. When the user hasn't typed anything yet (argument.value == ""), every candidate matches, so any handler over a list of more than 100 options (countries, time zones, repos, file names, and so on) fails as soon as the field is focused.

The 100-item cap is only enforced by the 2026-07-28 wire model (Completion.values: Annotated[list[str], Field(max_length=100)] in mcp_types/_v2026_07_28). runner.py:381 checks results against that model and turns the ValidationError into a generic INTERNAL_ERROR. The 2025-11-25 wire model has no such constraint, so nothing stops the oversize list there. The MCPServer.completion wrapper (server.py:759-766) passes the handler's Completion through as-is.

For comparison, the TypeScript SDK's McpServer truncates to 100 and fills the pagination hints (createCompletionResult: values.slice(0, 100), total: suggestions.length, hasMore: suggestions.length > 100).

Expected: the same handler works on both protocol versions. The client receives the first 100 values with total / hasMore telling it more exist, as Completion's own docstring ("total … can exceed the number of values actually sent") and the docs' total= / has_more= note describe.

Server log on the 2026-07-28 session:

ERROR    handler for 'completion/complete' returned an invalid result
pydantic_core._pydantic_core.ValidationError: 1 validation error for CompleteResult
completion.values
  List should have at most 100 items after validation, not 150 [type=too_long, ...]

I reported this and would like to fix it. Proposed approach: in the MCPServer.completion wrapper, when the handler returns more than 100 values, send the first 100 and set total (to the full count) and has_more=True. Values the handler set explicitly win. Handlers returning ≤100 values are unchanged. The lowlevel Server stays as it is, since a lowlevel handler builds the CompleteResult itself. I'd add a regression test in tests/server/mcpserver/ using an in-memory Client, covering both mode="auto" (2026-07-28) and mode="legacy" (2025-11-25). It's roughly 10 lines of source. If you'd prefer a different behaviour (for example, raising a clear error at the wrapper instead of truncating), I'm happy to do that.

I used an AI assistant to help narrow this down; I ran the reproduction myself on 2.3.0 and on main.

Example Code
import anyio
from mcp_types import Completion, PromptReference
from mcp.client import Client
from mcp.server.mcpserver import MCPServer

COUNTRIES = [f"country-{i:03}" for i in range(150)]

mcp = MCPServer("demo")


@mcp.prompt()
def travel(country: str) -> str:
    return f"Plan a trip to {country}"


@mcp.completion()
async def complete(ref, argument, context):
    # Filter by the typed prefix, as in docs/servers/completions.md; an empty prefix matches everything.
    return Completion(values=[c for c in COUNTRIES if c.startswith(argument.value)])


async def main() -> None:
    for mode in ("auto", "legacy"):
        async with Client(mcp, mode=mode) as client:
            try:
                result = await client.complete(
                    ref=PromptReference(type="ref/prompt", name="travel"),
                    argument={"name": "country", "value": ""},
                )
                c = result.completion
                print(f"{client.protocol_version}: {len(c.values)} values, total={c.total}, has_more={c.has_more}")
            except Exception as e:
                print(f"{client.protocol_version}: {type(e).__name__}: {e}")


anyio.run(main)

Output:

2026-07-28: MCPError: Handler returned an invalid result
2025-11-25: 150 values, total=None, has_more=None
Python & MCP Python SDK
Python 3.12.12, mcp 2.3.0, pydantic 2.13.5 (PyPI release)
Python 3.14.0, mcp main @ 91941ed, pydantic 2.12.5
Windows 11
Lenguaje dominante
Python
Estrellas
24.5k
Forks
4k
Merge medio
1 d 4 h
PR fusionados (30 d)
33

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de modelcontextprotocol/python-sdk

Todos los issues de modelcontextprotocol/python-sdk

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.