MCP Server Tool 开发学习文档

MCP Server Tool 开发学习文档

目录

  1. MCP Server Tool 简介
  2. 核心开发流程与知识点详解
    • 2.1 工具函数的实现
    • 2.2 MCP Server 的注册与启动
    • 2.3 工具注册与调用机制
    • 2.4 工具列表的声明与返回
    • 2.5 传输方式(stdio 与 sse)
  3. Python 源码详细解析
  4. SSE 方式本地部署方法
  5. 客户端访问与调用示例

1. MCP Server Tool 简介

MCP(Model Context Protocol)是一种用于模型与外部工具交互的协议。MCP Server Tool 是基于 MCP 协议开发的服务端工具,能够通过标准输入输出(stdio)或服务端事件(SSE)等方式暴露自定义工具,供客户端远程调用。

本例实现了一个简单的“网站抓取”工具,支持通过 MCP 协议获取指定网页内容。


2. 核心开发流程与知识点详解

2.1 工具函数的实现

工具函数是 MCP Server Tool 的核心业务逻辑。例如本例中的 fetch_website,用于异步抓取网页内容:

async def fetch_website(url: str) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
    headers = {"User-Agent": "MCP Test Server (github.com/modelcontextprotocol/python-sdk)"}
    async with create_mcp_http_client(headers=headers) as client:
        response = await client.get(url)
        response.raise_for_status()
        return [types.TextContent(type="text", text=response.text)]
  • 异步实现:利用 async/await,适合高并发场景。
  • 类型注解:返回值为内容对象列表,支持文本、图片、嵌入资源。
  • 自定义 User-Agent:便于调试和识别请求来源。

2.2 MCP Server 的注册与启动

MCP Server 通过 Server 类实例化,并注册工具与工具列表:

app = Server("mcp-website-fetcher")
  • Server 名称:用于标识服务实例。
  • 注册工具与工具列表:通过装饰器 @app.call_tool()@app.list_tools() 实现。

2.3 工具注册与调用机制

工具注册函数用于处理客户端的工具调用请求:

@app.call_tool()
async def fetch_tool(name: str, arguments: dict) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
    if name != "fetch":
        raise ValueError(f"Unknown tool: {name}")
    if "url" not in arguments:
        raise ValueError("Missing required argument 'url'")
    return await fetch_website(arguments["url"])
  • 参数校验:确保工具名和参数正确。
  • 调用业务逻辑:将参数传递给实际的工具函数。

2.4 工具列表的声明与返回

通过 @app.list_tools() 注册工具列表,供客户端查询:

@app.list_tools()
async def list_tools() -> list[types.Tool]:
    return [
        types.Tool(
            name="fetch",
            description="Fetches a website and returns its content",
            inputSchema={
                "type": "object",
                "required": ["url"],
                "properties": {
                    "url": {
                        "type": "string",
                        "description": "URL to fetch",
                    }
                },
            },
        )
    ]
  • Tool 对象:描述工具名称、功能、输入参数结构。
  • inputSchema:采用 JSON Schema 格式,便于前端自动生成表单或校验参数。

2.5 传输方式(stdio 与 sse)

MCP Server 支持两种传输方式:

  • stdio:通过标准输入输出进行通信,适合本地或嵌入式场景。
  • sse:通过 HTTP SSE(Server-Sent Events)协议,适合 Web 场景。

切换方式通过命令行参数 --transport 控制:

@click.option("--transport", type=click.Choice(["stdio", "sse"]), default="stdio", help="Transport type")
  • stdio 模式下,使用 mcp.server.stdio.stdio_server 启动服务。
  • sse 模式下,使用 starlette 框架和 uvicorn 启动 HTTP 服务,并挂载 SSE 路由。

3. Python 源码详细解析

3.1 入口函数

@click.command()
@click.option("--port", default=8000, help="Port to listen on for SSE")
@click.option("--transport", type=click.Choice(["stdio", "sse"]), default="stdio", help="Transport type")
def main(port: int, transport: str) -> int:
    ...
  • 使用 click 实现命令行参数解析。
  • 根据 transport 参数选择不同的服务启动方式。

3.2 stdio 模式

from mcp.server.stdio import stdio_server

async def arun():
    async with stdio_server() as streams:
        await app.run(streams[0], streams[1], app.create_initialization_options())

anyio.run(arun)
  • 通过 anyio 启动异步主循环。
  • 适合本地开发和调试。

3.3 sse 模式

from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
from starlette.responses import Response
from starlette.routing import Mount, Route

sse = SseServerTransport("/messages/")

async def handle_sse(request):
    async with sse.connect_sse(request.scope, request.receive, request._send) as streams:
        await app.run(streams[0], streams[1], app.create_initialization_options())
    return Response()

starlette_app = Starlette(
    debug=True,
    routes=[
        Route("/sse", endpoint=handle_sse, methods=["GET"]),
        Mount("/messages/", app=sse.handle_post_message),
    ],
)

import uvicorn
uvicorn.run(starlette_app, host="0.0.0.0", port=port)
  • 使用 starlette 框架搭建 HTTP 服务。
  • /sse 路由用于建立 SSE 连接。
  • /messages/ 路由用于消息传递。

4. SSE 方式本地部署方法

4.1 安装依赖

确保已安装 uvicornstarlettemcp 相关依赖:

pip install uvicorn starlette mcp

4.2 启动服务

python-sdk/examples/servers/simple-tool/ 目录下运行:

uv run mcp-simple-tool --transport sse --port 8000
  • --transport sse:指定使用 SSE 传输方式。
  • --port 8000:指定监听端口(可自定义)。

4.3 服务启动后,SSE 端点为:

  • /sse:用于建立 SSE 连接
  • /messages/:用于消息通信

5. 客户端访问与调用示例

5.1 客户端代码示例(STDIO,可类比改为 SSE)

import asyncio
from mcp.client.session import ClientSession
from mcp.client.sse import SseServerParameters, sse_client

async def main():
    async with sse_client(
        SseServerParameters(url="http://localhost:8000/sse")
    ) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # 列出可用工具
            tools = await session.list_tools()
            print(tools)

            # 调用 fetch 工具
            result = await session.call_tool("fetch", {"url": "https://example.com"})
            print(result)

asyncio.run(main())
  • SseServerParameters(url="http://localhost:8000/sse"):指定 SSE 服务端点。
  • session.list_tools():获取工具列表。
  • session.call_tool("fetch", {"url": "https://example.com"}):调用 fetch 工具抓取网页内容。

总结

  • MCP Server Tool 通过注册工具函数和工具列表,支持多种传输方式(stdio/sse)。
  • 工具函数需异步实现,参数和返回值需严格类型注解。
  • SSE 部署适合 Web 场景,需结合 starlette/uvicorn。
  • 客户端可通过 MCP 协议远程调用工具,支持自动发现和参数校验。
### MCP Server 开发教程和技术文档 #### 什么是 MCPMCP(Model Context Protocol)是一种用于连接大型语言模型(LLMs)、搜索引擎和其他数据源的协议。它通过定义标准化的数据交换方式,使得开发者可以轻松地集成不同的服务和工具[^1]。 #### 如何开发一个基于 MCP 的服务器? 为了开发一个 MCP Server,通常需要以下几个核心组件: 1. **SSE 协议支持** - 使用 SSE(Server-Sent Events),这是一种允许服务器向客户端推送实时更新的技术。在 MCP 中,SSE 被广泛应用于实现实时通信功能。 2. **安装依赖项** - 如果目标是创建一个特定用途的 MCP Server,比如 ArXiv 论文检索服务,则可以通过 `uv tool` 工具来简化安装过程。例如: ```bash uv tool install arxiv-mcp-server ``` 这条命令会自动完成所需环境配置并准备好基础框架[^2]。 3. **Docker 容器化部署** - 对于更复杂的项目或者希望快速启动测试环境的情况,推荐采用 Docker Compose 方法来进行容器编排。执行如下指令即可初始化整个系统架构: ```bash docker compose up --build ``` 此操作不仅能够构建镜像还能同步启动所有关联的服务实例[^3]。 4. **API 接口设计** - 设计 RESTful 或 GraphQL 类型 API 是必不可少的一环,这些接口负责处理来自外部请求并将结果返回给调用方。具体实现取决于业务逻辑需求以及所选技术栈特性。 5. **性能优化与安全性考量** - 在实际生产环境中还需要关注系统的响应速度、并发能力等方面的表现;同时也要加强身份验证机制防止未授权访问行为发生。 以下是关于如何编写简单的 Python 版本 MCP Server 示例代码片段: ```python from flask import Flask, Response, stream_with_context import time app = Flask(__name__) @app.route('/mcp/stream') def mcp_stream(): def generate(): count = 0 while True: yield f"data: {count}\n\n" count += 1 time.sleep(1) return Response(stream_with_context(generate()), mimetype="text/event-stream") if __name__ == "__main__": app.run(debug=True) ``` 上述脚本展示了基本的 SSE 功能模拟,在真实场景下可以根据实际情况调整消息格式等内容。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值