Skip to content
This repository was archived by the owner on Jan 19, 2026. It is now read-only.
This repository was archived by the owner on Jan 19, 2026. It is now read-only.

Reduce MCP token usage: truncate Tools/Resources responses and restrict fields/pagination for page/post searches #96

Description

@igor-adzz

Problem

  • tools/call and resources/read currently serialize full results without limits, pulling heavy fields (post HTML content, large plugin/theme lists, etc.) and quickly burning tokens in Claude.
  • Page/post searches via REST aliases (/wp/v2/pages, /wp/v2/posts) do not set _fields/context=embed or enforce small pagination, so large objects are returned.

Affected files: includes/RequestMethodHandlers/ToolsHandler.php, includes/RequestMethodHandlers/ResourcesHandler.php, includes/Tools/McpPostsTools.php, includes/Tools/McpPagesTools.php, optionally includes/Tools/McpCustomPostTypesTools.php.

Proposed solution

  • Truncate tool textual responses to 10k characters in ToolsHandler::call_tool (replace direct wp_json_encode($result) with an intermediate variable, clamp, append [truncated]).
  • Truncate resource text to 10k characters in ResourcesHandler::read_resource (build $json first, clamp, append [truncated]).
  • Add preCallback for wp_posts_search and wp_pages_search in McpPostsTools/McpPagesTools: enforce per_page <= 10 (default 5), set _fields=id,title,excerpt,link,date,slug and context=embed. Optionally, in McpCustomPostTypesTools::search_custom_post_types, map $query->posts to a minimal field set (exclude post_content).

Acceptance criteria

  • tools/call responses with long JSON include [truncated] and length ≤ 10,000 bytes.
  • resources/read responses are also truncated to 10,000 bytes and include [truncated] when applicable.
  • By default, page/post searches return ≤ 10 items and only the listed _fields (no heavy content.rendered).
  • Response sizes drop significantly on typical queries (expected 50–90%).

How to test (commands)

  • Tools (truncation):
export WP_URL="https://<site>/wp-json/wp/v2/wpmcp"; export JWT="<token>"
curl -s -X POST "$WP_URL" -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -H "Authorization: Bearer $JWT" \
-d '{"id":1,"jsonrpc":"2.0","method":"tools/call","params":{"name":"wp_posts_search","arguments":{}}}' \
| jq -r '.content[0].text | length, contains("[truncated]")'
  • Resources (truncation):
curl -s -X POST "$WP_URL" -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -H "Authorization: Bearer $JWT" \
-d '{"id":2,"jsonrpc":"2.0","method":"resources/read","params":{"uri":"WordPress://site-info"}}' \
| jq -r '.contents[0].text | length, contains("[truncated]")'
  • Page/post search (fields/pagination):
curl -s -X POST "$WP_URL" -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -H "Authorization: Bearer $JWT" \
-d '{"id":3,"jsonrpc":"2.0","method":"tools/call","params":{"name":"wp_pages_search","arguments":{}}}' \
| jq -r '.[0]? // . | if type=="array" then length else length end'

curl -s -X POST "$WP_URL" -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -H "Authorization: Bearer $JWT" \
-d '{"id":4,"jsonrpc":"2.0","method":"tools/call","params":{"name":"wp_pages_search","arguments":{}}}' \
| jq -r '.[0]? // . | if type=="array" then .[0] | keys|sort else . end'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions