Releases: cyanheads/socrata-mcp-server
Release list
v0.1.14: Discovery domain aliases, keyless token fallback
Discovery domain aliases, keyless token fallback
Two coupled fixes to socrata_find_datasets and app-token handling.
Changed:
invalid_app_tokenerror contract removed from socrata_find_datasets, socrata_get_dataset, and socrata_query_dataset — unreachable after the keyless-degradation fix below. (#23)
Fixed:
- socrata_find_datasets scoped to a portal with a Discovery domain alias (data.seattle.gov -> cos-data.seattle.gov) now returns its datasets, via a comma-joined domains filter that always retains the caller's original domain. (#21)
- An invalid or revoked SOCRATA_APP_TOKEN degrades to keyless requests with a one-time warning and immediate retry, instead of failing every call. (#23)
163 tests pass; bun run devcheck clean.
v0.1.13: mcp-ts-core ^0.10.14, supply-chain hardening
mcp-ts-core ^0.10.14, supply-chain hardening
Full content[] rendering, bounded paginated canvas spillover, and sql_rejected contract parity for socrata_dataframe_query.
Added:
table_not_founderror contract onsocrata_dataframe_querycanvas_row_countoutput field onsocrata_query_dataset
Changed:
- Canvas spillover drains a bounded copy of the matching set (up to 50,000 rows) across paginated SODA calls, not just the returned page (#20)
- Supply-chain hardening:
bunfig.tomlminimumReleaseAge hold + Socket install scanner, new.github/SECURITY.md - Dockerfile build-stage
--ignore-scripts+ BuildKit cache mounts
Fixed:
content[]renders every row/columnstructuredContentcarries — no more render-only truncation (#19)- DataCanvas SQL-gate rejections now surface the declared
sql_rejectedcontract with a recovery hint (#22)
Dependency bumps:
@cyanheads/mcp-ts-core^0.10.10 → ^0.10.14@socketsecurity/bun-security-scanner— new, ^1.1.2 (dev)
160 tests pass; bun run devcheck clean.
v0.1.12: Bundled DuckDB dependency, refreshed portal catalog
Bundled DuckDB dependency, refreshed portal catalog
DuckDB ships with the server for out-of-the-box dataframe tools; the
curated portal catalog now lists only live Discovery members.
Dependency bumps:
@duckdb/node-api(new) → ^1.5.4-r.1
Added:
@duckdb/node-apibundled as a regular dependency —socrata_dataframe_describe/socrata_dataframe_queryand canvas spillover work out of the box withCANVAS_PROVIDER_TYPE=duckdb, no manual peer install..mcpbbundle grows to ~39 MB. (#17)
Changed:
- Portal catalog refreshed from 36 to 40 entries — 17 dead Discovery domains pruned, 21 live-verified portals added. (#18)
148 tests pass; bun run devcheck clean.
v0.1.11: Dataset counts, row_count provenance, and upstream-text framing
Dataset counts, row_count provenance, and upstream-text framing
Real per-portal dataset counts, derived row_count with a provenance field, and a shared upstream-text framing convention across tool/resource formatters.
Added:
- socrata_list_portals / socrata://portals: real per-portal dataset_count from a live Discovery only=dataset&limit=0 catalog query, ~24h TTL cache, bounded concurrency; required-but-nullable (null = temporarily unavailable, 0 = genuinely none). (#12)
- socrata_get_dataset / socrata://datasets: new row_count_source ('top_level_cached_contents' | 'column_cached_contents') alongside row_count derived from column-level cachedContents.count when the top-level field is absent. (#14)
- src/mcp-server/tools/upstream-text.ts: shared framing helpers (inlineUpstream, upstreamBlockquote, escapeTableCell, fencedJson) applied across find-datasets, get-dataset, query-dataset, and dataframe-query formatters. (#13)
Changed:
- list-portals, portals.resource, and README no longer claim "hundreds" of Discovery-backed portals — the catalog is a curated, static 36-domain list with live counts layered on top. (#12)
Fixed:
- get-dataset: a cachedContents object without count fields no longer fabricates row_count: 0 — falls through to column-level derivation. (#14)
- get-dataset/find-datasets/query-dataset/dataframe-query format(): table-cell escaping now covers backslashes and newlines (not just pipes), and the wide-row JSON fallback fence is sized past embedded backtick runs. (#13)
148 tests pass; bun run devcheck clean.
v0.1.10: SODA error classification, invalid app token, canvas reachability, security
SODA error classification, invalid app token, canvas reachability, security
Five bug fixes plus a lockfile refresh that clears every previously-flagged advisory.
Fixed
socrata_query_dataset: SODA 400 bodies keyederrorCode(query-coordinator errors) fell through to a generic HTTP error and lost the upstream message.fetchJsonnow accepts eithercodeorerrorCodeand always throwssoql_error; the catch block re-throwssoql_error/rate_limitedthroughctx.failso the recovery hint reaches the wire. (#2)socrata_get_dataset,socrata_query_dataset,socrata_find_datasets: an invalidSOCRATA_APP_TOKENsurfaced as a generic Forbidden. A 403permission_deniedbody mentioning the app token now throwsinvalid_app_token(ConfigurationError) without leaking the token value;find-datasets.tool.tsgained the try/catch it was missing entirely. (#10)socrata_query_dataset: grouped/aggregate queries reportedtotal_countas the raw source-row count. The recount is now skipped whengroupis set. (#11)socrata_dataframe_describe: omittingcanvas_idsilently created and described an empty canvas. Now throwscanvas_id_required; every surface promising a nonexistent listing behavior corrected. (#15)- DataCanvas was unreachable on every transport — handlers read
ctx.core?.canvas, which the framework never populates. Newsrc/services/canvas-accessor.tswired fromsetup(core)fixes all three touchpoints. (#15) socrata_query_dataset: canvas spillover silently failed on datasets with:@computed_region_*columns. These are now stripped from the canvas projection beforeregisterTable. (#16)
Changed
- Vendored skills re-synced (
api-utils/parsing,polish-docs-meta/readme); README## Contributingsection removed to match.
Security
Lockfile refresh from the mcp-ts-core adoption clears all 8 flagged advisories (2 high, 6 moderate):
vite≤8.0.15 → 8.1.3 (high GHSA-fx2h-pf6j-xcff, moderate GHSA-v6wh-96g9-6wx3)hono<4.12.25 → 4.12.27 (high GHSA-88fw-hqm2-52qc, moderates GHSA-wwfh-h76j-fc44/GHSA-j6c9-x7qj-28xf/GHSA-rv63-4mwf-qqc2/GHSA-wgpf-jwqj-8h8p)js-yaml(transitive) 3.14.2 → 3.15.0 (moderate merge-key DoS)
Dependency bumps:
@cyanheads/mcp-ts-core^0.10.9 → ^0.10.10@biomejs/biome^2.5.0 → ^2.5.2@types/node^26.0.0 → ^26.1.0tsc-alias^1.8.17 → ^1.9.0
122 tests pass; bun run devcheck clean.
v0.1.9: mcp-ts-core ^0.10.9 maintenance
mcp-ts-core ^0.10.9 maintenance
Framework-maintenance release — no source or tool-behavior changes.
Dependency bumps:
@cyanheads/mcp-ts-core^0.10.6 → ^0.10.9@biomejs/biome^2.4.16 → ^2.5.0@types/node^25.9.3 → ^26.0.0vitest^4.1.8 → ^4.1.9
Added:
check-dependency-specifiersdevcheck step — rejects floating specifiers (latest/*/dist-tags) in package.json + bun.lock workspaces (cyanheads/mcp-ts-core#246)- Plugin-manifest packaging checks in lint:packaging, gated by devcheck.config.json packaging.pluginManifests (cyanheads/mcp-ts-core#240)
Fixed:
- Fresh-scaffold devcheck guards: git-dependent and changelog checks skip cleanly outside a repo (cyanheads/mcp-ts-core#242, cyanheads/mcp-ts-core#243)
- check-skill-versions skips a SKILL.md deleted from the worktree (cyanheads/mcp-ts-core#237)
Changed:
- 8 vendored agent skills re-synced for body drift (cyanheads/mcp-ts-core#238)
109 tests pass; bun run devcheck clean.
v0.1.8: mcp-ts-core ^0.10.6, truncation disclosure, server identity
mcp-ts-core ^0.10.6, truncation disclosure, server identity
Adopts @cyanheads/mcp-ts-core ^0.10.6 and surfaces result truncation to agents on the query tools.
Added:
- socrata_query_dataset and socrata_dataframe_query: truncated/shown/cap enrichment when a result fills the row limit — guides paging, raising the limit, or querying the spilled canvas
- createApp name/title set to socrata-mcp-server (served identity is the machine name, not the scoped npm package)
- Dockerfile HEALTHCHECK and org.opencontainers.image.version label
Changed:
- socrata_dataframe_query denies system-catalog references (information_schema, pg_catalog, sqlite_master, duckdb_*); sql_rejected recovery text documents it
- lint:packaging gains bundle-content and identity guards; check-framework-antipatterns gains a z.coerce.boolean() env-flag rule
- .mcpbignore patterns root-anchored; bundle runs clean-mcpb.ts to strip dependency-shipped agent docs
Dependency bumps:
- @cyanheads/mcp-ts-core ^0.9.21 → ^0.10.6
- @types/node ^25.9.1 → ^25.9.3
- vitest ^4.1.7 → ^4.1.8
109 tests pass; bun run devcheck clean.
v0.1.7: canvas_not_found contract fix
canvas_not_found contract fix
Both dataframe tools now correctly route canvas.acquire() NotFound errors
through ctx.fail('canvas_not_found', ...) so data.reason is set and agents
can act on the structured field.
Fixed:
- socrata_dataframe_describe, socrata_dataframe_query: canvas_not_found contract was declared but unreachable — canvas.acquire() threw a raw NotFound with data.reason unset when an unknown canvas_id was passed (#8). Both handlers now wrap acquire() in a try/catch; for dataframe-describe, re-routing only fires when canvasIdInput !== undefined (omitting canvas_id creates a fresh canvas, not a lookup). Both changes covered by new tests.
109 tests pass; bun run devcheck clean.
v0.1.6: mcp-ts-core ^0.9.21 framework adoption; README key rename
mcp-ts-core ^0.9.21 framework adoption; README key rename
Adopts three upstream framework fixes and syncs project scripts and skills.
Changed:
@cyanheads/mcp-ts-core^0.9.16 → ^0.9.21— per-request logs and traces carry fresh request + trace/span IDs (not frozen boot context);fetchWithTimeoutstrips query-string secrets from error messages and logs;withRetryfails fast on non-retryable errors;ctx.failauto-populatesretryableflag.- README client-config key renamed from
"socrata"to"socrata-mcp-server"in bunx, npx, and Docker install snippets.
Dependencies:
@cyanheads/mcp-ts-core^0.9.16 → ^0.9.21vitest^4.1.7 → ^4.1.8
105 tests pass; bun run devcheck clean.
v0.1.5: Enrichment adoption on search/list/collection tools
Enrichment adoption on search/list/collection tools
Query echoes, true result totals, and empty-result guidance now surface in a typed
enrichment block reaching both structuredContent JSON and content[] markdown.
Unreachable no_results error contract removed from socrata_find_datasets.
Changed:
- socrata_find_datasets: total_count, query, message moved to enrichment block (totalCount, effectiveQuery, notice)
- socrata_list_portals: total_count, message moved to enrichment block (totalCount, notice)
- socrata_query_dataset, socrata_dataframe_describe, socrata_dataframe_query: zero-row / no-canvas notices via ctx.enrich
Removed:
- no_results error contract on socrata_find_datasets (empty results return success with enrichment.notice)
Dependency bumps:
@cyanheads/mcp-ts-core^0.9.13 -> ^0.9.16
35 tests pass; bun run devcheck clean.