Georgia Civic Data
Server Details
Georgia education, Census, and immigration data: query, filter, aggregate, and link datasets.
- Status
- Healthy
- Uptime
- 99.9% over 22 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 12 tools
Each tool targets a distinct phase of the workflow: discovery, schema exploration, entity resolution, single-topic querying, aggregation, and cross-dataset linking. Even the metadata tools are clearly differentiated, and descriptions explicitly guide when to prefer one over another.
Tool names are almost uniformly verb_noun snake_case, such as query_dataset, describe_dataset, link_tables, and resolve_entity. The exceptions are aggregate (verb only) and distinct_values (noun phrase), which break the pattern slightly but remain readable and predictable.
Twelve tools is well within the ideal range for a read-only civic data platform. The count is neither bloated nor thin, and each tool covers a necessary function from discovery and schema inspection to querying, aggregation, and cross-dataset joins.
The tool set covers the full analytical read-only lifecycle: discover datasets, inspect schemas and contracts, resolve entity keys, query facts, aggregate, and join across datasets. Since the domain is data access rather than CRUD, there are no meaningful gaps, and bulk export is handled via pointers in results.
Available Tools
12 toolsaggregateAInspect
Compute a grouped aggregate over one topic — the aggregation-first path. agg is one of avg/sum/min/max/count/weighted_rate; metric is a metric column (DEFAULTS to the topic key_metric; ignored for count); group_by is a list of grain columns (year, FK codes like district_code or county_fips, or categoricals — see describe_dataset). weighted_rate computes a true population-weighted SUM(numerator)/SUM(denominator) for a rate key metric (when the contract declares the components) — prefer it over avg for a rate across multiple places/years, since avg means the per-row rates and ignores population. Supports the same filters / year / year_min-year_max / detail as query_dataset, plus order_by+order for top-N (order_by 'value' for the aggregated column; NULL cells sort LAST in either direction). Returns one small row per group with <metric>_<agg> (or row_count) plus coverage diagnostics (input_rows / non-null counts) so suppression is visible; aggregation_scope flags whether rows are source-published at this grain or recomputed from a finer detail (prefer source-published — see the advisory). A sum/weighted_rate ACROSS a column the contract declares non_additive (overlapping rows, e.g. county rows that count one application in several counties) still returns, but carries a top-level non_additive block and a leading non_additive_sum advisory: that figure is NOT a total — group_by the column or use the published total row instead. Aggregates SKIP NULLs and NULL means SUPPRESSED not zero. No raw SQL: all identifiers are contract-allowlisted.
| Name | Required | Description | Default |
|---|---|---|---|
| agg | No | avg | |
| year | No | ||
| limit | No | ||
| order | No | asc | |
| topic | Yes | ||
| detail | No | ||
| metric | No | ||
| offset | No | ||
| filters | No | ||
| group_by | No | ||
| order_by | No | ||
| year_max | No | ||
| year_min | No | ||
| main_topic | No | education |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly. It discloses NULL handling ('Aggregates SKIP NULLs and NULL means SUPPRESSED not zero'), non-additive behavior with a top-level block, aggregation_scope flags, suppression diagnostics, missing-value semantics, and security constraints (allowlisted identifiers, no raw SQL). This is far beyond basic expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence adds value: it covers purpose, parameter nuances, output shape, edge cases, and security. It is front-loaded with the core definition, then parameters, then caveats. It could be restructured into bullets for scannability, but there is no fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 14-parameter tool with no annotations and no schema descriptions, this description is exceptionally complete. It explains what the output looks like, how diagnostics work, when aggregation_scope matters, how non-additive results are flagged, and how NULLs behave. It also covers the security model. There is a clear mental model an agent needs to call the tool correctly, and the description provides it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the key parameters: agg (allowed values), metric (defaults to key_metric, ignored for count), group_by (grain types), order_by/order (top-N, NULL sort), and the meaning of weighted_rate. It omits limit/offset and main_topic, and only references 'same as query_dataset' for filters/year/detail rather than explaining them, but the coverage of the most semantically risky parameters is strong.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear, specific statement: 'Compute a grouped aggregate over one topic — the aggregation-first path.' It names the verb ('compute'), the resource ('one topic'), and the aggregation focus. It also differentiates from siblings by referencing query_dataset and describe_dataset, and by explaining how weighted_rate differs from avg.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit guidance for choosing weighted_rate over avg ('prefer it over avg for a rate across multiple places/years'), for handling non-additive columns ('group_by the column or use the published total row instead'), and for discovering valid group_by grains ('see describe_dataset'). It does not explicitly state when to use query_dataset instead of aggregate, leaving that to inference, but it does reference query_dataset for shared parameters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_datasetAInspect
Full schema for one topic: every column (name/type/role/unit/value range/null-meaning), the exact filters list with enum values (read this before query_dataset — it is the authoritative set of filter keys), the FK→dimension join shape (foreign_keys), example queries, usage, limitations, null semantics, tags, and schema_hash (for cache/drift detection). The top-level key_metric names the single headline column most answers want; each column carries key_metric_grain_contributor (a grain axis the key metric is only comparable within — pin or group by it) and metric_component (numerator/denominator of a rate/average metric). recommended_query gives the safe default query shape (key metric + filters to pin + required single-selects) plus a ranking recipe for top/bottom-N asks; filter_hints lists paired filters; non_additive lists columns whose rows overlap (never sum across them; a metric entry names metric columns never to add together) and value_implications values that imply another column's value; each categorical filter carries has_total / requires_single_value. Pass verbosity='schema' for a much smaller payload that drops the prose (description/usage/limitations/example queries/column descriptions) but keeps every field needed to compose a correct query — use it when you only need the filter keys and enums; prefer the default 'full' before reporting conclusions (the limitations prose carries the caveats). On an unknown topic returns a self-describing error listing available topics + a 'did you mean' hint. main_topic defaults to 'education'; pass 'census' for Census topics or 'immigration' for immigration topics.
| Name | Required | Description | Default |
|---|---|---|---|
| topic | Yes | ||
| verbosity | No | 'full' (default) or 'schema' (drops prose; keeps columns/filters/enums/key_metric/recommended_query). | full |
| main_topic | No | education |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly. It discloses the unknown-topic error behavior, payload differences between 'full' and 'schema', default main_topic, and semantic hazards such as non_additive columns, value_implications, and has_total/requires_single_value. No annotation contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense and front-loaded with the core purpose, but it is delivered as one long unbroken paragraph with many semicolon-separated clauses. Every piece of information earns its place, yet it would be much easier for an agent to scan with bullets or short sectioned sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and this is a metadata/read tool, the description is remarkably complete. It covers payload shape, verbosity behavior, error handling, default parameters, and important semantic warnings around aggregation. An agent has enough context to call this tool correctly and interpret its result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 33%, so the description must compensate. It adds meaning for verbosity ('full' vs 'schema' payload tradeoff), main_topic defaults and high-level routing to education/census/immigration, and topic failure behavior. It stops short of enumerating valid topic identifiers, but the self-describing error makes them discoverable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource: it returns the full schema for one topic. It enumerates the exact output components (columns, filters, foreign_keys, key_metric, recommended_query) and positions itself as the authoritative metadata endpoint to read before query_dataset, distinguishing it from data-returning siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit sequencing guidance: 'read this before query_dataset' and prefers 'full' before reporting conclusions. It also says to use verbosity='schema' when only filter keys and enums are needed. However, it does not explicitly compare against describe_dimension, list_datasets, or search_datasets, so it lacks a full routing matrix.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_dimensionAInspect
Schema for one dimension (districts / schools / counties / demographics): the (possibly composite) primary key, the attribute columns a join attaches, the cross-dataset link_keys (e.g. districts.district_census_id → Census via the crosswalk — a 5-digit school-district code, NOT a county FIPS), and demographics semantics (within a category the values are mutually exclusive; all is the denominator). Read this before writing a link_query join.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It explains what the returned schema contains, including cross-dataset link_keys and semantics constraints, and even warns that the district code is 'NOT a county FIPS.' This is valuable context beyond the tool name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-packed into a single informative block. It front-loads the core purpose ('Schema for one dimension') and then adds necessary detail, examples, and a critical caveat. It is not overly long given the complexity of the domain.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the key concepts needed to understand what will be returned and when to call it, and an output schema exists to fill in structural return details. The warning about the 5-digit code versus county FIPS and the semantics explanation make this complete for an agent preparing a link_query join.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only a 'name' parameter with 0% description coverage, so the description must compensate. It implies that 'name' identifies a dimension such as districts, schools, counties, or demographics, but it never explicitly states how to format or supply the value. Some meaning is added, but the parameter guidance remains indirect.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool returns the schema for a dimension, enumerating the primary key, attribute columns, link_keys, and semantics. It is specific about the resource type, but it does not explicitly differentiate itself from siblings like describe_dataset or get_dimension, relying on context rather than naming them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: 'Read this before writing a link_query join.' This tells the agent when to invoke it, though it does not explicitly state when not to use it or name alternatives such as describe_dataset.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
distinct_valuesAInspect
List the distinct values of ONE filterable column of a topic — the fast way to learn valid filter values before query_dataset, especially for FREE categoricals and FK codes (district_code/school_code/county_fips/demographic) that carry no enum in describe_dataset (a wrong guess otherwise returns an empty page with no error). column must be a filterable column (see describe_dataset's filters). Optional prefix does a case-insensitive starts-with filter; limit caps results (default 50). Enum-bearing columns return their contract enum directly; others run a capped SELECT DISTINCT over the gold data. truncated flags when the list is capped.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| topic | Yes | ||
| column | Yes | ||
| detail | No | ||
| prefix | No | ||
| main_topic | No | education |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it reveals the two execution paths (enum return vs capped SELECT DISTINCT), explains `truncated` as a cap flag, and notes case-insensitive prefix matching. It does not mention whether the operation is read-only or any error/rate-limit behavior, but 'List' implies a safe read and the behavioral details add meaningful value beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and front-loaded with the purpose and key usage context, followed by parameter behavior and execution details. Every sentence earns its place, though it could be slightly more structured for scanning. Overall it is well-organized and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For the primary workflow of discovering valid filter values before querying, the description is complete: it states prerequisites, parameter constraints, and behavior. The output schema exists, so return values need no explanation. However, the roles of `main_topic` and `detail` remain under-specified, so a fully autonomous agent might still need extra inference for those optional parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies `column` (must be filterable), `prefix` (case-insensitive starts-with), and `limit` (caps results, default 50). However, optional parameters like `topic`, `main_topic`, and `detail` are not explained, leaving gaps for a full understanding of all six parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource statement: 'List the distinct values of ONE filterable column of a topic.' It then differentiates itself from related siblings like query_dataset and describe_dataset by framing itself as 'the fast way to learn valid filter values before query_dataset.' No ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent when to use it: before query_dataset, especially for free-form categoricals and FK codes lacking enums in describe_dataset. It warns that guessing wrongly yields an empty page with no error, and points the agent to describe_dataset's `filters` for column eligibility. This gives strong when/why context and names alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_contractAInspect
Return the authoritative ODCS v3.2 data contract for a topic (kind='topic') or a dimension (kind='dimension') so you can consume the machine-readable schema without cloning the repo. fmt='yaml' (default) returns the document verbatim as text; fmt='json' returns it parsed. Only approved topics and loaded dimensions expose a contract.
| Name | Required | Description | Default |
|---|---|---|---|
| fmt | No | yaml | |
| kind | No | topic | |
| name | Yes | ||
| main_topic | No | education |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose real behavior: fmt='yaml' returns the document verbatim as text while fmt='json' returns it parsed, and contracts are gated on approved topics / loaded dimensions. It does not state what happens when the gate fails (error vs empty), whether any permission is required, or whether the output is cached/versioned, which are meaningful gaps for a no-annotation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the resource and its primary use, then the fmt semantics and the availability constraint. No filler, though the final constraint sentence is slightly compacted and the fmt/kind semantics are packed into a semicolon clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value structure need not be explained, and the description covers fmt output modes and the kind switch. The remaining gap is the unstated failure mode when a topic is not approved or a dimension is not loaded, plus the unexplained 'main_topic' parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and it partially does: it defines the two meaningful values of fmt and both values of kind, including the default behavior. It says nothing about the meaning or format of the required 'name' parameter, nor about 'main_topic' (schema default 'education'), leaving half the parameters undocumented anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Return') and a precisely scoped resource ('authoritative ODCS v3.2 data contract') and explicitly disambiguates the two supported targets (kind='topic' vs kind='dimension'). It also frames the value proposition against an alternative approach ('without cloning the repo'), so an agent can tell this is the in-band way to fetch the contract document rather than a dataset/dimension description tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear motivation ('so you can consume the machine-readable schema without cloning the repo') and one usage boundary ('Only approved topics and loaded dimensions expose a contract'), which implies when the call will fail. However, it never names an alternative sibling (e.g. describe_dimension, get_dimension, describe_dataset) or states when an agent should prefer those over this tool, so routing between near-named siblings is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dimensionAInspect
Paginated read of a dimension table — the label lookups (district names, school names, county names, demographic labels). Rows are ordered by the dimension's primary key so paging is stable. Use describe_dimension for the schema and link keys. Small page defaults; truncated + a bulk_export pointer signal when to pull the full table elsewhere.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| limit | No | ||
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden—which it meets. Discloses ordering by primary key for stable paging, small page defaults, and the truncated flag with bulk_export pointer. This makes behavior fully predictable for a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose, then pagination, then alternatives. Extremely efficient with no wasted words. Slightly dense but still well-structured; earns a 4 rather than 5 due to the packed phrasing requiring careful reading.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a paginated read tool with an output schema, the description covers all necessary context: purpose, pagination mechanics, and the bulk-export escape hatch. Nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description must compensate. It implies pagination via 'Paginated read' and 'Rows are ordered by primary key', but doesn't explicitly explain limit and offset parameters or the default limit value. While it gives a hint of page size defaults, it's not as explicit as needed for full compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Paginated read') and resource ('dimension table'), then clarifies it provides label lookups. Distinguishes itself from siblings like describe_dimension and query_dataset by focusing on read-only label retrieval, so an agent can immediately tell this from the other tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes to describe_dimension for schema and link keys, and mentions bulk_export for pulling the full table. This gives clear when-to-use and when-to-use-elsewhere guidance, leaving no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
link_queryAInspect
Run a cross-dataset / cross-topic analytical SQL query that the per-topic query_dataset filters can't express — e.g. join education, Census, or immigration facts to a dimension (or another dataset) on shared geography (immigration and Census county topics share county_fips directly). READ-ONLY, SANDBOXED DuckDB: one SELECT (or WITH … SELECT); no DDL/DML/COPY/ATTACH/INSTALL/PRAGMA/SET/CALL; you may only read_parquet() the curated gold paths returned by link_tables (call it first and paste the snippets) — querying a file path directly is rejected. Joins use the keys from describe_dimension's link_keys (districts.district_census_id bridges to Census via the crosswalk — it is a school-district code, not a county FIPS, so a district is not 1:1 with a county). Results are row- and byte-capped and time-limited; truncated flags when capped — add aggregation or a tighter WHERE rather than dumping rows. NULL means suppressed, not zero. On a violation you get a self-describing error naming the offending token/path.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | ||
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it discharges much of it: read-only sandboxed DuckDB, single SELECT/WITH only, an explicit forbidden-verb list, required read_parquet on curated gold paths, row/byte caps with a `truncated` flag, time limits, NULL-as-suppressed semantics, and self-describing errors. That is unusually rich disclosure. It remains a 3 only because it does not state authentication/authorization requirements or the exact cap thresholds, and no annotations exist to cover that residual gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and the disambiguating contrast to query_dataset before diving into constraints. Dense and long, but nearly every clause carries operational information; only the parenthetical on district_census_id versus county FIPS is a mild digression from what an agent needs to form the first call.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description still adds the non-obvious result semantics an agent needs: the `truncated` cap flag, NULL-as-suppression, and the format of violation errors. For a tool of this complexity, the definition is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it does so thoroughly for the dominant `sql` parameter — single-statement restriction, forbidden operators, required read_parquet gold-path form, and join-key guidance. The optional `limit` parameter is never mentioned in the description or schema, leaving that one parameter's semantics and its interaction with the server-side cap undefined.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('cross-dataset / cross-topic analytical SQL query') and immediately distinguishes itself from the sibling query_dataset by naming the case it cannot handle (per-topic filters can't express joins). An agent can tell it apart from query_dataset and aggregate without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit sequencing and prerequisites: call link_tables first, paste its read_parquet snippets, and use describe_dimension's link_keys for joins. It names the rejected alternative (querying a file path directly) and directs capped-result cases toward aggregation or tighter WHERE. Explicit when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
link_tablesAInspect
List the tables link_query can read (curated gold paths only) and the join keys that bridge facts → dimensions → Census geography. Call this BEFORE writing a link_query. Two-tier to stay context-cheap: with NO arguments it returns a LEAN index — every table's name, grain, detail levels, default read_parquet(...) snippet, and join keys (enough to pick tables and write a single-detail join). To get every column and a snippet per detail level for the few tables you actually need, call again with tables=["<name>", ...] (a name from the index, e.g. 'education/gosa/attendance' or 'attendance', or a dimension like 'districts'). Paste the read_parquet(...) snippets verbatim into your SQL — they are exactly what the sandbox accepts.
| Name | Required | Description | Default |
|---|---|---|---|
| tables | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It thoroughly discloses the two-tier behavior, the exact contents of each response level, and even the practical detail that read_parquet snippets must be pasted verbatim because the sandbox accepts them. This is strong behavioral transparency beyond the name and schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although the description is long, every sentence earns its place by adding operational detail: purpose, call timing, two-tier behavior, parameter examples, and usage instruction. It is front-loaded with the core purpose and structured logically, so the length is justified by the tool's richness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's entire workflow, parameter semantics, output contents at both tiers, and integration with link_query. Since an output schema exists, return values need not be enumerated. The only possible missing detail would be error conditions, but they are not necessary for an agent to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully explain the tables parameter. It does: no arguments returns the lean index, supplying tables=['<name>', ...] returns full columns and snippets, and it provides concrete example values like 'education/gosa/attendance', 'attendance', or 'districts'. This fully compensates for the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource ('tables link_query can read'), the scope ('curated gold paths only'), and the output (join keys bridging facts → dimensions → Census geography). It distinguishes itself from sibling tools like list_datasets and link_query by specifying it is the metadata lookup to use with link_query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit directive: 'Call this BEFORE writing a link_query.' It further specifies a clear two-tier invocation pattern: first call with no arguments to get the lean index, then call again with tables to get detailed columns. This leaves no ambiguity about when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_datasetsAInspect
Enumerate every approved Georgia dataset (topic) and the shared dimensions. Each topic entry is a LEAN summary — name/keys, year coverage (year_min/year_max + year_gaps), detail levels + default detail, a has_demographic flag (false = no demographic axis, so there is no all-students demographic row to filter), tags, contract version, and a one-line description — enough to pick a topic; call describe_dataset for its full schema (columns, filters, grain, source, example queries). Each dimension entry carries its primary key, attribute columns, and (for districts) cross-dataset link keys. Call this first to learn what exists — but for a NAMED task (you already know roughly the topic), prefer search_datasets, which returns far fewer bytes than this full catalog.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses substantial output behavior: LEAN summaries, year coverage fields, the has_demographic flag semantics, dimension keys, and the fact that this is a large full catalog. It does not mention pagination or rate limits, but for a read-only enumeration tool the disclosed detail is strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place: it front-loads the purpose, details the exact content of each entry, and closes with routing guidance. The structure is organized around what an agent needs to know before invoking the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter discovery tool, the description is remarkably complete: it specifies output contents for both topics and dimensions, explains the meaning of key flags, and gives clear alternative routes. The presence of an output schema reduces the need to explain return values, yet the description still provides useful semantic context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and 100% schema coverage, so the schema already makes it clear no arguments are needed. The description adds value by explaining what the no-argument call returns, which is beyond the empty schema, but there are no parameter semantics to clarify.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Enumerate every approved Georgia dataset (topic) and the shared dimensions.' It clearly distinguishes this catalog-listing tool from siblings by naming search_datasets and describe_dataset as alternatives for different needs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Call this first to learn what exists' and explicitly warns against using it for named tasks, directing the agent to search_datasets instead because it returns fewer bytes. It also routes to describe_dataset for full schema details.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_datasetAInspect
Query one topic's gold facts with dimension labels joined in (the district/school/county/demographic names come back on every row). filters is a dict of column → value or list-of-values: FK codes (district_code, school_code, county_fips, demographic) and any categorical column — see describe_dataset's filters for the exact keys and enum values. Use year (exact) OR year_min/year_max (range), never both. detail picks the grain (default is the finest available). Returns rows plus a columns descriptor array (type/role/unit/null-meaning, and is_key_metric flagging the headline column) so you interpret values and NULLs correctly — NULL usually means SUPPRESSED, not zero (see null_semantics). The top-level key_metric echoes which column is the answer. Use columns to project a subset, include_labels=false to skip the joined name columns (codes only), and order_by+order for server-side top-N instead of over-fetching. Pages are small (default 100, max 500); when truncated is true a bulk_export block points at the REST CSV/Parquet endpoint and the source path for the full pull — do not loop pagination to dump a table. A bad filter returns a self-describing error listing the valid keys/values.
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | Exact year. Use this OR year_min/max. | |
| limit | No | Page size (default 100, max 500). | |
| order | No | Sort direction for order_by: 'asc' or 'desc'. | asc |
| topic | Yes | Topic name, e.g. 'act_scores'. | |
| detail | No | Grain (e.g. schools/districts/states); default finest. | |
| offset | No | Row offset for paging (>= 0). | |
| columns | No | Project only these output columns (fact columns + joined label columns). Smaller pages / fewer column reads. Omit for all columns. | |
| filters | No | Column → value (or list of values) filters. Keys are FK columns (district_code, school_code, county_fips, demographic) and categorical columns; read describe_dataset's `filters` for the exact keys and enum values FIRST. A value list is a union (OR); multiple keys AND together. A wrong key/value returns a self-describing error listing the valid ones. | |
| order_by | No | Order by one fact column or joined label column (for server-side top-N). Default order is the row grain. NULL (suppressed) cells sort LAST in either direction, so a metric top-N is never polluted by suppressed rows. | |
| year_max | No | Inclusive upper year bound (range). | |
| year_min | No | Inclusive lower year bound (range). | |
| main_topic | No | Main topic: 'education', 'census', or 'immigration'. | education |
| include_labels | No | Join district/school/county/demographic name columns (default true); false = codes only (faster, leaner). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it delivers: NULL means SUPPRESSED not zero, page sizes (default 100, max 500), the `truncated` flag leading to a bulk_export block, NULL cells sorting last in either direction, and self-describing errors on bad filters. These are exactly the behavioral traits an agent needs and none are in structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries information and the purpose leads, but the content is packed into one dense paragraph with no separation between invocation rules, return shape, and pagination policy. It is efficient rather than bloated, yet scanning for a single rule is harder than it needs to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter, high-complexity query tool with an output schema and no annotations, the description covers filter construction, grain, projection, ordering, NULL handling, pagination limits, and the truncation escape hatch. It even explains the `columns` descriptor and `key_metric` echo, which it did not need to given the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description adds genuine meaning on top: the filters dict is a union across a value list and ANDs across keys, and the exact filter keys/enums live in describe_dataset — critical since `filters` is a free-form object with additionalProperties=true. It largely restates the year exclusivity and include_labels tradeoff that the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Query one topic's gold facts with dimension labels joined in') and pins the return grain (labels on every row), which lets an agent distinguish it from siblings like aggregate and describe_dataset without opening a schema. The scope constraint (one topic) is front-loaded.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives real routing guidance: 'see describe_dataset's filters for the exact keys and enum values' and 'do not loop pagination to dump a table' (route to bulk_export instead), plus the year vs year_min/max exclusivity rule. It never contrasts itself with the closest sibling, aggregate, so it stops short of explicit alternative selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_entityAInspect
Resolve a place or demographic NAME or CODE to its stable keys + labels — the right way to turn 'Atlanta Public Schools' / 'Fulton' / a raw code into the district_code / school_code / county_fips / demographic to filter by (a wrong code guess otherwise returns an empty query_dataset page). kind is district / school / county / demographic ('Fulton' as kind='county' → the county; as kind='district' → the school district — they are different things). Fuzzy-matches and ranks candidates, flags ambiguous when several tie, and reads only the small dimension table (no fact scan). A real Georgia place is never matched to a different one: a consolidated city returns its county (matched_on=consolidated_city: 'Columbus' -> Muscogee), another city asked as a county returns the county it lies in flagged ambiguous, and a one-letter misspelling returns matched_on=typo. Read place_note and tell the user when it is present.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | ||
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full behavioral burden and does it exceptionally well: fuzzy matching, ranking, ambiguity flags, read-only dimension-table access, and concrete edge-case behavior like consolidated_city, typo, and place_note handling are all disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then layers in necessary detail. It is dense and slightly run-on, but every sentence adds genuinely useful information about behavior or matching semantics rather than repeating the name or schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema, the description covers nearly everything needed: purpose, kind semantics, ambiguity, edge cases, and a user-facing instruction about place_note. The only incomplete piece is the `limit` parameter's effect on candidate ranking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It richly explains `kind` and `query`, including the ambiguous 'Fulton' example, but never describes `limit` even though it appears in the schema. This is a minor gap for an optional integer parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Resolve a place or demographic NAME or CODE to its stable keys + labels', and clarifies that it is the right way to produce filter values. The Fulton-as-county vs Fulton-as-district example makes the tool's scope and kind-sensitivity unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says to use this when converting a name/code into stable filter keys, and explicitly warns that guessing a code incorrectly returns an empty query_dataset page. It does not name sibling alternatives explicitly or state when not to use it, but the intended context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_datasetsAInspect
Keyword search over the catalog metadata (topic names, descriptions, tags, AND column names/descriptions) — the discovery entry point when you don't know the exact topic name. Returns lean topic summaries per hit with a relevance score and which fields matched, plus a dimension_matches list when the query also hits a dimension (e.g. 'district'). Most acronyms work; the short ones ap/el/ib are recognized. Follow up with describe_dataset. limit caps results (default 20, max 100).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it delivers: discloses return structure (lean summaries, relevance score, matched fields, dimension_matches list), acronym matching behavior, which short acronyms are recognized, and the result-limiting behavior. This is rich behavioral context beyond what schema or annotations would show.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense paragraph with zero filler: purpose is front-loaded, followed by return details, acronym edge behavior, next-step guidance, and limit semantics. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool that already has an output schema, the description covers the discovery context, when to use it, what to do next, return details, acronym edge cases, and limit behavior. Nothing needed for correct invocation or interpretation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must explain the parameters. It does: 'query' is defined as keyword search across catalog metadata with a dimension example, and 'limit' is explicitly described as capping results with default 20 and max 100. This adds meaning far beyond the bare schema names and types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('search'), resource ('catalog metadata'), and explicitly lists the fields searched (topic names, descriptions, tags, AND column names/descriptions). Positions itself as 'the discovery entry point when you don't know the exact topic name,' which clearly distinguishes it from describe_dataset and other siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a clear condition for use ('when you don't know the exact topic name') and a follow-up instruction ('Follow up with describe_dataset'). While it doesn't explicitly name an alternative or say 'don't use this when you know the exact name,' the guidance implies it strongly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
query_dataset1 field changed- changed
Input schema / properties / main_topic / descriptionPrevious value: -"Main topic: 'education' or 'census'."New value: +"Main topic: 'education', 'census', or 'immigration'."
12 tool updates
- First observed
aggregate - First observed
describe_dataset - First observed
describe_dimension - First observed
distinct_values - First observed
get_contract - First observed
get_dimension - First observed
link_query - First observed
link_tables - First observed
list_datasets - First observed
query_dataset - First observed
resolve_entity - First observed
search_datasets
Related MCP Connectors
School enrollment, graduation rates, demographics, finance, and Title I data
Query US Census Bureau data: demographics, economics, and housing statistics.
Read-only public data on Georgia's prisons: population, facilities, deaths, contraband, statutes.
Education Data MCP — US K-12 schools, districts, funding and child poverty.
Related MCP Servers
- 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.359 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-
- AlicenseAqualityDmaintenanceEnables natural language queries of U.S. Census Bureau data, translating plain English questions into proper API calls and returning demographic, economic, and housing statistics with proper statistical interpretation and context.320MIT

ew-mcpofficial
AlicenseAqualityCmaintenanceEnables querying of a locally pinned snapshot of the Education-to-Workforce Indicator Framework — 99 indicators and 11.8M observations — to browse questions, describe metrics, resolve places, and fetch or rank data across national, state, county, and district levels.4MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.