diff --git a/apps/cli/ai/system-prompt.ts b/apps/cli/ai/system-prompt.ts index e7fee4f705..9f804f64e4 100644 --- a/apps/cli/ai/system-prompt.ts +++ b/apps/cli/ai/system-prompt.ts @@ -70,6 +70,8 @@ IMPORTANT: Before doing ANY work, you MUST first check the site's plan by callin Use \`per_page\` and \`page\` for pagination. Use \`status\` to filter by publish status. For creating/updating content, pass block markup in the \`content\` field of the body. +**IMPORTANT: Minimize response sizes** to avoid exceeding tool output limits. Use \`_fields\` (wp/v2) or \`fields\` (v1.1) query parameters to request only the properties you need and exclude heavy fields like \`content\`. For listing endpoints, fetch with lightweight fields first (e.g. \`_fields=id,slug,title,status\` for wp/v2, or \`fields=ID,name,description,URL\` for v1.1), then fetch individual items by ID when you need the full content. When using \`fields\` with v1.1, always include \`ID\` in the field list. + ## Common WP.com v1.1 Endpoints (set apiNamespace to "") **Site**: \`GET /\` (site info), \`POST /settings\` diff --git a/apps/cli/ai/wpcom-tools.ts b/apps/cli/ai/wpcom-tools.ts index 327a4a0eb2..4dc9ef15d6 100644 --- a/apps/cli/ai/wpcom-tools.ts +++ b/apps/cli/ai/wpcom-tools.ts @@ -3,6 +3,41 @@ import wpcomFactory from '@studio/common/lib/wpcom-factory'; import wpcomXhrRequest from '@studio/common/lib/wpcom-xhr-request-factory'; import { z } from 'zod/v4'; +/** + * Strips oversized fields from API responses that can't be filtered via query params. + * + * Special case: the WP.com /sites/{id} endpoint returns a `plan` object whose + * `features` sub-field alone is 60K+ characters, which pushes the tool result past + * Claude Code's MCP output limit (~100k chars). The v1.1 API doesn't support + * sub-field filtering (e.g. `fields=plan.product_slug`), so we can't solve this + * via query params. The agent only needs a few plan properties to gate features + * since the system prompt hardcodes what each plan tier can do. + * + * This is NOT a pattern to follow for other endpoints. For general large responses, + * the system prompt instructs the agent to use `_fields` (wp/v2) or `fields` (v1.1) + * query params to request only the properties it needs. + */ +function stripOversizedFields( result: ApiResponse ): ApiResponse { + if ( + result && + typeof result === 'object' && + ! Array.isArray( result ) && + result.plan?.features + ) { + return { + ...result, + plan: { + product_id: result.plan.product_id, + product_slug: result.plan.product_slug, + product_name_short: result.plan.product_name_short, + expired: result.plan.expired, + is_free: result.plan.is_free, + }, + }; + } + return result; +} + function errorResult( message: string ) { return { content: [ { type: 'text' as const, text: message } ], @@ -106,7 +141,8 @@ export function createWpcomToolDefinitions( token: string, siteId: number ) { break; } - return textResult( JSON.stringify( result, null, 2 ) ); + const compacted = stripOversizedFields( result ); + return textResult( JSON.stringify( compacted ) ); } catch ( error ) { return errorResult( `WP.com API request failed (${ args.method } ${ args.path }): ${ getErrorMessage(