MCP這麼火,來一波簡單實操記錄

↓推薦關注↓

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 weathercd weather# 建立虛擬環境uv venvsource .venv/bin/activate# 安裝依賴uv add mcp httpx# 刪除示例檔案rm hello.py# 建立檔案mkdir -p src/weathertouch src/weather/__init__.pytouch src/weather/server.py

(三)編寫程式碼

1. 修改 pyproject.toml

在 pyproject.toml 尾部新增以下內容:
[build-system]requires = [ "hatchling",]build-backend = "hatchling.build"[project.scripts]weather = "weather:main"

2. 編寫 __init__.py

檔案路徑:src/weather/__init__.py
from . import serverimport asynciodefmain():"""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.py
from typing import Anyimport asyncioimport httpxfrom mcp.server.models import InitializationOptionsimport mcp.types as typesfrom mcp.server import NotificationOptions, Serverimport mcp.server.stdioNWS_API_BASE = "https://api.weather.gov"USER_AGENT = "weather-app/1.0"server = Server("weather")@server.list_tools()asyncdefhandle_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()asyncdefhandle_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}")asyncdefmain():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 呼叫本地服務並返回答案:

呼叫結果

四、原理解讀

(一)過程分析

  1. 我們向 Claude 提問;
  2. Claude 分析可用工具並決定呼叫某個工具;
  3. 客戶端(Claude for Desktop)透過 MCP 協議呼叫工具;
  4. 結果返回給 Claude;
  5. Claude 根據結果生成答案。

(二)程式碼核心

程式碼的核心功能集中在以下兩部分:
# 列出工具,供 LLM 選擇@server.list_tools()asyncdefhandle_list_tools() -> list[types.Tool]:# 執行方法,解析並處理 LLM 呼叫請求@server.call_tool()asyncdefhandle_call_tool(    name: str, arguments: dict | None) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
注: 示例程式碼中 handle_call_tool 返回固定回覆,是因為原版呼叫美國國家氣象資料局 API,配置較麻煩。實際使用時,可替換為真實 API。
更多問題可參考官方 故障排除文件https://modelcontextprotocol.io/quickstart#troubleshooting
那麼到這兒其實就基本能看明白了,後續深入會視情況再推進。

相關文章