Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .cursor/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"mcpServers": {
"rdb-local": {
"command": "npx",
"args": [ "-y", "@automattic/mcp-wordpress-remote@latest" ],
"env": {
"WP_API_URL": "http://localhost:8888/",
"JWT_TOKEN": "{{ JWT token from WordPress MCP settings }}",
"LOG_FILE": "/tmp/mcp-remote-data-blocks-local.log"
}
}
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ vendor/
!.idea/runConfigurations/
.vscode/*
!.vscode/launch.json
!.vscode/mcp.json
.zed
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20
22
4 changes: 3 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html/wp-content/plugins/remote-data-blocks": "${workspaceFolder}/"
"/var/www/html/wp-content/plugins/remote-data-blocks": "${workspaceFolder}/",
"/var/www/html/wp-content/plugins/wp-feature-api": "${workspaceFolder}/../wp-feature-api",
"/var/www/html/wp-content/plugins/wordpress-mcp": "${workspaceFolder}/../wordpress-mcp"
}
},
{
Expand Down
13 changes: 13 additions & 0 deletions .vscode/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"servers": {
"rdb-local": {
"command": "npx",
"args": [ "-y", "@automattic/mcp-wordpress-remote@latest" ],
"env": {
"WP_API_URL": "http://localhost:8888/",
"JWT_TOKEN": "{{ JWT token from WordPress MCP settings }}",
"LOG_FILE": "/tmp/mcp-remote-data-blocks-local.log"
}
}
}
}
4 changes: 3 additions & 1 deletion .wp-env.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"plugins": [
".",
"https://downloads.wordpress.org/plugin/query-monitor.latest-stable.zip",
"https://downloads.wordpress.org/plugin/redis-cache.latest-stable.zip"
"https://downloads.wordpress.org/plugin/redis-cache.latest-stable.zip",
"https://github.com/Automattic/wp-feature-api/releases/download/0.1.5/wp-feature-api.zip",
"https://github.com/Automattic/wordpress-mcp/releases/download/v0.2.0/wordpress-mcp.zip"
]
}
139 changes: 139 additions & 0 deletions inc/Integrations/Mcp/Features/ListDataSourcesFeature.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php declare(strict_types = 1);

namespace RemoteDataBlocks\Integrations\Mcp\Features;

use RemoteDataBlocks\Store\DataSource\DataSourceConfigManager;
use RemoteDataBlocks\Snippet\Snippet;
use WP_REST_Request;

use function add_action;
use function wp_register_feature;

defined( 'ABSPATH' ) || exit();

/**
* Feature that lists all Remote Data Block data sources through the WP Feature API.
*
* This feature provides access to all configured data sources including those from
* code, constants, and storage, with optional filtering capabilities and code snippets.
*/
class ListDataSourcesFeature {

/**
* Initialize and register the feature with the WP Feature API.
*/
public static function init(): void {
// Hook into the feature API initialization
add_action( 'wp_feature_api_init', [ __CLASS__, 'register_feature' ] );
}

/**
* Register the list data sources feature.
*/
public static function register_feature(): void {
/**
* @psalm-suppress UndefinedFunction
*/
wp_register_feature( [
'id' => 'rdb-list-data-sources',
'name' => 'List Remote Data Block data sources',
'description' => 'List all Remote Data Block data sources with optional filtering by service type or block enablement status, including code snippets',
'callback' => [ __CLASS__, 'handle_request' ],
'is_eligible' => '__return_true',
'permission_callback' => '__return_true',
'input_schema' => [
'type' => 'object',
'properties' => [
'service' => [
'type' => 'string',
'description' => 'Filter by service name (e.g., "airtable", "google-sheets", "shopify")',
'enum' => [
'airtable',
'generic-http',
'google-sheets',
'shopify',
],
],
'enable_blocks' => [
'type' => 'boolean',
'description' => 'Filter by blocks enabled status (true shows only sources with blocks enabled, false shows only disabled)',
],
'include_snippets' => [
'type' => 'boolean',
'description' => 'Include code snippets for each data source (default: true)',
'default' => true,
],
],
'additionalProperties' => false,
],
] );
}

/**
* Handle the feature request and return data sources.
*/
public static function handle_request( WP_REST_Request $request ): array {
// Validate and sanitize parameters
$params = $request->get_params();
$filters = [];

if ( isset( $params['service'] ) && is_string( $params['service'] ) ) {
$filters['service'] = sanitize_text_field( $params['service'] );
}

if ( isset( $params['enable_blocks'] ) && is_bool( $params['enable_blocks'] ) ) {
$filters['enable_blocks'] = $params['enable_blocks'];
}

$include_snippets = $params['include_snippets'] ?? true;
$data_sources = DataSourceConfigManager::get_all( $filters );

// Handle errors
if ( is_wp_error( $data_sources ) ) {
return [
'success' => false,
'error' => $data_sources->get_error_message(),
];
}

return [
'success' => true,
'data' => array_map(
function ( array $data_source ) use ( $include_snippets ): array {
return self::format_data_source( $data_source, $include_snippets );
},
$data_sources
),
'count' => count( $data_sources ),
];
}

/**
* Format data source
*/
private static function format_data_source( array $data_source, bool $include_snippets = true ): array {
// Add code snippets if requested and data source has UUID
$code_snippets = [];
if ( $include_snippets && isset( $data_source['uuid'] ) ) {
$code_snippets = Snippet::generate_snippets( $data_source['uuid'] );

// Only add snippets if generation was successful
if ( is_wp_error( $code_snippets ) ) {
$code_snippets = [];
}
}

return [
'uuid' => $data_source['uuid'] ?? null,
'display_name' => $data_source['service_config']['display_name'] ?? $data_source['display_name'] ?? null,
'code_snippets' => array_map(
function ( Snippet $snippet ): array {
return $snippet->jsonSerialize();
},
$code_snippets
),
'config_source' => $data_source['config_source'] ?? 'unknown',
'service' => $data_source['service'] ?? null,
];
}
}
12 changes: 12 additions & 0 deletions inc/Integrations/Mcp/Mcp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php declare(strict_types = 1);

namespace RemoteDataBlocks\Integrations\Mcp;

defined( 'ABSPATH' ) || exit();

class Mcp {
public static function init(): void {
Features\ListDataSourcesFeature::init();
Prompts\ListDataSourcesPrompt::init();
}
}
55 changes: 55 additions & 0 deletions inc/Integrations/Mcp/Prompts/ListDataSourcesPrompt.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php declare(strict_types=1);

namespace RemoteDataBlocks\Integrations\Mcp\Prompts;

use Automattic\WordpressMcp\Core\RegisterMcpPrompt;
use function add_action;

defined( 'ABSPATH' ) || exit();

/**
* Class ListDataSourcesPrompt
*
* Prompt for listing data sources
*/
class ListDataSourcesPrompt {
public static function init(): void {
add_action( 'wordpress_mcp_init', [ __CLASS__, 'register_prompt' ] );
}

public static function register_prompt(): void {
/**
* @psalm-suppress UndefinedClass
*/
new RegisterMcpPrompt(
[
'name' => 'list-remote-data-blocks-data-sources',
'description' => 'List Remote Data Blocks data sources.',
'arguments' => [
[
'name' => 'data-source-uuid',
'description' => 'The UUID of the Remote Data Blocks data source to retrieve (optional)',
'required' => false,
'type' => 'string',
],
],
],
[
[
'role' => 'user',
'content' => [
'type' => 'text',
'text' => 'List all registered Remote Data Blocks data source',
],
],
[
'role' => 'user',
'content' => [
'type' => 'text',
'text' => 'List the Remote Data Blocks data source with the UUID: {{data_source_uuid}}',
],
],
],
);
}
}
1 change: 1 addition & 0 deletions remote-data-blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
Integrations\Airtable\AirtableIntegration::init();
Integrations\Google\Sheets\GoogleSheetsIntegration::init();
Integrations\Shopify\ShopifyIntegration::init();
Integrations\Mcp\Mcp::init();
Integrations\VipBlockDataApi\VipBlockDataApi::init();

// REST endpoints
Expand Down
Loading