Skip to main content
Glama
vancouver-city-opendata-mcp

vancouver-city-opendata-mcp

by alexandre-do

Vancouver City Open Data MCP

An MCP server that exposes the City of Vancouver Open Data Portal (Opendatasoft Explore API v2.1) as tools an LLM can call directly: search datasets, inspect their schema, query/filter records, discover facet values, and export bounded slices of data.

Features

  • search_datasets — full-text and ODSQL search across the ~200 datasets in the catalog.

  • get_dataset — metadata and field schema for a single dataset.

  • query_records — filter/sort/paginate a dataset's records with ODSQL (where, select, order_by, group_by, q, refine).

  • get_facets — discover valid filter values (and counts) before writing a where/refine clause.

  • export_dataset — bulk export in csv/json/geojson/parquet, capped at a configurable row limit.

  • Runs over stdio (for Claude Desktop/Claude Code) or Streamable HTTP (for remote deployment) from the same codebase.

  • No API key required for public read access; an optional key raises Opendatasoft's rate limits.

Related MCP server: MCP Data Vermont

Install

npm install
npm run build

Usage — stdio (Claude Desktop / Claude Code)

stdio is the default transport — running the built binary with no flags starts it directly.

Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "vancouver-opendata": {
      "command": "node",
      "args": ["/absolute/path/to/vancouver-city-opendata-mcp/dist/index.js"]
    }
  }
}

Or explore it interactively with the MCP Inspector:

npx @modelcontextprotocol/inspector node dist/index.js

Usage — HTTP

MCP_TRANSPORT=http PORT=3000 node dist/index.js
# or: node dist/index.js --http

This exposes a single /mcp endpoint implementing the Streamable HTTP transport (session lifecycle via the mcp-session-id header — POST to initialize/call tools, GET for the SSE stream, DELETE to close a session).

curl -s -X POST http://127.0.0.1:3000/mcp \
  -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'

Note: there is no inbound authentication in v1. If deploying the HTTP transport somewhere reachable beyond localhost, put it behind your own auth/reverse proxy, and set ALLOWED_HOSTS for DNS-rebinding protection.

Environment variables

Variable

Default

Description

ODS_BASE_URL

https://opendata.vancouver.ca/api/explore/v2.1

Base URL of the Opendatasoft Explore API v2.1 to query.

ODS_API_KEY

(none)

Optional Opendatasoft API key, sent as Authorization: Apikey <key>. Not required for public data.

MCP_TRANSPORT

stdio

stdio or http (overridden by the --stdio/--http CLI flags).

HOST

127.0.0.1

Host to bind the HTTP transport to.

PORT

3000

Port used when MCP_TRANSPORT=http.

ALLOWED_HOSTS

(none)

Comma-separated hostnames allowed to reach the HTTP transport.

EXPORT_ROW_CAP

5000

Hard cap on rows export_dataset will return, regardless of the caller's requested limit.

Rate limits

Opendatasoft enforces a public per-IP quota (observed at 15,000 requests/day, plus per-dataset limits) surfaced via X-RateLimit-* response headers. export_dataset and friends will return a clear isError message if you're throttled. Set ODS_API_KEY to raise your limits.

Development

npm run test          # unit tests (no network access required)
RUN_LIVE_TESTS=1 npm test   # also runs the opt-in suite against the real API
npm run dev            # tsc --watch

License

MIT

Available Tools

5 tools
export_datasetA

Export rows from a dataset in csv, json, geojson, or parquet format. Returns the data inline as text (parquet is base64-encoded binary, since this is not a file-download channel) and is hard-capped at 5000 rows regardless of the requested limit. For larger datasets, narrow the export with where/select, or use query_records with offset-based pagination instead.

Inputs: datasetId (required), limit, where, format, +2 more.

get_datasetA

Get full metadata for a single dataset by its dataset_id, including its field schema (name, type, label, description) needed to write select/where/order_by expressions for query_records.

Inputs: datasetId (required).

get_facetsA

Get facet values and their record counts for a dataset's filterable fields. Call this before query_records to discover valid values for where/refine filters instead of guessing.

Inputs: datasetId (required), where, refine.

query_recordsA

Query and filter records within a dataset using ODSQL (where/select/order_by/group_by/q/refine), with pagination via limit/offset. For geographic datasets, results may include a geom GeoJSON field. Call get_dataset first if you don't know the field names.

Inputs: datasetId (required), q, limit, where, +5 more.

search_datasetsA

Search/list datasets in the City of Vancouver Open Data Portal catalog. Supports full-text search (q) and/or an ODSQL boolean filter (where). Returns dataset_id, title, description, theme, license, and record counts for each match.

Inputs: q, limit, where, offset, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.3/5.0

    Scored across 5 tools

    Disambiguation5/5

    Each tool targets a distinct stage of the open-data workflow: catalog search, metadata/schema retrieval, record querying, facet discovery, and dataset export. Even though query_records and export_dataset both return rows, their intended use cases are clear and non-conflicting.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun snake_case pattern: search_datasets, get_dataset, query_records, get_facets, export_dataset. The pattern is predictable and makes it easy to infer tool behavior from the name alone.

    Tool Count5/5

    Five tools is well-scoped for an open-data portal MCP server. Each tool earns its place by covering a necessary part of the exploration-and-extraction workflow without unnecessary redundancy.

    Completeness5/5

    The server covers the full read-only lifecycle for open data: discover datasets, inspect schema, explore facet values, query records, and export in multiple formats. There are no obvious dead ends or missing actions that would prevent an agent from accomplishing the apparent purpose.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables querying Calgary open data from data.calgary.ca using the Socrata SODA API through natural language questions or direct tool calls.
      153 npm
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables searching, querying, and retrieving metadata from Vermont Open Data (data.vermont.gov) datasets using Socrata SoQL, all via natural language.
      150 npm
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables querying and searching the Providence Open Data catalog via Socrata SoQL, including dataset search, data querying, and metadata retrieval.
      135 npm
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables searching and querying Virginia Open Data (datahub.va.gov) via the Socrata API, providing tools to search datasets, run SoQL queries, and retrieve metadata.
      131 npm
      MIT