modelcontextprotocol / modelcontextprotocol/python-sdk

`ClientSessionGroup` attempts to use capabilities that were not advertised

未關閉 適合新手
#2,689 3 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

bug fix proposed P2 ready for work
主要語言
Python
星號
24.3k
分支
4k
平均合併
1 天 1 小時
30 天內合併 PR
31

描述

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

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

從 mcp.client.session_group.ClientSessionGroup.connect_with_session 開始,檢查它如何使用 session 的 initialize_result capabilities。執行提供的 tools-only server reproduction,並確認不會查詢未宣告的 prompts 和 resources,同時已宣告的 tools 仍可用,且不會出現 Method not found 警告。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
api
Issue 類型
缺陷
難度
2/5
預估耗時
1-3 小時
活躍度
冷清
描述清晰度
描述清楚
新手友好度
76/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。