Skip to main content
Glama

Query a table exactly

query_table
Read-only

Run an EXACT, deterministic query over ONE tabular file (a CSV, or the first table of a spreadsheet/PDF/Word document). Use this instead of ask_docs whenever the question needs COUNTING, SUMMING, AVERAGING, MIN/MAX, FILTERING, or exact row lookups over structured data ('how many rows...', 'total amount by region', 'list orders where status is failed') - semantic search undercounts tables, while this executes over EVERY row and returns exact numbers. Use ask_docs for prose/meaning questions and get_file to read a whole document. The query argument is a JSON object: { select?: [column names to return as raw rows], where?: [{col, op, value}, ...] filters combined with AND - ops eq | neq | contains compare text case-insensitively, gt | gte | lt | lte compare numerically (rows whose cell is not a number are skipped and counted in skippedNonNumeric), groupBy?: 'column' gives one result row per distinct value, aggregates?: [{fn, col}] with fn count | sum | avg | min | max ('col' required except for count), limit?: max raw rows (default 50, max 200) }. Column names match the file's header row case-insensitively. Examples: {"where":[{"col":"status","op":"eq","value":"failed"}],"aggregates":[{"fn":"count"}]} counts failed rows; {"groupBy":"region","aggregates":[{"fn":"sum","col":"amount"}]} totals amount per region; {"select":["name","email"],"where":[{"col":"country","op":"eq","value":"FR"}]} returns the matching rows. If you name a column that does not exist, the error lists the file's real columns - retry with one of those. Read-only; nothing is written, so it is safe to call.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesThe constrained query object (grammar in the tool description): select?, where?, groupBy?, aggregates?, limit?.
fileIdYesThe id of the file to query (from list_files / search_files - the same id get_file takes).
handleNoOptional: name one of the user's OWN profiles by its public @handle (with or without the leading @), as listed by list_profiles - an alternative to projectId, and it takes precedence if both are given. Honored only for an account-wide connection; a single-project connection is already scoped and ignores it. A handle that is not one of the user's own profiles is refused outright, never quietly swapped for another profile. To read context someone ELSE shared with the user or published, use shared_context instead.
projectIdNoOptional: which of the user's projects holds the file. Honored only for an account-wide connection; a single-project connection is already scoped and ignores this.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
rowsNoRaw matching rows (select mode). Either rows or groups is present, never both.
groupsNoAggregate rows (aggregate / groupBy mode).
columnsYes
truncatedYesTrue when rows/groups were clipped by a cap.
tableSourceYesWhether the rows came from a native CSV parse, an extracted document table, or a table read out of an image (image numbers may be misread - treat them as approximate).
rowCountTotalYesTotal data rows in the table.
rowCountMatchedYesRows that passed the where filter.
skippedNonNumericNoCells skipped as non-numeric during a numeric comparison or aggregate (present only when > 0).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedOutput schema / properties / tableSource / description
      Previous value: -"Whether the rows came from a native CSV parse or an extracted document table."New value: +"Whether the rows came from a native CSV parse, an extracted document table, or a table read out of an image (image numbers may be misread - treat them as approximate)."
    • changedOutput schema / properties / tableSource / enum
      Previous value: -[
      -  "csv",
      -  "extracted"
      -]New value: +[
      +  "csv",
      +  "extracted",
      +  "image"
      +]
  2. Changed1 schema field changed
    • addedInput schema / properties / handle
      Added value: +{
      +  "description": "Optional: name one of the user's OWN profiles by its public @handle (with or without the leading @), as listed by list_profiles - an alternative to projectId, and it takes precedence if both are given. Honored only for an account-wide connection; a single-project connection is already scoped and ignores it. A handle that is not one of the user's own profiles is refused outright, never quietly swapped for another profile. To read context someone ELSE shared with the user or published, use shared_context instead.",
      +  "type": "string"
      +}
  3. First observed

TDQS

A5/5.0
Behavior5/5

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

Beyond the readOnlyHint and destructiveHint annotations, the description discloses substantive behavior: the query is deterministic, executes over EVERY row rather than semantic sampling, skips non-numeric cells under numeric comparisons (tracked as skippedNonNumeric), matches column names case-insensitively, and returns real-column names in errors. It also reaffirms the read-only safety promise, consistent with annotations.

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

Conciseness5/5

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

The description is long, but every section earns its place: purpose and routing first, then query grammar, then worked examples, then error and safety behavior. The density is justified by the complexity of the nested query object, and the costliest information (when to use vs alternatives) is front-loaded.

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 tool with a nested query object, multiple siblings, and edge-case semantics, the description covers everything needed to invoke it correctly: the exact JSON shape, supported operators and aggregates, case-insensitivity, limit behavior, error recovery guidance, and read-only nature. An output schema also exists, so the absence of return-format detail is not a gap.

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?

Although schema description coverage is 100%, the tool description goes considerably further by defining the exact query grammar, operator semantics (eq/neq/contains vs gt/gte/lt/lte), the distinction between raw rows and aggregate results, default and maximum limits, and the requirement that col is optional only for count. It also gives three concrete examples mapping JSON forms to intended outcomes.

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 opens with a precise verb-object pair: 'Run an EXACT, deterministic query over ONE tabular file' and immediately specifies supported sources (CSV, first table of spreadsheet/PDF/Word). It also differentiates itself from ask_docs and get_file, so an agent can tell exactly which tool handles structured tabular lookups.

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 explicitly states when to use this tool instead of ask_docs: 'whenever the question needs COUNTING, SUMMING, AVERAGING, MIN/MAX, FILTERING, or exact row lookups over structured data'. It also gives the routing for prose/meaning questions to ask_docs and whole-document reads to get_file, leaving no ambiguity about alternatives.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.