9.3 核心调用方法:调用工具、读取资源、获取提示词 本节摘要:连接就绪后,接下来就是「消费服务端能力」。本节讲透 的核心调用方法—— (调工具,拿 content + structuredcontent)、 / / / (列清单)、 (读资源)、 (渲染提示词)。每个方法对应服务端的一个原语,形成「消费侧」的完整 API。读完本节,你能用客户端消费 MCP 服务的全部三类能力。 一、调用工具:calltool 最核心的方法是 ——调用服务端的工具: 接两个参数: 工具名( ) 参数字典( ) 返回的 是一个结构化对象(回顾第 4.
本节摘要:连接就绪后,接下来就是「消费服务端能力」。本节讲透
Client的核心调用方法——call_tool(调工具,拿 content + structured_content)、list_tools/list_resources/list_resource_templates/list_prompts(列清单)、read_resource(读资源)、get_prompt(渲染提示词)。每个方法对应服务端的一个原语,形成「消费侧」的完整 API。读完本节,你能用客户端消费 MCP 服务的全部三类能力。
最核心的方法是 call_tool——调用服务端的工具:
async with Client(mcp) as client: result = await client.call_tool("add", {"a": 1, "b": 2})
call_tool 接两个参数:
"add"){"a": 1, "b": 2})返回的 result 是一个结构化对象(回顾第 4.2 节),含:
| 字段 | 内容 | 给谁 |
|---|---|---|
content |
文本(可多段) | 给模型 |
structured_content |
类型化数据 | 给应用 |
is_error |
是否出错 | 判断成功/失败 |
result = await client.call_tool("add", {"a": 1, "b": 2}) # 给应用的:结构化数据(标量被包成 {"result": ...}) print(result.structured_content) # {"result": 3} # 给模型的:文本 print(result.content) # [{"type": "text", "text": "3"}] # 判断成功/失败 if result.is_error: print("工具失败")
调用前,你可能想知道「服务端有哪些工具/资源/提示词」。这就是 list_* 系列:
async with Client(mcp) as client: # 列出所有工具 tools = await client.list_tools() for tool in tools: print(tool.name, tool.description, tool.input_schema) # 列出具体资源 resources = await client.list_resources() # 列出资源模板 templates = await client.list_resource_templates() # 列出提示词 prompts = await client.list_prompts()
每个 list_* 返回对应的清单。注意资源有两个 list 方法——list_resources(具体资源)与 list_resource_templates(资源模板),对应第 5.1 节讲的两种资源形态。
读取资源用 read_resource,传完整 URI:
async with Client(mcp) as client: # 读具体资源 config = await client.read_resource("config://app") print(config) # 配置内容 # 读资源模板(填参数实例化) greeting = await client.read_resource("greeting://World") print(greeting) # "Hello, World!"
回顾第 5.1 节:读资源模板时,要传完整实例化 URI(greeting://World,不是模板模式 greeting://{name})。SDK 据此找到对应模板处理器,填参数,执行。
获取提示词用 get_prompt,传提示词名与参数:
async with Client(mcp) as client: # 获取提示词(带参数) messages = await client.get_prompt("summarize", {"text": "..."}) for msg in messages: print(msg.role, msg.content)
返回的是一组消息(回顾第 5.3 节,提示词返回消息列表)。最常见的是一条用户消息,但也可能含系统消息(提示词返回多消息时)。
把客户端方法与服务端原语放一起,对应关系清晰:
| 客户端方法 | 服务端原语 | 协议方法 |
|---|---|---|
call_tool(name, args) |
工具 | tools/call |
list_tools() |
工具清单 | tools/list |
read_resource(uri) |
资源 | resources/read |
list_resources() |
具体资源清单 | resources/list |
list_resource_templates() |
资源模板清单 | resources/templates/list |
get_prompt(name, args) |
提示词 | prompts/get |
list_prompts() |
提示词清单 | prompts/list |
每个客户端方法背后,是对应的协议方法(JSON-RPC)。SDK 替你处理协议细节,你只调用高级方法。
把所有方法合起来,看一个完整的「消费 MCP 服务」示例:
import asyncio from mcp import Client async def main(): async with Client("http://localhost:8000/mcp") as client: # 1. 先看看服务端有什么 print("工具:", [t.name for t in await client.list_tools()]) print("资源:", [r.uri for r in await client.list_resources()]) print("模板:", [t.uri_template for t in await client.list_resource_templates()]) print("提示词:", [p.name for p in await client.list_prompts()]) # 2. 调一个工具 result = await client.call_tool("add", {"a": 1, "b": 2}) print(f"add 结果:{result.structured_content}") # 3. 读一个资源 config = await client.read_resource("config://app") print(f"配置:{config}") # 4. 获取一个提示词 messages = await client.get_prompt("summarize", {"text": "hello"}) print(f"提示词消息:{messages}") asyncio.run(main())
这就是「消费 MCP 服务」的标准模式:先 list 看有什么,再按需 call/read/get。
调用方法时,可能遇到几种错误:
try: result = await client.call_tool("nonexistent", {}) except Exception as e: # 工具不存在、参数错、执行失败 print(f"调用失败:{e}") result = await client.call_tool("add", {"a": 1, "b": 2}) if result.is_error: # 工具执行了但返回错误(第 4.4 节) print(f"工具报错:{result.content}")
两类错误要区分:
is_error=True(工具执行了但抛异常):拿到 result,但内容是错误信息第 4.4 节讲过,工具抛异常会被 SDK 转成 is_error=True 的响应。客户端要检查这个标志,别假设 call_tool 成功返回就是工具执行成功。
💡 技巧:写客户端代码时,永远检查
is_error。即使工具名对、参数对,工具内部仍可能失败(数据库连不上、外部 API 超时)。不检查is_error直接用structured_content,会基于错误数据继续,导致后续逻辑出错。
call_tool(name, args) 调工具,返回含 content、structured_content、is_error。list_* 系列 列举工具/资源/资源模板/提示词的清单。read_resource(uri) 读资源,传完整 URI(模板要填参数实例化)。get_prompt(name, args) 获取提示词,返回消息列表。is_error=True(工具执行报错),永远检查 is_error。核心方法清楚了,下一节讲客户端的能力声明——告诉服务端「我支持什么」。