From 53c9c0c4f964d5f247d97ef49b022da4125de165 Mon Sep 17 00:00:00 2001 From: Jakob Wennberg Date: Tue, 1 Sep 2026 21:45:31 +0200 Subject: [PATCH] feat(mcp): second examples batch: five more tools, seven examples, 80 tokens (#2137) Continues #2100 under the margin the envelope trim (#2123) created: 58 999 to 59 079 against the 60 000 ceiling, spending under half the room and leaving ~920. Picked by evidence, not traffic alone: gnubok_search_tools was sent a nonexistent `offset` in prod today, so its examples show the actual levers (query, detail, limit) and the description of the mistake; the create/complete document-upload pair's examples ARE the two-step flow, same upload_id and file_name on both sides; list_uncategorized_transactions is the highest-traffic read (15 122 calls/30d) and gets the pagination shape; link_document_to_voucher gets the minimal linking call. All seven pass the input-examples validation suite (same unknown-key guard the server runs, plus required/type/enum/pattern and the placeholder-id check), and the pinned tool list is updated. Claude-Session: https://claude.ai/code/session_01L3P2hr19PhQuCoTSGoegcY Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Opus 5 --- .../mcp-server/__tests__/input-examples.test.ts | 5 +++++ .../mcp-server/__tests__/payload-size.bench.test.ts | 7 +++++++ extensions/general/mcp-server/server.ts | 10 ++++++++++ 3 files changed, 22 insertions(+) diff --git a/extensions/general/mcp-server/__tests__/input-examples.test.ts b/extensions/general/mcp-server/__tests__/input-examples.test.ts index a2eda1c6..8d883f06 100644 --- a/extensions/general/mcp-server/__tests__/input-examples.test.ts +++ b/extensions/general/mcp-server/__tests__/input-examples.test.ts @@ -72,9 +72,14 @@ describe('inputSchema examples are calls the server would accept', () => { expect(withExamples.map((t) => t.name).sort()).toEqual([ 'gnubok_approve_pending_operation', 'gnubok_categorize_transaction', + 'gnubok_complete_document_upload', + 'gnubok_create_document_upload', 'gnubok_create_voucher', 'gnubok_get_kpi_report', + 'gnubok_link_document_to_voucher', + 'gnubok_list_uncategorized_transactions', 'gnubok_query_journal', + 'gnubok_search_tools', ]) }) diff --git a/extensions/general/mcp-server/__tests__/payload-size.bench.test.ts b/extensions/general/mcp-server/__tests__/payload-size.bench.test.ts index 311fc936..7c72d536 100644 --- a/extensions/general/mcp-server/__tests__/payload-size.bench.test.ts +++ b/extensions/general/mcp-server/__tests__/payload-size.bench.test.ts @@ -375,6 +375,13 @@ describe('tools/list payload size guard', () => { // costs ~11 800 tokens across those 58 tools, and the structural fix is // to stop repeating it, not to trim it further. // + // * 59.0K to 59.1K: second examples batch (2026-09-01, #2066), 7 + // examples on 5 more tools for 80 tokens, spending under half the + // margin the envelope trim created. Picked by evidence: search_tools + // was sent a nonexistent `offset` in prod the same day, the upload + // pair's examples ARE the two-step flow, and + // list_uncategorized_transactions is the highest-traffic read. + // // Long-term answer to growth is no longer a ceiling bump. gnubok_call_tool // makes `catalogVisibility: 'search'` usable for READ tools on hosts that // can only invoke what tools/list showed them, which is the constraint that diff --git a/extensions/general/mcp-server/server.ts b/extensions/general/mcp-server/server.ts index 4f880309..7558ccb5 100644 --- a/extensions/general/mcp-server/server.ts +++ b/extensions/general/mcp-server/server.ts @@ -3033,6 +3033,9 @@ export const tools: McpTool[] = [ scope: { type: 'string', description: 'Optional filter: only tools requiring this API key scope (e.g. "invoices:write").' }, limit: { type: 'number', description: 'Max results, 1-50 (default 20).' }, }, + // No offset exists: a caller paged with one today (2026-09-01) and was + // rejected. Raise limit instead, or narrow the query. + examples: [{ query: 'moms', detail: 'summary' }, { query: 'faktura', limit: 50 }], }, outputSchema: { type: 'object', @@ -5106,6 +5109,7 @@ export const tools: McpTool[] = [ offset: { type: 'number', description: 'Number of results to skip for pagination (default 0)' }, cash_account_id: { type: 'string' }, }, + examples: [{}, { limit: 100, offset: 100 }], }, outputSchema: paginatedSchema('transactions', { type: 'object', @@ -12030,6 +12034,9 @@ export const tools: McpTool[] = [ }, }, required: ['file_name'], + // Step 1 of 2: PUT the bytes to upload_url, then complete with the SAME + // upload_id and file_name. + examples: [{ file_name: 'kvitto-sl-2026-03-12.pdf' }], }, outputSchema: { type: 'object', @@ -12097,6 +12104,8 @@ export const tools: McpTool[] = [ }, }, required: ['upload_id', 'file_name'], + // Step 2 of 2: same upload_id and file_name as gnubok_create_document_upload. + examples: [{ upload_id: 'f00d...', file_name: 'kvitto-sl-2026-03-12.pdf' }], }, outputSchema: { type: 'object', @@ -13170,6 +13179,7 @@ export const tools: McpTool[] = [ dry_run: { type: 'boolean', description: 'Preview without staging' }, }, required: ['document_id', 'journal_entry_id'], + examples: [{ document_id: 'd0c1...', journal_entry_id: 'a44e...' }], }, outputSchema: STAGED_OPERATION_SCHEMA, annotations: {