MCP server for accessing U.S. Census Bureau datasets including population, demographics, income, housing, employment, and economic indicators with geographic filtering and data table discovery.
The Census MCP server has strong schema definitions with proper Zod validation, clear tool names starting with action verbs (fetch-, list-, resolve-, search-), and comprehensive descriptions that explain when and why to use each tool. All 5 tools have documented input schemas with typed parameters. However, there are gaps: output schemas are not formally documented, error handling lacks recovery guidance, and some parameter descriptions could be more detailed about constraints and formats. The server uses a well-structured BaseTool pattern with proper error wrapping, but does not exploit all opportunities for parameter validation hints (e.g., no enums for constrained string values, no explicit min/max ranges). Parameter descriptions are mostly present but average ~60 characters vs. the 72-character baseline, leaving some ambiguity about expected formats.
Fetches statistical data from U.S. Census Bureau datasets including population, demographics, income, housing, employment, and economic indicators. Use this tool when users request Census statistics, demographic breakdowns, or socioeconomic data for specific geographic areas. Requires a dataset identifier, year/vintage, geographic scope (state, county, tract, etc.), and specific variables or table groups. Returns structured data with proper citations for authoritative government statistics.
Returns available geographic levels and filtering options for a specific Census dataset. Use this tool BEFORE fetch-aggregate-data when you need to discover what geographic breakdowns are available (state, county, tract, place, etc.) for a dataset, or when users ask about geographic coverage. Required when constructing geography queries for unfamiliar datasets. Provides query syntax, codes, and hierarchy information for each geographic level.
Returns complete catalog of available U.S. Census Bureau datasets with titles, identifiers, and available years. Use this tool FIRST when users request Census data but don't specify which dataset, or when you're unsure which dataset contains the requested statistics. Essential for mapping user requests about demographics, economics, housing, business, or government data to the correct Census dataset. After receiving results, analyze the catalog to identify the best dataset match based on topic relevance and temporal scope, then explain your reasoning to the user.
Output schemas not formally documented. While input schemas are well-defined with Zod and JSON Schema, the response structure for each tool is not explicitly documented in machine-readable form. LLMs need to understand what fields (and their types) will be returned to plan downstream tool calls and extract the right data.
Parameter constraints not expressed as enums or formal schema constraints. Geographic scope values (e.g., 'state', 'county', 'tract', 'place'), summary level filters ('State', 'County', 'Place'), and api_endpoint values could be enums rather than free-form strings. This invites hallucinated values from LLMs.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 64 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 52 | - | v1 |
Converts geographic place names into Census FIPS codes and query parameters. Use this tool when users reference locations by name (e.g., "Philadelphia", "Cook County", "New York State") rather than codes. Accepts natural language geography names and optional summary level filters (State, County, Place, County Subdivision). Returns FIPS codes, query syntax for fetch-aggregate-data tool, available vintages, and geographic hierarchy. Essential for translating human-readable location references into Census API parameters.
Search for Census Bureau data tables by ID, label, or data API endpoint (e.g. acs/acs1). Use this tool when users reference a topic or variable category (e.g., "language spoken at home", "income by race") and need to identify the correct table ID before calling fetch-aggregate-data to retrieve the actual data. Accepts a table ID prefix (e.g., "B16005"), a natural language label query, and an optional API endpoint scope. Returns a ranked list of matching table metadata with their canonical labels, component, and available years. Coverage: 32,000+ indexed tables, concentrated in ACS (~83%), CPS (~14%), and SIPP (~3%). Decennial Census, Population Estimates, and Decennial Census of Island Areas have limited coverage. Economic Census, Economic Surveys, Geography, Census Planning Database, and several other programs have no indexed tables — use variables with fetch-aggregate-data for those programs. For best results, provide api_endpoint whenever the target survey or dataset is known. Scoping to a specific endpoint significantly improves ranking quality by eliminating cross-survey noise. Each result object includes: - data_table_id: maps to the get.group parameter in fetch-aggregate-data - label: canonical label for the data table - component: the program and component this table belongs to (e.g., "American Community Survey - ACS 1-Year Estimates") - datasets: an object mapping years to arrays of API endpoints in which this table is available
Error handling does not guide recovery. BaseTool.handler() catches errors and wraps them as text responses, but does not categorize errors as retryable, user-fixable, or fatal. When fetch-aggregate-data fails due to invalid dataset, the response should suggest 'Try list-datasets() first to see available options.'
Parameter descriptions lack format/constraint details. 'dataset' is described as 'Census dataset identifier' but does not specify expected format (e.g., 'ACS 5-year identifier like "acs/acs5"'). 'year' accepts a string but does not clarify if it expects '2020', '2020-2024', or 'latest'. 'limit' in search-data-tables defaults to 20 but max is not stated.
Pagination not documented or offered by list-datasets. The tool accepts no limit or offset parameters. If the Census Bureau catalog has thousands of datasets, a single response could overwhelm the context window. list-datasets should accept limit and offset/cursor, and return a total_count or next_cursor.
Dependency hints are implicit rather than explicit. search-data-tables mentions 'before calling fetch-aggregate-data' in its description, which is good, but resolve-geography-fips does not explain that fetch-aggregate-data expects the 'for' parameter format it produces. Multi-step workflows should have explicit dependency notes.