MCP Adapter 开发文档

架构概述

Estimated reading: 9 minutes 2 views 贡献人员

架构概述

本文档解释了 MCP Adapter 如何将 WordPress 能力转化为 MCP 组件并处理来自 AI 代理的请求。

系统架构

MCP Adapter 使用分层架构,具有清晰的关注点分离:

  1. 传输层:处理通信协议(HTTP、STDIO)
  2. 核心层:管理服务器、路由和组件注册
  3. 组件层:工具、资源和提示词
  4. WordPress 层:Abilities API 集成

核心组件

McpAdapter(单例注册表)

  • 用途:中央注册表,管理多个 MCP 服务器
  • 关键方法createserver()getservers()instance()
  • 初始化:钩子到 restapiinit 并触发 mcpadapterinit 动作

McpServer(服务器实例)

  • 用途:具有特定配置的单个 MCP 服务器
  • 组件:使用 McpComponentRegistry 管理工具、资源、提示词
  • 依赖:错误处理程序、可观测性处理程序、传输权限回调

McpTransportFactory

  • 用途:使用依赖注入创建传输实例
  • 上下文创建:构建包含所有所需处理程序的 McpTransportContext
  • 验证:确保传输类实现 McpTransportInterface

RequestRouter

  • 用途:将 MCP 方法调用路由到适当的处理程序
  • 方法:将方法名称映射到处理程序函数
  • 可观测性:跟踪请求指标和时序

请求流程

系统中的简单请求流程:

AI 代理 → 传输 → 请求路由器 → 处理程序 → WordPress 能力 → 响应

详细流程

  1. 传输 接收 MCP 请求并进行身份验证
  2. 请求路由器 将方法映射到适当的处理程序
  3. 处理程序 找到组件(工具/资源/提示词)并验证输入
  4. WordPress 能力 执行并进行权限检查
  5. 响应 格式化并通过传输返回

方法路由

RequestRouter 将 MCP 方法映射到处理程序:

$handlers = [
    'initialize'          => InitializeHandler,
    'tools/list'          => ToolsHandler::list_tools(),
    'tools/call'          => ToolsHandler::call_tool(),
    'resources/list'      => ResourcesHandler::list_resources(),
    'resources/read'      => ResourcesHandler::read_resource(),
    'prompts/list'        => PromptsHandler::list_prompts(),
    'prompts/get'         => PromptsHandler::get_prompt(),
    'ping'                => SystemHandler::ping(),
    'logging/setLevel'    => SystemHandler::set_logging_level(),
    'completion/complete' => SystemHandler::complete(),
    'roots/list'          => SystemHandler::list_roots(),
];

组件创建

能力到 MCP 组件的转换

WordPress 能力使用工厂类转换为 MCP 组件:

// 工具
$tool = RegisterAbilityAsMcpTool::make($ability, $server);

// 资源(需要能力元数据中的 'uri')
$resource = RegisterAbilityAsMcpResource::make($ability, $server);

// 提示词(支持能力元数据中的 'arguments' 和 'annotations')
$prompt = RegisterAbilityAsMcpPrompt::make($ability, $server);

组件注册表

McpComponentRegistry 管理组件注册:

class McpComponentRegistry {
    public function register_ability_as_tool(string $ability_name): void;
    public function register_ability_as_resource(string $ability_name): void;
    public function register_ability_as_prompt(string $ability_name): void;
    
    // 为注册事件自动记录可观测性
}

传输层

传输接口

interface McpTransportInterface {
    public function __construct(McpTransportContext $context);
    public function register_routes(): void;
}

interface McpRestTransportInterface extends McpTransportInterface {
    public function check_permission(WP_REST_Request $request);
    public function handle_request(WP_REST_Request $request): WP_REST_Response;
}

内置传输

  • HttpTransport:推荐(符合 MCP 2025-06-18 规范)
  • STDIO Transport:通过 WP-CLI 命令

依赖注入

传输通过 McpTransportContext 接收所有依赖:

class McpTransportContext {
    public McpServer $mcp_server;
    public InitializeHandler $initialize_handler;
    public ToolsHandler $tools_handler;
    public ResourcesHandler $resources_handler;
    public PromptsHandler $prompts_handler;
    public SystemHandler $system_handler;
    public RequestRouter $request_router;
    public string $observability_handler;
    public McpErrorHandlerInterface $error_handler;
    public $transport_permission_callback;
}

错误处理

两部分系统

  1. 错误响应创建McpErrorFactory 创建 JSON-RPC 错误响应
  2. 错误日志记录McpErrorHandlerInterface 实现负责日志记录
// 错误响应(返回给客户端)
$error_response = McpErrorFactory::tool_not_found($request_id, $tool_name);

// 错误日志记录(用于监控)
$error_handler->log('工具未找到', [
    'tool_name' => $tool_name,
    'user_id' => get_current_user_id(),
    'server_id' => $server_id
], 'error');

内置错误处理程序

  • ErrorLogMcpErrorHandler:记录到 PHP 错误日志
  • NullMcpErrorHandler:无操作处理程序(默认)

可观测性

事件发射模式

系统发射事件而不是存储计数器:

interface McpObservabilityHandlerInterface {
    public static function record_event(string $event, array $tags = []): void;
    public static function record_timing(string $metric, float $duration_ms, array $tags = []): void;
}

跟踪的事件

  • 请求事件mcp.request.countmcp.request.successmcp.request.error
  • 组件事件mcp.component.registeredmcp.component.registration_failed
  • 工具事件mcp.tool.executionsuccessmcp.tool.executionfailed
  • 时序事件mcp.request.duration

设计模式

单例模式(McpAdapter)

class McpAdapter {
    private static self $instance;
    
    public static function instance(): self {
        if (!isset(self::$instance)) {
            self::$instance = new self();
            add_action('rest_api_init', [self::$instance, 'init'], 15);
        }
        return self::$instance;
    }
}

工厂模式(组件创建)

class RegisterAbilityAsMcpTool {
    public static function make(WP_Ability $ability, McpServer $server): McpTool {
        // 将 WordPress 能力转换为 MCP 工具
        return McpTool::from_array($tool_data, $server);
    }
}

策略模式(传输层)

不同的传输实现共享相同的接口:

class HttpTransport implements McpRestTransportInterface {
    public function __construct(McpTransportContext $context) {
        // 依赖注入
    }
    
    public function handle_request(WP_REST_Request $request): WP_REST_Response {
        // HTTP 特定处理
    }
}

扩展点

自定义传输

class MyTransport implements McpRestTransportInterface {
    use McpTransportHelperTrait;
    
    private McpTransportContext $context;
    
    public function __construct(McpTransportContext $context) {
        $this->context = $context;
        $this->register_routes();
    }
    
    public function check_permission(WP_REST_Request $request) {
        // 自定义身份验证逻辑
        return current_user_can('manage_options');
    }
    
    public function handle_request(WP_REST_Request $request): WP_REST_Response {
        // 通过注入的路由器路由
        $body = $request->get_json_params();
        $result = $this->context->request_router->route_request(
            $body['method'],
            $body['params'] ?? [],
            $body['id'] ?? 0,
            $this->get_transport_name()
        );
        
        return rest_ensure_response($result);
    }
}

自定义错误处理程序

class MyErrorHandler implements McpErrorHandlerInterface {
    public function log(string $message, array $context = [], string $type = 'error'): void {
        // 发送到您的监控系统
        MyMonitoringSystem::send($message, $context, $type);
        
        // 回退到本地日志记录
        error_log("[MCP {$type}] {$message}");
    }
}

自定义可观测性处理程序

class MyObservabilityHandler implements McpObservabilityHandlerInterface {
    use McpObservabilityHelperTrait;
    
    public static function record_event(string $event, array $tags = []): void {
        $formatted_event = self::format_metric_name($event);
        $merged_tags = self::merge_tags($tags);
        
        // 发送到您的指标系统
        MyMetricsSystem::counter($formatted_event, 1, $merged_tags);
    }
    
    public static function record_timing(string $metric, float $duration_ms, array $tags = []): void {
        $formatted_metric = self::format_metric_name($metric);
        $merged_tags = self::merge_tags($tags);
        
        // 发送时序数据
        MyMetricsSystem::timing($formatted_metric, $duration_ms, $merged_tags);
    }
}

关键架构决策

依赖注入

  • 所有传输通过 McpTransportContext 接收依赖
  • 无全局状态或静态依赖
  • 易于测试和模拟

基于接口的设计

  • 所有主要组件都实现接口
  • 可交换的实现(错误处理程序、可观测性、传输)
  • 清晰的关注点分离

事件发射

  • 系统发射事件而不是存储本地计数器
  • 外部系统处理聚合和分析
  • 禁用可观测性时零内存开销

WordPress 集成

  • 利用 WordPress Abilities API 进行组件定义
  • 使用 WordPress REST API 进行 HTTP 传输
  • 与 WordPress 权限系统集成

性能考虑

延迟加载

  • 组件仅在需要时创建
  • 验证可以被禁用以提高性能
  • 禁用功能的空对象模式

缓存

  • WordPress 对象缓存集成
  • 组件注册表缓存
  • 能力查找优化

内存管理

  • 无持久状态存储
  • 事件发射模式防止内存泄漏
  • 可配置的验证以减少开销

下一步

留下第一个评论