
4.3.3 MCP服务器的实现
文件src/mcp/server/lowlevel/server.py定义了FastMCP服务器的核心组件Server类,该类实现了MCP(Model Context Protocol)协议的基本逻辑。Server类负责处理来自客户端的请求,包括初始化、心跳检测、工具调用、资源读取等。它提供了一个通用框架,用于注册和处理不同类型的请求和通知,例如工具调用、资源订阅和进度通知。此外,代码还包含了一个默认的生命周期管理器lifespan,用于在服务器启动和关闭时执行必要的设置和清理工作。
(1)下面代码的功能是定义了FastMCP服务器的Server类,该类是FastMCP服务器的核心,负责处理客户端请求、管理会话、执行生命周期管理等。Server类通过泛型参数支持不同的生命周期结果类型和请求类型,提供了注册请求处理程序、通知处理程序和工具调用的方法。
class Server(Generic[LifespanResultT, RequestT]):
def __init__(
self,
name: str,
version: str | None = None,
instructions: str | None = None,
lifespan: Callable[
[Server[LifespanResultT, RequestT]],
AbstractAsyncContextManager[LifespanResultT],
] = lifespan,
):
self.name = name
self.version = version
self.instructions = instructions
self.lifespan = lifespan
self.request_handlers: dict[type, Callable[..., Awaitable[types.ServerResult]]] = {
types.PingRequest: _ping_handler,
}
self.notification_handlers: dict[type, Callable[..., Awaitable[None]]] = {}
self.notification_options = NotificationOptions()
self._tool_cache: dict[str, types.Tool] = {}
logger.debug("Initializing server %r", name)
def create_initialization_options(
self,
notification_options: NotificationOptions | None = None,
experimental_capabilities: dict[str, dict[str, Any]] | None = None,
) -> InitializationOptions:
"""从这个服务器实例创建初始化选项。"""
# ...
def get_capabilities(
self,
notification_options: NotificationOptions,
experimental_capabilities: dict[str, dict[str, Any]],
) -> types.ServerCapabilities:
"""将现有的处理程序转换为ServerCapabilities对象。"""
# ...
(2)下面代码的功能是实现了FastMCP服务器的请求处理机制。通过装饰器函数,可以注册不同类型的请求处理程序,如列出提示(list_prompts)、获取提示(get_prompt)、列出资源(list_resources)等。这些装饰器简化了请求处理程序的注册过程,并使得服务器能够灵活地扩展新的请求类型。
def list_prompts(self):
def decorator(func: Callable[[], Awaitable[list[types.Prompt]]]):
logger.debug("Registering handler for PromptListRequest")
async def handler(_: Any):
prompts = await func()
return types.ServerResult(types.ListPromptsResult(prompts=prompts))
self.request_handlers[types.ListPromptsRequest] = handler
return func
return decorator
def get_prompt(self):
def decorator(
func: Callable[[str, dict[str, str] | None], Awaitable[types.GetPromptResult]],
):
logger.debug("Registering handler for GetPromptRequest")
async def handler(req: types.GetPromptRequest):
prompt_get = await func(req.params.name, req.params.arguments)
return types.ServerResult(prompt_get)
self.request_handlers[types.GetPromptRequest] = handler
return func
return decorator
(3)下面代码的功能是实现了FastMCP服务器的工具调用处理机制。通过call_tool装饰器,可以注册工具调用的处理程序。这个装饰器负责验证输入、调用工具函数,并构建包含结果的CallToolResult。
def call_tool(self, *, validate_input: bool = True):
def decorator(
func: Callable[
...,
Awaitable[UnstructuredContent | StructuredContent | CombinationContent],
],
):
logger.debug("Registering handler for CallToolRequest")
async def handler(req: types.CallToolRequest):
try:
tool_name = req.params.name
arguments = req.params.arguments or {}
tool = await self._get_cached_tool_definition(tool_name)
# 输入验证
if validate_input and tool:
try:
jsonschema.validate(instance=arguments, schema=tool.inputSchema)
except jsonschema.ValidationError as e:
return self._make_error_result(f"输入验证错误:{e.message}")
# 工具调用
results = await func(tool_name, arguments)
# 输出规范化
unstructured_content: UnstructuredContent
maybe_structured_content: StructuredContent | None
if isinstance(results, tuple) and len(results) == 2:
# 工具返回了结构化和非结构化内容
unstructured_content, maybe_structured_content = cast(CombinationContent, results)
elif isinstance(results, dict):
# 工具仅返回结构化内容
maybe_structured_content = cast(StructuredContent, results)
unstructured_content = [types.TextContent(type="text", text=json.dumps(results, indent=2))]
elif hasattr(results, "__iter__"):
# 工具仅返回非结构化内容
unstructured_content = cast(UnstructuredContent, results)
maybe_structured_content = None
else:
return self._make_error_result(f"工具返回了意外类型:{type(results).__name__}")
# 输出验证
if tool and tool.outputSchema is not None:
if maybe_structured_content is None:
return self._make_error_result(
"输出验证错误:定义了outputSchema但没有返回结构化输出"
)
else:
try:
jsonschema.validate(instance=maybe_structured_content, schema=tool.outputSchema)
except jsonschema.ValidationError as e:
return self._make_error_result(f"输出验证错误:{e.message}")
# 结果
return types.ServerResult(
types.CallToolResult(
content=list(unstructured_content),
structuredContent=maybe_structured_content,
isError=False,
)
)
except Exception as e:
return self._make_error_result(str(e))
self.request_handlers[types.CallToolRequest] = handler
return func
return decorator
(4)下面代码的功能是实现了FastMCP服务器的心跳处理程序。当客户端发送心跳请求时,服务器将调用此处理程序以确认其处于活动状态。这是一个简单的请求处理程序,用于维护与客户端的连接。
async def _ping_handler(request: types.PingRequest) -> types.ServerResult:
return types.ServerResult(types.EmptyResult())
(5)下面代码的功能是实现了FastMCP服务器的初始化选项创建。create_initialization_options方法根据服务器实例创建初始化选项,这些选项包括服务器名称、版本、功能和指示等。这些信息对于客户端了解服务器的能力和配置非常重要。
def create_initialization_options(
self,
notification_options: NotificationOptions | None = None,
experimental_capabilities: dict[str, dict[str, Any]] | None = None,
) -> InitializationOptions:
"""从这个服务器实例创建初始化选项。"""
def pkg_version(package: str) -> str:
try:
from importlib.metadata import version
return version(package)
except Exception:
pass
return "unknown"
return InitializationOptions(
server_name=self.name,
server_version=self.version if self.version else pkg_version("mcp"),
capabilities=self.get_capabilities(
notification_options or NotificationOptions(),
experimental_capabilities or {},
),
instructions=self.instructions,
)
整体而言,这段代码是FastMCP服务器与客户端交互的基础,它确保了服务器能够按照MCP协议正确响应客户端的请求。文件src/mcp/server/fastmcp/server.py 和前面的文件src/mcp/server/lowlevel/server.py在FastMCP服务器的架构中扮演不同的角色,具有不同的功能和设计目标,两者的区别如下所示。
(1)src/mcp/server/fastmcp/server.py
- 高级接口:fastmcp/server.py 提供了一个更高级、更易于使用的接口,用于构建和运行FastMCP服务器。它封装了底层的复杂性,提供了一些简化的方法和装饰器来注册工具、提示和资源。
- 功能丰富:这个文件定义了FastMCP服务器的核心类,如FastMCP,它负责初始化服务器、配置路由、处理请求和响应。它还提供了方法来添加工具、资源和提示,以及运行服务器。
- 面向开发者:它主要面向希望快速构建和部署MCP服务器的开发者,提供了一个简单的方式来扩展服务器功能,而无需深入了解MCP协议的所有细节。
(2)src/mcp/server/lowlevel/server.py
- 低级接口:lowlevel/server.py 提供了一个更接近底层的接口,用于那些需要更细粒度控制或想要实现自定义MCP服务器行为的开发者。
- 协议实现:这个文件包含了MCP协议的具体实现,包括请求处理、会话管理和消息传递。它定义了服务器如何接收和响应不同类型的请求,如工具调用、资源读取等。
- 灵活性:它提供了更多的灵活性和控制能力,允许开发者自定义服务器的行为,包括请求处理程序、通知处理程序和生命周期管理。
- 面向协议:这个文件更适合那些需要直接与MCP协议交互的开发者,或者想要实现特定MCP扩展的开发者。
总之,文件fastmcp/server.py 是面向应用开发者的,提供了一个高级、易用的接口来构建服务器。文件lowlevel/server.py 是面向协议开发者的,提供了一个低级、灵活的接口来实现协议细节。两者共同构成了FastMCP服务器的核心,fastmcp/server.py 依赖于 lowlevel/server.py 来实现其高级功能。开发者可以根据自己的需求选择使用哪个接口,或者两者结合使用,以实现所需的功能。
Python SDK仓库:MCP服务器端(3)MCP服务器的实现&spm=1001.2101.3001.5002&articleId=154062825&d=1&t=3&u=01f559732d304cdc9f83b945eb1bb844)
278

被折叠的 条评论
为什么被折叠?



