wikipedia-mcp v3.4.2 summarize_article_for_query has no max_length cap — 243x response amplification blows agent context windows
Reproduction
Server: wikipedia-mcp v3.4.2 via uvx wikipedia-mcp (stdio transport, no auth)
Tool: summarize_article_for_query — described as returning "a snippet around the query within the article text or summary"
Step 1: Baseline call (max_length=250, the default)
{"method":"tools/call","params":{"name":"summarize_article_for_query","arguments":{"title":"United States","query":"history","max_length":250}}}Result: 253-char summary, 778-byte response, isError: false ✅
Step 2: max_length=999999
{"method":"tools/call","params":{"name":"summarize_article_for_query","arguments":{"title":"United States","query":"history","max_length":999999}}}Result: 93,435-char "summary" (the ENTIRE article text), 188,923-byte response, isError: false
Amplification: 243x the baseline response size.
The "summary" field contains the full article — every section, code example, reference list, and See Also link — returned as a single string in a field called summary.
Step 3: max_length=-9999 (negative value)
{"method":"tools/call","params":{"name":"summarize_article_for_query","arguments":{"title":"Python (programming language)","query":"history","max_length":-9999}}}Result: Returns 41,660 bytes of full article text. The negative value causes Python's slice arithmetic (text[pos:pos+max_length] → text[pos:pos-9999]) to wrap around and return most of the article.
The exact output varies by article and query position — sometimes 3 chars, sometimes 40KB+ — making the behavior unpredictable for agents.
Step 4: Confirm isError is never set
All four cases — baseline, huge, negative, and zero — return isError: false. An MCP client has no machine-readable signal that the response is abnormal.
Why this matters for agents
- Context window exhaustion: A single
summarize_article_for_querycall returns 189KB. Most agent context windows are 100K-200K tokens. One bad call on a large article fills a significant chunk.
- Schema misleads agents: The schema declares
max_lengthasinteger, default: 250with nomaximumbound. An agent optimizing for coverage might reasonably pass a large value, expecting the server to clamp it.
- Silent degradation:
isError: falsemeans the agent processes 93K chars of raw text believing it received a "snippet." No error, no warning, no pagination.
- Contrast with `summarize_article_section`: The sibling tool
summarize_article_sectioncorrectly caps output —max_length=999999andmax_length=-9999both produce a reasonable 67-char response. So one summarize tool is bounded and the other is not.
Root cause
The summarize_article_for_query implementation uses unclamped Python string slicing: text[match_pos:match_pos + max_length]. No min(max_length, SOME_CAP) guard exists. summarize_article_section has a different code path that naturally bounds output.
Impact
| max_length | summary chars | response bytes | amplification |
|---|---|---|---|
| 250 (default) | 253 | 778 | 1x |
| 999999 | 93,435 | 188,923 | 243x |
| -9999 | 3–41,660 | 258–41,660 | unpredictable |
| 0 | 3 ("...") | ~250 | ~0.3x |