mcp协议概要和FastMCP示例
Model Context Protocol (MCP) 是 Anthropic 公司推出的用于大模型交互的标准化方法,FastMCP 是其 Python SDK(需 Python 3.10+)。示例展示了 MCP 的三大组件:工具(Tools)、资源(Resources)和提示(Prompts)的使用方式。服务端通过装饰器定义功能,客户端可异步调用这些功能(如 greet/add 工具、读取资源
Model Context Protocol是 为大模型提供上下文和工具的全新标准化方法,FastMCP 使构建 MCP 服务器和客户端变得简单直观。
MCP这个标准是anthropic公司搞的,如果大家不了解的话,anthropic就是那个Claud Code产品的母公司。
https://www.anthropic.com/news/model-context-protocol
更进一步的 这个公司就是那个禁止中国公司和个人使用AI产品的那个。
https://www.anthropic.com/news/updating-restrictions-of-sales-to-unsupported-regions
抛开这些,mcp是他们搞的一个事实标准。用于LLM与外界进行交互。
fastmcp是python版本的SDK。
此SDK目前已经升级到v2.0,并且更新特别快。
所以网上的文档很多更新的不是特别及时。
很多人对于如何使用fastmcp搞不清楚。
这里我就给个demo,让大家搞清大概的用法。
有两个部分 server 和 client。
fastmcp需要python3.10以上版本。
如果没有的话,可以使用pyenv安装高版本的python
pyenv
# 安装依赖
sudo apt install -y build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl libncursesw5-dev \
xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
## 安装脚本会提示你将 pyenv 所需的环境变量添加到.bashrc文件中。
## 按照提示操作,并重启终端或运行source ~/.bashrc 使其生效。
curl https://pyenv.run | bash
pyenv install 3.12
#安装完成后,你可以通过以下命令来管理版本:
#查看已安装的所有版本
pyenv versions
#将全局默认版本设置为 Python 3.12
pyenv global 3.12
#在当前目录设置本地 Python 版本
pyenv local 3.12
mcp协议中有三种组件
Tools 工具
Resources 资源
Prompts 提示
下面的代码示例三种组件如何使用。
server.py
from fastmcp import FastMCP
mcp = FastMCP("My MCP Server")
@mcp.tool
def greet(name: str) -> str:
'''Send hello to my friend.'''
return f"Hello, {name}!"
@mcp.tool
def add(a: int, b: int) -> int:
'''Add two integer numbers together.'''
return a + b
# Basic dynamic resource returning a string
@mcp.resource("resource://greeting")
def get_greeting() -> str:
"""Provides a simple greeting message."""
return "Hello from FastMCP Resources!"
# Resource returning JSON data (dict is auto-serialized)
@mcp.resource("data://config")
def get_config() -> dict:
"""Provides application configuration as JSON."""
return {
"theme": "dark",
"version": "1.2.0",
"features": ["tools", "resources"],
}
# Basic prompt returning a string (converted to user message automatically)
@mcp.prompt
def ask_about_topic(topic: str) -> str:
"""Generates a user message asking for an explanation of a topic."""
return f"Can you please explain the concept of '{topic}'?"
if __name__ == "__main__":
mcp.run(transport="http", port=8000)
运行:
python server.py
client.py
import asyncio
from fastmcp import Client
from fastmcp.client.logging import LogMessage
async def log_handler(message: LogMessage):
print(f"Server log: {message.data}")
async def progress_handler(progress: float, total: float | None, message: str | None):
print(f"Progress: {progress}/{total} - {message}")
async def sampling_handler(messages, params, context):
# Integrate with your LLM service here
return "Generated response"
client = Client("http://localhost:8000/mcp")
client.log_handler = log_handler
client.progress_handler = progress_handler
client.sampling_handler = sampling_handler
#client = Client( "server.py")
async def main():
async with client:
# Basic server interaction
await client.ping()
# List available operations
tools = await client.list_tools()
resources = await client.list_resources()
prompts = await client.list_prompts()
# Execute operations
result = await client.call_tool("greet", {"name": "BaBa"})
print(result)
print("-------------------------");
# Execute operations
result = await client.call_tool("add", {"a": 3, "b": 5})
print(result)
print("-------------------------");
print("Tools:", tools)
print("-------------------------");
print("Resources:", resources)
print("-------------------------");
print("Prompts:", prompts)
print("-------------------------");
# Read a resource
content = await client.read_resource("resource://greeting")
print(content[0].text)
print("-------------------------");
# Get a rendered prompt
messages = await client.get_prompt("ask_about_topic", {"topic": "Python"})
print(messages.messages)
asyncio.run(main())
运行
python3 client.py
运行结果:
pp@dell:~/fastmcp$ python3 client1.py
CallToolResult(content=[TextContent(type='text', text='Hello, BaBa!', annotations=None, meta=None)], structured_content={'result': 'Hello, BaBa!'}, data='Hello, BaBa!', is_error=False)
-------------------------
CallToolResult(content=[TextContent(type='text', text='8', annotations=None, meta=None)], structured_content={'result': 8}, data=8, is_error=False)
-------------------------
Tools: [Tool(name='greet', title=None, description='Send hello to my friend.', inputSchema={'properties': {'name': {'title': 'Name', 'type': 'string'}}, 'required': ['name'], 'type': 'object'}, outputSchema={'properties': {'result': {'title': 'Result', 'type': 'string'}}, 'required': ['result'], 'title': '_WrappedResult', 'type': 'object', 'x-fastmcp-wrap-result': True}, annotations=None, meta={'_fastmcp': {'tags': []}}), Tool(name='add', title=None, description='Add two integer numbers together.', inputSchema={'properties': {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}, 'required': ['a', 'b'], 'type': 'object'}, outputSchema={'properties': {'result': {'title': 'Result', 'type': 'integer'}}, 'required': ['result'], 'title': '_WrappedResult', 'type': 'object', 'x-fastmcp-wrap-result': True}, annotations=None, meta={'_fastmcp': {'tags': []}})]
-------------------------
Resources: [Resource(name='get_greeting', title=None, uri=AnyUrl('resource://greeting'), description='Provides a simple greeting message.', mimeType='text/plain', size=None, annotations=None, meta={'_fastmcp': {'tags': []}}), Resource(name='get_config', title=None, uri=AnyUrl('data://config'), description='Provides application configuration as JSON.', mimeType='text/plain', size=None, annotations=None, meta={'_fastmcp': {'tags': []}})]
-------------------------
Prompts: [Prompt(name='ask_about_topic', title=None, description='Generates a user message asking for an explanation of a topic.', arguments=[PromptArgument(name='topic', description=None, required=True)], meta={'_fastmcp': {'tags': []}})]
-------------------------
Hello from FastMCP Resources!
-------------------------
[PromptMessage(role='user', content=TextContent(type='text', text="Can you please explain the concept of 'Python'?", annotations=None, meta=None))]
可以看出调用的结果。
大家都说CSDN不好,里面的文章骗人。
可是技术类文章不在CSDN上发,还能到哪里发呢?
Looking in my eyes!
Tell me where!
参考:
更多推荐
所有评论(0)