Skip to main content
Glama

Cdc Query Dataset

cdc_query_dataset
Read-only

Execute a SoQL query against any CDC dataset. Supports filtering, aggregation, sorting, full-text search, and field selection. Use cdc_discover_datasets to find dataset IDs and cdc_get_dataset_schema to inspect columns before querying.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
groupNoSoQL GROUP BY clause. Requires aggregate functions in select.
limitNoMax rows to return (default 100). One call returns at most 5,000 rows: a larger limit, up to 1,000,000, is capped at 5,000, and the response says so and gives a nextOffset when more rows remain. Fewer come back when the page would carry the response past its 200,000-character budget, counted over the whole result — the rows as JSON and as the rendered table together; the response says so and gives a nextOffset to resume from.
orderNoSoQL ORDER BY clause. Field name with optional ASC/DESC: "total_deaths DESC". Set one from the first page whenever paging with offset, and keep it for the whole walk: SODA does not order results implicitly, so consecutive offsets without a deterministic order, or under a changed one, can skip or repeat rows. End it with a tie-breaker unique to each row: on ungrouped rows, the system field `:id`, present on every dataset (order="year DESC, :id"); on a grouped query, the grouped columns (order="total DESC, state"); on a distinct select, the selected columns. Socrata rejects `:id` once rows are grouped.
whereNoSoQL WHERE clause. Strings must be single-quoted: "state='California' AND year=2020". If a column name matches a SoQL keyword (group, select, where, order, limit, offset, having, search), wrap it in backticks: "`group`='By Year'".
domainNoCDC Socrata host to query. "data.cdc.gov" (default) and "chronicdata.cdc.gov" front the same catalog, so a four-by-four ID returns the same rows from either and the default works whichever host the dataset was found on.data.cdc.gov
havingNoSoQL HAVING clause. Filters aggregated results.
offsetNoRow offset for pagination (max 1,000,000). Pair with a deterministic order clause — an offset walk over unordered results can skip or repeat rows.
searchNoFull-text search across all text columns. For precise filtering use the where parameter instead.
selectNoSoQL SELECT clause — column names, aliases, or aggregates: "state, sum(deaths) as total_deaths". Omit for all columns. To enumerate distinct values of a column, set select to "{column}, count(*) as count" with group="{column}" and order="count DESC, {column}".
datasetIdYesFour-by-four dataset identifier (e.g., "bi63-dtpu"). Obtain from cdc_discover_datasets.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
capNoThe row limit that bounded this response: the requested limit, or 5,000 when a larger one was capped.
rowsNoResult rows with requested fields. Most values are strings (including numbers/dates); geo columns return GeoJSON objects.
errorNoPresent when the call failed. Absent on success.
shownNoNumber of rows returned in this response.
noticeNoGuidance when no rows matched, when offset ran past the end of the result set, when further rows remain (naming a limit above 5,000 that was capped), or when the response budget cut the page short — how to verify filters, lower offset, resume paging under the same order or restart it from offset 0 under one that makes the walk gap-free, or broaden the query.
rowCountNoNumber of rows returned in this response.
truncatedNoTrue when rows exist beyond the ones returned, established by fetching one row more than the limit rather than inferred from the row count. Absent means this response is the complete remainder of the result set.
nextOffsetNoOffset to pass on the next call, under the same order, to resume immediately after the last row returned. Present only when further rows exist and the resume point is within the offset ceiling. The walk is gap-free only when that order ends in a tie-breaker unique to each row; when it does not, the notice says to restart from offset 0 with one.
effectiveQueryNoThe SoQL clauses sent to Socrata, as `$clause=value` pairs joined by "&". Values read exactly as they were supplied — not URL-encoded — so a clause can be copied back into the matching parameter of another call.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Max rows to return (default 100, max 5000). Fewer come back when the page would carry the response past its 200,000-character budget, counted over the whole result — the rows as JSON and as the rendered table together; the response says so and gives a nextOffset to resume from."New value: +"Max rows to return (default 100). One call returns at most 5,000 rows: a larger limit, up to 1,000,000, is capped at 5,000, and the response says so and gives a nextOffset when more rows remain. Fewer come back when the page would carry the response past its 200,000-character budget, counted over the whole result — the rows as JSON and as the rendered table together; the response says so and gives a nextOffset to resume from."
    • changedInput schema / properties / limit / maximum
      Previous value: -5000New value: +1000000
    • changedInput schema / properties / order / description
      Previous value: -"SoQL ORDER BY clause. Field name with optional ASC/DESC: \"total_deaths DESC\". Set one whenever paging with offset: SODA does not order results implicitly, so consecutive offsets without a deterministic order can skip or repeat rows. When the dataset has no natural unique column, Socrata's documented minimum tie-breaker is the system field `:id`, present on every dataset — order=\":id\"."New value: +"SoQL ORDER BY clause. Field name with optional ASC/DESC: \"total_deaths DESC\". Set one from the first page whenever paging with offset, and keep it for the whole walk: SODA does not order results implicitly, so consecutive offsets without a deterministic order, or under a changed one, can skip or repeat rows. End it with a tie-breaker unique to each row: on ungrouped rows, the system field `:id`, present on every dataset (order=\"year DESC, :id\"); on a grouped query, the grouped columns (order=\"total DESC, state\"); on a distinct select, the selected columns. Socrata rejects `:id` once rows are grouped."
    • changedInput schema / properties / select / description
      Previous value: -"SoQL SELECT clause — column names, aliases, or aggregates: \"state, sum(deaths) as total_deaths\". Omit for all columns. To enumerate distinct values of a column, set select to \"{column}, count(*) as count\" with group=\"{column}\" and order=\"count DESC\"."New value: +"SoQL SELECT clause — column names, aliases, or aggregates: \"state, sum(deaths) as total_deaths\". Omit for all columns. To enumerate distinct values of a column, set select to \"{column}, count(*) as count\" with group=\"{column}\" and order=\"count DESC, {column}\"."
    • changedOutput schema / properties / cap / description
      Previous value: -"The requested limit that bounded this response."New value: +"The row limit that bounded this response: the requested limit, or 5,000 when a larger one was capped."
    • changedOutput schema / properties / nextOffset / description
      Previous value: -"Offset to pass on the next call to resume immediately after the last row returned. Present only when further rows exist and the resume point is within the offset ceiling; a deterministic order clause is what makes the walk gap-free."New value: +"Offset to pass on the next call, under the same order, to resume immediately after the last row returned. Present only when further rows exist and the resume point is within the offset ceiling. The walk is gap-free only when that order ends in a tie-breaker unique to each row; when it does not, the notice says to restart from offset 0 with one."
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when no rows matched, when offset ran past the end of the result set, when further rows remain, or when the response budget cut the page short — how to verify filters, lower offset, resume paging, or broaden the query."New value: +"Guidance when no rows matched, when offset ran past the end of the result set, when further rows remain (naming a limit above 5,000 that was capped), or when the response budget cut the page short — how to verify filters, lower offset, resume paging under the same order or restart it from offset 0 under one that makes the walk gap-free, or broaden the query."
  2. Changed2 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Max rows to return (default 100, max 5000). Fewer come back when the page would cross the 200,000-character response budget; the response says so and gives a nextOffset to resume from."New value: +"Max rows to return (default 100, max 5000). Fewer come back when the page would carry the response past its 200,000-character budget, counted over the whole result — the rows as JSON and as the rendered table together; the response says so and gives a nextOffset to resume from."
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when no rows matched, when further rows remain, or when the response budget cut the page short — how to verify filters, resume paging, or broaden the query."New value: +"Guidance when no rows matched, when offset ran past the end of the result set, when further rows remain, or when the response budget cut the page short — how to verify filters, lower offset, resume paging, or broaden the query."
  3. Changed2 schema fields changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset ID does not exist or has been retired. `no_such_column`: WHERE/SELECT/GROUP/ORDER references a column that does not exist on this dataset. `type_mismatch`: Filter value type does not match the column data type (e.g., quoting a number). `invalid_query`: Socrata rejected the SoQL query for other syntax or semantic reasons. `access_denied`: Socrata returned 403 — typically an ID naming a chart, map, story, file, or external link rather than a tabular dataset. `rate_limited`: Socrata API returns 429 Too Many Requests. `upstream_error`: Socrata data API returned a 5xx server error. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset ID does not exist or has been retired. `no_such_column`: WHERE/SELECT/GROUP/ORDER references a column that does not exist on this dataset. `type_mismatch`: Filter value type does not match the column data type (e.g., quoting a number). `invalid_query`: Socrata rejected the SoQL query for other syntax or semantic reasons. `not_queryable`: The ID names a non-tabular asset: the data endpoint answered with rows carrying no fields, and the asset reports no columns. `access_denied`: Socrata returned 403 — typically an ID naming a story, file, or external link rather than a tabular dataset. `rate_limited`: Socrata API returns 429 Too Many Requests. `upstream_error`: Socrata data API returned a 5xx server error. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "dataset_not_found",
      -  "no_such_column",
      -  "type_mismatch",
      -  "invalid_query",
      -  "access_denied",
      -  "rate_limited",
      -  "upstream_error"
      -]New value: +[
      +  "dataset_not_found",
      +  "no_such_column",
      +  "type_mismatch",
      +  "invalid_query",
      +  "not_queryable",
      +  "access_denied",
      +  "rate_limited",
      +  "upstream_error"
      +]
  4. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "rows",
      +      "rowCount",
      +      "effectiveQuery"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset ID does not exist or has been retired. `no_such_column`: WHERE/SELECT/GROUP/ORDER references a column that does not exist on this dataset. `type_mismatch`: Filter value type does not match the column data type (e.g., quoting a number). `invalid_query`: Socrata rejected the SoQL query for other syntax or semantic reasons. `access_denied`: Socrata returned 403 — typically an ID naming a chart, map, story, file, or external link rather than a tabular dataset. `rate_limited`: Socrata API returns 429 Too Many Requests. `upstream_error`: Socrata data API returned a 5xx server error. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "dataset_not_found",
      +            "no_such_column",
      +            "type_mismatch",
      +            "invalid_query",
      +            "access_denied",
      +            "rate_limited",
      +            "upstream_error"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "rows",
      -  "rowCount",
      -  "effectiveQuery"
      -]
  5. Changed6 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Max rows to return (default 100, max 5000)."New value: +"Max rows to return (default 100, max 5000). Fewer come back when the page would cross the 200,000-character response budget; the response says so and gives a nextOffset to resume from."
    • changedInput schema / properties / offset / description
      Previous value: -"Row offset for pagination (max 1,000,000)."New value: +"Row offset for pagination (max 1,000,000). Pair with a deterministic order clause — an offset walk over unordered results can skip or repeat rows."
    • changedInput schema / properties / order / description
      Previous value: -"SoQL ORDER BY clause. Field name with optional ASC/DESC: \"total_deaths DESC\"."New value: +"SoQL ORDER BY clause. Field name with optional ASC/DESC: \"total_deaths DESC\". Set one whenever paging with offset: SODA does not order results implicitly, so consecutive offsets without a deterministic order can skip or repeat rows. When the dataset has no natural unique column, Socrata's documented minimum tie-breaker is the system field `:id`, present on every dataset — order=\":id\"."
    • addedOutput schema / properties / nextOffset
      Added value: +{
      +  "description": "Offset to pass on the next call to resume immediately after the last row returned. Present only when further rows exist and the resume point is within the offset ceiling; a deterministic order clause is what makes the walk gap-free.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when no rows matched or results were truncated — how to verify filters, paginate, or broaden the query."New value: +"Guidance when no rows matched, when further rows remain, or when the response budget cut the page short — how to verify filters, resume paging, or broaden the query."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when the result row count hit the requested limit and may be incomplete."New value: +"True when rows exist beyond the ones returned, established by fetching one row more than the limit rather than inferred from the row count. Absent means this response is the complete remainder of the result set."
  6. Changed2 schema fields changed
    • changedInput schema / properties / domain / description
      Previous value: -"CDC Socrata portal hosting the dataset. Must match the portal the dataset lives on: \"data.cdc.gov\" (default) or \"chronicdata.cdc.gov\" (PLACES and other chronic-disease/small-area datasets)."New value: +"CDC Socrata host to query. \"data.cdc.gov\" (default) and \"chronicdata.cdc.gov\" front the same catalog, so a four-by-four ID returns the same rows from either and the default works whichever host the dataset was found on."
    • changedOutput schema / properties / effectiveQuery / description
      Previous value: -"Assembled SoQL query string sent to the Socrata API."New value: +"The SoQL clauses sent to Socrata, as `$clause=value` pairs joined by \"&\". Values read exactly as they were supplied — not URL-encoded — so a clause can be copied back into the matching parameter of another call."
  7. Changed2 schema fields changed
    • changedInput schema / properties / offset / description
      Previous value: -"Row offset for pagination."New value: +"Row offset for pagination (max 1,000,000)."
    • changedInput schema / properties / offset / maximum
      Previous value: -9007199254740991New value: +1000000
  8. Changed1 schema field changed
    • addedInput schema / properties / domain
      Added value: +{
      +  "default": "data.cdc.gov",
      +  "description": "CDC Socrata portal hosting the dataset. Must match the portal the dataset lives on: \"data.cdc.gov\" (default) or \"chronicdata.cdc.gov\" (PLACES and other chronic-disease/small-area datasets).",
      +  "enum": [
      +    "data.cdc.gov",
      +    "chronicdata.cdc.gov"
      +  ],
      +  "type": "string"
      +}
  9. Changed1 schema field changed
    • changedInput schema / properties / where / description
      Previous value: -"SoQL WHERE clause. Strings must be single-quoted: \"state='California' AND year=2020\"."New value: +"SoQL WHERE clause. Strings must be single-quoted: \"state='California' AND year=2020\". If a column name matches a SoQL keyword (group, select, where, order, limit, offset, having, search), wrap it in backticks: \"`group`='By Year'\"."
  10. Changed4 schema fields changed
    • addedOutput schema / properties / cap
      Added value: +{
      +  "description": "The requested limit that bounded this response.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when no rows matched — suggests how to verify filter values or broaden the WHERE clause."New value: +"Guidance when no rows matched or results were truncated — how to verify filters, paginate, or broaden the query."
    • addedOutput schema / properties / shown
      Added value: +{
      +  "description": "Number of rows returned in this response.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when the result row count hit the requested limit and may be incomplete.",
      +  "type": "boolean"
      +}
  11. Changed1 schema field changed
    • changedInput schema / properties / datasetId / description
      Previous value: -"Four-by-four dataset identifier (e.g., \"bi63-dtpu\")."New value: +"Four-by-four dataset identifier (e.g., \"bi63-dtpu\"). Obtain from cdc_discover_datasets."
  12. Changed4 schema fields changed
    • addedOutput schema / properties / effectiveQuery
      Added value: +{
      +  "description": "Assembled SoQL query string sent to the Socrata API.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Guidance when no rows matched — suggests how to verify filter values or broaden the WHERE clause.",
      +  "type": "string"
      +}
    • removedOutput schema / properties / query
      Removed value: -{
      -  "description": "Assembled SoQL query string sent to Socrata.",
      -  "type": "string"
      -}
    • changedOutput schema / required
      Previous value: -[
      -  "rows",
      -  "rowCount",
      -  "query"
      -]New value: +[
      +  "rows",
      +  "rowCount",
      +  "effectiveQuery"
      +]
  13. Changed4 schema fields changed
    • changedInput schema / properties / limit / default
      Previous value: -1000New value: +100
    • changedInput schema / properties / limit / description
      Previous value: -"Max rows to return (default 1000, max 5000)."New value: +"Max rows to return (default 100, max 5000)."
    • changedInput schema / properties / search / description
      Previous value: -"Full-text search across all text columns (maps to $q). For precise filtering use where instead."New value: +"Full-text search across all text columns. For precise filtering use the where parameter instead."
    • changedOutput schema / properties / query / description
      Previous value: -"Assembled SoQL query string (for debugging)."New value: +"Assembled SoQL query string sent to Socrata."
  14. Changed1 schema field changed
    • changedInput schema / properties / select / description
      Previous value: -"SoQL SELECT clause. Column names, aliases, aggregates: \"state, sum(deaths) as total_deaths\". Omit for all columns."New value: +"SoQL SELECT clause — column names, aliases, or aggregates: \"state, sum(deaths) as total_deaths\". Omit for all columns. To enumerate distinct values of a column, set select to \"{column}, count(*) as count\" with group=\"{column}\" and order=\"count DESC\"."
  15. First observed

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds the capability surface (filtering, aggregation, full-text search) which frames what the query can do, but it does not disclose result-size limits, pagination behavior, or rate limits in the prose — those live in the schema. Adequate but not rich given the annotation baseline.

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?

Three tight sentences: purpose first, capabilities second, prerequisite workflow third. No redundancy and the most important information is front-loaded.

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

Completeness4/5

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

With an output schema present, return values need not be explained, and the inputs are exhaustively documented in the schema. The description supplies the needed orientation for a 10-parameter query tool; only the relationship to cdc_query_wonder is left unstated.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline is 3. The description maps its capability list to the corresponding parameters (where, group, order, search, select), adding marginal connective value, but every parameter already carries detailed inline documentation.

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

Purpose4/5

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

States a specific verb and resource: 'Execute a SoQL query against any CDC dataset', and enumerates the supported operations (filtering, aggregation, sorting, full-text search, field selection). It distinguishes itself from cdc_discover_datasets and cdc_get_dataset_schema by naming them as prerequisites, though it does not clarify how it differs from cdc_query_wonder.

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

Usage Guidelines4/5

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

Gives clear workflow context: call cdc_discover_datasets for dataset IDs and cdc_get_dataset_schema to inspect columns before querying. It provides positive routing guidance but no explicit exclusions or when-not conditions (e.g., vs cdc_query_wonder).

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.