Skip to content
Draft
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
2 changes: 1 addition & 1 deletion admin/section/class-convertkit-admin-section-base.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ abstract class ConvertKit_Admin_Section_Base {
*
* @since 1.9.6
*
* @var false|ConvertKit_Settings|ConvertKit_ContactForm7_Settings|ConvertKit_Wishlist_Settings|ConvertKit_Settings_Restrict_Content|ConvertKit_Settings_Broadcasts|ConvertKit_Forminator_Settings
* @var false|ConvertKit_Settings|ConvertKit_ContactForm7_Settings|ConvertKit_Wishlist_Settings|ConvertKit_Settings_Restrict_Content|ConvertKit_Settings_Broadcasts|ConvertKit_Forminator_Settings|ConvertKit_Settings_MCP
*/
public $settings;

Expand Down
176 changes: 176 additions & 0 deletions admin/section/class-convertkit-admin-section-mcp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<?php
/**
* ConvertKit Settings MCP Settings class.
*
* @package ConvertKit
* @author ConvertKit
*/

/**
* Registers MCP Settings that can be edited at Settings > Kit > MCP.
*
* @package ConvertKit
* @author ConvertKit
*/
class ConvertKit_Admin_Section_MCP extends ConvertKit_Admin_Section_Base {

/**
* Constructor.
*
* @since 3.4.0
*/
public function __construct() {

// Define the class that reads/writes settings.
$this->settings = new ConvertKit_Settings_MCP();

// Define the settings key.
$this->settings_key = $this->settings::SETTINGS_NAME;

// Define the programmatic name, Title and Tab Text.
$this->name = 'mcp';
$this->title = __( 'MCP', 'convertkit' );
$this->tab_text = __( 'MCP', 'convertkit' );

// Identify that this is beta functionality.
$this->is_beta = true;

// Define settings sections.
$this->settings_sections = array(
'general' => array(
'title' => $this->title,
'callback' => array( $this, 'print_section_info' ),
'wrap' => true,
),
);

// Register and maybe output notices for this settings screen, and the Intercom messenger.
if ( $this->on_settings_screen( $this->name ) ) {
add_action( 'convertkit_settings_base_render_before', array( $this, 'maybe_output_notices' ) );
}

// Enqueue scripts and CSS.
add_action( 'convertkit_admin_settings_enqueue_scripts', array( $this, 'enqueue_scripts' ) );

parent::__construct();

}

/**
* Enqueues scripts for the Settings > MCP screen.
*
* @since 3.4.0
*
* @param string $section Settings section / tab (general|tools|restrict-content|broadcasts|mcp).
*/
public function enqueue_scripts( $section ) {

// Bail if we're not on the MCP section.
if ( $section !== $this->name ) {
return;
}

// Enqueue JS.
wp_enqueue_script( 'convertkit-admin-settings-conditional-display', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/settings-conditional-display.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );

}

/**
* Registers settings fields for this section.
*
* @since 3.4.0
*/
public function register_fields() {

// Enable.
add_settings_field(
'enabled',
__( 'Enable MCP Server', 'convertkit' ),
array( $this, 'enabled_callback' ),
$this->settings_key,
$this->name,
array(
'name' => 'enabled',
'label_for' => 'enabled',
'label' => __( 'When enabled, allows AI clients to connect to the Kit Plugin using MCP.', 'convertkit' ),
'description' => sprintf(
'%s<br /><code>%s</code>',
__( 'Go to your AI tool to add a custom connector by pasting this URL to connect to this plugin:', 'convertkit' ),
get_site_url() . '/wp-json/kit/mcp/v1'
),
)
);

}

/**
* Prints help info for this section
*
* @since 3.4.0
*/
public function print_section_info() {

?>
<span class="convertkit-beta-label"><?php esc_html_e( 'Beta', 'convertkit' ); ?></span>
<p class="description"><?php esc_html_e( 'Defines whether AI clients can connect to the Kit Plugin using MCP.', 'convertkit' ); ?></p>
<?php

}


/**
* Returns the URL for the ConvertKit documentation for this setting section.
*
* @since 3.4.0
*
* @return string Documentation URL.
*/
public function documentation_url() {

return '#';

}

/**
* Renders the input for the Enable setting.
*
* @since 3.4.0
*
* @param array $args Setting field arguments (name,description).
*/
public function enabled_callback( $args ) {

// Output field.
$this->output_checkbox_field(
$args['name'],
'on',
$this->settings->enabled(),
$args['label'],
$args['description'],
array( 'convertkit-conditional-display' )
);

}

}

// Bootstrap.
add_filter(
'convertkit_admin_settings_register_sections',
function ( $sections ) {

// Don't register the MCP section if the Abilities API is not available (WordPress < 6.9).
if ( ! function_exists( 'wp_register_ability' ) ) {
return $sections;
}

// Don't register the MCP section if PHP 7.4+ is not installed.
if ( version_compare( PHP_VERSION, '7.4', '<' ) ) {
return $sections;
}

$sections['mcp'] = new ConvertKit_Admin_Section_MCP();
return $sections;

}
);
121 changes: 121 additions & 0 deletions includes/class-convertkit-settings-mcp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php
/**
* ConvertKit MCP Settings class.
*
* @package ConvertKit
* @author ConvertKit
*/

/**
* Class to read ConvertKit MCP Settings.
*
* @since 3.4.0
*/
class ConvertKit_Settings_MCP {

/**
* Holds the Settings Key that stores site wide ConvertKit settings
*
* @var string
*
* @since 3.4.0
*/
const SETTINGS_NAME = '_wp_convertkit_settings_mcp';

/**
* Holds the Settings
*
* @var array
*
* @since 3.4.0
*/
private $settings = array();

/**
* Constructor. Reads settings from options table, falling back to defaults
* if no settings exist.
*
* @since 3.4.0
*/
public function __construct() {

// Get Settings.
$settings = get_option( self::SETTINGS_NAME );

// If no Settings exist, falback to default settings.
if ( ! $settings ) {
$this->settings = $this->get_defaults();
} else {
$this->settings = array_merge( $this->get_defaults(), $settings );
}

}

/**
* Returns Plugin settings.
*
* @since 3.4.0
*
* @return array
*/
public function get() {

return $this->settings;

}

/**
* Returns whether the MCP server is enabled.
*
* @since 3.4.0
*
* @return bool
*/
public function enabled() {

return ( $this->settings['enabled'] === 'on' ? true : false );

}

/**
* The default settings, used when the ConvertKit MCP Settings haven't been saved
* e.g. on a new installation.
*
* @since 2.1.0
*
* @return array
*/
public function get_defaults() {

$defaults = array(
'enabled' => '', // blank|on.
);

/**
* The default settings, used when the ConvertKit MCP Settings haven't been saved
* e.g. on a new installation.
*
* @since 3.4.0
*
* @param array $defaults Default settings.
*/
$defaults = apply_filters( 'convertkit_settings_mcp_get_defaults', $defaults );

return $defaults;

}

/**
* Saves the given array of settings to the WordPress options table.
*
* @since 3.4.0
*
* @param array $settings Settings.
*/
public function save( $settings ) {

update_option( self::SETTINGS_NAME, array_merge( $this->get(), $settings ) );

}

}
44 changes: 44 additions & 0 deletions includes/class-wp-convertkit.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public function initialize() {
$this->initialize_cli_cron();
$this->initialize_frontend();
$this->initialize_global();
$this->initialize_mcp();

}

Expand Down Expand Up @@ -218,6 +219,49 @@ private function initialize_global() {

}

/**
* Initializes the MCP server if enabled in the Plugin's settings.
*
* @since 3.4.0
*/
public function initialize_mcp() {

// Bail if the MCP server is not enabled.
$settings = new ConvertKit_Settings_MCP();
if ( ! $settings->enabled() ) {
return;
}

// Bail if the Abilities API is unavailable (WordPress < 6.9).
if ( ! function_exists( 'wp_register_ability' ) ) {
return;
}

// Bail if PHP 7.4+ is not installed, as this is required for the MCP Adapter classes.
if ( version_compare( PHP_VERSION, '7.4', '<' ) ) {
return;
}

// Bail if the WordPress MCP Adapter autoloader is missing.
if ( ! file_exists( CONVERTKIT_PLUGIN_PATH . '/vendor/autoload.php' ) ) {
return;
}

// Load MCP Adapter.
require_once CONVERTKIT_PLUGIN_PATH . '/vendor/autoload.php';

// Bail if the MCP Adapter class doesn't exist - something went wrong with the autoloader.
if ( ! class_exists( 'WP\\MCP\\Core\\McpAdapter' ) ) {
return;
}

// Bootstrap the MCP Adapter, per WordPress/mcp-adapter's recommended
// integration pattern.
// @see https://github.com/WordPress/mcp-adapter#using-mcp-adapter-in-your-plugin.
\WP\MCP\Core\McpAdapter::instance();

}

/**
* Runs the Plugin's initialization and update routines, which checks if
* the Plugin has just been updated to a newer version,
Expand Down
Loading
Loading