[FastMCP设计、原理与应用-02]以命令行和客户端与MCP服务器交互

在"Hello, MCP",我们采用HTTP传输协议搭建了一个简单FastMCP服务器,并直接采用HTTP请求的形式完整MCP的基本操作,包括读取组件列表、调用工具、读取资源和渲染提示词等操作。接下来我们来演示其他两种交互方法,一是使用fastmcp命令行,而是以编程的方式是客户端SDK。

1. 搭建MCP服务器

我们直接使用"Hello, MCP"中搭建的服务器,相关代码如下:

python 复制代码
from fastmcp import FastMCP

mcp = FastMCP("Greeting")

@mcp.tool()
async def greet(name: str) -> str:
    """Get a greeting message for the given name"""
    return f"Hi, {name}!"

@mcp.resource("greeting://everyone")
async def greet_everyone() -> str:
    """Get a greeting message for everyone"""
    return f"Hey, everyone!"    

@mcp.resource("greeting://{name}")
async def greet_to_name(name: str) -> str:
    """Get a greeting message for the given name"""
    return f"Hello, {name}!"

@mcp.prompt()
async def greet_prompt(name: str) -> str:
    """Get a greeting message for the given name"""
    return f"Hi, {name}!"

mcp.run(transport="http", host="0.0.0.0", port=3721)

在根据名称Greeting创建了代表MCP服务器的FastMCP对象之后,我们利用该对象的三种装饰器方法注册了四种典型的组件:

  • greet:利用@mcp.tool装饰器注册的工具;
  • greet_everyone: 利用@mcp.resource装饰器注册的静态文本资源,表示绑定于固定URI的单个资源;
  • greet_to_name:利用@mcp.resource装饰器注册的动态资源模板,表示绑定于URI模板的一组资源;
  • greet_prompt:利用@mcp.prompt装饰器注册的提示词(模板);

然后我们调用FastMCP的run方法启动服务器。为了方便后面的演示,我们设置了如下四个参数:

  • transport:将传输协议设置为HTTP,那么我们就可以单纯地发送HTTP请求的方式与MCP服务交互了;
  • host: 设置成"0.0.0.0",那么我们可以利用localhost、127.0.0.1以及绑定的主机名和真实IP地址访问MCP服务器;
  • port:显式指定的端口号3721,默认为8000;

2 以命令行的方法与MCP服务器交互

FastMCP提供了同名的CLI,所以我们可以以命令行的形式与MCP服务器交互。比如我们通过如下的方式读取工具列表。

shell 复制代码
PS C:\Users\jinnan> fastmcp list http://localhost:3721/mcp
Tools (1)

  greet(name: str) -> dict
    Get a greeting message for the given name

可以进一步添加命令行开关--input-schema--output-schema显式工具输入和输出Schema。

shell 复制代码
PS C:\Users\jinnan> fastmcp list http://localhost:3721/mcp --input-schema --output-schema
Tools (1)

  greet(name: str) -> dict
    Get a greeting message for the given name
    Input: {"additionalProperties": false, "properties": {"name": {"type": "string"}}, "required": ["name"], "type": "object"}
    Output: {"properties": {"result": {"type": "string"}}, "required": ["result"], "type": "object", "x-fastmcp-wrap-result": true}

如果希望看到工具更多细节,可以添加--json开关以JSON格式输出工具信息。

shell 复制代码
PS C:\Users\jinnan> fastmcp list http://localhost:3721/mcp --json
{
  "tools": [
    {
      "name": "greet",
      "description": "Get a greeting message for the given name",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "outputSchema": {
        "properties": {
          "result": {
            "type": "string"
          }
        },
        "required": [
          "result"
        ],
        "type": "object",
        "x-fastmcp-wrap-result": true
      }
    }
  ]
}

如果进一步添加命令行开关--resources --prompts,可以列出资源和提示词,不过貌似只能显式静态资源。

shell 复制代码
PS C:\Users\jinnan> fastmcp list http://localhost:3721/mcp --json --resources --prompts
{
  "tools": [
    {
      "name": "greet",
      "description": "Get a greeting message for the given name",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "outputSchema": {
        "properties": {
          "result": {
            "type": "string"
          }
        },
        "required": [
          "result"
        ],
        "type": "object",
        "x-fastmcp-wrap-result": true
      }
    }
  ],
  "resources": [
    {
      "uri": "greeting://everyone",
      "name": "greet_everyone",
      "description": "Get a greeting message for everyone",
      "mimeType": "text/plain"
    }
  ],
  "prompts": [
    {
      "name": "greet_prompt",
      "description": "Get a greeting message for the given name",
      "arguments": [
        {
          "name": "name",
          "description": null,
          "required": true
        }
      ]
    }
  ]
}

我们还可以执行按照如下的方式执行fastmcp call命令调用工具greet,并将参数name指定为MCP。关于fastmcp cli的详细用法,可以参考官方文档

shell 复制代码
PS C:\Users\jinnan> fastmcp call http://localhost:3721/mcp greet name=MCP --json
{
  "content": [
    {
      "type": "text",
      "text": "Hi, MCP!"
    }
  ],
  "is_error": false,
  "structured_content": {
    "result": "Hi, MCP!"
  }
}

3 利用FastMCP客户端SDK

fastmcp库还提供了客户端SDK,我们利用它不仅仅可以采用单纯的请求-响应模式完成诸如读取组件和调用工具这样的操作,还能提供接收并处理来自服务端的请求和通知。MCP是一个涉及服务端和客户端双边协议,fastmcp客户端SDK是MCP客户端协议的实现。

对于上面构建的MCP服务器,我们可以根据其URL(http://localhost:3721/mcp)创建一个`Client`对象,并调用其`list_tools`、`list_resources`、`list_resource_templates`和`list_prompts`方法读取工具、静态资源、动态资源模板和提示词(模板)列表。

python 复制代码
import asyncio
from fastmcp import Client

client = Client("http://localhost:3721/mcp") 

async def main():
    async with client:
        tools = await client.list_tools()
        print(f"Tools ({len(tools)}):",end="")
        for tool in tools:
            print(f"""
    name: {tool.name}
    description: {tool.description}
    input_schema: {tool.inputSchema}
    output_schema: {tool.outputSchema}""")
        
        resources = await client.list_resources()
        print(f"\nResources ({len(resources)}):",end="")
        for resource in resources:
            print(f"""
    name: {resource.name}
    description: {resource.description}
    mimeType: {resource.mimeType}""")
            
        resource_templates = await client.list_resource_templates()
        print(f"\nResource Templates ({len(resource_templates)}):",end="")
        for template in resource_templates:
            print(f"""
    name: {template.name}
    description: {template.description} 
    mimeType: {template.mimeType}""")
            
        prompts = await client.list_prompts()
        print(f"\nPrompts ({len(prompts)}):",end="")
        for prompt in prompts:
            print(f"""
    name: {prompt.name}
    description: {prompt.description}
    arguments: {prompt.arguments}""")

if __name__ == "__main__":
    asyncio.run(main())

输出:

复制代码
Tools (1):
    name: greet
    description: Get a greeting message for the given name
    input_schema: {'additionalProperties': False, 'properties': {'name': {'type': 'string'}}, 'required': ['name'], 'type': 'object'}
    output_schema: {'properties': {'result': {'type': 'string'}}, 'required': ['result'], 'type': 'object', 'x-fastmcp-wrap-result': True}

Resources (1):
    name: greet_everyone
    description: Get a greeting message for everyone
    mimeType: text/plain

Resource Templates (1):
    name: greet_to_name
    description: Get a greeting message for the given name
    mimeType: text/plain

Prompts (1):
    name: greet_prompt
    description: Get a greeting message for the given name
    arguments: [PromptArgument(name='name', description=None, required=True)]

我们还可以按照如下的方式调用Client对象的call_tool方法调用工具,调用read_resource方法读取指定URI的资源,以及调用get_prompt方法完整指定提示词的渲染。

python 复制代码
import asyncio
from typing import cast
from fastmcp import Client
from mcp.types import TextResourceContents

client = Client("http://localhost:3721/mcp") 

async def main():
    async with client:
        result = await client.call_tool("greet", {"name": "MCP"})
        print("Tool call result:",end="")
        print(f"""
    content: {result.content}
    data: {result.data}
    structured_content: {result.structured_content}
    is_error: {result.is_error}
""")
        
        resource = cast(list[TextResourceContents], await client.read_resource("greeting://MCP"))[0]
        print("Resource:", end="")
        print(f"""
    uri: {resource.uri}
    mimeType: {resource.mimeType}
    text: {resource.text}
""")
        
        propmpt = await client.get_prompt(name ="greet_prompt",arguments= {"name": "MCP"})
        print("Prompt:", end="")
        print(f"""
    description: {propmpt.description}
    messages: {propmpt.messages}
""")

if __name__ == "__main__":
    asyncio.run(main())

输出:

复制代码
Tool call result:
    content: [TextContent(type='text', text='Hi, MCP!', annotations=None, meta=None)]
    data: Hi, MCP!
    structured_content: {'result': 'Hi, MCP!'}
    is_error: False

Resource:
    uri: greeting://MCP
    mimeType: text/plain
    text: Hello, MCP!

Prompt:
    description: Get a greeting message for the given name
    messages: [PromptMessage(role='user', content=TextContent(type='text', text='Hi, MCP! This is a prompt response.', annotations=None, meta=None))]
相关推荐
倔强的石头_8 小时前
不想每次都从头解释:我用 Doubao-Seed-Evolving 做了一个「稿件接力站」
ai编程
新知图书9 小时前
11.3 详细实现与核心配置(作业批改智能体开发)
人工智能·agent·ai agent·智能体·扣子
大模型码小白10 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
-XWB-11 小时前
【LLM】Agent Planning 完全指南:8 种纯 LLM 范式 + 8 种混合规划模式详解(二)
人工智能·经验分享·aigc·学习方法·ai编程
沉默王二11 小时前
腾讯一面,我霸气反问:“你说你们在做Agent项目,说说 SubAgent、Plan 模式、Skill 调用这些你们都是怎么做的?”面试官一直在擦汗。。
面试·agent·ai编程
kyriewen12 小时前
我让AI改一个bug——它偷偷动了5个我没让它碰的地方
前端·javascript·ai编程
新知图书13 小时前
10.1 项目背景与需求分析(智能客服智能体开发)
人工智能·agent·ai agent·智能体·扣子
神奇霸王龙14 小时前
Claude Code屠榜:MiMo与Grok紧追Codex
服务器·网络·人工智能·gpt·ai·ai编程
z1234567898615 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
GeekArch15 小时前
第24讲:Vibe模式代码风格控制——适配Keil/STM32工程规范
人工智能·stm32·单片机·嵌入式硬件·mcu·决策树·ai编程