Skip to main content
Glama

run_query

Read-onlyIdempotent

Query large JSON files with JSONPath filters and aggregation pipes to count, sum, group, rank, and project fields, returning only bounded results from a file path or open document.

Instructions

Use this instead of ad-hoc Python for JSON counts, filtered exact sums/averages/min/max, composite groups, distinct values, top/bottom ranking, and field projection. It scans server-side and returns only the bounded answer. Pass filePath for a one-call answer, or docId to reuse an open document. For field names and types use get_schema; for coverage and statistics of many fields at once, profile; to judge counts against expectations, run_checks. Grammar (a JSONPath subset with aggregation pipes):

Paths: $.key $['odd key'] $[3] $[-1] $[1:5] $.arr[] $..key (recursive) A [...] step attaches directly to what precedes it: $['odd key'], $.a['b c'] — never $.['odd key']. Any key that is not a plain identifier (space, '-', '.') must be bracketed: $['line-items'], @['unit price']. $.arr is the array itself; $.arr[] is its elements — $.orders[] | count counts the orders, $.orders | count is 1. Predicates filter the CHILDREN of the current node: $.tasks[?(...)] A [?(...)] step already yields the matched elements — never follow it with []. Operators: == != > >= < <= (numbers and strings) Boolean: && || ! Grouping: ( ) — there is no !~; negate with !( … ) Strings: @.name contains 'x' | startsWith | endsWith | @.name =~ /safe-regex/i Membership: @.status in ['A','B'] Arrays: @.tags contains 'x' Set: @.field — true unless the key is missing, null or false ('' and 0 count as set) Explicit: @.field present (key exists) | missing (no key) | isNull (value is null) Fields compare to fields: @.capacity.used > @.capacity.max A predicate holds one level only: no predicate inside a predicate, no $ path inside it Pipes: append AT MOST ONE, at the very end. Pipes never chain — | top(...) | pluck(...) is invalid. | count | sum(@.x) | avg(@.x) | min(@.x) | max(@.x) | distinct | group(@.x, @.y) | top(@.score, @.id) | bottom(@.score, @.id) | pluck(@.a, @.b.c) top/bottom/pluck already name their output columns — never add a second pipe to project them. A pipe argument is one plain field path (@.a.b) — no [], no arithmetic, no second query. A pipe without args operates on the matched values themselves: $.a[].n | sum

Examples: "how many tasks have no route" → $.tasks[?(!@.routeId)] | count "how many orders are there" → $.orders[] | count "failed tasks by reason" → $.tasks[?(@.status =~ /^failed$/i)] | group(@.failureReason) "tasks that are not cancelled" → $.tasks[?(!(@.status =~ /^cancelled$/i))] "top delayed tasks" → $.tasks[] | top(@.delayMinutes, @.id, @.status) "highest value orders showing just their id and amount" → $.orders[] | top(@.amount, @.id) "all statuses that appear" → $..status | distinct "ids and etas of pending tasks" → $.tasks[?(@.status =~ /^pending$/i)] | pluck(@.id, @.eta) "total line value of failed orders" → $.orders[?(@.status =~ /^failed$/i)].items[].lineTotal | sum "sum of the line-total column" → $['line-items'][*] | sum(@['line-total']) "the run id" → $['meta data']['run id'] "tasks outside india" → $.tasks[?(@.loc.lat < 8 || @.loc.lat > 37)]

Matches come back as path + preview; use | pluck(@.a, @.b) to project real fields into rows, or the sample tool for whole values. Only 10 detail rows return by default; set limit=0 for a count-only summary or page with offset+limit. Aggregates always scan every match. Numeric predicates and aggregates keep int64 and decimal digits exact. For only a count, append | count; the response is one scalar.

Input Schema

NameRequiredDescriptionDefault
docIdNoA docId returned by load_doc.
limitNoMaximum detail rows returned (default 10, 0 for summary only, max 100).
queryYesA query, e.g. $.tasks[?(@.status == 'FAILED')] | count; $.tasks[*] | group(@.region, @.status); $.tasks[*] | top(@.delay, @.id)
offsetNoDetail rows to skip (default 0).
filePathNoFile to open and query now instead of supplying docId.

Output Schema

NameRequiredDescriptionDefault
okYes
hintNo
toolYes
errorNo
evictedNo
structuredTruncatedNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the read-only annotations, the description discloses server-side scanning, bounded responses, default detail-row limits, count-only summaries, offset/limit paging, and exact int64/decimal handling. It also explains that matches return path plus preview and that pluck projects real fields into rows.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core use case and alternatives before diving into grammar, and its length is largely justified by the query language. However, it is very long and includes some repeated guidance, so it is comprehensive rather than maximally concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex query tool, the description covers selection, alternatives, parameter roles, grammar, pagination, projection, and aggregate behavior. With an output schema also present, no critical calling information appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers all parameters, but the description adds meaningful semantics: filePath versus docId usage, limit=0 as a summary-only mode, offset/limit paging, and an extensive query grammar. This goes well beyond what the schema alone provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific operation on a specific resource: running JSONPath-style queries that count, group, rank, and aggregate JSON. It clearly distinguishes itself from siblings such as get_schema, profile, run_checks, and sample, so an agent can identify when this tool is the right one.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit routing guidance: use this instead of ad-hoc Python for counts and aggregations, pass filePath for a one-call answer or docId to reuse an open document. It also names alternatives for field discovery, profiling, expectation checking, and whole-value sampling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.