PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.6.19
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.6.19
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
metasync / wp-mcp-server / class-mcp-tool-registry.php

class-mcp-tool-registry.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.6.19, at wp-mcp-server/class-mcp-tool-registry.php

248 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MCP Tool Registry
4 *
5 * Manages registration, storage, and retrieval of MCP tools.
6 * Provides the central registry for all available tools.
7 *
8 * @package MetaSync
9 * @subpackage MCP_Server
10 */
11
12 if (!defined('ABSPATH')) {
13 exit;
14 }
15
16 class MCP_Tool_Registry {
17
18 /**
19 * Registered tools
20 *
21 * @var array Array of MCP_Tool_Base instances
22 */
23 private $tools = [];
24
25 /**
26 * Cache key for tools list
27 */
28 const CACHE_KEY = 'metasync_mcp_tools_list';
29
30 /**
31 * Cache expiration (5 minutes)
32 */
33 const CACHE_EXPIRATION = 300;
34
35 /**
36 * Singleton instance
37 *
38 * @var MCP_Tool_Registry
39 */
40 private static $instance = null;
41
42 /**
43 * Get singleton instance
44 *
45 * @return MCP_Tool_Registry
46 */
47 public static function get_instance() {
48 if (self::$instance === null) {
49 self::$instance = new self();
50 }
51 return self::$instance;
52 }
53
54 /**
55 * Constructor
56 */
57 private function __construct() {
58 // Private constructor for singleton
59 }
60
61 /**
62 * Register a tool
63 *
64 * @param MCP_Tool_Base $tool Tool instance
65 * @return bool
66 * @throws InvalidArgumentException If tool is invalid
67 */
68 public function register_tool(MCP_Tool_Base $tool) {
69 $name = $tool->get_name();
70
71 // Validate tool name
72 if (empty($name)) {
73 throw new InvalidArgumentException('Tool name cannot be empty');
74 }
75
76 // Check for duplicate
77 if (isset($this->tools[$name])) {
78 throw new InvalidArgumentException("Tool '{$name}' is already registered");
79 }
80
81 // Validate tool has required methods
82 if (!method_exists($tool, 'execute')) {
83 throw new InvalidArgumentException("Tool '{$name}' must implement execute() method");
84 }
85
86 // Store tool
87 $this->tools[$name] = $tool;
88
89 // Fire action
90 do_action('metasync_mcp_tool_registered', $name, $tool);
91
92 return true;
93 }
94
95 /**
96 * Unregister a tool
97 *
98 * @param string $name Tool name
99 * @return bool
100 */
101 public function unregister_tool($name) {
102 if (!isset($this->tools[$name])) {
103 return false;
104 }
105
106 unset($this->tools[$name]);
107
108 // Clear cache
109 delete_transient(self::CACHE_KEY);
110
111 // Fire action
112 do_action('metasync_mcp_tool_unregistered', $name);
113
114 return true;
115 }
116
117 /**
118 * Get a specific tool
119 *
120 * @param string $name Tool name
121 * @return MCP_Tool_Base|null
122 */
123 public function get_tool($name) {
124 return isset($this->tools[$name]) ? $this->tools[$name] : null;
125 }
126
127 /**
128 * Get all registered tools
129 *
130 * @return array Array of MCP_Tool_Base instances
131 */
132 public function get_all_tools() {
133 return $this->tools;
134 }
135
136 /**
137 * Get tools list (for tools/list MCP method)
138 *
139 * @param bool $use_cache Whether to use cached list
140 * @return array
141 */
142 public function get_tools_list($use_cache = true) {
143 // Try cache first
144 if ($use_cache) {
145 $cached = get_transient(self::CACHE_KEY);
146 if ($cached !== false) {
147 return $cached;
148 }
149 }
150
151 $tools_list = [];
152
153 foreach ($this->tools as $name => $tool) {
154 $tools_list[] = $tool->get_definition();
155 }
156
157 // Apply filter to allow modifications
158 $tools_list = apply_filters('metasync_mcp_tools_list', $tools_list);
159
160 // Cache the result
161 set_transient(self::CACHE_KEY, $tools_list, self::CACHE_EXPIRATION);
162
163 return $tools_list;
164 }
165
166 /**
167 * Execute a tool
168 *
169 * @param string $name Tool name
170 * @param array $params Tool parameters
171 * @return array Result
172 * @throws Exception If tool not found or execution fails
173 */
174 public function execute_tool($name, $params = []) {
175 $tool = $this->get_tool($name);
176
177 if (!$tool) {
178 throw new Exception(sprintf("Tool not found: %s", esc_html($name)));
179 }
180
181 // Execute tool (tools validate their own params internally)
182 $start_time = microtime(true);
183 do_action('metasync_mcp_tool_before_execute', $name, $params);
184 $result = $tool->execute($params);
185 $execution_time = microtime(true) - $start_time;
186
187 // Log execution
188 $this->log_execution($name, $params, $result, $execution_time);
189
190 // Fire action
191 do_action('metasync_mcp_tool_executed', $name, $params, $result, $execution_time);
192
193 return $result;
194 }
195
196 /**
197 * Check if tool exists
198 *
199 * @param string $name Tool name
200 * @return bool
201 */
202 public function has_tool($name) {
203 return isset($this->tools[$name]);
204 }
205
206 /**
207 * Get tool count
208 *
209 * @return int
210 */
211 public function get_tool_count() {
212 return count($this->tools);
213 }
214
215 /**
216 * Clear all tools
217 *
218 * @return void
219 */
220 public function clear_all() {
221 $this->tools = [];
222 delete_transient(self::CACHE_KEY);
223 }
224
225 /**
226 * Log tool execution
227 *
228 * @param string $name Tool name
229 * @param array $params Parameters
230 * @param mixed $result Result
231 * @param float $execution_time Execution time in seconds
232 */
233 private function log_execution($name, $params, $result, $execution_time) {
234 // Only log in debug mode or if execution took > 1 second
235 if (!WP_DEBUG && $execution_time < 1.0) {
236 return;
237 }
238
239 $log_message = sprintf(
240 'MCP Tool Executed: %s (%.3fs)',
241 $name,
242 $execution_time
243 );
244
245 error_log($log_message);
246 }
247 }
248