modelcontextprotocol / modelcontextprotocol/python-sdk

`ClientSessionGroup` attempts to use capabilities that were not advertised

Aperta Adatta ai principianti
#2,689 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug fix proposed P2 ready for work
Lingua principale
Python
Stelle
24.3k
Fork
4k
Merge medio
1g 1h
PR unite (30g)
31

Descrizione

Initial Checks
Description

ClientSessionGroup calls session.list_tools, session.list_prompts(), and session.list_resources() unconditionally on every connect. It never consults the ServerCapabilities returned by initialize.

For a server that doesn't implement tools, prompts, or resources, the corresponding calls return a JSON-RPC Method not found error. The MCPError is squashed and a WARNING is emitted, e.g.,

WARNING:root:Could not fetch prompts: Method not found

This seems to contradict the MCP lifecycle spec (2025-11-25, Capability Negotiation / Operation):

Both parties MUST: ... Only use capabilities that were successfully negotiated.

ClientSessionGroup should inspect session.initialize_result.capabilities and only interrogate capabilities that the server advertised, e.g.,

caps = session.initialize_result.capabilities if session.initialize_result else None

if caps and caps.prompts is not None:
    prompts = (await session.list_prompts()).prompts
    ...
if caps and caps.resources is not None:
    resources = (await session.list_resources()).resources
    ...
if caps and caps.tools is not None:
    tools = (await session.list_tools()).tools
    ...
Example Code
"""Repro: tools-only server + ClientSessionGroup emits WARNINGs."""

from __future__ import annotations

import anyio

from mcp import Client, types
from mcp.client.session_group import ClientSessionGroup
from mcp.server import Server, ServerRequestContext


async def handle_list_tools(
    ctx: ServerRequestContext, params: types.PaginatedRequestParams | None
) -> types.ListToolsResult:
    return types.ListToolsResult(
        tools=[
            types.Tool(
                name="ping",
                description="Ping",
                input_schema={"type": "object", "properties": {}},
            )
        ]
    )


async def handle_call_tool(
    ctx: ServerRequestContext, params: types.CallToolRequestParams
) -> types.CallToolResult:
    return types.CallToolResult(content=[types.TextContent(type="text", text="pong")])


async def main() -> None:
    server = Server(
        "tools-only-server",
        on_list_tools=handle_list_tools,
        on_call_tool=handle_call_tool,
    )

    async with Client(server) as client:
        # Server omits prompts/resources capabilities:
        assert client.initialize_result.capabilities.prompts is None
        assert client.initialize_result.capabilities.resources is None

        group = ClientSessionGroup()
        await group.connect_with_session(client.initialize_result.server_info, client.session)


if __name__ == "__main__":
    anyio.run(main)
Python & MCP Python SDK
Python: 3.14.4
MCP Python SDK: main @ da4c118 (also reproducible on v1.27.1)
OS: Linux 6.6.87.2-microsoft-standard-WSL2 x86_64

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia da mcp.client.session_group.ClientSessionGroup.connect_with_session e verifica come utilizza le capacità di initialize_result della sessione. Esegui la riproduzione fornita del server tools-only e conferma che prompts e risorse non pubblicizzati non vengano interrogati, mentre i tools pubblicizzati rimangano disponibili senza avvisi Method not found.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
api
Tipo di issue
Bug
Difficoltà
2/5
Tempo stimato
1-3 ore
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
76/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.