| 1 |
<?php |
| 2 |
/** |
| 3 |
* Publishes the registry's capabilities through the `wordpress/mcp-adapter` |
| 4 |
* plugin, when that plugin is installed (spec 044, FR-010/FR-012). |
| 5 |
* |
| 6 |
* Relocated from `MCP::register_server()`. This is now the ONLY file in the |
| 7 |
* module that references the adapter's classes — the top-level imports used to |
| 8 |
* sit in MCP.php, which forced the whole module to care about a soft dependency |
| 9 |
* it mostly does not use. |
| 10 |
* |
| 11 |
* The adapter's route (`/wp-json/templately/mcp`) and the native server's |
| 12 |
* (`/wp-json/templately/v1/mcp`) are distinct paths and both may serve |
| 13 |
* concurrently — neither registration displaces the other (FR-007). |
| 14 |
* |
| 15 |
* @package Templately\Modules\WpAbilitiesApi\Adapters |
| 16 |
*/ |
| 17 |
|
| 18 |
namespace Templately\Modules\WpAbilitiesApi\Adapters; |
| 19 |
|
| 20 |
use Templately\Modules\McpCore\Registry\ToolRegistry; |
| 21 |
use WP\MCP\Core\McpAdapter; |
| 22 |
use WP\MCP\Transport\HttpTransport; |
| 23 |
|
| 24 |
class McpAdapterBridge { |
| 25 |
|
| 26 |
const SERVER_ID = 'templately'; |
| 27 |
const NAMESPACE = 'templately'; |
| 28 |
const ROUTE = 'mcp'; |
| 29 |
|
| 30 |
/** |
| 31 |
* Whether the adapter path can serve at all: WordPress core's Abilities API |
| 32 |
* (core 6.9+) AND the separately-installed mcp-adapter plugin. Both are soft |
| 33 |
* dependencies, never bundled via Composer. |
| 34 |
* |
| 35 |
* This is ONLY a statement about the adapter transport. It used to be |
| 36 |
* `MCP::is_available()` and gated the whole feature, which meant every |
| 37 |
* capability was unreachable on the large majority of sites running this |
| 38 |
* plugin — Templately supports WordPress 5.0+. Since 046 the built-in server |
| 39 |
* serves the same capabilities regardless of what this returns; the |
| 40 |
* Settings → MCP tab reads it purely to decide whether to offer the |
| 41 |
* "Install & Activate" CTA. |
| 42 |
* |
| 43 |
* @return bool |
| 44 |
*/ |
| 45 |
public static function is_available(): bool { |
| 46 |
return AbilitiesBridge::is_available() && self::has_adapter(); |
| 47 |
} |
| 48 |
|
| 49 |
/** |
| 50 |
* Whether the separately-installed mcp-adapter plugin is present, and nothing |
| 51 |
* else. A soft dependency, never bundled via Composer. |
| 52 |
* |
| 53 |
* Deliberately separate from {@see self::is_available()}: the adapter path |
| 54 |
* needs the Abilities API too (its server is registered by ability id), but |
| 55 |
* "is the plugin installed" and "can the adapter path serve" are different |
| 56 |
* questions, and collapsing them is what produced the single all-or-nothing |
| 57 |
* gate 046 removed. |
| 58 |
* |
| 59 |
* @return bool |
| 60 |
*/ |
| 61 |
public static function has_adapter(): bool { |
| 62 |
return class_exists( McpAdapter::class ); |
| 63 |
} |
| 64 |
|
| 65 |
public static function attach(): void { |
| 66 |
if ( ! class_exists( McpAdapter::class ) ) { |
| 67 |
return; |
| 68 |
} |
| 69 |
|
| 70 |
McpAdapter::instance(); |
| 71 |
add_action( 'mcp_adapter_init', [ self::class, 'register_server' ] ); |
| 72 |
} |
| 73 |
|
| 74 |
/** |
| 75 |
* @param McpAdapter $adapter |
| 76 |
*/ |
| 77 |
public static function register_server( $adapter ): void { |
| 78 |
if ( ! is_object( $adapter ) || ! method_exists( $adapter, 'create_server' ) ) { |
| 79 |
return; |
| 80 |
} |
| 81 |
|
| 82 |
$adapter->create_server( |
| 83 |
self::SERVER_ID, |
| 84 |
self::NAMESPACE, |
| 85 |
self::ROUTE, |
| 86 |
__( 'Templately', 'templately' ), |
| 87 |
__( 'Search, preview, and import Templately designs on this WordPress site.', 'templately' ), |
| 88 |
defined( 'TEMPLATELY_VERSION' ) ? TEMPLATELY_VERSION : '1.0.0', |
| 89 |
[ HttpTransport::class ], |
| 90 |
null, |
| 91 |
null, |
| 92 |
// Derived from the registry, never a constant (FR-010). Listing the |
| 93 |
// abilities explicitly surfaces them directly in the adapter's tool |
| 94 |
// listing rather than behind its default discover/execute indirection. |
| 95 |
ToolRegistry::get_instance()->ids() |
| 96 |
); |
| 97 |
} |
| 98 |
} |
| 99 |
|