---
summary: "Real per-portal dataset counts, derived row_count with provenance, and upstream-text framing across tool and resource output"
breaking: false
security: false
---

# 0.1.11 — 2026-07-04

## Added

- **`socrata_list_portals`** / **`socrata://portals`** — real per-portal `dataset_count` from a live Discovery `only=dataset&limit=0` catalog query, cached ~24h at module scope with bounded concurrency; the field is required-but-nullable (`null` = the live count is temporarily unavailable, `0` = the portal genuinely exposes no dataset-type assets). ([#12](https://github.com/cyanheads/socrata-mcp-server/issues/12))
- **`socrata_get_dataset`** / **`socrata://datasets/{domain}/{datasetId}`** — new `row_count_source` (`'top_level_cached_contents' | 'column_cached_contents'`) alongside a `row_count` now derived from the max of column-level `cachedContents.count` when the views API omits the top-level field. ([#14](https://github.com/cyanheads/socrata-mcp-server/issues/14))
- `src/mcp-server/tools/upstream-text.ts` — shared framing helpers (`inlineUpstream`, `upstreamBlockquote`, `escapeTableCell`, `fencedJson`) for portal-authored free text, applied across the `find-datasets`, `get-dataset`, `query-dataset`, and `dataframe-query` formatters. ([#13](https://github.com/cyanheads/socrata-mcp-server/issues/13))

## Changed

- `socrata_list_portals`, `socrata://portals`, and `README.md` no longer claim the catalog is "backed by the Discovery API domains catalog" with "hundreds" of portals — the catalog is a curated, static list of 36 well-known domains with live counts layered on top. ([#12](https://github.com/cyanheads/socrata-mcp-server/issues/12))

## Fixed

- **`socrata_get_dataset`** — a `cachedContents` object present without count fields fell back to a fabricated `row_count: 0` instead of falling through to column-level derivation. ([#14](https://github.com/cyanheads/socrata-mcp-server/issues/14))
- **`get-dataset`**, **`find-datasets`**, **`query-dataset`**, **`dataframe-query`** `format()` — upstream dataset names, descriptions, column descriptions, and row values rendered as bare markdown; table-cell escaping handled only pipes, not backslashes or newlines, and the wide-row JSON fallback had no guard against an embedded triple-backtick sequence breaking the fence. ([#13](https://github.com/cyanheads/socrata-mcp-server/issues/13))
