MCP这么火,来一波简单实操记录

360影视 国产动漫 2025-03-12 00:34 3

摘要:2024年底,Anthropic发布了MCP协议。Anthropic就是发布了Claude系列模型的公司(现在gpt基础模型不更新还退步,claude真的很棒)

2024年底,Anthropic发布了MCP协议。Anthropic就是发布了Claude系列模型的公司(现在gpt基础模型不更新还退步,claude真的很棒)

除去官方的各种美化和包装,这到底是什么?我大胆说一说:这其实是另一种形式的Function Calling

一、简单解释 Function Calling

大模型可以看作在一个封闭的“盒子”里,无法实时获取外部信息。为了让大模型获取外部数据,我们可以提供一些“方法”,例如:

方法:获取天气 需要传入的参数:经度、纬度 返回结果:空气质量、温度、湿度...

在提问时,我们携带一个方法列表,里面写着各种方法。大模型决定调用某个方法时,会输出方法名和参数;该方法在本地执行,并将结果返回给大模型。

二、快速开始 简介

模型上下文协议 (MCP)是一种开放协议,可实现 LLM 应用与外部数据源和工具之间的无缝集成。

GitHub地址(https://github.com/modelcontextprotocol](https://github.com/modelcontextprotocol)

在此处我们还是跳开这些枯燥的理论,直接上手官方案例(有条件的小伙伴可以亲自试试!)

我是Mac环境、Python语言(TS也支持)(一)安装包管理器 - uv

执行以下命令安装 uv:

curl -LsSf https://astral.sh/uv/install.sh | sh提示:安装后需重启终端。如果环境变量写入失败,手动修改 ~/.zshrc: export PATH="$HOME/.local/bin:$PATH" 吐槽:官方居然选了个刚发布不久的依赖管理工具 uv,坑点一堆。我后续探索下给换成poetry版本的吧

以下是完整步骤:

# 创建项目 uv init weather cd weather # 创建虚拟环境 uv venv source .venv/bin/activate # 安装依赖 uv add mcp httpx # 删除示例文件 rm hello.py # 创建文件 mkdir -p src/weather touch src/weather/__init__.py touch src/weather/server.py(三)编写代码 1. 修改pyproject.toml在尾部添加以下内容:[build-system] requires = [ "hatchling",] build-backend = "hatchling.build" [project.scripts] weather = "weather:main"2. 编写__init__.py文件路径:src/weather/__init__.pyfrom . import server import asyncio def main: """Main entry point for the package.""" asyncio.run(server.main) # Optionally expose other important items at package level __all__ = ['main', 'server']3. 编写server.py文件路径:src/weather/server.pyfrom typing import Any import asyncio import httpx from mcp.server.models import InitializationOptions import mcp.types as types from mcp.server import NotificationOptions, Server import mcp.server.stdio NWS_API_BASE = "https://api.weather.gov" USER_AGENT = "weather-app/1.0" server = Server("weather") @server.list_tools asyncdef handle_list_tools -> list[types.Tool]: return [ types.Tool( name="get-alerts", description="Get weather alerts for a state", inputSchema={ "type": "object", "properties": { "state": { "type": "string", "description": "Two-letter state code (e.g. CA, NY)", }, }, "required": ["state"], }, ), types.Tool( name="get-forecast", description="Get weather forecast for a location", inputSchema={ "type": "object", "properties": { "latitude": { "type": "number", "description": "Latitude of the location", }, "longitude": { "type": "number", "description": "Longitude of the location", }, }, "required": ["latitude", "longitude"], }, ), ] @server.call_tool asyncdef handle_call_tool( name: str, arguments: dict | None ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: ifnot arguments: raise ValueError("Missing arguments") if name == "get-alerts": return [ types.TextContent( type="text", text="气温38,湿度60%" ) ] elif name == "get-forecast": return [types.TextContent( type="text", text="气温18,湿度10%" )] else: raise ValueError(f"Unknown tool: {name}") asyncdef main: asyncwith mcp.server.stdio.stdio_server as (read_stream, write_stream): await server.run( read_stream, write_stream, InitializationOptions( server_name="weather", server_version="0.1.0", capabilities=server.get_capabilities( notification_options=NotificationOptions, experimental_capabilities={}, ), ), ) if __name__ == "__main__": asyncio.run(main)

项目编写完成后,运行以下命令启动服务:

uv run src/weather/server.py三、使用 Claude for Desktop 测试

第二章我们就完成了代码部分,接下来就要看效果

我前面说:MCP 是 Function Calling 的另一种实现。因此需要一个大模型主动调用。这里我们使用Claude for Desktop,它可以作为测试客户端(不是唯一的,你也可以用vscode搭建一个客户端)

Claude for Desktop 下载链接(https://claude.ai/download)

修改配置文件

将第二章写的服务注册到 Claude for Desktop:

vim ~/Library/Application Support/Claude/claude_desktop_config.json

添加如下内容:

{ "mcpServers": { "weather": { "command": "uv", //缺少环境变量的话可以写绝对路径 "args": [ "--directory", "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather",# 目录记得改 "run", "weather" ] } } }

保存后,重启Claude for Desktop。

测试 MCP 工具

重新打开 Claude 后,点击工具栏中的锤子图标:

基于可以看到我们实现的工具了:

可用工具

输入问题,即可看到 Claude 调用本地服务并返回答案:

调用结果 四、原理解读 (一)过程分析

我们向 Claude 提问;

Claude 分析可用工具并决定调用某个工具;

客户端(Claude for Desktop)通过 MCP 协议调用工具;

结果返回给 Claude;

Claude 根据结果生成答案。

代码的核心功能集中在以下两部分:

# 列出工具,供 LLM 选择 @server.list_tools async def handle_list_tools -> list[types.Tool]: # 执行方法,解析并处理 LLM 调用请求 @server.call_tool async def handle_call_tool( name: str, arguments: dict | None ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:注: 示例代码中 handle_call_tool 返回固定回复,是因为原版调用美国国家气象数据局 API,配置较麻烦。实际使用时,可替换为真实 API。

更多问题可参考官方 故障排除文档(https://modelcontextprotocol.io/quickstart#troubleshooting)。

那么到这儿其实就基本能看明白了,后续深入会视情况再推进。

来源:电竞青铜三

相关推荐