Georgia Civic Data
Server Details
Query, filter, aggregate, and link Georgia education, Census, immigration, and health datasets.
- Status
- Healthy
- Uptime
- 95.7% over the last 24 hours
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 12 tools
Most tools occupy clearly distinct roles: query_dataset (raw rows) vs aggregate (summaries) vs link_query (read-only SQL), and describe_dataset (schema) vs describe_dimension/get_dimension (lookup tables vs their rows). The one real overlap is describe_dataset and get_contract, which return the same schema in different sizes/formats; the descriptions do explicitly steer between them (get_contract is 'long', describe_dataset is 'query-ready'), which keeps it from being confusing. list_datasets vs search_datasets are also close but separated by browse-vs-semantic intent.
Nearly every name is snake_case verb_noun (describe_dataset, query_dataset, list_datasets, search_datasets, get_contract, resolve_entity, link_query). Minor deviations: 'aggregate' is a bare verb with no noun, and 'lookup_school_zone' uses a different verb style than the get_/describe_/query_ family. Still highly readable and predictable.
Twelve tools is well within a comfortable range for a multi-dataset civic data server. Each one covers a distinct step in the workflow — discover (list/search), understand (describe_*, get_contract, link_tables), resolve geography (resolve_entity, lookup_school_zone), and retrieve (query_dataset, aggregate, link_query, get_dimension) — with no obvious filler.
The read-only data surface is thorough: catalog discovery, schema introspection, contract retrieval, filtered queries, aggregation, cross-dataset SQL, dimension paging, entity resolution, and geospatial zone lookup are all present. The main gap is that bulk retrieval is punted to an external REST endpoint via `bulk_export` rather than a tool, and there is no way to list all tables/filters in a single flat form, but agents can work around both.
Available Tools
12 toolsaggregateSummarize a Dataset by GroupARead-onlyIdempotentInspect
A summary of one dataset computed on the server: one small row per group instead of raw rows. agg is avg, sum, min, max, count, or weighted_rate. To list observed values of a filter column, use agg='count', group_by=[] (one value per row, plus its count); describe_dataset lists allowed enum values without a scan. metric is the figure to summarize (default: the dataset's key_metric; ignored for count). group_by lists columns to group by (year, code columns like district_code or county_fips, or category columns). weighted_rate is a population-weighted rate, SUM(numerator) / SUM(denominator) times the rate's per-N scale (1,000 for a rate per 1,000, so the figure reads like the rows' own rates; the value column's rate_scale), over the rows that publish both counts (pooled_rows; a row withholding its numerator is left out, not counted as zero); for a rate across several places or years it is the right figure, since avg averages the rows' rates without weighting by population. With metric set to one of the dataset's pooled_rates (a school zone's people per square mile), it pools that rate's own numerator and denominator. Takes the same filters, years, and detail as query_dataset, plus order_by ('value' for the summarized figure) and order. Each row has <metric>_<agg> (or row_count) and coverage counts (input rows, pooled rows, non-null counts), so suppression is visible. aggregation_scope says whether the source publishes rows at this level or they are recomputed from finer rows. A sum or weighted_rate across a column the dataset declares non_additive (overlapping rows) is returned with a non_additive block and a leading non_additive_sum advisory: that figure is not a total. NULLs are skipped. No SQL: every column name is checked against the dataset's schema.
Inputs: topic (required), agg, year, limit, +10 more. Returns: object
describe_datasetDescribe a DatasetARead-onlyIdempotentInspect
The full schema of one dataset: every column (type, role, unit, value range, what a NULL means), the exact filters with their valid values (the keys query_dataset and aggregate accept), how the code columns join to the lookup tables (foreign_keys), example queries, usage notes, limitations, and null semantics. key_metric names the headline figure most answers want. Per column, key_metric_grain_contributor marks a category the headline figure is only comparable within (pin it or group by it) and metric_component marks the numerator and denominator of a rate. recommended_query is a safe default query (headline figure, the filters to pin, required single-value choices) plus a ranking recipe for top or bottom N. filter_hints lists paired filters. non_additive lists columns whose rows overlap, so summing across them double counts; partitions lists columns with no total whose values partition the whole (each value's share adds up to 1 across them), so they are read side by side and never pinned by default; value_implications lists values that imply another column's value. year_meaning, when set, says what year labels when it is not when the figures were measured. pooled_rates lists rates whose figure for several rows is scale * SUM(numerator) / SUM(denominator), scale the rate's per-N factor (1,000 for a rate per 1,000) (aggregate with agg='weighted_rate'), not an average of the rows' rates. series_breaks lists years from which figures are not comparable with earlier years (each with its reason; metrics, when present, limits it to those columns), so the step into such a year is not a trend. year_window, when set, says every figure pools years years named by the window's last year, and overlapping whether consecutive windows share years (then they are not an annual series). Each category filter carries has_total and requires_single_value. verbosity='schema' drops the prose (descriptions, usage, limitations, examples) for a much smaller payload that still has everything needed to build a query; the limitations prose in the default 'full' carries the caveats. An unknown dataset returns an error listing the available ones with a 'did you mean'.
Inputs: topic (required), verbosity. Returns: object
describe_dimensionDescribe a Lookup TableARead-onlyIdempotentInspect
The schema of one shared lookup table (a dimension: districts, schools, counties, tracts, block_groups, or demographics): its key columns (schools use district_code plus school_code together), the attribute columns a join adds, the keys that link to other data (link_keys: districts.district_census_id reaches Census data through a crosswalk; it is a 5-digit Census school-district code, not a county FIPS code), and, for demographics, how the values relate (semantics: groups may overlap across or within categories; use the dataset's definitions and non_additive declarations, and its published all total when available). Useful before a link_query join.
Inputs: name (required). Returns: object
get_contractGet a Dataset's Data ContractARead-onlyIdempotentInspect
The full data contract of one dataset (kind='topic') or lookup table (kind='dimension'): the machine-readable document, in the Open Data Contract Standard (ODCS) v3.2 format, that defines its columns, keys, units, quality checks, source, and limitations. fmt='yaml' (default) returns the document as published; fmt='json' returns it parsed. It is long (often 10 to 50 KB); describe_dataset gives the same schema in a smaller, query-ready form.
Inputs: name (required), fmt, kind. Returns: object
get_dimensionList a Lookup Table's RowsARead-onlyIdempotentInspect
The rows of one shared lookup table: district, school, county, census tract, or demographic codes with their names and attributes, in key order so paging is stable. describe_dimension gives the schema. Pages are small; when truncated is true, bulk_export gives the REST API address for the full table.
Inputs: name (required), limit, offset. Returns: object
link_queryRun a Read-Only SQL QueryARead-onlyIdempotentInspect
Runs one read-only SQL query across datasets, for analysis the per-dataset filters cannot express, such as joining education, Census, immigration, or health figures to a lookup table or to each other on shared geography (immigration, county-level Census, and health data share county_fips; Census and health tract data share tract_geoid). The dialect is DuckDB SQL (https://duckdb.org/docs/sql/introduction). Allowed: one SELECT (or WITH ... SELECT) that names only the tables link_tables lists, by their table names (FROM education.attendance a JOIN dimensions.districts d ON a.district_code = d.district_code; without an alias a table is referenced by its bare name, 'attendance'); no DDL, DML, COPY, ATTACH, INSTALL, PRAGMA, SET, or CALL, and no read_parquet(), other file readers, or file paths. Joins use the keys from describe_dimension's link_keys (districts.district_census_id reaches Census data through the crosswalk; it is a school-district code, not a county FIPS code, and a district is not the same as a county). Results are capped by rows, bytes, and time; truncated says a cap was hit, and grouping or a tighter WHERE fits more. NULL means suppressed, not zero. A rejected query returns an error naming the token or table at fault, with the closest table names.
Inputs: sql (required), limit. Returns: object
link_tablesList Tables for SQL QueriesARead-onlyIdempotentInspect
The tables link_query can read and the keys that join them: datasets to lookup tables to Census geography. With no arguments, a short index: each dataset's table name for SQL (e.g. 'education.attendance', its default detail level), what one row is (grain), detail levels, and join keys, plus each lookup table's name (e.g. 'dimensions.districts'). tables (names from the index, e.g. 'education.attendance', 'education/gosa/attendance', 'attendance', or 'districts') returns those tables in full: every column and a table name per detail level ('education.attendance__districts'). main_topic limits either form to one subject area.
Inputs: tables, main_topic. Returns: object
list_datasetsList DatasetsARead-onlyIdempotentInspect
The catalog: every published Georgia dataset and the shared lookup tables (district, school, county, census tract, and demographic names). By default each dataset is compact: its name (what every other tool takes), key (main_topic/sub_topic/topic), title, one-line summary, and first and last year. detail='full' adds detail levels, year gaps, whether it has a demographic breakdown, tags, and the contract version. main_topic ('education', 'census', 'immigration', 'health') limits the list to one subject area. The license object gives the terms the data is published under (CC BY 4.0). For a question about a known subject, search_datasets returns fewer, more relevant entries; describe_dataset gives one dataset's full schema.
Inputs: detail, main_topic. Returns: object
lookup_school_zoneLook Up School Attendance ZonesARead-onlyIdempotentInspect
Which Georgia public school attendance zones (elementary, middle, high) contain a place, or (attendance_rules=true) how attendance zones work in Georgia. Give exactly one of: lat and lon; an address (located with the U.S. Census Geocoder, an outside service); a 2020 census tract_geoid (every zone covering the tract with the share of its 2020 population in each, or, when none does, a coverage_reason); or attendance_rules=true with no place. Optional grade (pk, k, 01-12) and year. Returns the district, the zoned schools with names and where each zone came from (method, accuracy_class, positional_rmse_m, boundary_vintage, currency_status, currency_note, source_url), a level_status per school level, a coverage_status (zoned; gap: some level has no zone there; one_school_per_grade; not_available: the district publishes no zones at some level, with the reason; not_zoned: no zone assigns the grade asked, i.e. pre-K), a currency_warning when a zone's source predates an adopted change that could not be applied, an overlap_warning when two schools' zones cover the point for the same grades, the point's tract and county, and a geojson_url per zone (never the shapes themselves). Zones are rebuilt from published sources of varying currency and are not an official enrollment determination; families confirm with the district. The zoned school is the default assignment (assignment_note). attendance_rules=true returns instead who draws zones and the main ways a student attends a public school other than the zoned one, with the statute or rule behind each, for questions about how zones work. A dated summary, not legal advice; lang="es" gives it in Spanish. Addresses and points are never stored or logged.
Inputs: lat, lon, lang, year, +4 more. Returns: object
query_datasetQuery a DatasetARead-onlyIdempotentInspect
Rows of one dataset, filtered, with the district, school, county, and demographic names joined in. filters takes code columns and category columns (describe_dataset's filters lists the exact keys and valid values). Use year or year_min/year_max, not both. detail picks what one row describes (default: the dataset's finest level). Returns rows and a columns list (type, role, unit, what a NULL means, and is_key_metric on the headline column); key_metric repeats the headline column's name. A NULL usually means the source suppressed the value, not zero. columns returns only the listed columns, include_labels=false leaves out the names, and order_by with order sorts on the server, so a top-N needs only N rows. Pages are small (default 100, at most 500); when truncated is true, bulk_export gives the REST API address that returns the whole result as CSV or Parquet. A bad filter returns an error listing the valid keys and values.
Inputs: topic (required), year, limit, order, +9 more. Returns: object
resolve_entityFind a Place or Group CodeARead-onlyIdempotentInspect
Turns a place or demographic name or code into the code the data uses (district_code, school_code, county_fips, or demographic) with its label, e.g. 'Atlanta Public Schools' or 'Fulton'. A guessed code otherwise returns an empty page. kind is district, school, county, or demographic; 'Fulton' as a county is the county and as a district is the school district, which are different things. Matches loosely, ranks candidates, and flags ambiguous when several are close. A real Georgia place is never matched to a different one: a consolidated city returns its county ('Columbus' -> Muscogee, matched_on=consolidated_city), another city asked as a county returns the county it is in, flagged ambiguous, and a one-letter misspelling returns matched_on=typo. A city school system answers to the common forms of its name ('Decatur Public Schools' -> City Schools Of Decatur, matched_on=city_system), and a county's system to its place name ('Cobb Schools' -> the county's district, matched_on=county_system). A school or district is also found by an earlier name ('Brookhaven Innovation Academy' -> BIA Charter School, matched_on=former_name). place_note, when present, explains the match and is worth passing on to the user. Census tracts have no kind here: filter by tract_geoid, the 11-digit Census tract ID.
Inputs: kind (required), query (required), limit. Returns: object
search_datasetsSearch DatasetsARead-onlyIdempotentInspect
Search the catalog by meaning and keywords: dataset names, titles, everyday search phrases in English and Spanish, summaries, descriptions, and column names and descriptions. Plain wording works ('kids missing school', 'jobless', 'desempleo'), as do acronyms ('ap', 'el', 'ib'). Returns short dataset summaries, best first, with the fields and columns that matched, a confidence of 'high', 'medium' or 'low' (low: nothing in the catalog may fit), plus dimension_matches when a lookup table fits (e.g. 'school directory'). main_topic, level and year narrow the results to datasets that have them. The query text is sent to Voyage AI to compute its meaning; the results come only from this catalog.
Inputs: query (required), year, level, limit, +1 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
Related MCP Connectors
Query US Census Bureau data: demographics, economics, and housing statistics.
Search and query CDC public health data — mortality, vaccinations, surveillance, behavioral risk.
School enrollment, graduation rates, demographics, finance, and Title I data
Read-only public data on Georgia's prisons: population, facilities, deaths, contraband, statutes.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables searching and querying Fulton County Open Data (Socrata) for datasets, metadata, and rows via tools like datasets, query, and metadata.137 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables querying metro Atlanta census tracts for gaps between need and access to groceries, pharmacies, clinics, and MARTA service, with tools to rank priority tracts, inspect tract profiles, find nearby tracts, and compare counties.MIT
- AlicenseNot gradedqualityBmaintenanceEnables natural-language queries about US K-12 public schools, districts, per-pupil funding and spending, and child poverty estimates from keyless federal data.127 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables access to U.S. Census Bureau data including demographics, population, income, and housing statistics. Users can query specific variables, search datasets, and retrieve geographic FIPS codes across various surveys like the American Community Survey and Decennial Census.1-
Glama MCP Gateway
Add one secure layer between your agents and this server.