Skip to content
Merged
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
12 changes: 10 additions & 2 deletions projects/plugins/jetpack/_inc/client/ai/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@

import { AdminPage, JetpackLogo } from '@automattic/jetpack-components';
import { Spinner } from '@wordpress/components';
import { useCallback, useState } from '@wordpress/element';
import { useCallback, useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Notice, Stack } from '@wordpress/ui';
import analytics from 'lib/analytics';
import McpHub from './mcp/index';
import McpRead from './mcp/read';
import McpSetup from './mcp/setup';
import McpUpsell from './mcp/upsell';
import { useMcpSettings } from './mcp/use-mcp-settings';
import McpWrite from './mcp/write';

const { blogId, apiRoot, apiNonce } = window?.jetpackAiSettings ?? {};
const { blogId, activityLogUrl, apiRoot, apiNonce } = window?.jetpackAiSettings ?? {};

const VIEW_TITLES = {
hub: __( 'AI', 'jetpack' ),
Expand Down Expand Up @@ -74,6 +75,12 @@ export default function App() {
const { isLoading, savingToolIds, mcpAbilities, hasMcpAccess, error, updateMcpAbilities } =
useMcpSettings();

useEffect( () => {
if ( ! isLoading && hasMcpAccess ) {
analytics.tracks.recordEvent( 'jetpack_mcp_settings_viewed' );
}
}, [ isLoading, hasMcpAccess ] );

const handleUpdate = useCallback(
update => {
setSaveError( null );
Expand Down Expand Up @@ -138,6 +145,7 @@ export default function App() {
<McpHub
mcpAbilities={ mcpAbilities }
blogId={ blogId }
activityLogUrl={ activityLogUrl }
savingToolIds={ savingToolIds }
onNavigate={ setView }
onUpdate={ handleUpdate }
Expand Down
63 changes: 54 additions & 9 deletions projects/plugins/jetpack/_inc/client/ai/mcp/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,18 @@ import {
} from '@wordpress/components';
import { useCallback } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { seen, pencil, connection, chevronRight, info, published, caution } from '@wordpress/icons';
import {
seen,
pencil,
connection,
chevronRight,
info,
published,
caution,
list,
} from '@wordpress/icons';
import { Badge, Button, Stack } from '@wordpress/ui';
import analytics from 'lib/analytics';
import { isWriteTool } from './categories';
import {
getAccountMcpAbilities,
Expand Down Expand Up @@ -152,15 +162,23 @@ function ConnectRow( { title, description, onClick } ) {
/**
* MCP hub component.
*
* @param {object} props - Component props.
* @param {object} props.mcpAbilities - Full mcp_abilities object from API.
* @param {number} props.blogId - Current site's blog ID.
* @param {Set} props.savingToolIds - Set of toolIds currently being saved.
* @param {Function} props.onNavigate - Called with 'read' | 'write' | 'setup'.
* @param {Function} props.onUpdate - Called with partial mcp_abilities update.
* @param {object} props - Component props.
* @param {object} props.mcpAbilities - Full mcp_abilities object from API.
* @param {number} props.blogId - Current site's blog ID.
* @param {string} props.activityLogUrl - URL for the activity log link.
* @param {Set} props.savingToolIds - Set of toolIds currently being saved.
* @param {Function} props.onNavigate - Called with 'read' | 'write' | 'setup'.
* @param {Function} props.onUpdate - Called with partial mcp_abilities update.
* @return {object} Component markup.
*/
export default function McpHub( { mcpAbilities, blogId, savingToolIds, onNavigate, onUpdate } ) {
export default function McpHub( {
mcpAbilities,
blogId,
activityLogUrl,
savingToolIds,
onNavigate,
onUpdate,
} ) {
const accountAbilities = getAccountMcpAbilities( mcpAbilities ?? {} );
const siteContextToolIds = getSiteContextToolIds( mcpAbilities ?? {} );
const siteAbilities = getSiteMcpAbilities( mcpAbilities ?? {}, blogId );
Expand Down Expand Up @@ -191,6 +209,7 @@ export default function McpHub( { mcpAbilities, blogId, savingToolIds, onNavigat

const handleMcpToggle = useCallback(
enabled => {
analytics.tracks.recordEvent( 'jetpack_mcp_enabled_toggled', { enabled } );
const abilities = {};
if ( enabled ) {
readTools.forEach( ( [ toolId ] ) => {
Expand Down Expand Up @@ -258,7 +277,7 @@ export default function McpHub( { mcpAbilities, blogId, savingToolIds, onNavigat
</Card>

{ isMcpEnabled && (
<Card>
<Card className="jetpack-ai-mcp__action-card">
<ConnectRow
title={ __( 'Connect external AI agent', 'jetpack' ) }
description={ __(
Expand All @@ -269,6 +288,32 @@ export default function McpHub( { mcpAbilities, blogId, savingToolIds, onNavigat
/>
</Card>
) }

{ isMcpEnabled && activityLogUrl && (
<Card className="jetpack-ai-mcp__action-card">
<a
className="jetpack-ai-mcp__connect-row"
href={ activityLogUrl }
target="_blank"
rel="noopener noreferrer"
>
<span className="jetpack-ai-mcp__connect-row-icon">
<Icon icon={ list } size={ 24 } />
</span>
<span className="jetpack-ai-mcp__connect-row-text">
<Text as="p" className="jetpack-ai-mcp__connect-row-title" weight={ 600 }>
{ __( 'Activity log', 'jetpack' ) }
</Text>
<Text as="p" className="jetpack-ai-mcp__connect-row-description" variant="muted">
{ __( 'Review recent actions taken by AI agents on your site.', 'jetpack' ) }
</Text>
</span>
<span className="jetpack-ai-mcp__connect-row-chevron">
<Icon icon={ chevronRight } size={ 24 } />
</span>
</a>
</Card>
) }
</>
);
}
11 changes: 11 additions & 0 deletions projects/plugins/jetpack/_inc/client/ai/mcp/read.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { Fragment, useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Stack } from '@wordpress/ui';
import analytics from 'lib/analytics';
import {
CATEGORY_ORDER,
SUB_CATEGORY_ORDER,
Expand Down Expand Up @@ -122,6 +123,11 @@ export default function McpRead( { mcpAbilities, blogId, savingToolIds, onUpdate

const handleToolChange = useCallback(
( toolId, enabled ) => {
analytics.tracks.recordEvent( 'jetpack_mcp_allowlist_updated', {
tool_id: toolId,
enabled,
view: 'read',
} );
Comment thread
eoigal marked this conversation as resolved.
onUpdate( {
sites: [
{
Expand All @@ -136,6 +142,11 @@ export default function McpRead( { mcpAbilities, blogId, savingToolIds, onUpdate

const handleEnableAll = useCallback(
( categoryTools, enabled ) => {
analytics.tracks.recordEvent( 'jetpack_mcp_allowlist_updated', {
enabled,
tool_count: categoryTools.length,
view: 'read',
} );
Comment thread
eoigal marked this conversation as resolved.
const overrides = {};
categoryTools.forEach( ( [ toolId ] ) => {
overrides[ toolId ] = enabled;
Expand Down
16 changes: 15 additions & 1 deletion projects/plugins/jetpack/_inc/client/ai/mcp/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@
}
}

&__action-card {
overflow: hidden;
}

&__connect-row {
display: flex;
box-sizing: border-box;
gap: 16px;
align-items: flex-start;
padding: 24px;
Expand All @@ -36,6 +41,15 @@
text-align: left;
border-radius: 0;

// Reset browser link styles when rendered as <a>
&,
&:visited,
&:hover,
&:active {
color: inherit;
text-decoration: none;
}

&:hover {
background: var(--color-surface-backdrop, #f0f0f1);
}
Expand Down Expand Up @@ -84,7 +98,7 @@
}

&__access-card {
// Override default card margin if any
overflow: hidden;
}
}

Expand Down
11 changes: 11 additions & 0 deletions projects/plugins/jetpack/_inc/client/ai/mcp/write.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { Fragment, useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Stack } from '@wordpress/ui';
import analytics from 'lib/analytics';
import {
CATEGORY_ORDER,
SUB_CATEGORY_ORDER,
Expand Down Expand Up @@ -123,6 +124,11 @@ export default function McpWrite( { mcpAbilities, blogId, savingToolIds, onUpdat

const handleToolChange = useCallback(
( toolId, enabled ) => {
analytics.tracks.recordEvent( 'jetpack_mcp_allowlist_updated', {
tool_id: toolId,
enabled,
view: 'write',
} );
Comment thread
eoigal marked this conversation as resolved.
onUpdate( {
sites: [
{
Expand All @@ -137,6 +143,11 @@ export default function McpWrite( { mcpAbilities, blogId, savingToolIds, onUpdat

const handleEnableAll = useCallback(
( categoryTools, enabled ) => {
analytics.tracks.recordEvent( 'jetpack_mcp_allowlist_updated', {
enabled,
tool_count: categoryTools.length,
view: 'write',
} );
Comment thread
eoigal marked this conversation as resolved.
const overrides = {};
categoryTools.forEach( ( [ toolId ] ) => {
overrides[ toolId ] = enabled;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

use Automattic\Jetpack\Admin_UI\Admin_Menu;
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
use Automattic\Jetpack\Redirect;
use Automattic\Jetpack\Status;
use Automattic\Jetpack\Status\Host;

if ( ! defined( 'ABSPATH' ) ) {
exit( 0 );
Expand Down Expand Up @@ -77,7 +80,18 @@ public function page_admin_scripts() {
$script_version = $asset_manifest['version'];
}

$blog_id = Connection_Manager::get_site_id( true );
$blog_id = Connection_Manager::get_site_id( true );
$site_suffix = ( new Status() )->get_site_suffix();
// Use the plain hostname for the Atomic activity log URL — get_site_suffix() can
// include '::' for subdirectory installs, which would break the URL. This matches
// the approach used by jetpack-mu-wpcom for the sidebar Activity Log link.
$site_host = wp_parse_url( home_url(), PHP_URL_HOST );
// On Atomic, jetpack-mu-wpcom replaces the cloud redirect with a direct WPCOM URL.
// Mirror that behaviour here so the activity log link resolves consistently.
$activity_log_site = ( is_string( $site_host ) && '' !== $site_host ) ? $site_host : $site_suffix;
$activity_log_url = ( new Host() )->is_woa_site()
? 'https://wordpress.com/activity-log/' . $activity_log_site
: Redirect::get_url( 'cloud-activity-log-wp-menu', array( 'site' => $blog_id ? $blog_id : $site_suffix ) );

wp_enqueue_script(
'jetpack-ai-admin',
Expand All @@ -93,12 +107,13 @@ public function page_admin_scripts() {
'jetpack-ai-admin',
'var jetpackAiSettings = ' . wp_json_encode(
array(
'blogId' => $blog_id ? (int) $blog_id : 0,
'siteAdminUrl' => admin_url(),
'apiRoot' => esc_url_raw( rest_url() ),
'apiNonce' => wp_create_nonce( 'wp_rest' ),
'pluginUrl' => plugins_url( '', JETPACK__PLUGIN_FILE ),
'upgradeUrl' => 'https://wordpress.com/plans/' . rawurlencode( wp_parse_url( home_url(), PHP_URL_HOST ) ?? '' ),
'blogId' => $blog_id ? (int) $blog_id : 0,
'activityLogUrl' => $activity_log_url,
'siteAdminUrl' => admin_url(),
'apiRoot' => esc_url_raw( rest_url() ),
'apiNonce' => wp_create_nonce( 'wp_rest' ),
'pluginUrl' => plugins_url( '', JETPACK__PLUGIN_FILE ),
'upgradeUrl' => 'https://wordpress.com/plans/' . rawurlencode( wp_parse_url( home_url(), PHP_URL_HOST ) ?? '' ),
Comment thread
eoigal marked this conversation as resolved.
),
JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP
) . ';',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: enhancement

AI MCP settings: add activity log link and Tracks analytics events (jp_mcp_settings_viewed, jp_mcp_enabled_toggled, jp_mcp_allowlist_updated)
Loading