Skip to content

Commit df40a97

Browse files
refactor(mcp): trim SERVER_INSTRUCTIONS to lean on authoritative docs (koala73#3910)
* refactor(mcp): trim SERVER_INSTRUCTIONS to lean on authoritative docs JMESPath and describe_tool stanzas previously inlined grammar / envelope / quota detail that is now documented in docs/mcp-jmespath.mdx, docs/mcp-error-catalog.mdx, and docs/mcp-tools-reference.mdx. Each stanza collapses to one sentence stating the affordance + use case + canonical-docs URL. Prompts and resources stanzas are unchanged. initialize.result.instructions: 1945 B → 1397 B (-548 B / 28.2%) emitted once per session. SERVER_VERSION 1.9.0 → 1.10.0; server-card.json synced; version assertions in mcp-jmespath and mcp-tools-list-compression updated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(mcp): keep describe_tool 60/min + unknown-tool hint in-band Greptile P2: the trimmed describe_tool stanza dropped two pieces of load-bearing guidance — the 60/min rate-limit caveat that qualifies "use freely", and the {error: 'unknown_tool', available: [...]} self-correction hint. The block comment above SERVER_INSTRUCTIONS explicitly says stanzas must stand alone because LLMs don't reliably fetch URLs mid-session, so both belong in-band. SERVER_INSTRUCTIONS: 1397 B → 1577 B (+180 B). Net trim vs pre-PR baseline: 1945 B → 1577 B (-368 B / -18.9%). Version-history comment updated with the corrected delta and rationale. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9eda3d4 commit df40a97

4 files changed

Lines changed: 40 additions & 21 deletions

File tree

api/mcp/constants.ts

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,28 @@ export const SERVER_NAME = 'worldmonitor';
184184
// don't dedup / cache responses whose content drifts between calls.
185185
// - Purely additive on the wire — clients that read only the legacy two
186186
// hints keep working; new four-hint clients get a richer signal.
187+
// Bumped 1.9.0 → 1.10.0 (2026-05-25) reflecting:
188+
// - SERVER_INSTRUCTIONS trimmed from 1945 B → 1577 B (368 B / 18.9%
189+
// reduction) emitted once per initialize. The JMESPath stanza
190+
// previously inlined grammar/envelope/quota detail that is now
191+
// authoritatively documented in docs/mcp-jmespath.mdx and
192+
// docs/mcp-error-catalog.mdx; it collapses to one sentence per
193+
// concern + canonical-docs URL. The describe_tool stanza was tightened
194+
// in similar fashion but the 60/min rate-limit caveat and the
195+
// `{error: 'unknown_tool', available: [...]}` self-correction hint
196+
// are intentionally retained in-band — the block-comment contract
197+
// above says stanzas must stand alone (LLMs do not reliably fetch
198+
// URLs mid-session), so "use freely" without the rate-limit qualifier
199+
// would mislead. The prompts and resources stanzas are unchanged —
200+
// they have no single authoritative docs anchor today, so
201+
// duplicating them in-band is still load-bearing.
202+
// - Pure metadata edit: no behaviour change, no input/output schema
203+
// change, no envelope-shape change. The constant emitted into
204+
// initialize.result.instructions is the only wire-visible diff. The
205+
// bump records it in the audit trail; rollback is git revert.
187206
// Keep aligned with public/.well-known/mcp/server-card.json::serverInfo.version
188207
// — discovery scanners cross-check both values.
189-
export const SERVER_VERSION = '1.9.0';
208+
export const SERVER_VERSION = '1.10.0';
190209

191210
// MCP logging capability — valid severity levels per the 2025-03-26 spec
192211
// (RFC 5424 subset). Stateless HTTP transport: we ACK the level but do not
@@ -221,20 +240,20 @@ export const TOOL_DESCRIPTION_MAX_BYTES = 120;
221240

222241
// Session-level discovery instructions. Per MCP 2025-03-26 lifecycle spec,
223242
// servers MAY return an `instructions` string in the `initialize` result;
224-
// clients SHOULD surface this to the model. We carry the JMESPath contract
225-
// (grammar URL, projection guide URL, limits) and the describe_tool affordance
226-
// here — once per session — so per-tool advertisements stay terse. Worked
227-
// examples used to live inline; they now live in docs/mcp-jmespath.mdx, which
228-
// the LLM can fetch on demand instead of amortising ~500 bytes per session.
243+
// clients SHOULD surface this to the model. Each stanza names an affordance
244+
// (JMESPath, describe_tool, prompts/list, resources/list), states its one-line
245+
// use case, and points at the authoritative docs URL for full detail — the
246+
// LLM does not reliably fetch URLs mid-session, so the in-band sentences must
247+
// stand alone. Inline guide/envelope detail used to live here; it now lives in
248+
// docs/mcp-jmespath.mdx, docs/mcp-error-catalog.mdx, and
249+
// docs/mcp-tools-reference.mdx, fetched on demand instead of amortising
250+
// ~550 bytes per session.
229251
export const SERVER_INSTRUCTIONS = [
230-
'Every tool accepts an optional `jmespath` string argument. The server applies the expression server-side AFTER any per-tool filter/summary args, projecting the response before serialization. This is the single most effective way to reduce response tokens — typical 80-95% reduction when you only need a subset of fields.',
252+
'Every tool accepts an optional `jmespath` string. Server-side projection applied AFTER per-tool filter/summary; typical 80-95% token reduction. Grammar: https://jmespath.org/specification.html. Guide + 12 worked examples: https://www.worldmonitor.app/docs/mcp-jmespath.',
231253
'',
232-
'Grammar: https://jmespath.org/specification.html',
233-
'Guide with 12 worked examples against real response shapes: https://www.worldmonitor.app/docs/mcp-jmespath',
254+
`Limits: expr ≤ ${JMESPATH_MAX_EXPR_BYTES}B, output ≤ ${JMESPATH_MAX_OUTPUT_BYTES}B. Bad expressions soft-fail via {_jmespath_error, original_keys} envelope (consumes one daily quota unit on retry — self-correct from original_keys). Full envelope reference: https://www.worldmonitor.app/docs/mcp-error-catalog.`,
234255
'',
235-
`Limits: expression ≤ ${JMESPATH_MAX_EXPR_BYTES} bytes; projected payload ≤ ${JMESPATH_MAX_OUTPUT_BYTES} bytes. Failures return {_jmespath_error, original_keys} inside the normal result envelope. Bad expressions DO consume one daily quota unit on retry — original_keys is echoed so you can self-correct in one extra call.`,
236-
'',
237-
`tools/list returns COMPRESSED tool descriptions (first sentence, ≤${TOOL_DESCRIPTION_MAX_BYTES}B per tool). Call describe_tool({tool_name}) to get the full uncompressed definition for any tool you're considering — especially useful when the compressed entry is ambiguous about behaviour or argument semantics. describe_tool is metadata-only and is EXEMPT from the Pro daily quota (still counts toward the 60/min rate limit), so use it freely while exploring. describe_tool({tool_name: 'nonexistent'}) returns {error: 'unknown_tool', available: [...]} so you can self-correct.`,
256+
`tools/list ships compressed tool descriptions (≤${TOOL_DESCRIPTION_MAX_BYTES}B). Call describe_tool({tool_name}) for the full uncompressed definition — quota-exempt (still counts toward the 60/min rate limit), so use freely while exploring. describe_tool({tool_name: 'nonexistent'}) returns {error: 'unknown_tool', available: [...]} so you can self-correct. Full reference: https://www.worldmonitor.app/docs/mcp-tools-reference.`,
238257
'',
239258
'Issue prompts/list to discover pre-built workflow templates (country-briefing, energy-shock-watch, market-open-prep, conflict-pulse, route-risk-check, freshness-audit). Each prompt pre-bakes a JMESPath projection per step so the first execution lands on the right shape. prompts/list + prompts/get are quota-exempt (per-minute limit only).',
240259
'',

public/.well-known/mcp/server-card.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"serverInfo": {
33
"name": "worldmonitor",
4-
"version": "1.9.0",
4+
"version": "1.10.0",
55
"description": "WorldMonitor's live global-intelligence stack as an MCP server: real-time markets, conflict events, aviation, maritime, energy, climate, health, displacement, supply chain, and AI-generated regional briefs.",
66
"vendor": "WorldMonitor",
77
"homepage": "https://www.worldmonitor.app"

tests/mcp-jmespath.test.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,12 @@ describe('api/mcp.ts — JMESPath projection (v1.7.0)', () => {
300300
// Initialize handshake — version + instructions
301301
// ============================================================
302302
describe('initialize handshake', () => {
303-
it('serverInfo.version === "1.9.0"', async () => {
303+
it('serverInfo.version === "1.10.0"', async () => {
304304
// Tracks current SERVER_VERSION. Each minor bump needs to update
305305
// this assertion + the cross-check at line 327 below.
306306
const res = await mod.default(makeReq(initBody(1)));
307307
const body = await res.json();
308-
assert.equal(body.result?.serverInfo?.version, '1.9.0');
308+
assert.equal(body.result?.serverInfo?.version, '1.10.0');
309309
});
310310

311311
it('result.instructions is present and mentions jmespath', async () => {
@@ -326,12 +326,12 @@ describe('api/mcp.ts — JMESPath projection (v1.7.0)', () => {
326326
assert.ok(/daily quota/i.test(inst), 'missing quota note');
327327
});
328328

329-
it('server-card.json version matches SERVER_VERSION (currently 1.9.0)', () => {
329+
it('server-card.json version matches SERVER_VERSION (currently 1.10.0)', () => {
330330
// Cross-check the comment at api/mcp.ts:~56 — discovery scanners
331331
// verify both values; a future bump that misses one would break
332332
// discovery. This is the test that prevents that drift.
333333
const card = JSON.parse(readFileSync(new URL('../public/.well-known/mcp/server-card.json', import.meta.url), 'utf8'));
334-
assert.equal(card.serverInfo.version, '1.9.0');
334+
assert.equal(card.serverInfo.version, '1.10.0');
335335
assert.equal(card.features?.responseProjection, 'jmespath');
336336
});
337337

tests/mcp-tools-list-compression.test.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,14 @@ describe('api/mcp.ts — tools/list description compression (v1.7.0)', () => {
359359
// ============================================================
360360
// U4: Version bump + SERVER_INSTRUCTIONS + server-card sync
361361
// ============================================================
362-
it('serverInfo.version === "1.9.0"', async () => {
362+
it('serverInfo.version === "1.10.0"', async () => {
363363
const res = await mod.default(new Request('https://worldmonitor.app/mcp', {
364364
method: 'POST',
365365
headers: { 'Content-Type': 'application/json', 'X-WorldMonitor-Key': VALID_KEY },
366366
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { protocolVersion: '2025-03-26', capabilities: {}, clientInfo: { name: 't', version: '1' } } }),
367367
}));
368368
const body = await res.json();
369-
assert.equal(body.result?.serverInfo?.version, '1.9.0');
369+
assert.equal(body.result?.serverInfo?.version, '1.10.0');
370370
});
371371

372372
it('initialize.result.instructions mentions describe_tool AND the TOOL_DESCRIPTION_MAX_BYTES cap value', async () => {
@@ -383,9 +383,9 @@ describe('api/mcp.ts — tools/list description compression (v1.7.0)', () => {
383383
'instructions should mention the TOOL_DESCRIPTION_MAX_BYTES cap');
384384
});
385385

386-
it('server-card.json version matches SERVER_VERSION (1.9.0) AND tools.count matches (39)', () => {
386+
it('server-card.json version matches SERVER_VERSION (1.10.0) AND tools.count matches (39)', () => {
387387
const card = JSON.parse(readFileSync(new URL('../public/.well-known/mcp/server-card.json', import.meta.url), 'utf8'));
388-
assert.equal(card.serverInfo.version, '1.9.0');
388+
assert.equal(card.serverInfo.version, '1.10.0');
389389
assert.equal(card.tools.count, 39);
390390
assert.equal(card.features?.toolDescriptionCompression, true);
391391
assert.equal(card.features?.responseProjection, 'jmespath',

0 commit comments

Comments
 (0)