#!/usr/bin/env php getMessage() . "\n"); fwrite(STDERR, "Request: " . $line . "\n"); // Send JSON-RPC error response $error_response = [ 'jsonrpc' => '2.0', 'id' => isset($request['id']) ? $request['id'] : null, 'error' => [ 'code' => -32603, 'message' => $e->getMessage(), 'data' => [ 'line' => $line, 'trace' => $e->getTraceAsString() ] ] ]; fwrite(STDOUT, json_encode($error_response) . "\n"); fflush(STDOUT); } } fwrite(STDERR, "MCP stdio bridge terminated\n"); /** * Process MCP JSON-RPC request * * @param array $request JSON-RPC request * @return array JSON-RPC response */ function process_mcp_request($request) { global $metasync_mcp_server; $method = $request['method'] ?? ''; $params = $request['params'] ?? []; $id = $request['id'] ?? null; switch ($method) { case 'initialize': return handle_initialize($id, $params); case 'notifications/initialized': // Client confirms initialization - no response needed return null; case 'tools/list': return handle_tools_list($id); case 'tools/call': return handle_tools_call($id, $params); case 'ping': return [ 'jsonrpc' => '2.0', 'id' => $id, 'result' => [ 'status' => 'ok', 'timestamp' => time() ] ]; default: throw new Exception("Unknown method: $method"); } } /** * Handle initialize request */ function handle_initialize($id, $params) { $client_info = $params['clientInfo'] ?? []; fwrite(STDERR, "Client connected: " . json_encode($client_info) . "\n"); return [ 'jsonrpc' => '2.0', 'id' => $id, 'result' => [ 'protocolVersion' => '2024-11-05', 'capabilities' => [ 'tools' => (object)[] ], 'serverInfo' => [ 'name' => 'wordpress-metasync', 'version' => defined('METASYNC_VERSION') ? METASYNC_VERSION : '2.0.0' ] ] ]; } /** * Handle tools/list request */ function handle_tools_list($id) { global $metasync_mcp_server; $tools = []; $tool_objects = $metasync_mcp_server->get_tools(); fwrite(STDERR, "Listing " . count($tool_objects) . " tools\n"); foreach ($tool_objects as $tool) { $tools[] = [ 'name' => $tool->get_name(), 'description' => $tool->get_description(), 'inputSchema' => $tool->get_input_schema() ]; } return [ 'jsonrpc' => '2.0', 'id' => $id, 'result' => [ 'tools' => $tools ] ]; } /** * Handle tools/call request */ function handle_tools_call($id, $params) { global $metasync_mcp_server; $tool_name = $params['name'] ?? ''; $arguments = $params['arguments'] ?? []; if (empty($tool_name)) { throw new Exception('Tool name is required'); } fwrite(STDERR, "Calling tool: $tool_name\n"); // Find tool $tool = $metasync_mcp_server->get_tool($tool_name); if (!$tool) { throw new Exception("Tool not found: $tool_name"); } // Execute tool $start_time = microtime(true); $result = $tool->execute($arguments); $execution_time = round((microtime(true) - $start_time) * 1000, 2); fwrite(STDERR, "Tool executed in {$execution_time}ms\n"); // Format result as MCP response $content = []; if (is_array($result) || is_object($result)) { $content[] = [ 'type' => 'text', 'text' => json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) ]; } else { $content[] = [ 'type' => 'text', 'text' => (string)$result ]; } return [ 'jsonrpc' => '2.0', 'id' => $id, 'result' => [ 'content' => $content, 'isError' => false ] ]; }