socrata-mcp-server
Server Details
Search and query government open-data portals (Socrata SODA API).
- Status
- Healthy
- Uptime
- 99.9% over 82 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- cyanheads/socrata-mcp-server
- GitHub Stars
- 4
- Server Listing
- @cyanheads/socrata-mcp-server
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 6 tools
Each tool targets a distinct stage of the workflow: portal listing, dataset discovery, schema fetch, SoQL execution, and canvas SQL/description. The only mild overlap is that both socrata_find_datasets and socrata_get_dataset return column information (names vs. typed schema), which could tempt misselection, but the descriptions explicitly steer the agent to the right one.
All names are snake_case with a consistent socrata_ prefix, and most follow verb_noun (find_datasets, get_dataset, list_portals, query_dataset). The two canvas tools use noun_verb (dataframe_describe, dataframe_query), a minor but readable deviation that usefully groups them.
Six tools cleanly cover the server's scope: discovery, metadata, querying, and local SQL analysis of staged results. Nothing appears redundant and no tool feels like filler.
The read-only open-data lifecycle (find portal -> find dataset -> inspect schema -> query -> analyze spilled rows) is fully covered, and no write operations are expected. Minor gaps remain, such as no explicit export/download or pagination control beyond the staging behavior, but agents can work around these via SoQL.
Available Tools
6 toolssocrata_dataframe_describeDescribe DataCanvas TablesARead-onlyIdempotentInspect
List registered tables in a DataCanvas session — schema, row count, and column names. Shows what datasets are available for SQL queries via socrata_dataframe_query. Meaningful when the server has a DataCanvas. Use after socrata_query_dataset spills a large result set to canvas.
| Name | Required | Description | Default |
|---|---|---|---|
| canvas_id | No | Canvas ID returned by socrata_query_dataset when a large result spills to canvas. Required in practice when canvas is enabled — canvases cannot be enumerated, so omitting it fails with canvas_id_required instead of listing tables. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Status message when canvas is not enabled or no tables are registered. Absent when tables are present. |
| tables | No | Tables available for SQL queries. Empty when none registered. |
| canvas_id | No | Canvas ID resolved, when canvas is enabled. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint=false, so safety and side-effect profile need no repeating. The description adds genuine context beyond that: the tool is only meaningful when a DataCanvas exists, and it is meant to be called after a spill event. The canvas_id_required failure mode is left to the schema rather than surfaced here, which keeps it from a 5.
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?
Three short sentences, each earning its place: what it returns, what it is for, and when it becomes relevant. The return contents are front-loaded before the usage conditions.
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 tool is a single-parameter read with full schema coverage and an output schema, so return-value detail need not be described. The description supplies the prerequisite context (DataCanvas present) and the upstream trigger (a spill from socrata_query_dataset), leaving nothing an agent needs in order to call it 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 100%, and the canvas_id description already explains the pattern, provenance, and the canvas_id_required failure when omitted. The tool description adds only an indirect hint about canvas usage, so the baseline 3 applies — the schema does the heavy lifting.
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 ('List registered tables in a DataCanvas session') and immediately scopes what each entry contains (schema, row count, column names). It also differentiates from siblings by naming socrata_dataframe_query as the consumer of what this tool lists, so an agent can separate discovery from querying.
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 triggering context — 'Meaningful when the server has a DataCanvas' and 'Use after socrata_query_dataset spills a large result set to canvas' — plus the alternative workflow (query via socrata_dataframe_query). The when-to-use condition and the sibling relationship are both spelled out rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
socrata_dataframe_queryQuery DataCanvas TableARead-onlyIdempotentInspect
Run SELECT-only SQL against a DataCanvas table populated by socrata_query_dataset. Columns SODA types as number (including aggregate aliases like count(*) as n) are staged as DOUBLE, so numeric comparisons work without a cast (year > 2020, amount < 500). Text and timestamp columns stay VARCHAR — compare times with CAST(date AS TIMESTAMP). Works when the server has a DataCanvas. Use socrata_dataframe_describe to see registered tables and their schemas.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | SELECT-only SQL to run against registered canvas tables. DDL, DML, and file-reading functions are rejected. Use table names from socrata_dataframe_describe. | |
| limit | No | Max rows to return (1–50,000). One call returns at most 10,000 rows: a larger limit is served as 10,000, with a notice naming how to page through the rest when more rows match. Default 1000. | |
| canvas_id | Yes | Canvas ID returned from socrata_query_dataset or socrata_dataframe_describe. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The row limit that was applied when capped. |
| sql | No | SQL that was executed. |
| rows | No | Query result rows. DuckDB may return native JS types (number, boolean, null) for numeric/boolean columns. |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Rows returned in this response when capped. |
| notice | No | Guidance for this page: how to adjust the SQL when it returned zero rows, or how to reach the rest when rows were capped, naming the requested and served limit when a limit above the 10,000-row per-call cap was served as 10,000. Absent otherwise. |
| canvas_id | No | Canvas ID queried. |
| row_count | No | Number of rows returned. |
| truncated | No | True when results were capped at the limit — more rows match the query. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so the safety profile is covered. The description adds genuinely useful behavior beyond that: SODA numeric types are staged as DOUBLE while text/timestamps remain VARCHAR, which determines whether comparisons need CAST. It adds little about failure modes or the row-cap/paging behavior, which the schema already carries.
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?
Four compact sentences, front-loaded with purpose, then the type-staging rule that most affects query authoring, then the environment precondition and discovery pointer. No redundant restatement of the schema or annotations.
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?
With an output schema and fully described parameters, the description only needs to supply the type-system and environment context, which it does. The main gap is lifecycle: nothing says whether the canvas persists between calls or how it relates to prior socrata_query_dataset runs.
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 baseline is 3, but the description adds real semantic guidance for the sql parameter: which column types allow bare numeric comparison and which require CAST(date AS TIMESTAMP). That is meaning an agent would not get from the schema alone.
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 ("Run SELECT-only SQL against a DataCanvas table") and ties the table back to socrata_query_dataset, which distinguishes it from the SODA query sibling. An agent can tell this is an analytics step over staged data, not a dataset fetch.
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 a clear precondition ("Works when the server has a DataCanvas") and routes the agent to socrata_dataframe_describe to discover registered tables. It does not explicitly state when to prefer this over socrata_query_dataset or what to do when no canvas exists, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
socrata_find_datasetsFind Socrata DatasetsARead-onlyIdempotentInspect
Search for datasets across all Socrata-powered government open-data portals, or scope to one portal with the domain parameter. Returns dataset IDs, names, domains, update timestamps, and column_names — the API field names SoQL takes, not display labels. Use socrata_get_dataset to fetch the typed column schema before writing queries — column_names carry no type information.
| Name | Required | Description | Default |
|---|---|---|---|
| only | No | Filter by asset type. Omit to include all types. Usually "datasets" is what you want. | |
| tags | No | Filter by the portal's own tags (e.g. ["covid19", "permits"]). Requires domain: each portal assigns its own tags. Multiple values are ORed: a dataset carrying any listed tag matches. Across portals, search with query instead. | |
| limit | No | Number of results to return (1–10,000). One call returns at most 100 results: a larger limit is served as 100, with a notice naming the offset that continues. Default 10. | |
| order | No | Sort order. Defaults to relevance. Use updated_at to surface recently-refreshed datasets. | |
| query | No | Full-text search across dataset names and descriptions. Omit to browse without filtering. | |
| domain | No | Scope search to a single portal by bare hostname (e.g. data.seattle.gov, data.cityofnewyork.us); URL forms like https://data.seattle.gov/ are accepted and reduced to the host. Omit to search all portals. Required with categories or tags. | |
| offset | No | Pagination offset. Default 0. Must be below 10,000: the Discovery catalog serves only the first 10,000 matches of a search. | |
| categories | No | Filter by the portal's own categories (e.g. ["Public Safety", "Transportation"]). Requires domain: each portal assigns its own categories. Multiple values are ORed: a dataset in any listed category matches. Across portals, search with query instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Guidance for this page. When limit was served below the requested value (the 100-result per-call cap or the 10,000-match window), names the served limit and where paging continues; when results are empty, echoes the filters and suggests how to broaden, or, when offset passed the last match, names the offset to page below. Absent otherwise. |
| results | No | Matching datasets. Empty when no results. |
| totalCount | No | Total matches before pagination. 0 when empty. Discovery counts no further than 10,000: when totalCountCapped is true, 10,000 is a lower bound. |
| effectiveQuery | No | Search query applied, for reference. |
| totalCountCapped | No | True when totalCount reached Discovery's 10,000-match count ceiling, so more datasets may match than totalCount says. Absent otherwise. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the safety profile is covered. The description adds real behavioral context beyond that: it lists returned fields and warns that column_names are SoQL API field names, not display labels, and carry no type information — a non-obvious gotcha. It omits the 100-result-per-call pagination cap, but the schema already documents that.
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?
Three sentences, zero filler, with the search scope and returned fields front-loaded and the follow-up action placed last where it naturally belongs in a workflow.
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?
With 8 fully documented optional parameters, an output schema, and rich annotations, the description covers the essentials an agent needs to invoke it correctly. The only meaningful omission is the per-call result cap, which the schema handles, leaving this near-complete rather than fully self-contained.
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 100%, so every parameter (including domain, only, categories, tags) is already fully explained in the schema. The description restates domain scoping but adds no syntax or format detail beyond what the schema provides; baseline 3 applies when the schema does the heavy lifting.
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 ('Search for datasets') plus the scope options (all Socrata portals or one via domain). It also enumerates what comes back (dataset IDs, names, domains, update timestamps, column_names) and explicitly names the sibling socrata_get_dataset, so an agent can distinguish it without opening a 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 clear routing guidance: search here, then call socrata_get_dataset before writing queries because column_names lack type information. It does not address when to prefer socrata_list_portals or socrata_query_dataset, so the alternative coverage is partial rather than exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
socrata_get_datasetGet Dataset SchemaARead-onlyIdempotentInspect
Fetch full metadata and column schema for a Socrata dataset by ID. Returns field names, data types, descriptions, row count, and licensing. Always call this before writing a socrata_query_dataset — the column types determine correct WHERE clause syntax: Number columns accept bare literals (year=2023) while Text columns require single-quoted strings (year='2023').
| Name | Required | Description | Default |
|---|---|---|---|
| domain | No | Portal the dataset lives on, as a bare hostname (e.g. data.cityofnewyork.us); URL forms like https://data.cityofnewyork.us/ are accepted and reduced to the host. Pass the domain from the same socrata_find_datasets result as dataset_id. Defaults to SOCRATA_DEFAULT_DOMAIN or data.seattle.gov, which is wrong for another portal’s ID. | |
| dataset_id | Yes | Four-by-four dataset ID matching pattern like kzjm-xkqj. IDs are portal-scoped: take it from socrata_find_datasets together with that result’s domain. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Dataset display name. |
| tags | No | Associated tags. |
| error | No | Present when the call failed. Absent on success. |
| domain | No | Portal domain hosting this dataset. |
| columns | No | Column schema. Computed region columns (:@computed_region_*) are excluded to reduce noise. |
| license | No | License name when available. |
| category | No | Domain category when available. |
| row_count | No | Approximate row count when available. See row_count_source for provenance. |
| asset_type | No | Catalog asset type, such as dataset, filter (a filtered view), map, chart, calendar, visualization, measure, story, href (an external link), federated_href, file. Only dataset and filter answer socrata_query_dataset with rows. Absent when the catalog lists none. |
| dataset_id | No | Four-by-four dataset ID. |
| description | No | Dataset description when available. |
| data_updated_at | No | ISO 8601 timestamp of last data update when available. |
| row_count_source | No | How row_count was obtained: 'top_level_cached_contents' — reported directly by the portal's views metadata; 'column_cached_contents' — derived as the maximum per-column cached count when the top-level value is absent. Absent when row_count is absent. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, openWorld), so the description earns credit for adding the concrete payoff of calling it: column types dictate WHERE clause quoting. Returned fields are listed, though that partially duplicates the existing output 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?
Two tight sentences, front-loaded with purpose, followed by the mandatory-call ordering and a concrete quoted/unquoted literal example. Nothing is redundant or padded.
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 a full output schema and rich parameter descriptions, the definition covers the agent's decision needs — when to call, what comes back in broad terms, and how the result feeds the query tool. Minor gaps like error behavior on an unknown ID are not addressed but are not essential.
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 100% and the schema already explains the dataset_id pattern, portal scoping, and the domain default fallback trap in detail. The description only restates 'by ID' without adding syntax or format meaning beyond the 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?
States a specific verb and resource ('Fetch full metadata and column schema for a Socrata dataset by ID') and enumerates the returned fields, which cleanly separates it from socrata_find_datasets (discovery) and socrata_query_dataset (row retrieval).
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 instructs 'Always call this before writing a socrata_query_dataset' and names the sibling tool that follows it, giving a clear ordering rule rather than vague context. The rationale for the sequencing is also given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
socrata_list_portalsList Socrata PortalsARead-onlyIdempotentInspect
List known Socrata-powered government open-data portals with their domain, organization name, and approximate dataset count. The catalog is a curated list of 39 well-known portals; dataset counts are fetched from the Discovery API and cached for ~24 hours. Filtering is client-side substring match on the query parameter. Use this first when you do not know which portal to target, then pass the domain to socrata_find_datasets.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max portals to return (1–200). Default 50. | |
| query | No | Keyword to filter portal names or organization names (case-insensitive substring match). Omit to list all portals. | |
| offset | No | Pagination offset. Default 0. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Recovery hint for an empty page: no portals matched the filter, or offset passed the last portal (names the offset to page below). Absent on non-empty pages. |
| portals | No | Matching portals. Empty when no results. |
| totalCount | No | Total portals before pagination. 0 when empty. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and openWorld, so safety basics are covered. The description adds genuinely non-obvious traits: the catalog is a fixed curated set of 39 portals, dataset counts come from the Discovery API and are cached ~24 hours (hence "approximate" and potentially stale), and filtering happens client-side. It does not explain how limit/offset interact with the client-side filter, which keeps it below a 5.
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?
Three compact sentences, each carrying distinct information: what it returns, how counts are sourced/cached, and where it sits in the workflow. The routing instruction is front-loaded at the end with no filler.
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 annotations cover the safety profile. The description supplies everything else an agent needs: catalog size bounds, staleness of counts, filter semantics, and the next step in the workflow.
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 100%, with limit, query, and offset each documented including ranges and defaults. The description largely restates the query parameter's substring-match behavior already in the schema; the only added nuance is that the match is client-side, which is marginal beyond what the schema provides.
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 ("List known Socrata-powered government open-data portals") and enumerates the returned fields: domain, organization name, approximate dataset count. The scope (curated list of 39 portals) makes it clearly distinct from socrata_find_datasets, which operates on a single portal.
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 an explicit entry-point rule ("Use this first when you do not know which portal to target") and the follow-on action ("then pass the domain to socrata_find_datasets"), naming the sibling tool that consumes the output. No inference is required about when this tool applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
socrata_query_datasetQuery DatasetARead-onlyIdempotentInspect
Execute a SoQL query against any dataset on any Socrata portal. Use the search parameter for quick full-text lookup, or combine select/where/group/having/order for full analytical control. Returns rows plus the assembled SoQL string so you can learn the pattern. Columns are referenced by API field name (field_name from socrata_get_dataset, e.g. cuisine_description), never the display label. All SODA 2.1 row values are strings even for numeric columns — check data_type from socrata_get_dataset to determine correct WHERE quoting: Number columns use bare literals (year=2023), Text columns use single-quoted strings (year='2023'). To enumerate distinct values, use select="col, count(*) as n" with group="col" and order="n DESC". When the server has a canvas and more rows match past a full page, up to 50,000 matching rows spill to a DataCanvas table whatever the limit: list its columns with socrata_dataframe_describe, then run SQL with socrata_dataframe_query. Pass stage false to return the page alone, without staging.
| Name | Required | Description | Default |
|---|---|---|---|
| group | No | SoQL GROUP BY clause over API field names (field_name from socrata_get_dataset). Requires an aggregate function in select. | |
| limit | No | Max rows to return (1–50,000). One call returns at most 5,000 rows: a larger limit is served as 5,000, with a notice naming the offset that continues when more rows match. Default 100. Use with offset for pagination. When the server has a canvas and more rows match past a full page, up to 50,000 matching rows are staged on it whatever the limit — pass a small limit (e.g. 10) to stage a large match without a large inline page, or stage false to return the page without staging. | |
| order | No | SoQL ORDER BY clause over API field names or select aliases, e.g. "total_deaths DESC" or "date ASC". | |
| stage | No | Stage the matching rows on a canvas when more rows match past this page and the server has a canvas. Default true. Pass false to return the page alone, skipping the staging request; canvas_id and table_name then go unused. | |
| where | No | SoQL WHERE clause over API field names (field_name from socrata_get_dataset). Check column data_type there first — Number columns: year=2023, Text columns: year='2023'; an unquoted text value is read as a column name. Operators: =, !=, >, <, LIKE, IN(...), BETWEEN, IS NULL, starts_with(), contains(), AND, OR, NOT. | |
| domain | No | Portal the dataset lives on, as a bare hostname (e.g. data.cityofnewyork.us); URL forms like https://data.cityofnewyork.us/ are accepted and reduced to the host. Pass the domain from the same socrata_find_datasets result as dataset_id. Defaults to SOCRATA_DEFAULT_DOMAIN or data.seattle.gov, which is wrong for another portal’s ID. | |
| having | No | SoQL HAVING clause. Filters on aggregated results, e.g. count > 100. | |
| offset | No | Row offset for pagination. Default 0. | |
| search | No | Full-text search across all text columns ($q). For field-specific filtering, use where instead. | |
| select | No | SoQL SELECT clause — API field names (field_name from socrata_get_dataset, not display labels), aliases, aggregates: "state, sum(deaths) as total_deaths". Omit for all columns. | |
| canvas_id | No | Optional 10-char DataCanvas token from a prior socrata_query_dataset or socrata_dataframe_describe call. Omit on first call to mint a fresh canvas. Large result sets spill here automatically unless stage is false. | |
| dataset_id | Yes | Four-by-four dataset ID (e.g. kzjm-xkqj). IDs are portal-scoped: take it from socrata_find_datasets together with that result’s domain. | |
| table_name | No | Name for the canvas table a spill stages: letters, digits, and underscores, starting with a letter or underscore, 63 characters at most; lowercased, and not a SQL keyword such as select or order. Defaults to a name derived from dataset_id (ijzp_q8t2_rows). A spill under a name the canvas already holds replaces that table, so give each extract its own name, with the same canvas_id, to keep several on one canvas. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The row limit that was applied when capped. |
| rows | No | Result rows. Scalar values are strings (SODA 2.1); geo/location columns return nested objects. Use column schema from socrata_get_dataset for type context. |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Rows returned in this response when capped. |
| domain | No | Portal hostname queried, normalized from the domain input. |
| notice | No | Guidance when the query returned zero rows (review the SoQL or broaden the filter; past offset 0, whether the offset passed the end of the match), or when more rows match past this page: how to page, naming the requested and served limit when a limit above the 5,000-row per-call cap was served as 5,000; the staged table to query when the result spilled, and the earlier table of that name it replaced; or why nothing was staged, naming a canvas_id or table_name that stage false left unused. Absent otherwise. |
| canvas_id | No | DataCanvas token when results spilled. Pass to socrata_dataframe_query to run SQL over the staged rows in table_name — a bounded copy of the matching set (up to 50,000 rows, reported in canvas_row_count), not the full set when total_count exceeds that cap. Page with offset to reach rows beyond it. |
| row_count | No | Rows returned in this response. |
| truncated | No | True when more rows match past this page: total_count exceeds offset + row_count, or rows filled the limit and no count was made. Spills to canvas when enabled and stage is not false; table_name names the staged table. |
| dataset_id | No | Dataset ID queried. |
| table_name | No | Canvas table holding the staged rows; present when canvas_id is. Use it as the FROM target in socrata_dataframe_query SQL; list its columns with socrata_dataframe_describe. |
| total_count | No | Rows the query matches, in the same unit as rows: groups for a grouped query, distinct values for a distinct select. Counted when rows fill limit or a page past offset 0 comes back empty; present when the match holds more rows than this response. Absent otherwise, and when the count failed or ran past its 15-second bound. |
| assembled_query | No | SoQL clauses assembled for this request — useful for learning the syntax. |
| canvas_row_count | No | Rows staged onto the DataCanvas — a bounded copy of the matching result set (capped at 50,000). Fewer than total_count when the match exceeds the cap. Present only when canvas_id is. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent/openWorld annotations, the description discloses non-obvious behavior: results return the assembled SoQL string, all SODA 2.1 values are strings regardless of column type, a full page is 5,000 rows while up to 50,000 matching rows spill to the canvas, and a spill under an existing table name replaces it. That is exactly the operational context annotations cannot convey.
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?
Dense but well ordered — core purpose, then query-shape advice, then type/quoting caveats, then the canvas spill escalation, then the stage opt-out. The closing 'Pass stage false to return the page alone, without staging' duplicates the stage parameter's schema description and could be trimmed.
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 tool with an output schema and annotations already covering safety, the description fills the remaining gaps an agent needs: correct quoting per data_type, domain scoping risks (default portal is wrong for another portal's ID), the 5,000-row page vs 50,000-row spill behavior, and the downstream canvas tools.
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, but the description adds genuine meaning: columns must be API field names not display labels, and WHERE quoting depends on data_type from socrata_get_dataset (bare literals for Number, single-quoted for Text). It slightly restates the stage/limit behavior already in the schema, which keeps it from a 5.
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?
Opens with a specific verb+resource: 'Execute a SoQL query against any dataset on any Socrata portal.' It immediately carves out the division of labor versus siblings (socrata_find_datasets for discovery, socrata_get_dataset for field names, socrata_dataframe_* for follow-up), so an agent can place it in the toolchain without opening the 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 routing rules: 'Use the search parameter for quick full-text lookup, or combine select/where/group/having/order for full analytical control,' and a concrete alternate path ('To enumerate distinct values, use select="col, count(*) as n" with group="col"...'). It also names when to leave the tool (spill rows → socrata_dataframe_describe then socrata_dataframe_query) and how to opt out ('Pass stage false').
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.
3 tool updates
- Changed
socrata_find_datasets7 fields changed- changed
Input schema / properties / categories / descriptionPrevious value: -"Filter by domain categories (e.g. [\"Public Safety\", \"Transportation\"]). Multiple values are ORed: a dataset in any listed category matches."New value: +"Filter by the portal's own categories (e.g. [\"Public Safety\", \"Transportation\"]). Requires domain: each portal assigns its own categories. Multiple values are ORed: a dataset in any listed category matches. Across portals, search with query instead." - changed
Input schema / properties / domain / descriptionPrevious value: -"Scope search to a single portal by bare hostname (e.g. data.seattle.gov, data.cityofnewyork.us); URL forms like https://data.seattle.gov/ are accepted and reduced to the host. Omit to search all portals."New value: +"Scope search to a single portal by bare hostname (e.g. data.seattle.gov, data.cityofnewyork.us); URL forms like https://data.seattle.gov/ are accepted and reduced to the host. Omit to search all portals. Required with categories or tags." - changed
Input schema / properties / tags / descriptionPrevious value: -"Filter by tags (e.g. [\"covid19\", \"permits\"]). Multiple values are ORed: a dataset carrying any listed tag matches."New value: +"Filter by the portal's own tags (e.g. [\"covid19\", \"permits\"]). Requires domain: each portal assigns its own tags. Multiple values are ORed: a dataset carrying any listed tag matches. Across portals, search with query instead." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `result_window_exceeded`: offset is 10,000 or more: the Discovery catalog serves only the first 10,000 matches of a search. `rate_limited`: Discovery API returned 429. `unknown_domain`: The Discovery catalog does not index the domain (\"Domain not found\"). `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `retry_deadline_exceeded`: The Discovery API did not answer within the 50-second time limit the call shares across its requests, retries included. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `domain_required`: categories or tags was sent without domain: both match one portal's own vocabulary, and without domain the catalog matches them against a Socrata-wide taxonomy that portal results do not report. `result_window_exceeded`: offset is 10,000 or more: the Discovery catalog serves only the first 10,000 matches of a search. `rate_limited`: Discovery API returned 429. `unknown_domain`: The Discovery catalog does not index the domain (\"Domain not found\"). `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `retry_deadline_exceeded`: The Discovery API did not answer within the 50-second time limit the call shares across its requests, retries included. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "result_window_exceeded", - "rate_limited", - "unknown_domain", - "invalid_domain", - "retry_deadline_exceeded" -]New value: +[ + "domain_required", + "result_window_exceeded", + "rate_limited", + "unknown_domain", + "invalid_domain", + "retry_deadline_exceeded" +] - added
Output schema / properties / results / items / properties / asset_typeAdded value: +{ + "description": "Catalog asset type, such as dataset, filter (a filtered view), map, chart, calendar, visualization, measure, story, href (an external link), federated_href, file. Only dataset and filter answer socrata_query_dataset with rows. Absent when the catalog lists none.", + "type": "string" +} - added
Output schema / properties / results / items / properties / parent_dataset_idsAdded value: +{ + "description": "IDs, on the same domain, of the assets this one is built from (Discovery parent_fxf): the table a filter, map, chart, or calendar reads, or every asset a story embeds, charts and maps included. Not every parent is public. Absent when the catalog lists none.", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
socrata_get_dataset4 fields changed- added
Input schema / properties / dataset_id / patternAdded value: +"^[A-Za-z0-9]{4}-[A-Za-z0-9]{4}$" - added
Output schema / properties / asset_typeAdded value: +{ + "description": "Catalog asset type, such as dataset, filter (a filtered view), map, chart, calendar, visualization, measure, story, href (an external link), federated_href, file. Only dataset and filter answer socrata_query_dataset with rows. Absent when the catalog lists none.", + "type": "string" +} - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: Valid ID format but the dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `rate_limited`: SODA endpoint returned 429. `retry_deadline_exceeded`: The portal did not answer within the 50-second time limit the call shares across its requests, retries included. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: Valid ID format but the dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `rate_limited`: SODA endpoint returned 429. `retry_deadline_exceeded`: The portal did not answer within the 50-second time limit the call shares across its requests, retries included. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_id", - "not_found", - "unknown_domain", - "invalid_domain", - "rate_limited", - "retry_deadline_exceeded" -]New value: +[ + "not_found", + "unknown_domain", + "invalid_domain", + "rate_limited", + "retry_deadline_exceeded" +]
- Changed
socrata_query_dataset8 fields changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Optional 10-char DataCanvas token from a prior socrata_query_dataset or socrata_dataframe_describe call. Omit on first call to mint a fresh canvas. Large result sets spill here automatically."New value: +"Optional 10-char DataCanvas token from a prior socrata_query_dataset or socrata_dataframe_describe call. Omit on first call to mint a fresh canvas. Large result sets spill here automatically unless stage is false." - added
Input schema / properties / dataset_id / patternAdded value: +"^[A-Za-z0-9]{4}-[A-Za-z0-9]{4}$" - changed
Input schema / properties / limit / descriptionPrevious value: -"Max rows to return (1–50,000). One call returns at most 5,000 rows: a larger limit is served as 5,000, with a notice naming the offset that continues when more rows match. Default 100. Use with offset for pagination. When the server has a canvas and more rows match past a full page, up to 50,000 matching rows are staged on it whatever the limit — pass a small limit (e.g. 10) to stage a large match without a large inline page."New value: +"Max rows to return (1–50,000). One call returns at most 5,000 rows: a larger limit is served as 5,000, with a notice naming the offset that continues when more rows match. Default 100. Use with offset for pagination. When the server has a canvas and more rows match past a full page, up to 50,000 matching rows are staged on it whatever the limit — pass a small limit (e.g. 10) to stage a large match without a large inline page, or stage false to return the page without staging." - added
Input schema / properties / stageAdded value: +{ + "default": true, + "description": "Stage the matching rows on a canvas when more rows match past this page and the server has a canvas. Default true. Pass false to return the page alone, skipping the staging request; canvas_id and table_name then go unused.", + "type": "boolean" +} - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `query_rejected`: The gateway refused query clauses but a bare row request succeeded. `not_tabular`: SODA returned the non-tabular asset access error. `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: The dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `soql_error`: SoQL syntax error, unknown column, or literal/column type mismatch. data.socrataCode carries the upstream code and data.column the offending token when upstream names one. `rate_limited`: SODA endpoint returned 429. `retry_deadline_exceeded`: The portal did not answer the query within the 50-second time limit the call shares across its requests, retries included. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `query_rejected`: The gateway refused query clauses but a bare row request succeeded. `not_tabular`: The asset has no queryable rows: SODA refused row access to a non-tabular asset (HTTP 403), or answered with no fields, as maps, charts, calendars, and visualizations do. data.asset_type and data.parent_dataset_ids then name the asset type and the tables it is built on, when the catalog lists them. `not_found`: The dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `soql_error`: SoQL syntax error, unknown column, or literal/column type mismatch. data.socrataCode carries the upstream code and data.column the offending token when upstream names one. `rate_limited`: SODA endpoint returned 429. `retry_deadline_exceeded`: The portal did not answer the query within the 50-second time limit the call shares across its requests, retries included. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "query_rejected", - "not_tabular", - "invalid_id", - "not_found", - "unknown_domain", - "invalid_domain", - "soql_error", - "rate_limited", - "retry_deadline_exceeded" -]New value: +[ + "query_rejected", + "not_tabular", + "not_found", + "unknown_domain", + "invalid_domain", + "soql_error", + "rate_limited", + "retry_deadline_exceeded" +] - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the query returned zero rows (review the SoQL or broaden the filter; past offset 0, whether the offset passed the end of the match), or when more rows match past this page: how to page, naming the requested and served limit when a limit above the 5,000-row per-call cap was served as 5,000; the staged table to query when the result spilled, and the earlier table of that name it replaced; or why nothing was staged. Absent otherwise."New value: +"Guidance when the query returned zero rows (review the SoQL or broaden the filter; past offset 0, whether the offset passed the end of the match), or when more rows match past this page: how to page, naming the requested and served limit when a limit above the 5,000-row per-call cap was served as 5,000; the staged table to query when the result spilled, and the earlier table of that name it replaced; or why nothing was staged, naming a canvas_id or table_name that stage false left unused. Absent otherwise." - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when more rows match past this page: total_count exceeds offset + row_count, or rows filled the limit and no count was made. Spills to canvas when enabled; table_name names the staged table."New value: +"True when more rows match past this page: total_count exceeds offset + row_count, or rows filled the limit and no count was made. Spills to canvas when enabled and stage is not false; table_name names the staged table."
5 tool updates
- Changed
socrata_dataframe_query3 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max rows to return (1–10000). Default 1000."New value: +"Max rows to return (1–50,000). One call returns at most 10,000 rows: a larger limit is served as 10,000, with a notice naming how to page through the rest when more rows match. Default 1000." - changed
Input schema / properties / limit / maximumPrevious value: -10000New value: +50000 - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the SQL returned zero rows. Absent when rows are present."New value: +"Guidance for this page: how to adjust the SQL when it returned zero rows, or how to reach the rest when rows were capped, naming the requested and served limit when a limit above the 10,000-row per-call cap was served as 10,000. Absent otherwise."
- Changed
socrata_find_datasets10 fields changed- changed
Input schema / properties / categories / descriptionPrevious value: -"Filter by domain categories (e.g. [\"Public Safety\", \"Transportation\"])."New value: +"Filter by domain categories (e.g. [\"Public Safety\", \"Transportation\"]). Multiple values are ORed: a dataset in any listed category matches." - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of results to return (1–100). Default 10."New value: +"Number of results to return (1–10,000). One call returns at most 100 results: a larger limit is served as 100, with a notice naming the offset that continues. Default 10." - changed
Input schema / properties / limit / maximumPrevious value: -100New value: +10000 - changed
Input schema / properties / offset / descriptionPrevious value: -"Pagination offset. Default 0."New value: +"Pagination offset. Default 0. Must be below 10,000: the Discovery catalog serves only the first 10,000 matches of a search." - changed
Input schema / properties / tags / descriptionPrevious value: -"Filter by tags (e.g. [\"covid19\", \"permits\"])."New value: +"Filter by tags (e.g. [\"covid19\", \"permits\"]). Multiple values are ORed: a dataset carrying any listed tag matches." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `rate_limited`: Discovery API returned 429. `unknown_domain`: The Discovery catalog does not index the domain (\"Domain not found\"). `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `result_window_exceeded`: offset is 10,000 or more: the Discovery catalog serves only the first 10,000 matches of a search. `rate_limited`: Discovery API returned 429. `unknown_domain`: The Discovery catalog does not index the domain (\"Domain not found\"). `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `retry_deadline_exceeded`: The Discovery API did not answer within the 50-second time limit the call shares across its requests, retries included. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "rate_limited", - "unknown_domain", - "invalid_domain" -]New value: +[ + "result_window_exceeded", + "rate_limited", + "unknown_domain", + "invalid_domain", + "retry_deadline_exceeded" +] - changed
Output schema / properties / notice / descriptionPrevious value: -"Recovery hint when results are empty — echoes filters and suggests how to broaden. Absent on non-empty result pages."New value: +"Guidance for this page. When limit was served below the requested value (the 100-result per-call cap or the 10,000-match window), names the served limit and where paging continues; when results are empty, echoes the filters and suggests how to broaden, or, when offset passed the last match, names the offset to page below. Absent otherwise." - changed
Output schema / properties / totalCount / descriptionPrevious value: -"Total matches before pagination. 0 when empty."New value: +"Total matches before pagination. 0 when empty. Discovery counts no further than 10,000: when totalCountCapped is true, 10,000 is a lower bound." - added
Output schema / properties / totalCountCappedAdded value: +{ + "description": "True when totalCount reached Discovery's 10,000-match count ceiling, so more datasets may match than totalCount says. Absent otherwise.", + "type": "boolean" +}
- Changed
socrata_get_dataset2 fields changed- changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: Valid ID format but the dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `rate_limited`: SODA endpoint returned 429. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: Valid ID format but the dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `rate_limited`: SODA endpoint returned 429. `retry_deadline_exceeded`: The portal did not answer within the 50-second time limit the call shares across its requests, retries included. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_id", - "not_found", - "unknown_domain", - "invalid_domain", - "rate_limited" -]New value: +[ + "invalid_id", + "not_found", + "unknown_domain", + "invalid_domain", + "rate_limited", + "retry_deadline_exceeded" +]
- Changed
socrata_list_portals1 field changed- changed
Output schema / properties / notice / descriptionPrevious value: -"Recovery hint when no portals matched the filter. Absent on non-empty pages."New value: +"Recovery hint for an empty page: no portals matched the filter, or offset passed the last portal (names the offset to page below). Absent on non-empty pages."
- Changed
socrata_query_dataset10 fields changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Optional 10-char DataCanvas token from a prior socrata_query_dataset or socrata_dataframe_describe call. Omit on first call when CANVAS_PROVIDER_TYPE=duckdb to mint a fresh canvas. Large result sets spill here automatically."New value: +"Optional 10-char DataCanvas token from a prior socrata_query_dataset or socrata_dataframe_describe call. Omit on first call to mint a fresh canvas. Large result sets spill here automatically." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max rows to return (1–5000). Default 100. Use with offset for pagination. When the canvas is enabled and the page fills limit, up to 50,000 matching rows are staged on it whatever the limit — pass a small limit (e.g. 10) to stage a large match without a large inline page."New value: +"Max rows to return (1–50,000). One call returns at most 5,000 rows: a larger limit is served as 5,000, with a notice naming the offset that continues when more rows match. Default 100. Use with offset for pagination. When the server has a canvas and more rows match past a full page, up to 50,000 matching rows are staged on it whatever the limit — pass a small limit (e.g. 10) to stage a large match without a large inline page." - changed
Input schema / properties / limit / maximumPrevious value: -5000New value: +50000 - added
Input schema / properties / table_nameAdded value: +{ + "description": "Name for the canvas table a spill stages: letters, digits, and underscores, starting with a letter or underscore, 63 characters at most; lowercased, and not a SQL keyword such as select or order. Defaults to a name derived from dataset_id (ijzp_q8t2_rows). A spill under a name the canvas already holds replaces that table, so give each extract its own name, with the same canvas_id, to keep several on one canvas.", + "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,62}$", + "type": "string" +} - changed
Output schema / properties / canvas_id / descriptionPrevious value: -"DataCanvas token when results spilled (requires CANVAS_PROVIDER_TYPE=duckdb). Pass to socrata_dataframe_query to run SQL over the staged rows in table_name — a bounded copy of the matching set (up to 50,000 rows, reported in canvas_row_count), not the full set when total_count exceeds that cap. Page with offset to reach rows beyond it."New value: +"DataCanvas token when results spilled. Pass to socrata_dataframe_query to run SQL over the staged rows in table_name — a bounded copy of the matching set (up to 50,000 rows, reported in canvas_row_count), not the full set when total_count exceeds that cap. Page with offset to reach rows beyond it." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `query_rejected`: The gateway refused query clauses but a bare row request succeeded. `not_tabular`: SODA returned the non-tabular asset access error. `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: The dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `soql_error`: SoQL syntax error, unknown column, or literal/column type mismatch. data.socrataCode carries the upstream code and data.column the offending token when upstream names one. `rate_limited`: SODA endpoint returned 429. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `query_rejected`: The gateway refused query clauses but a bare row request succeeded. `not_tabular`: SODA returned the non-tabular asset access error. `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: The dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `soql_error`: SoQL syntax error, unknown column, or literal/column type mismatch. data.socrataCode carries the upstream code and data.column the offending token when upstream names one. `rate_limited`: SODA endpoint returned 429. `retry_deadline_exceeded`: The portal did not answer the query within the 50-second time limit the call shares across its requests, retries included. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "query_rejected", - "not_tabular", - "invalid_id", - "not_found", - "unknown_domain", - "invalid_domain", - "soql_error", - "rate_limited" -]New value: +[ + "query_rejected", + "not_tabular", + "invalid_id", + "not_found", + "unknown_domain", + "invalid_domain", + "soql_error", + "rate_limited", + "retry_deadline_exceeded" +] - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the query returned zero rows (review the SoQL or broaden the filter), or when rows filled the limit (how to page, and the staged table to query when the result spilled). Absent otherwise."New value: +"Guidance when the query returned zero rows (review the SoQL or broaden the filter; past offset 0, whether the offset passed the end of the match), or when more rows match past this page: how to page, naming the requested and served limit when a limit above the 5,000-row per-call cap was served as 5,000; the staged table to query when the result spilled, and the earlier table of that name it replaced; or why nothing was staged. Absent otherwise." - changed
Output schema / properties / total_count / descriptionPrevious value: -"Total matching source rows when a plain row query is truncated (row_count < total_count). Absent when the full result fits and for grouped/aggregate queries (group set), where a source-row count would not describe the returned groups."New value: +"Rows the query matches, in the same unit as rows: groups for a grouped query, distinct values for a distinct select. Counted when rows fill limit or a page past offset 0 comes back empty; present when the match holds more rows than this response. Absent otherwise, and when the count failed or ran past its 15-second bound." - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when rows filled the limit — more rows may match (see total_count when present). Spills to canvas when enabled; table_name names the staged table."New value: +"True when more rows match past this page: total_count exceeds offset + row_count, or rows filled the limit and no count was made. Spills to canvas when enabled; table_name names the staged table."
1 tool update
- Changed
socrata_query_dataset2 fields changed- changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: The dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `soql_error`: SoQL syntax error, unknown column, or literal/column type mismatch. data.socrataCode carries the upstream code and data.column the offending token when upstream names one. `rate_limited`: SODA endpoint returned 429. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `query_rejected`: The gateway refused query clauses but a bare row request succeeded. `not_tabular`: SODA returned the non-tabular asset access error. `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: The dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `soql_error`: SoQL syntax error, unknown column, or literal/column type mismatch. data.socrataCode carries the upstream code and data.column the offending token when upstream names one. `rate_limited`: SODA endpoint returned 429. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_id", - "not_found", - "unknown_domain", - "invalid_domain", - "soql_error", - "rate_limited" -]New value: +[ + "query_rejected", + "not_tabular", + "invalid_id", + "not_found", + "unknown_domain", + "invalid_domain", + "soql_error", + "rate_limited" +]
2 tool updates
- Changed
socrata_dataframe_describe2 fields changed- changed
Output schema / properties / tables / items / properties / columns / descriptionPrevious value: -"Column names and DuckDB types. Numeric SODA columns become queryable with numeric comparisons after spillover."New value: +"Column names and DuckDB types. SODA number columns are staged as DOUBLE, so numeric comparisons (year > 2020) need no cast; compare timestamps with CAST(col AS TIMESTAMP)." - changed
Output schema / properties / tables / items / properties / columns / items / properties / type / descriptionPrevious value: -"DuckDB inferred type (e.g. VARCHAR, DOUBLE, BIGINT)."New value: +"DuckDB column type (e.g. VARCHAR, DOUBLE, BOOLEAN, JSON). SODA number columns are DOUBLE; text and timestamp columns are VARCHAR."
- Changed
socrata_query_dataset5 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max rows to return (1–5000). Default 100. Use with offset for pagination."New value: +"Max rows to return (1–5000). Default 100. Use with offset for pagination. When the canvas is enabled and the page fills limit, up to 50,000 matching rows are staged on it whatever the limit — pass a small limit (e.g. 10) to stage a large match without a large inline page." - changed
Output schema / properties / canvas_id / descriptionPrevious value: -"DataCanvas token when results spilled (requires CANVAS_PROVIDER_TYPE=duckdb). Pass to socrata_dataframe_query to run SQL over the staged rows — a bounded copy of the matching set (up to 50,000 rows, reported in canvas_row_count), not the full set when total_count exceeds that cap. Page with offset to reach rows beyond it."New value: +"DataCanvas token when results spilled (requires CANVAS_PROVIDER_TYPE=duckdb). Pass to socrata_dataframe_query to run SQL over the staged rows in table_name — a bounded copy of the matching set (up to 50,000 rows, reported in canvas_row_count), not the full set when total_count exceeds that cap. Page with offset to reach rows beyond it." - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the query returned zero rows — suggests narrowing or reviewing the SoQL. Absent on non-empty result sets."New value: +"Guidance when the query returned zero rows (review the SoQL or broaden the filter), or when rows filled the limit (how to page, and the staged table to query when the result spilled). Absent otherwise." - added
Output schema / properties / table_nameAdded value: +{ + "description": "Canvas table holding the staged rows; present when canvas_id is. Use it as the FROM target in socrata_dataframe_query SQL; list its columns with socrata_dataframe_describe.", + "type": "string" +} - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when rows filled the limit — more rows may match (see total_count when present). Spills to canvas when enabled."New value: +"True when rows filled the limit — more rows may match (see total_count when present). Spills to canvas when enabled; table_name names the staged table."
4 tool updates
- Changed
socrata_find_datasets4 fields changed- changed
Input schema / properties / domain / descriptionPrevious value: -"Scope search to a single portal (e.g. data.seattle.gov, data.cityofnewyork.us). Omit to search all portals."New value: +"Scope search to a single portal by bare hostname (e.g. data.seattle.gov, data.cityofnewyork.us); URL forms like https://data.seattle.gov/ are accepted and reduced to the host. Omit to search all portals." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `rate_limited`: Discovery API returned 429. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `rate_limited`: Discovery API returned 429. `unknown_domain`: The Discovery catalog does not index the domain (\"Domain not found\"). `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "rate_limited" -]New value: +[ + "rate_limited", + "unknown_domain", + "invalid_domain" +] - changed
Output schema / properties / results / items / properties / column_names / descriptionPrevious value: -"Preview column name list (no type info). Call socrata_get_dataset for typed schema."New value: +"API field names — the identifiers SoQL takes in select/where/group/order (e.g. cuisine_description), not display labels. Computed-region system columns are dropped; empty when the catalog lists no field names. No type info — call socrata_get_dataset for the typed schema."
- Changed
socrata_get_dataset4 fields changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Four-by-four dataset ID matching pattern like kzjm-xkqj. Obtain from socrata_find_datasets."New value: +"Four-by-four dataset ID matching pattern like kzjm-xkqj. IDs are portal-scoped: take it from socrata_find_datasets together with that result’s domain." - changed
Input schema / properties / domain / descriptionPrevious value: -"Portal domain (e.g. data.seattle.gov). Defaults to SOCRATA_DEFAULT_DOMAIN env var or data.seattle.gov."New value: +"Portal the dataset lives on, as a bare hostname (e.g. data.cityofnewyork.us); URL forms like https://data.cityofnewyork.us/ are accepted and reduced to the host. Pass the domain from the same socrata_find_datasets result as dataset_id. Defaults to SOCRATA_DEFAULT_DOMAIN or data.seattle.gov, which is wrong for another portal’s ID." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: Valid ID format but dataset does not exist on this domain. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: Valid ID format but the dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `rate_limited`: SODA endpoint returned 429. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_id", - "not_found" -]New value: +[ + "invalid_id", + "not_found", + "unknown_domain", + "invalid_domain", + "rate_limited" +]
- Changed
socrata_list_portals2 fields changed- changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `rate_limited`: Discovery API returned 429. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode." - removed
Output schema / properties / error / properties / data / properties / reason / examplesRemoved value: -[ - "rate_limited" -]
- Changed
socrata_query_dataset9 fields changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Four-by-four dataset ID (e.g. kzjm-xkqj). Obtain from socrata_find_datasets."New value: +"Four-by-four dataset ID (e.g. kzjm-xkqj). IDs are portal-scoped: take it from socrata_find_datasets together with that result’s domain." - changed
Input schema / properties / domain / descriptionPrevious value: -"Portal domain (e.g. data.seattle.gov). Defaults to SOCRATA_DEFAULT_DOMAIN or data.seattle.gov."New value: +"Portal the dataset lives on, as a bare hostname (e.g. data.cityofnewyork.us); URL forms like https://data.cityofnewyork.us/ are accepted and reduced to the host. Pass the domain from the same socrata_find_datasets result as dataset_id. Defaults to SOCRATA_DEFAULT_DOMAIN or data.seattle.gov, which is wrong for another portal’s ID." - changed
Input schema / properties / group / descriptionPrevious value: -"SoQL GROUP BY clause. Requires an aggregate function in select."New value: +"SoQL GROUP BY clause over API field names (field_name from socrata_get_dataset). Requires an aggregate function in select." - changed
Input schema / properties / order / descriptionPrevious value: -"SoQL ORDER BY clause, e.g. \"total_deaths DESC\" or \"date ASC\"."New value: +"SoQL ORDER BY clause over API field names or select aliases, e.g. \"total_deaths DESC\" or \"date ASC\"." - changed
Input schema / properties / select / descriptionPrevious value: -"SoQL SELECT clause — column names, aliases, aggregates: \"state, sum(deaths) as total_deaths\". Omit for all columns."New value: +"SoQL SELECT clause — API field names (field_name from socrata_get_dataset, not display labels), aliases, aggregates: \"state, sum(deaths) as total_deaths\". Omit for all columns." - changed
Input schema / properties / where / descriptionPrevious value: -"SoQL WHERE clause. Check column dataType from socrata_get_dataset first — Number columns: year=2023, Text columns: year='2023'. Operators: =, !=, >, <, LIKE, IN(...), BETWEEN, IS NULL, starts_with(), contains(), AND, OR, NOT."New value: +"SoQL WHERE clause over API field names (field_name from socrata_get_dataset). Check column data_type there first — Number columns: year=2023, Text columns: year='2023'; an unquoted text value is read as a column name. Operators: =, !=, >, <, LIKE, IN(...), BETWEEN, IS NULL, starts_with(), contains(), AND, OR, NOT." - changed
Output schema / properties / domain / descriptionPrevious value: -"Portal domain queried."New value: +"Portal hostname queried, normalized from the domain input." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: Dataset does not exist on this domain. `soql_error`: SoQL syntax error or unknown column name. `rate_limited`: SODA endpoint returned 429. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: The dataset does not exist on the domain queried — including a gateway HTTP 403 for an ID the portal does not serve. `unknown_domain`: The domain does not serve the Socrata API to this server: its hostname does not resolve (DNS ENOTFOUND), its API answered HTTP 404 without a Socrata error body, it redirected the request to another host that did not answer with Socrata data, or a gateway refused a dataset the Discovery catalog lists there. `invalid_domain`: The domain is not a hostname, even after dropping a URL scheme, path, or query. `soql_error`: SoQL syntax error, unknown column, or literal/column type mismatch. data.socrataCode carries the upstream code and data.column the offending token when upstream names one. `rate_limited`: SODA endpoint returned 429. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_id", - "not_found", - "soql_error", - "rate_limited" -]New value: +[ + "invalid_id", + "not_found", + "unknown_domain", + "invalid_domain", + "soql_error", + "rate_limited" +]
4 tool updates
- Changed
socrata_dataframe_describe2 fields changed- added
Input schema / properties / canvas_id / patternAdded value: +"^[A-Za-z0-9_-]{10}$" - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `canvas_id_required`: Canvas is enabled but canvas_id was omitted or blank. `canvas_not_found`: Provided canvas_id does not match any registered canvas. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `canvas_id_required`: Canvas is enabled but canvas_id was omitted. `canvas_not_found`: Provided canvas_id does not match any registered canvas. Other values are possible when a failure originates below the handler."
- Changed
socrata_dataframe_query1 field changed- added
Input schema / properties / canvas_id / patternAdded value: +"^[A-Za-z0-9_-]{10}$"
- Changed
socrata_list_portals2 fields changed- removed
Output schema / properties / portals / items / properties / dataset_count / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - added
Output schema / properties / portals / items / properties / dataset_count / typeAdded value: +[ + "number", + "null" +]
- Changed
socrata_query_dataset2 fields changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Optional 10-char DataCanvas token from a prior call. Omit on first call when CANVAS_PROVIDER_TYPE=duckdb to mint a fresh canvas. Large result sets spill here automatically."New value: +"Optional 10-char DataCanvas token from a prior socrata_query_dataset or socrata_dataframe_describe call. Omit on first call when CANVAS_PROVIDER_TYPE=duckdb to mint a fresh canvas. Large result sets spill here automatically." - added
Input schema / properties / canvas_id / patternAdded value: +"^[A-Za-z0-9_-]{10}$"
6 tool updates
- Changed
socrata_dataframe_describe6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "tables" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `canvas_id_required`: Canvas is enabled but canvas_id was omitted or blank. `canvas_not_found`: Provided canvas_id does not match any registered canvas. Other values are possible when a failure originates below the handler.", + "examples": [ + "canvas_id_required", + "canvas_not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "tables" -]
- Changed
socrata_dataframe_query6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "rows", + "row_count", + "sql", + "canvas_id" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `canvas_disabled`: CANVAS_PROVIDER_TYPE is not set to duckdb — DataCanvas is unavailable. `canvas_not_found`: canvas_id does not match any registered canvas. `table_not_found`: The SQL referenced a canvas table that does not exist — expired, dropped, or a mistyped name. `sql_rejected`: SQL was not a SELECT statement, referenced a system catalog, or contained disallowed functions. Other values are possible when a failure originates below the handler.", + "examples": [ + "canvas_disabled", + "canvas_not_found", + "table_not_found", + "sql_rejected" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "rows", - "row_count", - "sql", - "canvas_id" -]
- Changed
socrata_find_datasets6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "results", + "totalCount" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `rate_limited`: Discovery API returned 429. Other values are possible when a failure originates below the handler.", + "examples": [ + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "results", - "totalCount" -]
- Changed
socrata_get_dataset6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "dataset_id", + "domain", + "name", + "tags", + "columns" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: Valid ID format but dataset does not exist on this domain. Other values are possible when a failure originates below the handler.", + "examples": [ + "invalid_id", + "not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "dataset_id", - "domain", - "name", - "tags", - "columns" -]
- Changed
socrata_list_portals6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "portals", + "totalCount" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `rate_limited`: Discovery API returned 429. Other values are possible when a failure originates below the handler.", + "examples": [ + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "portals", - "totalCount" -]
- Changed
socrata_query_dataset6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "rows", + "row_count", + "assembled_query", + "domain", + "dataset_id" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `invalid_id`: Dataset ID does not match the four-by-four pattern. `not_found`: Dataset does not exist on this domain. `soql_error`: SoQL syntax error or unknown column name. `rate_limited`: SODA endpoint returned 429. Other values are possible when a failure originates below the handler.", + "examples": [ + "invalid_id", + "not_found", + "soql_error", + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "rows", - "row_count", - "assembled_query", - "domain", - "dataset_id" -]
1 tool update
- Changed
socrata_query_dataset2 fields changed- changed
Output schema / properties / canvas_id / descriptionPrevious value: -"DataCanvas token when results spilled (requires CANVAS_PROVIDER_TYPE=duckdb). Pass to socrata_dataframe_query for SQL over the full result set."New value: +"DataCanvas token when results spilled (requires CANVAS_PROVIDER_TYPE=duckdb). Pass to socrata_dataframe_query to run SQL over the staged rows — a bounded copy of the matching set (up to 50,000 rows, reported in canvas_row_count), not the full set when total_count exceeds that cap. Page with offset to reach rows beyond it." - added
Output schema / properties / canvas_row_countAdded value: +{ + "description": "Rows staged onto the DataCanvas — a bounded copy of the matching result set (capped at 50,000). Fewer than total_count when the match exceeds the cap. Present only when canvas_id is.", + "type": "number" +}
2 tool updates
- Changed
socrata_get_dataset2 fields changed- changed
Output schema / properties / row_count / descriptionPrevious value: -"Approximate row count when available."New value: +"Approximate row count when available. See row_count_source for provenance." - added
Output schema / properties / row_count_sourceAdded value: +{ + "description": "How row_count was obtained: 'top_level_cached_contents' — reported directly by the portal's views metadata; 'column_cached_contents' — derived as the maximum per-column cached count when the top-level value is absent. Absent when row_count is absent.", + "enum": [ + "top_level_cached_contents", + "column_cached_contents" + ], + "type": "string" +}
- Changed
socrata_list_portals3 fields changed- added
Output schema / properties / portals / items / properties / dataset_count / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - changed
Output schema / properties / portals / items / properties / dataset_count / descriptionPrevious value: -"Number of datasets on this portal."New value: +"Approximate count of dataset-type assets on this portal from the Discovery API catalog (point-in-time, refreshed ~daily). 0 means the portal exposes no dataset assets to the catalog; null means the live count is temporarily unavailable." - removed
Output schema / properties / portals / items / properties / dataset_count / typeRemoved value: -"number"
2 tool updates
- Changed
socrata_dataframe_describe1 field changed- changed
Input schema / properties / canvas_id / descriptionPrevious value: -"Canvas ID returned from socrata_query_dataset. Omit to list all tables visible in the current session."New value: +"Canvas ID returned by socrata_query_dataset when a large result spills to canvas. Required in practice when canvas is enabled — canvases cannot be enumerated, so omitting it fails with canvas_id_required instead of listing tables."
- Changed
socrata_query_dataset2 fields changed- changed
Output schema / properties / total_count / descriptionPrevious value: -"Total matching rows when result is truncated (row_count < total_count). Absent when the full result fits."New value: +"Total matching source rows when a plain row query is truncated (row_count < total_count). Absent when the full result fits and for grouped/aggregate queries (group set), where a source-row count would not describe the returned groups." - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when rows filled the limit — more rows match (see total_count). Spills to canvas when enabled."New value: +"True when rows filled the limit — more rows may match (see total_count when present). Spills to canvas when enabled."
2 tool updates
- Changed
socrata_dataframe_query3 fields changed- added
Output schema / properties / capAdded value: +{ + "description": "The row limit that was applied when capped.", + "type": "number" +} - added
Output schema / properties / shownAdded value: +{ + "description": "Rows returned in this response when capped.", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when results were capped at the limit — more rows match the query.", + "type": "boolean" +}
- Changed
socrata_query_dataset3 fields changed- added
Output schema / properties / capAdded value: +{ + "description": "The row limit that was applied when capped.", + "type": "number" +} - added
Output schema / properties / shownAdded value: +{ + "description": "Rows returned in this response when capped.", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when rows filled the limit — more rows match (see total_count). Spills to canvas when enabled.", + "type": "boolean" +}
5 tool updates
- Changed
socrata_dataframe_describe2 fields changed- removed
Output schema / properties / messageRemoved value: -{ - "description": "Status message when canvas is not enabled or no tables are registered. Absent when tables are present.", - "type": "string" -} - added
Output schema / properties / noticeAdded value: +{ + "description": "Status message when canvas is not enabled or no tables are registered. Absent when tables are present.", + "type": "string" +}
- Changed
socrata_dataframe_query1 field changed- added
Output schema / properties / noticeAdded value: +{ + "description": "Guidance when the SQL returned zero rows. Absent when rows are present.", + "type": "string" +}
- Changed
socrata_find_datasets7 fields changed- added
Output schema / properties / effectiveQueryAdded value: +{ + "description": "Search query applied, for reference.", + "type": "string" +} - removed
Output schema / properties / messageRemoved value: -{ - "description": "Recovery hint when results are empty — echoes filters and suggests how to broaden. Absent on non-empty result pages.", - "type": "string" -} - added
Output schema / properties / noticeAdded value: +{ + "description": "Recovery hint when results are empty — echoes filters and suggests how to broaden. Absent on non-empty result pages.", + "type": "string" +} - removed
Output schema / properties / queryRemoved value: -{ - "description": "Search query applied, for reference.", - "type": "string" -} - added
Output schema / properties / totalCountAdded value: +{ + "description": "Total matches before pagination. 0 when empty.", + "type": "number" +} - removed
Output schema / properties / total_countRemoved value: -{ - "description": "Total matches before pagination. 0 when empty.", - "type": "number" -} - changed
Output schema / requiredPrevious value: -[ - "results", - "total_count" -]New value: +[ + "results", + "totalCount" +]
- Changed
socrata_list_portals5 fields changed- removed
Output schema / properties / messageRemoved value: -{ - "description": "Recovery hint when no portals matched the filter. Absent on non-empty pages.", - "type": "string" -} - added
Output schema / properties / noticeAdded value: +{ + "description": "Recovery hint when no portals matched the filter. Absent on non-empty pages.", + "type": "string" +} - added
Output schema / properties / totalCountAdded value: +{ + "description": "Total portals before pagination. 0 when empty.", + "type": "number" +} - removed
Output schema / properties / total_countRemoved value: -{ - "description": "Total portals before pagination. 0 when empty.", - "type": "number" -} - changed
Output schema / requiredPrevious value: -[ - "portals", - "total_count" -]New value: +[ + "portals", + "totalCount" +]
- Changed
socrata_query_dataset1 field changed- added
Output schema / properties / noticeAdded value: +{ + "description": "Guidance when the query returned zero rows — suggests narrowing or reviewing the SoQL. Absent on non-empty result sets.", + "type": "string" +}
Related MCP Connectors
Query and explore Nova Scotia open datasets via the Socrata SODA API.
Search and call 422 official public-data APIs: elections, courts, permits, SEC filings.
Search openFDA drug, device, food and adverse-event datasets.
ArcGIS Hub — open government geospatial data (search + Feature Service query).
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables querying and searching the Providence Open Data catalog via Socrata SoQL, including dataset search, data querying, and metadata retrieval.643 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables querying Seattle open data from data.seattle.gov via the Socrata SODA API.9 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables searching, querying, and retrieving metadata from Sonoma County Open Data datasets via Socrata SoQL or natural language.7 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables searching and querying Norfolk Open Data datasets through Socrata SoQL, including metadata retrieval.667 npmMIT
Glama MCP Gateway
Add one secure layer between your agents and this server.