|
| 1 | +# MCP Access |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +The MCP Access experiment wires a site up to the [MCP Adapter](https://wordpress.org/plugins/mcp-adapter/) companion plugin and gives site owners control over which abilities are exposed to AI agents over the Model Context Protocol. Enabling the experiment installs and activates the MCP Adapter plugin from WordPress.org if it is not already active. |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +### For End Users |
| 10 | + |
| 11 | +When enabled, a new admin page appears under `Tools > MCP Access`. The page provides: |
| 12 | + |
| 13 | +- The MCP server **endpoint URL**, read from the adapter's registered servers |
| 14 | +- The adapter's **install state**, with a manual install/activate button when it is missing or inactive |
| 15 | +- A table of registered abilities with per-ability **expose/hide** controls; a **Status** column shows which abilities are overridden, and toggling a checkbox back restores the default |
| 16 | + |
| 17 | +This plugin's own abilities (`ai/*`) are exposed by default, since they only register while the feature or experiment providing them is enabled. Other abilities keep their developer-declared visibility unless the site owner changes them. Two groups are not listed: the adapter's own default-server abilities (`mcp-adapter/*`), which are the server's machinery and are active whenever the server runs, and deprecated aliases, which stay hidden because their replacement is listed instead. |
| 18 | + |
| 19 | +While the experiment is enabled, the MCP Adapter plugin is installed and activated automatically on the first admin page load by a user who can install plugins. The attempt runs once per experiment activation: deactivating the adapter afterwards is respected, and toggling the experiment off and on runs the install again. Exposure overrides are only enforced while the experiment is enabled. |
| 20 | + |
| 21 | +### For Developers |
| 22 | + |
| 23 | +The experiment consists of: |
| 24 | + |
| 25 | +1. **Experiment class** (`WordPress\AI\Experiments\MCP_Adapter\MCP_Adapter`): Boots the exposure filter, REST route, admin page, and installer |
| 26 | +2. **Auto-installer** (`WordPress\AI\Experiments\MCP_Adapter\Plugin_Installer`): Installs and activates the adapter from WordPress.org once per experiment enable, via `plugins_api()` and `Plugin_Upgrader` |
| 27 | +3. **Exposure overrides** (`WordPress\AI\Experiments\MCP_Adapter\Exposure_Overrides`): Injects saved overrides into ability registration meta so the adapter's default server honors them |
| 28 | +4. **REST controller** (`WordPress\AI\Experiments\MCP_Adapter\Settings_Controller`): Powers the admin page over `ai/v1/mcp/settings` |
| 29 | +5. **React admin app** (`src/experiments/mcp-adapter/`): Renders the install state and the ability exposure table |
| 30 | + |
| 31 | +## Architecture & Implementation |
| 32 | + |
| 33 | +### Key Hooks & Entry Points |
| 34 | + |
| 35 | +`WordPress\AI\Experiments\MCP_Adapter\MCP_Adapter::register()` wires: |
| 36 | + |
| 37 | +- `wp_register_ability_args` (via `Exposure_Overrides`) to apply exposure defaults and saved overrides as `meta.mcp.public` |
| 38 | +- `rest_api_init` to register the `ai/v1/mcp/settings` route |
| 39 | +- `admin_menu` and `admin_enqueue_scripts` for the Tools page |
| 40 | +- `admin_init` (via `Plugin_Installer`) for the once-per-enable install attempt |
| 41 | + |
| 42 | +### Exposure Flow |
| 43 | + |
| 44 | +1. The MCP Adapter resolves an ability's exposure from `meta.mcp.public`, falling back to `meta.public`. |
| 45 | +2. Overrides saved on the MCP Access screen are stored as an ability-name map and injected into that meta key at registration time, so the adapter picks them up with no hard dependency between the plugins. Class-based abilities extending `Abstract_Ability` merge the filtered meta over the meta their class declares. |
| 46 | +3. Without an override, `ai/*` abilities are injected as exposed, and abilities whose meta has a `deprecated` key are injected as hidden. Everything else is left untouched. |
| 47 | +4. The default is captured before injection, so the screen can always report and restore it. |
| 48 | +5. Overrides for the reserved `mcp-adapter/*` namespace and for deprecated aliases are never listed, accepted, or applied. |
| 49 | + |
| 50 | +### Install Flow |
| 51 | + |
| 52 | +1. On `admin_init`, if the current enable cycle has not been handled and the visitor can activate plugins, the installer resolves the adapter's install state. |
| 53 | +2. An active copy (including one installed under a non-standard directory, detected via the adapter's classes) marks the cycle handled with no action. |
| 54 | +3. Otherwise the installer claims the cycle atomically, downloads the plugin from WordPress.org if missing, and activates it. Success or failure is recorded; a failure is surfaced on the MCP Access screen with the manual button as the retry path. |
| 55 | +4. Disabling the experiment clears the marker, so re-enabling runs a fresh attempt. |
| 56 | + |
| 57 | +### Data Storage |
| 58 | + |
| 59 | +The experiment uses two options: |
| 60 | + |
| 61 | +- `wpai_mcp_exposed_abilities`: exposure override map (`ability_name -> bool`); abilities not present keep their default |
| 62 | +- `wpai_mcp_adapter_autoinstall_handled`: once-per-enable marker (`'1'` on success, the error message on failure) |
| 63 | + |
| 64 | +### Filters |
| 65 | + |
| 66 | +- `wpai_mcp_adapter_plugin_slug`: Filters the WordPress.org slug of the companion plugin (useful for testing the install flow against a stand-in plugin) |
| 67 | +- `wpai_pre_mcp_adapter_autoinstall`: Short-circuits the automatic install; return `true` to report success or a `WP_Error` to report failure without touching the filesystem |
0 commit comments