Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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: 2 additions & 0 deletions apps/cli/ai/system-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,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. For wp/v2 listing endpoints (templates, posts, pages, etc.), use the \`_fields\` query parameter to request only the properties you need and exclude heavy fields like \`content\`. Fetch the list with lightweight fields first (e.g. \`_fields=id,slug,title,status\`), then fetch individual items by ID when you need the full content.

## Common WP.com v1.1 Endpoints (set apiNamespace to "")

**Site**: \`GET /\` (site info), \`POST /settings\`
Expand Down
36 changes: 35 additions & 1 deletion apps/cli/ai/wpcom-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,39 @@ import wpcomFactory from '@studio/common/lib/wpcom-factory';
import wpcomXhrRequest from '@studio/common/lib/wpcom-xhr-request-factory';
import { z } from 'zod/v4';

/**
* 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 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)
Copy link
Copy Markdown
Member

@sejas sejas Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this accurate? I didn’t see the system prompt mention fields for v1.1. Should we add that information to the system prompt?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! I have updated the system prompt as part of e21a84e as I identified that sometimes fields were failing. I have added a suggestion to use both _fields for wp/v2 or fields for v1.1 to reduce the response size. I have tested multiple scenarios and they all work fine. I have tested:

  • What's the current name, tagline, and active theme of this site?
  • Redesign my site to be more polished
  • Can you update the coming-soon template to have a light background instead of the current one?

And I have not obtained the error

* query params to request only the properties it needs.
*/
function compactResponse( result: ApiResponse ): ApiResponse {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should use a more specific function name, like stripPlanFeatures.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I have renamed it as part of e21a84e

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 } ],
Expand Down Expand Up @@ -106,7 +139,8 @@ export function createWpcomToolDefinitions( token: string, siteId: number ) {
break;
}

return textResult( JSON.stringify( result, null, 2 ) );
const compacted = compactResponse( result );
return textResult( JSON.stringify( compacted, null, 2 ) );
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it’s better to use JSON.stringify(result) instead of JSON.stringify(compacted, null, 2), since the added indentation increases token usage. I learned this in #3011. I think we can close that PR in favor of this one?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion @lezama! I will apply that

I learned this in #3011. I think we can close that PR in favor of this one?

I think so, and we can apply the learnings on #3011 on follow-ups if required.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @lezama, I went ahead and merged this. You'll want to merge trunk into #3005 to pick up the changes and continue from there or maybe just close it as discussed

} catch ( error ) {
return errorResult(
`WP.com API request failed (${ args.method } ${ args.path }): ${ getErrorMessage(
Expand Down
Loading