v2.2.0: includes/MCP/Registry.php
This commit is contained in:
@@ -23,9 +23,17 @@ class Registry {
|
||||
public function getHandler(string $name): ?callable {
|
||||
if (!isset($this->tools[$name])) return null;
|
||||
$h = $this->tools[$name]['handler'];
|
||||
if (is_callable($h)) return $h;
|
||||
[$class, $method] = explode('::', $h);
|
||||
return [new $class(), $method];
|
||||
// Already a closure or array callable
|
||||
if ($h instanceof \Closure) return $h;
|
||||
if (is_array($h)) return $h;
|
||||
// String handler: 'Namespace\\Class::method' — resolve to static callable
|
||||
if (is_string($h) && str_contains($h, '::')) {
|
||||
[$class, $method] = explode('::', $h, 2);
|
||||
return function(array $args) use ($class, $method) {
|
||||
return $class::$method($args);
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getTool(string $name): ?array {
|
||||
@@ -47,6 +55,13 @@ class Registry {
|
||||
$this->registerSiteTools();
|
||||
if (class_exists('WooCommerce')) $this->registerWooCommerceTools();
|
||||
if (defined('ELEMENTOR_VERSION')) $this->registerElementorTools();
|
||||
$this->registerFileManagerTools();
|
||||
$this->registerEmailTools();
|
||||
$this->registerTransientTools();
|
||||
$this->registerWidgetTools();
|
||||
$this->registerCliTools();
|
||||
$this->registerRawSqlTools();
|
||||
$this->registerThemeDiscoveryTools();
|
||||
do_action('asktam_mcp_register_tools', $this);
|
||||
}
|
||||
|
||||
@@ -158,10 +173,62 @@ class Registry {
|
||||
['name'=>'wc_update_product','description'=>'Update a WooCommerce product.','handler'=>'AskTamMCP\\Tools\\WooTools::updateProduct','scope'=>'woocommerce','inputSchema'=>['type'=>'object','required'=>['product_id'],'properties'=>['product_id'=>['type'=>'integer'],'name'=>['type'=>'string'],'regular_price'=>['type'=>'string'],'sale_price'=>['type'=>'string'],'status'=>['type'=>'string'],'stock_quantity'=>['type'=>'integer'],'description'=>['type'=>'string']]]],
|
||||
['name'=>'wc_list_orders','description'=>'List WooCommerce orders.','handler'=>'AskTamMCP\\Tools\\WooTools::listOrders','scope'=>'read','inputSchema'=>['type'=>'object','properties'=>['status'=>['type'=>'string','default'=>'any'],'per_page'=>['type'=>'integer','default'=>20],'page'=>['type'=>'integer','default'=>1],'customer_id'=>['type'=>'integer']]]],
|
||||
['name'=>'wc_get_order','description'=>'Get a WooCommerce order.','handler'=>'AskTamMCP\\Tools\\WooTools::getOrder','scope'=>'read','inputSchema'=>['type'=>'object','required'=>['order_id'],'properties'=>['order_id'=>['type'=>'integer']]]],
|
||||
['name'=>'wc_update_order_status','description'=>'Update a WooCommerce order status.','handler'=>'AskTamMCP\\Tools\\WooTools::updateOrderStatus','scope'=>'woocommerce','inputSchema'=>['type'=>'object','required'=>['order_id','status'],'properties'=>['order_id'=>['type'=>'integer'],'status'=>['type'=>'string','enum'=>['pending','processing','on-hold','completed','cancelled','refunded','failed']]]]],
|
||||
['name'=>'wc_update_order_status','description'=>'Update WooCommerce order status.','handler'=>'AskTamMCP\\Tools\\WooTools::updateOrderStatus','scope'=>'woocommerce','inputSchema'=>['type'=>'object','required'=>['order_id','status'],'properties'=>['order_id'=>['type'=>'integer'],'status'=>['type'=>'string','enum'=>['pending','processing','on-hold','completed','cancelled','refunded','failed']]]]],
|
||||
['name'=>'wc_list_customers','description'=>'List WooCommerce customers.','handler'=>'AskTamMCP\\Tools\\WooTools::listCustomers','scope'=>'read','inputSchema'=>['type'=>'object','properties'=>['per_page'=>['type'=>'integer','default'=>20],'page'=>['type'=>'integer','default'=>1],'search'=>['type'=>'string']]]],
|
||||
['name'=>'wc_get_store_stats','description'=>'Get WooCommerce store stats.','handler'=>'AskTamMCP\\Tools\\WooTools::getStoreStats','scope'=>'read','inputSchema'=>['type'=>'object','properties'=>['period'=>['type'=>'string','enum'=>['day','week','month','year'],'default'=>'month']]]],
|
||||
];
|
||||
foreach ($tools as $tool) $this->register($tool);
|
||||
}
|
||||
|
||||
private function registerFileManagerTools(): void {
|
||||
$this->register(['name'=>'fs_list_dir','description'=>'List files and directories in the uploads folder. Sandboxed to /wp-content/uploads/.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\FileManagerTools::listDir','inputSchema'=>['type'=>'object','properties'=>['path'=>['type'=>'string','description'=>'Relative path within uploads, e.g. "2024/01"']]]]);
|
||||
$this->register(['name'=>'fs_read_file','description'=>'Read a file from the uploads directory. Returns text content or base64 for binary files.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\FileManagerTools::readFile','inputSchema'=>['type'=>'object','required'=>['path'],'properties'=>['path'=>['type'=>'string']]]]);
|
||||
$this->register(['name'=>'fs_delete_file','description'=>'Delete a file from the uploads directory.','scope'=>'write','handler'=>'AskTamMCP\\Tools\\FileManagerTools::deleteFile','inputSchema'=>['type'=>'object','required'=>['path'],'properties'=>['path'=>['type'=>'string']]]]);
|
||||
$this->register(['name'=>'fs_delete_dir','description'=>'Delete a directory and all its contents from uploads. Cannot delete uploads root.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\FileManagerTools::deleteDirectory','inputSchema'=>['type'=>'object','required'=>['path'],'properties'=>['path'=>['type'=>'string']]]]);
|
||||
$this->register(['name'=>'fs_uploads_info','description'=>'Get uploads directory path, URL, and total disk usage.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\FileManagerTools::getUploadsInfo','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
}
|
||||
|
||||
private function registerEmailTools(): void {
|
||||
$this->register(['name'=>'email_send_test','description'=>'Send a test email to verify WordPress mail is working.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\EmailTools::sendTestEmail','inputSchema'=>['type'=>'object','properties'=>['to'=>['type'=>'string'],'subject'=>['type'=>'string'],'message'=>['type'=>'string']]]]);
|
||||
$this->register(['name'=>'email_get_config','description'=>'Get the current WordPress email configuration: admin email, SMTP settings, active mail plugins.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\EmailTools::getEmailConfig','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
$this->register(['name'=>'email_list_log','description'=>'List recent emails from WP Mail SMTP log (if plugin is active).','scope'=>'read','handler'=>'AskTamMCP\\Tools\\EmailTools::listEmailLog','inputSchema'=>['type'=>'object','properties'=>['per_page'=>['type'=>'integer','default'=>20]]]]);
|
||||
}
|
||||
|
||||
private function registerTransientTools(): void {
|
||||
$this->register(['name'=>'transient_get','description'=>'Get a WordPress transient value by key.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\TransientTools::getTransient','inputSchema'=>['type'=>'object','required'=>['key'],'properties'=>['key'=>['type'=>'string']]]]);
|
||||
$this->register(['name'=>'transient_set','description'=>'Set a WordPress transient with optional expiration.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\TransientTools::setTransient','inputSchema'=>['type'=>'object','required'=>['key','value'],'properties'=>['key'=>['type'=>'string'],'value'=>[],'expiration'=>['type'=>'integer','description'=>'Seconds until expiry. Default 3600.']]]]);
|
||||
$this->register(['name'=>'transient_delete','description'=>'Delete a WordPress transient by key.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\TransientTools::deleteTransient','inputSchema'=>['type'=>'object','required'=>['key'],'properties'=>['key'=>['type'=>'string']]]]);
|
||||
$this->register(['name'=>'transient_list','description'=>'List WordPress transients, optionally filtered by key prefix/search.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\TransientTools::listTransients','inputSchema'=>['type'=>'object','properties'=>['search'=>['type'=>'string']]]]);
|
||||
$this->register(['name'=>'transient_flush_expired','description'=>'Delete all expired transients from the database.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\TransientTools::flushExpiredTransients','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
}
|
||||
|
||||
private function registerWidgetTools(): void {
|
||||
$this->register(['name'=>'widget_list_areas','description'=>'List all registered WordPress widget areas (sidebars).','scope'=>'read','handler'=>'AskTamMCP\\Tools\\WidgetTools::listWidgetAreas','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
$this->register(['name'=>'widget_get_area','description'=>'Get all widgets in a specific widget area with their settings.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\WidgetTools::getWidgetArea','inputSchema'=>['type'=>'object','required'=>['sidebar_id'],'properties'=>['sidebar_id'=>['type'=>'string']]]]);
|
||||
$this->register(['name'=>'widget_list_registered','description'=>'List all registered WordPress widget types.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\WidgetTools::listRegisteredWidgets','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
$this->register(['name'=>'widget_update_area','description'=>'Reorder or set the widget list for a widget area.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\WidgetTools::updateWidgetArea','inputSchema'=>['type'=>'object','required'=>['sidebar_id','widget_ids'],'properties'=>['sidebar_id'=>['type'=>'string'],'widget_ids'=>['type'=>'array','items'=>['type'=>'string']]]]]);
|
||||
$this->register(['name'=>'widget_remove','description'=>'Remove a specific widget from a widget area.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\WidgetTools::removeWidgetFromArea','inputSchema'=>['type'=>'object','required'=>['sidebar_id','widget_id'],'properties'=>['sidebar_id'=>['type'=>'string'],'widget_id'=>['type'=>'string']]]]);
|
||||
}
|
||||
|
||||
private function registerCliTools(): void {
|
||||
$this->register(['name'=>'cli_run','description'=>'Run a WP-CLI command (admin scope). Allowed: cache, cron, db, media, option, plugin, post, rewrite, theme, transient, user, widget, elementor, wc, yoast.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\CliTools::run','inputSchema'=>['type'=>'object','required'=>['command'],'properties'=>['command'=>['type'=>'string','description'=>'WP-CLI command without the "wp" prefix, e.g. "cache flush" or "elementor flush-css"']]]]);
|
||||
$this->register(['name'=>'cli_available','description'=>'Check if WP-CLI is available on the server and list allowed commands.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\CliTools::isAvailable','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
}
|
||||
|
||||
private function registerRawSqlTools(): void {
|
||||
$this->register(['name'=>'sql_query','description'=>'Run a SELECT query against the WordPress database (admin scope, must be enabled in Settings).','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\RawSqlTools::query','inputSchema'=>['type'=>'object','required'=>['sql'],'properties'=>['sql'=>['type'=>'string'],'limit'=>['type'=>'integer','default'=>100,'maximum'=>500]]]]);
|
||||
$this->register(['name'=>'sql_list_tables','description'=>'List WordPress database tables with row count and size.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\RawSqlTools::listTables','inputSchema'=>['type'=>'object','properties'=>['prefix'=>['type'=>'string']]]]);
|
||||
$this->register(['name'=>'sql_describe_table','description'=>'Describe the columns of a WordPress database table.','scope'=>'admin','handler'=>'AskTamMCP\\Tools\\RawSqlTools::describeTable','inputSchema'=>['type'=>'object','required'=>['table'],'properties'=>['table'=>['type'=>'string']]]]);
|
||||
}
|
||||
|
||||
private function registerThemeDiscoveryTools(): void {
|
||||
$this->register(['name'=>'theme_elementor_support','description'=>'Check what Elementor features the active theme supports: full-width, canvas, templates, Pro theme builder.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\ThemeDiscoveryTools::getThemeElementorSupport','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
$this->register(['name'=>'theme_widget_areas','description'=>'List all widget areas registered by the active theme.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\ThemeDiscoveryTools::getThemeWidgetAreas','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
$this->register(['name'=>'theme_custom_post_types','description'=>'List all custom post types registered by the theme and active plugins.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\ThemeDiscoveryTools::getThemeCustomPostTypes','inputSchema'=>['type'=>'object','properties'=>['include_builtin'=>['type'=>'boolean','default'=>false]]]]);
|
||||
$this->register(['name'=>'theme_taxonomies','description'=>'List all public taxonomies registered by the theme and active plugins.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\ThemeDiscoveryTools::getThemeTaxonomies','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
$this->register(['name'=>'theme_elementor_tokens','description'=>'Get Elementor kit design tokens: global colors (with CSS vars), typography presets.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\ThemeDiscoveryTools::getElementorKitTokens','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
$this->register(['name'=>'theme_woodmart_elements','description'=>'Discover WoodMart theme custom Elementor widgets, shortcodes, and widget areas. Returns nothing if WoodMart is not active.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\ThemeDiscoveryTools::getWoodmartElements','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
$this->register(['name'=>'theme_page_templates','description'=>'List all page templates available in the active theme, including Elementor canvas and full-width.','scope'=>'read','handler'=>'AskTamMCP\\Tools\\ThemeDiscoveryTools::getAllPageTemplates','inputSchema'=>['type'=>'object','properties'=>[]]]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user