Every WorldMonitor MCP tool accepts an optionalDocumentation Index
Fetch the complete documentation index at: https://worldmonitor.app/docs/llms.txt
Use this file to discover all available pages before exploring further.
jmespath string argument. The server applies the expression after any per-tool filter and summary args, then projects the response before serialisation. A well-chosen projection typically cuts payload size by 80–95% — the single most effective lever you have for keeping a long agent loop inside its context window.
This page is the practical reference: a quick orientation, then twelve worked examples against three real captured tool responses. For the grammar itself, lean on the spec — jmespath.org/specification.html. Coming back here is faster than re-reading the spec.
Quick orientation
-
Pass the expression as the
jmespathargument on anytools/call. The expression root is the full response envelope —{ cached_at, stale, data: { … } }for cache tools — so most expressions start withdata.<key>to reach the payload, andcached_at/staleare addressable from the same root when you want them. -
Hyphenated keys must be quoted with double quotes. Most WorldMonitor tools have hyphenated cache keys (
stocks-bootstrap,ucdp-events,etf-flows,fear-greed,transit-summaries). Usedata."stocks-bootstrap".quotes[*].symbol, notdata.stocks-bootstrap.…. -
Numbers and JSON literals go in backticks, strings in single quotes.
[?deathsBest > \5`](numeric),[?country == ‘Iraq’]` (string). Mixing them up silently parses the value as something else. -
Two server-side limits keep edge functions healthy:
- Expression itself: ≤ 1024 bytes.
- Projected output: ≤ 256 KB.
{ _jmespath_error, original_keys, ... }inside the normal result envelope — the tool call still succeeds at the JSON-RPC layer (noisError: true), andoriginal_keysechoes the top-level keys of the unprojected response so the model can self-correct on the next call.
tests/fixtures/jmespath-samples/ (re-captured periodically against the prod MCP endpoint). They were picked deliberately — fat (~100 KB), medium (~30 KB), and thin (~10 KB) — to span the size tiers you’ll actually project against.
The twelve examples
1. Drill into a single nested object
Intent. Skip the equity list and just get the WorldMonitor fear-greed composite score fromget_market_data.
Tool call:
data."fear-greed" quotes the hyphenated key, then .composite plucks the nested object. Everything else in the payload — the 100 KB of quotes — never crosses the wire.
2. Slim each item to a few fields (multiselect-hash)
Intent. Fromget_market_data, get a compact table of all equity quotes: symbol, price, percent change.
Tool call:
name, display, and a sparkline array — none of which the model usually needs for a “what moved today” question:
[*] projects across every array element; {s:symbol, p:price, chg:change} is the multiselect-hash — it builds a new object per element using whichever fields you list. Shorter output keys (s, p, chg) shave a few more bytes; standard keys (symbol, price, change) are fine too if you want readability.
3. Filter on a numeric comparator
Intent. Fromget_conflict_events, keep only UCDP events with at least one confirmed fatality.
Tool call:
deathsBest: 0 — political incidents, intercepted attacks, near-misses:
deathsBest: 0 entry is dropped.
Why this works. [?expr] is the filter projection; > is the numeric comparator. Backticks around the literal matter — [?deathsBest > 0] (no backticks) treats 0 as an identifier, which JMESPath parses but then evaluates to null, and the comparison silently returns no rows. Always wrap numeric and boolean literals in backticks.
4. Filter on string equality
Intent. Fromget_conflict_events, get every UCDP event whose country is exactly "Iraq".
Tool call:
"stocks-bootstrap"). A common first-time mistake is [?country == "Iraq"], which JMESPath parses as “compare country to a field literally named Iraq”, evaluates the right-hand side to null, and returns no rows.
5. Array projection — flat list of one field
Intent. Fromget_market_data, get a flat list of sector ETF tickers.
Tool call:
[*] projects across every array element, and .symbol is applied to each one in turn. The result is an array of just the symbol strings — no enclosing objects.
6. Slice — first N elements
Intent. Fromget_conflict_events, return only the first five UCDP events.
Tool call:
events[].
Why this works. [start:stop] is the slice projection (stop is exclusive). Negative indices and a step are also supported — [-5:] for the last five, [::-1] to reverse, [::2] for every other element. Slicing is post-filter in the pipeline — to slice the filtered set, pipe (see example 12).
7. length() for counting
Intent. How many UCDP events are in the latest bundle?
Tool call:
length() is one of JMESPath’s built-in functions; it works on arrays, strings, and objects (where it returns the key count). Useful as a sanity check before a longer call — a length() projection returns a single integer, costs nothing in tokens, and tells the model whether the bundle is empty before deciding what to project next.
8. sort_by + reverse + slice — Top-N
Intent. From get_conflict_events, give me the three deadliest UCDP events with country + death count only.
Tool call:
|:
sort_by(events, &deathsBest)— JMESPath sorts ascending;&expris an expression reference (sort key).reverse(@)— flip ascending to descending.@is the current node.[0:3].{...}— slice the top three, then multiselect-hash to slim each row.
9. Filter on enum-string field
Intent. Fromget_conflict_events, return only UCDP events classified as state-based violence — the highest-severity tier.
Tool call:
[?...].{a:..., b:...} filters first, then slims each surviving row. Most WorldMonitor responses use upper-snake enum strings (SEVERITY_LEVEL_HIGH, TREND_DIRECTION_STABLE, UCDP_VIOLENCE_TYPE_*); search them with == and single quotes exactly as written.
10. Object-as-map navigation
Intent. Fromget_chokepoint_status, get the risk level + 7-day incident count for the Strait of Hormuz only.
Tool call:
summaries is keyed by chokepoint name (object map), not an array of {name, ...} records:
fear-greed.categories, EU member-keyed series in get_eu_housing_cycle. Treat them as dotted path navigation: known key → use the key directly. If you don’t know the key, see the next example.
11. Object-as-map projection — * and keys()
Intent. From get_chokepoint_status, list every chokepoint currently rated “critical” with its incident count.
Tool call:
summaries.* flattens the map’s values into an array — so suez, hormuz_strait, bab_el_mandeb, etc. become indexable array elements. Then a normal [?…] filter and multiselect-hash apply.
The flatten drops the original map keys (the chokepoint names). If you need the names too, project them separately with keys(data."transit-summaries".summaries), or accept the structural mismatch and switch to the sibling chokepoint_transits.transits payload, which IS keyed-as-map of {tanker, cargo, other, total} with the chokepoint name as the key — keys(data.chokepoint_transits.transits) gets you a flat list of every chokepoint covered.
12. Pipe combinator — multi-stage projection
Intent. Fromget_conflict_events, give me the five deadliest fatality-positive events with country, death count, and violence type.
Tool call:
| resets the context to “the result so far” and starts a new projection — so the filter runs first, the sort runs against the filtered set (not the whole array), reverse flips it, slice takes the top five, and the multiselect-hash slims each row. Pipe is the right tool whenever you need to apply a projection (like sort_by) after a filter rather than across the original array.
Escape hatches
Get the full payload (no projection)
Omit thejmespath argument entirely. Some tools (get_country_macro, the three get_eu_* tools, get_displacement_data) also default-cap their list-shaped fields at 30 rows for the same reason; pass limit: 0 to disable that cap when you genuinely want the whole bundle:
_budget_exceeded — when the payload is too big
Each tool declares a per-tool output budget (_outputBudgetBytes). When a tool’s serialised response exceeds that budget after all filtering, summary, and JMESPath have been applied, the server returns this envelope instead of the oversized payload — still inside the normal MCP result, still HTTP 200, still isError: false:
country, since, limit) underneath it. The Pro daily quota is automatically rolled back when this envelope fires — you don’t pay a quota slot for a response you can’t use.
_jmespath_error — when the projection itself fails
A JMESPath expression can fail in two ways: it can be syntactically invalid, or it can blow up the per-call output limit (256 KB) via a runaway multiselect-hash. Either way you get this envelope back:
original_keys is the top-level keys of the unprojected response — enough context for the model to retry with a corrected expression in one extra call. A bad expression does consume one daily quota slot per attempt; the echoed original_keys exists specifically to make the retry self-correcting rather than guesswork.
Complements to projection
summary: true flag
Every cache tool also accepts a universal summary: true argument that returns a server-built summary (counts + samples) instead of the full payload. Use it when:
- You want a quick sanity-check of what’s in the bundle before designing a projection —
summary: truereturns the shape and tier counts in a handful of fields. - The model only needs aggregate counts (“how many active conflicts?”, “how many critical chokepoints?”) and not the underlying rows.
summary: true and jmespath compose: the summary is built first, then the projection applies on top. Combine the two when you want the summary’s pre-aggregated counts but only some of the categories.
describe_tool
When tools/list returns a compressed description that’s ambiguous about a tool’s response shape, call describe_tool({ tool_name: "get_market_data" }) to fetch the full uncompressed definition. describe_tool is metadata-only and exempt from the Pro daily quota — use it freely while authoring projections. If the name is wrong, the response is { error: "unknown_tool", available: [...] }, again with no quota cost.
See also
- JMESPath specification — the canonical grammar reference.
- MCP Quickstart — five-minute zero-to-first-call onboarding.
- MCP Tools Reference — per-tool parameters, freshness budgets, and response shapes for every tool.
- MCP Server reference — auth, OAuth setup, plans, quotas, errors.
