Skip to main content

opendata-atlas

CI Python License: MIT

Agent-friendly access to public Socrata open-data portals, as an MCP server. It is read-only: it reads public datasets through each portal's SODA API and writes nothing.

Status: preview. Nothing is published yet; until the first release, run the server from a checkout (Try it locally). The server holds a registry of public Socrata portals; atlas_find_portals lists them. Three portals are curated: Seattle (seattle), Chicago (chicago) and City of Everett (everett).

Tools

Tool Purpose
atlas_find_portals Find portals by place name, alias, portal name or host
atlas_search_datasets Find a portal's datasets by topic
atlas_describe_dataset Columns, row count, time coverage, place fields, geo columns, knowledge level
atlas_query_dataset Bounded reads and aggregates (SoQL clauses or raw SoQL)
atlas_get_reference Capability summary, SoQL help, portals, guides, error catalog

Choosing a portal

Every data tool takes a required portal: a portal id (its hostname, such as data.seattle.gov) or an alias (such as seattle). Without the id, call atlas_find_portals with a place name. It never picks for you: a city and its county are both candidates, told apart by jurisdiction.level, and the server's rules tell the agent to ask the user which one they mean unless the request names the level.

Knowledge levels

Portals are tiered (generic, profiled, curated), but the tier never vouches for a dataset. atlas_describe_dataset reports a knowledge level for the dataset: none (nothing recorded), profiled (the profiler recorded observations that nobody reviewed) or reviewed (a contributor reviewed its unit of observation, place fields and primary time column). atlas_query_dataset adds a knowledge_notice when the dataset is not reviewed, or when your query uses a place or time column with no reviewed claim. Each knowledge also reports validation, what the claims' checks found when the drift run (uv run pytest --run-integration -m integration) last ran them: passed, contradicted or inconclusive, unchecked for a claim with no check, and stale when the checks last ran over 180 days ago by the server's clock. The server reads the recorded outcomes and runs no check itself. A stale claim stops vouching for the data: for example, a place field it reviewed as ok reports unknown, and coverage_warnings fire on it.

Install

These paths work after the first release, which has not happened yet; until then, use Try it locally. The server runs over stdio. The uvx commands below need uv.

Claude Desktop: download opendata-atlas-<version>.mcpb from the latest release and open it with Claude Desktop.

Claude Code:

claude mcp add opendata-atlas -- uvx opendata-atlas

Codex:

codex mcp add opendata-atlas -- uvx opendata-atlas

Any other MCP client: run uvx opendata-atlas as a stdio server:

{
  "mcpServers": {
    "opendata-atlas": { "command": "uvx", "args": ["opendata-atlas"] }
  }
}

Try it locally

Three ways to run the server before it is published, each from a checkout and each over stdio. Each needs uv; path (c) also needs the mcpb CLI (npm install -g @anthropic-ai/mcpb). Replace /path/to/opendata-atlas with the absolute path of your checkout.

By default (--scope local), claude mcp add makes the server available only to you, in the current project. To use it in every project, add --scope user. For Claude Desktop, merge the snippet's opendata-atlas entry into mcpServers in claude_desktop_config.json (on macOS, ~/Library/Application Support/Claude/claude_desktop_config.json), then restart Claude Desktop. If Claude Desktop cannot find uv or uvx, set command to the absolute path that which uv or which uvx prints.

(a) From the checkout. The server runs from your working tree, so edits take effect on the next start.

claude mcp add opendata-atlas -- uv run --directory /path/to/opendata-atlas --frozen opendata-atlas
{
  "mcpServers": {
    "opendata-atlas": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/opendata-atlas", "--frozen", "opendata-atlas"]
    }
  }
}

(b) From a built wheel. Run uv build in the checkout; it writes the wheel and sdist to dist/. Replace /path/to/dist with the absolute path of that dist/ directory.

claude mcp add opendata-atlas -- uvx --from /path/to/dist/opendata_atlas-0.1.0-py3-none-any.whl opendata-atlas
{
  "mcpServers": {
    "opendata-atlas": {
      "command": "uvx",
      "args": ["--from", "/path/to/dist/opendata_atlas-0.1.0-py3-none-any.whl", "opendata-atlas"]
    }
  }
}

(c) From the bundle (Claude Desktop only). Run make mcpb in the checkout. Open dist/opendata-atlas-0.1.0.mcpb with Claude Desktop and follow its install prompt. The app token setting is optional: leave it blank to run without one.

To check a path without a client, run scripts/smoke_test.py from the checkout. It starts the server the same way and checks offline that it answers: uv run python scripts/smoke_test.py --checkout . for (a); after (b)'s uv build, --uvx dist/opendata_atlas-0.1.0-py3-none-any.whl; after (c)'s make mcpb, --bundle dist/opendata-atlas-0.1.0.mcpb. Add --live for one free live call to Seattle's portal.

Configuration

  • SOCRATA_APP_TOKEN (optional): a Socrata application token, for example claude mcp add opendata-atlas -e SOCRATA_APP_TOKEN=... -- uvx opendata-atlas. The bundle asks for it in Claude Desktop's settings. A rejected token is reported as app_token_rejected, never silently dropped. Whether one token is accepted by every portal is unprobed.
  • OPENDATA_ATLAS_PORTALS (optional): a comma-separated list of portal ids or aliases. Set, it limits the server to those portals; any other fails with portal_not_enabled. Unset or blank, every registered portal is served.

Adding a missing portal

If a Socrata portal is not in the registry:

  1. Add an entry for it to src/opendata_atlas/portals/registry_overrides.toml. The comments in the file and docs/design.md (Registry) describe the fields.
  2. Open a pull request. scripts/build_registry.py rebuilds registry.json from the entries and fails unless the portal is eligible and its identity holds.

Issues

Report bugs and gaps at github.com/briandconnelly/opendata-atlas/issues.

Develop

From a checkout:

uv sync
uv run opendata-atlas                                  # run the server over stdio
uv run pytest
uv run ruff check && uv run ruff format --check && uv run ty check
UPDATE_SNAPSHOTS=1 uv run pytest tests/test_contract.py   # after an intended tool-surface change
uv run pytest --run-integration -m integration            # live tests against Socrata portals
uv run python evals/run.py [--host claude|codex] <out_dir> [task_id ...]
uv run python evals/report.py <out_dir> --answers

To build the MCPB bundle locally: make mcpb (needs the mcpb CLI; see Try it locally, path (c)).

Release

Tag vX.Y.Z after bumping the version: the release workflow builds and smoke-tests the wheel, sdist, and .mcpb, publishes to PyPI after maintainer approval, and attaches all three to a GitHub Release. See docs/releasing.md for the steps. Before the first release, work through docs/release-checklist.md: the one-time setup, the TestPyPI rehearsal and the maintainer's open decisions.

The documentation is this README and the files in docs/, as they stand in the repository; there is no hosted docs site.

License

MIT

Metadata

Release files for opendata-atlas 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for opendata-atlas 0.1.0
File Size Uploaded Provenance
opendata_atlas-0.1.0.tar.gz 155.4 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for opendata-atlas 0.1.0
File Interpreter ABI Platform
opendata_atlas-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 345.0 kB

Release files / opendata_atlas-0.1.0.tar.gz

Download URL opendata_atlas-0.1.0.tar.gz
Size 155.4 kB
Tags Source
SHA-256 checksum
How to use checksums
025d69e0349a281ab7052498dfc7f9ebaa64da5f199e5047d959373d9b4f5ca0
BLAKE2b-256 checksum
How to use checksums
8145258a8e304cac8b4e032aa165a642971fd9844b2a05f1e62dbaad403a12a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / opendata_atlas-0.1.0-py3-none-any.whl

Download URL opendata_atlas-0.1.0-py3-none-any.whl
Size 189.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d4dc1feb1cd684a5888e489eec850216051bf630d45defa6950708f1c299ad23
BLAKE2b-256 checksum
How to use checksums
a717b01d67c189fa271ac27d0e799a7b7c098177005d59eb36341c6370d79400
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Security for opendata-atlas 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for opendata_atlas-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page