[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))]
相关推荐
GISer_Jing3 小时前
AI前端(From豆包)
前端·aigc·ai编程
码途漫谈3 小时前
Easy-Vibe开发篇阅读笔记(四)——前端开发之结合 Agent Skills 美化界面
人工智能·笔记·ai·开源·ai编程
J_Xiong01174 小时前
【Harness篇】05:长任务Harness
ai agent
小虎AI生活4 小时前
K2.6、DeepSeek V4、GPT-5.5 都来了,组合拳打起来
ai编程
杨同学technotes5 小时前
Claude Code 进阶指南:从记忆系统到子代理编排
ai编程
@PHARAOH5 小时前
WHAT - cursor cli 开发范式
前端·ai·ai编程
Aleeeeex6 小时前
RAG 那点事:从 8 份企业文档到能用的问答系统,全过程拆给你看
人工智能·python·ai编程
ws_qy6 小时前
从大模型原理到前端 AI Coding 工程化实践
前端·ai编程
AI自动化工坊6 小时前
Late框架技术深度解析:5GB VRAM实现10倍AI编码效率的工程架构
人工智能·5g·架构·ai编程·late
2601_949925187 小时前
AI Agent如何重构跨境物流的决策?
大数据·人工智能·重构·ai agent·geo优化·物流科技