Skip to main content
Glama

Compare Census Geographies

census_compare_geographies
Read-only

Compare one or more variables across multiple geographies at the same level — all counties in a state, all states nationally, or a named set of specific geographies — ranked on the value of one of them. Covers queries like "compare median income across WA counties" or "which states have the most people below the poverty line." A count ranks geographies by size, not by rate, so to rank a rate, rank a published percentage: S1701_C03_001E (percent below the poverty level, dataset acs/acs5/subject), DP03_0128PE (the same percentage, acs/acs5/profile), or DP04_0047PE (percent of occupied housing units that are renter-occupied, acs/acs5/profile). Profile and subject tables reach tracts but not block groups. Omit within to compare all geographies nationally at the level. Suppressed values are decoded to human-readable labels rather than passed through as raw negative sentinels. On the business datasets (cbp, ecnbasic, nonemp), pep/charv, dec/ddhca, and acs/acs1/spp, use predicates to rank within one industry, size class, or population group — a comparison that omits one ranks on a default the Census API picks, which is an all-categories total on some dimensions and a single category on others. Each row names the defaults that were applied in applied_filters, and census_list_predicate_values enumerates the codes a dimension accepts. A dataset that publishes several records per geography cannot be ranked until one is pinned: pep/charv publishes an April estimates base and a July estimate, so a comparison that pins neither fails with ambiguous_rows rather than giving every geography two ranks — pass predicates {"MONTH": "7"} for the July estimate.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
yearNoVintage year (default: latest available for the dataset).
limitNoMaximum geographies to return (default: 50, max: 500). When results are truncated, totalCount says how many matched.
withinNoState FIPS to constrain results (e.g., "53" to compare counties or tracts within WA only). Omit to compare all geographies at the level nationally. Use census_resolve_geography to get state_fips. Pass "*" to span every state. Blank is treated as omitted.
datasetNoDataset to query (default: "acs/acs5"). Use census_list_datasets for valid values. Case is ignored, and a two-part code can be given by its last part alone — "acs5" is acs/acs5, "pl" is dec/pl. Three-part codes such as acs/acs5/profile must be given in full. The response echoes the resolved code.
sort_byNoVariable code to rank on (default: the first code in variables), uppercased like the variables. Must be one of the requested codes, or the call fails with sort_by_not_requested. Geographies rank on that code's own value, so a count ranks by size and only a published percentage such as S1701_C03_001E or DP03_0128PE ranks by rate.
sort_dirNoSort direction (default: "desc" — highest value first).
variablesYesVariable codes to compare (e.g., ["B19013_001E", "B19013_001M"]); the ranking is on one of them, set by sort_by. Codes are uppercased before the request, and each row is keyed by the uppercase code. At most 49 per call: the Census API accepts 50 columns per request and every query also sends NAME. On datasets where a label column is added for each filter dimension left unset, or record columns are added (cbp, ecnbasic, nonemp, pep/charv, dec/ddhca, acs/acs1/spp), the maximum is lower, and too_many_variables states the exact number for the comparison. On ACS datasets, add the margin-of-error counterpart of a code (same code, E suffix swapped for M) for reliability context. The ACS comparison profiles (acs/acs5/cprofile, acs/acs1/cprofile) and the other dataset families (pep, dec, cbp, ecnbasic, nonemp) publish no margins of error.
predicatesNoFilter values keyed by variable code, applied to every geography in the comparison — e.g. {"NAICS2017": "5112"} to rank counties by their software-publisher establishment count in cbp. The business datasets (cbp, ecnbasic, nonemp), pep/charv, dec/ddhca, and acs/acs1/spp declare filter dimensions such as industry (NAICS2017/NAICS2022), legal form (LFO), size class (EMPSZES/RCPSZES), tax status (TAXSTAT), operation type (TYPOP), sex (SEX), age (AGE), and population group (POPGROUP). Leaving one unset is not an error: the Census API substitutes its own default, which is the all-categories total on cbp NAICS2017 but a single population group on dec/ddhca POPGROUP and a single sector on ecnbasic NAICS2022 — so a ranking can read like an overall one without being it. Every unset dimension is named in the response notice and its applied default is echoed per row in applied_filters. Keys are matched case-insensitively, and a blank value is treated as omitted. A value of "*" returns every geography once per category of that dimension, which a ranking cannot hold, so it fails with ambiguous_rows naming the dimension to pin — use census_query_data for a per-category breakdown. Code names vary by dataset and vintage — cbp 2023 uses NAICS2017 while nonemp 2023 uses NAICS2022 — so read them from the notice or from census_search_variables. Call census_list_predicate_values for the codes a dimension accepts; NAICS values are standard North American Industry Classification System codes at any depth (51 information, 5112 software publishers).
geographiesNoOptional list of specific geographies to include; only these are returned. Prefer full GEOIDs — the level concatenated with its parents, e.g. "53033" for King County WA and "06037" for Los Angeles County CA — which are nationally unique and so work across states. Bare level codes ("033") are also accepted but match that code in every state unless within scopes them to one. A GEOID is easiest taken from the geography_geoid field of a census_query_data or census_compare_geographies row; from census_resolve_geography, concatenate state_fips, then county_fips when it is present, then fips_summary. Entries that match nothing, and bare codes that match more than one state, are named in the response notice.
within_countyNoCounty FIPS to constrain tract or block-group comparisons to a single county within the state specified by within (e.g., "033" for King County). Required when geography_level is "tract" or "block group" and you want county-scoped results. census_resolve_geography returns this as county_fips. Pass "*" to span every county in the state, which is the only way a block-group comparison reaches a whole state. Blank is treated as omitted.
geography_levelYesThe level to compare across (e.g., "state", "county", "tract"). Use census_list_geographies to see valid values for the dataset.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
rowsNoGeographies sorted by the requested variable. Suppressed values are labeled.
yearNoVintage year queried.
errorNoPresent when the call failed. Absent on success.
noticeNoGuidance when results were truncated, when the sort column holds no number on any row (so the rows are in the order the Census returned them rather than ranked), when geographies entries matched no row, when a bare level code matched more than one state, or when the dataset declares filter dimensions the comparison left unset — how to narrow scope, raise the limit, correct the FIPS codes, or add the predicates that pin what the ranking covers. For an unset dimension it also quotes the label of the default the Census API applied, which is what says whether the ranking is on a total or on one category. Also names any variable codes whose flags could not be checked because the request had no room left under the Census 50-column limit — a withheld value there reads as 0 and ranks as one.
datasetNoDataset queried.
truncatedNoTrue when totalCount exceeds the limit and results were cut off.
totalCountNoTotal number of geographies matched before the limit was applied.
sortVariableNoVariable code the rows are ranked on, uppercased as it appears in variables.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • changedInput schema / properties / dataset / description
      Previous value: -"Dataset to query (default: \"acs/acs5\"). Use census_list_datasets for valid values."New value: +"Dataset to query (default: \"acs/acs5\"). Use census_list_datasets for valid values. Case is ignored, and a two-part code can be given by its last part alone — \"acs5\" is acs/acs5, \"pl\" is dec/pl. Three-part codes such as acs/acs5/profile must be given in full. The response echoes the resolved code."
    • changedInput schema / properties / predicates / description
      Previous value: -"Filter values keyed by variable code, applied to every geography in the comparison — e.g. {\"NAICS2017\": \"5112\"} to rank counties by their software-publisher establishment count in cbp. The business datasets (cbp, ecnbasic, nonemp), pep/charv, and dec/ddhca declare filter dimensions such as industry (NAICS2017/NAICS2022), legal form (LFO), size class (EMPSZES/RCPSZES), tax status (TAXSTAT), operation type (TYPOP), sex (SEX), age (AGE), and population group (POPGROUP). Leaving one unset is not an error: the Census API substitutes its own default, which is the all-categories total on cbp NAICS2017 but a single population group on dec/ddhca POPGROUP and a single sector on ecnbasic NAICS2022 — so a ranking can read like an overall one without being it. Every unset dimension is named in the response notice and its applied default is echoed per row in applied_filters. Keys are matched case-insensitively, and a blank value is treated as omitted. A value of \"*\" returns every geography once per category of that dimension, which a ranking cannot hold, so it fails with ambiguous_rows naming the dimension to pin — use census_query_data for a per-category breakdown. Code names vary by dataset and vintage — cbp 2023 uses NAICS2017 while nonemp 2023 uses NAICS2022 — so read them from the notice or from census_search_variables. Call census_list_predicate_values for the codes a dimension accepts; NAICS values are standard North American Industry Classification System codes at any depth (51 information, 5112 software publishers)."New value: +"Filter values keyed by variable code, applied to every geography in the comparison — e.g. {\"NAICS2017\": \"5112\"} to rank counties by their software-publisher establishment count in cbp. The business datasets (cbp, ecnbasic, nonemp), pep/charv, dec/ddhca, and acs/acs1/spp declare filter dimensions such as industry (NAICS2017/NAICS2022), legal form (LFO), size class (EMPSZES/RCPSZES), tax status (TAXSTAT), operation type (TYPOP), sex (SEX), age (AGE), and population group (POPGROUP). Leaving one unset is not an error: the Census API substitutes its own default, which is the all-categories total on cbp NAICS2017 but a single population group on dec/ddhca POPGROUP and a single sector on ecnbasic NAICS2022 — so a ranking can read like an overall one without being it. Every unset dimension is named in the response notice and its applied default is echoed per row in applied_filters. Keys are matched case-insensitively, and a blank value is treated as omitted. A value of \"*\" returns every geography once per category of that dimension, which a ranking cannot hold, so it fails with ambiguous_rows naming the dimension to pin — use census_query_data for a per-category breakdown. Code names vary by dataset and vintage — cbp 2023 uses NAICS2017 while nonemp 2023 uses NAICS2022 — so read them from the notice or from census_search_variables. Call census_list_predicate_values for the codes a dimension accepts; NAICS values are standard North American Industry Classification System codes at any depth (51 information, 5112 software publishers)."
    • changedInput schema / properties / variables / description
      Previous value: -"Variable codes to compare (e.g., [\"B19013_001E\", \"B19013_001M\"]); the ranking is on one of them, set by sort_by. Codes are uppercased before the request, and each row is keyed by the uppercase code. At most 49 per call: the Census API accepts 50 columns per request and every query also sends NAME. On datasets where a label column is added for each filter dimension left unset, or record columns are added (cbp, ecnbasic, nonemp, pep/charv, dec/ddhca), the maximum is lower, and too_many_variables states the exact number for the comparison. On ACS datasets, add the margin-of-error counterpart of a code (same code, E suffix swapped for M) for reliability context. Other dataset families (pep, dec, cbp, ecnbasic, nonemp) publish no margins of error."New value: +"Variable codes to compare (e.g., [\"B19013_001E\", \"B19013_001M\"]); the ranking is on one of them, set by sort_by. Codes are uppercased before the request, and each row is keyed by the uppercase code. At most 49 per call: the Census API accepts 50 columns per request and every query also sends NAME. On datasets where a label column is added for each filter dimension left unset, or record columns are added (cbp, ecnbasic, nonemp, pep/charv, dec/ddhca, acs/acs1/spp), the maximum is lower, and too_many_variables states the exact number for the comparison. On ACS datasets, add the margin-of-error counterpart of a code (same code, E suffix swapped for M) for reliability context. The ACS comparison profiles (acs/acs5/cprofile, acs/acs1/cprofile) and the other dataset families (pep, dec, cbp, ecnbasic, nonemp) publish no margins of error."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS but within, or within_county, was not provided. `parent_not_accepted`: within or within_county names a parent the geography level does not sit within. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for this dataset and year. It names only the first unknown code in a request. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `sort_by_not_requested`: sort_by names a code that is not among the requested variables, so no column exists to rank on. `ambiguous_rows`: The dataset publishes several records per geography and the comparison pinned none of them, so every geography would occupy several ranks with different values. `no_data`: No geographies were returned for the query, or no row matched any entry in the geographies list. `upstream_error`: Census API was unreachable or returned an 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 code is not recognized, even after case and shorthand resolution. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS but within, or within_county, was not provided. `parent_not_accepted`: within or within_county names a parent the geography level does not sit within. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for this dataset and year. It names only the first unknown code in a request. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `sort_by_not_requested`: sort_by names a code that is not among the requested variables, so no column exists to rank on. `ambiguous_rows`: The dataset publishes several records per geography and the comparison pinned none of them, so every geography would occupy several ranks with different values. `no_data`: No geographies were returned for the query, or no row matched any entry in the geographies list. `upstream_error`: Census API was unreachable or returned an error. Other values are possible when a failure originates below the handler."
  2. Changed12 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum geographies to return (default: 50, max: 500). When results are truncated, total_count indicates how many matched."New value: +"Maximum geographies to return (default: 50, max: 500). When results are truncated, totalCount says how many matched."
    • addedInput schema / properties / limit / maximum
      Added value: +500
    • addedInput schema / properties / limit / minimum
      Added value: +1
    • changedInput schema / properties / limit / type
      Previous value: -"number"New value: +"integer"
    • changedInput schema / properties / predicates / description
      Previous value: -"Filter values keyed by variable code, applied to every geography in the comparison — e.g. {\"NAICS2017\": \"5112\"} to rank counties by their software-publisher establishment count in cbp. The business datasets (cbp, ecnbasic, nonemp), pep/charv, and dec/ddhca declare filter dimensions such as industry (NAICS2017/NAICS2022), legal form (LFO), size class (EMPSZES/RCPSZES), tax status (TAXSTAT), operation type (TYPOP), sex (SEX), age (AGE), and population group (POPGROUP). Leaving one unset is not an error: the Census API substitutes its own default, which is the all-categories total on cbp NAICS2017 but a single population group on dec/ddhca POPGROUP and a single sector on ecnbasic NAICS2022 — so a ranking can read like an overall one without being it. Every unset dimension is named in the response notice and its applied default is echoed per row in applied_filters. Code names vary by dataset and vintage — cbp 2023 uses NAICS2017 while nonemp 2023 uses NAICS2022 — so read them from the notice or from census_search_variables. Call census_list_predicate_values for the codes a dimension accepts; NAICS values are standard North American Industry Classification System codes at any depth (51 information, 5112 software publishers)."New value: +"Filter values keyed by variable code, applied to every geography in the comparison — e.g. {\"NAICS2017\": \"5112\"} to rank counties by their software-publisher establishment count in cbp. The business datasets (cbp, ecnbasic, nonemp), pep/charv, and dec/ddhca declare filter dimensions such as industry (NAICS2017/NAICS2022), legal form (LFO), size class (EMPSZES/RCPSZES), tax status (TAXSTAT), operation type (TYPOP), sex (SEX), age (AGE), and population group (POPGROUP). Leaving one unset is not an error: the Census API substitutes its own default, which is the all-categories total on cbp NAICS2017 but a single population group on dec/ddhca POPGROUP and a single sector on ecnbasic NAICS2022 — so a ranking can read like an overall one without being it. Every unset dimension is named in the response notice and its applied default is echoed per row in applied_filters. Keys are matched case-insensitively, and a blank value is treated as omitted. A value of \"*\" returns every geography once per category of that dimension, which a ranking cannot hold, so it fails with ambiguous_rows naming the dimension to pin — use census_query_data for a per-category breakdown. Code names vary by dataset and vintage — cbp 2023 uses NAICS2017 while nonemp 2023 uses NAICS2022 — so read them from the notice or from census_search_variables. Call census_list_predicate_values for the codes a dimension accepts; NAICS values are standard North American Industry Classification System codes at any depth (51 information, 5112 software publishers)."
    • changedInput schema / properties / sort_by / description
      Previous value: -"Variable code to sort by (default: first variable in the list). Must be one of the requested variable codes."New value: +"Variable code to rank on (default: the first code in variables), uppercased like the variables. Must be one of the requested codes, or the call fails with sort_by_not_requested. Geographies rank on that code's own value, so a count ranks by size and only a published percentage such as S1701_C03_001E or DP03_0128PE ranks by rate."
    • changedInput schema / properties / variables / description
      Previous value: -"Variable codes to compare (e.g., [\"B17001_002E\", \"B17001_001E\"]). On ACS datasets, add the margin-of-error counterpart of a code (same code, E suffix swapped for M) for reliability context. Other dataset families (pep, dec, cbp, ecnbasic, nonemp) publish no margins of error."New value: +"Variable codes to compare (e.g., [\"B19013_001E\", \"B19013_001M\"]); the ranking is on one of them, set by sort_by. Codes are uppercased before the request, and each row is keyed by the uppercase code. At most 49 per call: the Census API accepts 50 columns per request and every query also sends NAME. On datasets where a label column is added for each filter dimension left unset, or record columns are added (cbp, ecnbasic, nonemp, pep/charv, dec/ddhca), the maximum is lower, and too_many_variables states the exact number for the comparison. On ACS datasets, add the margin-of-error counterpart of a code (same code, E suffix swapped for M) for reliability context. Other dataset families (pep, dec, cbp, ecnbasic, nonemp) publish no margins of error."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS but within, or within_county, was not provided. `parent_not_accepted`: within or within_county names a parent the geography level does not sit within. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: One or more variable codes are not found in this dataset and year. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `ambiguous_rows`: The dataset publishes several records per geography and the comparison pinned none of them, so every geography would occupy several ranks with different values. `no_data`: No geographies were returned for the query, or no row matched any entry in the geographies list. `upstream_error`: Census API was unreachable or returned an 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 code is not recognized. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS but within, or within_county, was not provided. `parent_not_accepted`: within or within_county names a parent the geography level does not sit within. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for this dataset and year. It names only the first unknown code in a request. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `sort_by_not_requested`: sort_by names a code that is not among the requested variables, so no column exists to rank on. `ambiguous_rows`: The dataset publishes several records per geography and the comparison pinned none of them, so every geography would occupy several ranks with different values. `no_data`: No geographies were returned for the query, or no row matched any entry in the geographies list. `upstream_error`: Census API was unreachable or returned an 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",
      -  "missing_api_key",
      -  "geography_not_supported",
      -  "parent_required",
      -  "parent_not_accepted",
      -  "year_not_available",
      -  "variable_not_found",
      -  "variables_unavailable",
      -  "predicate_not_supported",
      -  "ambiguous_rows",
      -  "no_data",
      -  "upstream_error"
      -]New value: +[
      +  "dataset_not_found",
      +  "missing_api_key",
      +  "geography_not_supported",
      +  "parent_required",
      +  "parent_not_accepted",
      +  "year_not_available",
      +  "variable_not_found",
      +  "too_many_variables",
      +  "variables_unavailable",
      +  "predicate_not_supported",
      +  "sort_by_not_requested",
      +  "ambiguous_rows",
      +  "no_data",
      +  "upstream_error"
      +]
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when results were truncated, when geographies entries matched no row, when a bare level code matched more than one state, or when the dataset declares filter dimensions the comparison left unset — how to narrow scope, raise the limit, correct the FIPS codes, or add the predicates that pin what the ranking covers. For an unset dimension it also quotes the label of the default the Census API applied, which is what says whether the ranking is on a total or on one category."New value: +"Guidance when results were truncated, when the sort column holds no number on any row (so the rows are in the order the Census returned them rather than ranked), when geographies entries matched no row, when a bare level code matched more than one state, or when the dataset declares filter dimensions the comparison left unset — how to narrow scope, raise the limit, correct the FIPS codes, or add the predicates that pin what the ranking covers. For an unset dimension it also quotes the label of the default the Census API applied, which is what says whether the ranking is on a total or on one category. Also names any variable codes whose flags could not be checked because the request had no room left under the Census 50-column limit — a withheld value there reads as 0 and ranks as one."
    • changedOutput schema / properties / rows / items / properties / variables / description
      Previous value: -"Map of variable code to value entry. Each key is a variable code from the variables input; each value has: estimate (number|null), moe (number|null, optional), label (string), suppressed (boolean), value (string, optional). An estimate of null means one of three things and the other fields say which: suppressed true is a number the Census withheld, a value field is a cell holding text rather than a number (GEO_ID returns \"0500000US53033\"; the older ACS profile vintages write not-applicable as \"(X)\" in a column that is a number elsewhere), and neither is a cell with nothing in it. Text has no ordering, so sorting on a column of it leaves every row tied and ranked in the order the Census returned them."New value: +"Map of variable code to value entry. Each key is a variable code from the variables input, uppercased; each value has: estimate (number|null), moe (number|null, optional), label (string), suppressed (boolean), suppression_reason (string, optional), open_ended (true, optional), flag ({code, meaning}, optional), value (string, optional). An estimate of null means one of three things and the other fields say which: suppressed true is a number the Census withheld, a value field is a cell holding text rather than a number (GEO_ID returns \"0500000US53033\"; the older ACS profile vintages write not-applicable as \"(X)\" in a column that is a number elsewhere), and neither is a cell with nothing in it. suppression_reason carries the meaning the Census publishes for the sentinel or flag, and a suppressed value ranks after every number in either sort direction. On ACS, a margin of error the Census treats as zero (a controlled estimate) is moe 0. open_ended true marks an ACS median that falls in the lowest or highest interval of an open-ended distribution, so the estimate is that interval's boundary (250001 for \"250,000+\") — it ranks by that figure, so geographies sharing it are tied, and it appears only when the matching M code was requested. flag is the symbol a business dataset (cbp, ecnbasic, nonemp) published beside the value: a withholding flag comes with suppressed true, and so does a noise or data-quality band beside a 0, which is the range a range column such as EMP_N or RCPTOT_IMP publishes in place of a number; a quality note keeps the estimate. Text has no ordering, so sorting on a column of it leaves every row tied and ranked in the order the Census returned them, and the notice says so."
    • changedOutput schema / properties / sortVariable / description
      Previous value: -"Variable code used for sorting."New value: +"Variable code the rows are ranked on, uppercased as it appears in variables."
  3. First observed

TDQS

A4.9/5.0
Behavior5/5

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

The description discloses many non-obvious behaviors: suppressed values are decoded to labels, unpinned predicate dimensions get Census-API defaults that are echoed in applied_filters, and some datasets publish multiple records per geography requiring a pinned predicate. These go well beyond the readOnlyHint and openWorldHint annotations.

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 long but dense and almost every sentence carries operational guidance. It is front-loaded with the core purpose before diving into dataset-specific caveats. Slight length is justified by the high complexity of the tool.

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?

The description covers error cases, default behaviors, dataset-specific ranking hazards, and links to sibling tools for supporting tasks. With an output schema present and readOnlyHint set, nothing essential for correct invocation is 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?

Even though schema coverage is 100%, the description meaningfully extends parameter understanding: sort_by must be one of the requested variables, at most 49 variables are allowed because NAME consumes a column, GEOID construction is explained for geographies, and predicate defaults vary by dataset. This is substantial value beyond the schema.

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 specific verb and resource: 'Compare one or more variables across multiple geographies at the same level,' and immediately gives concrete example queries. It clearly distinguishes this from siblings like census_query_data by focusing on ranked cross-geography comparison.

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?

The description explicitly names when to use alternatives: census_resolve_geography for obtaining FIPS codes, census_list_predicate_values for filter codes, and census_query_data for per-category breakdowns. It also explains when a comparison is invalid and why, such as the ambiguous_rows failure when predicates are unpinned.

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.