freshcrate
Skin:/
Home > MCP Servers > ckan-mcp-server

ckan-mcp-server

MCP server for querying CKAN open data portals (package search, DataStore SQL, organizations, groups, tags)

Why this rank:Strong adoptionRecent releaseHealthy release cadence

Description

MCP server for querying CKAN open data portals (package search, DataStore SQL, organizations, groups, tags)

README

npm version GitHub deepwiki License: MIT Newsletter

CKAN MCP Server

Turn any (CKAN) open data portal into a conversation.

Give your AI assistant direct access to any CKAN open data portal โ€” search datasets, explore organizations, query tabular data, and read metadata, all through natural language.

CKAN is the open-source platform behind most public open data portals worldwide (Italy's dati.gov.it, the US data.gov, Canada's open.canada.ca, and many more). Navigating these portals usually requires knowing their structure, APIs, and search syntax. This MCP server removes that barrier: once connected, your AI tool can do it all for you.

This is possible because of open standards and open source. CKAN exposes a fully documented, public API. Metadata follows DCAT, an open W3C standard for describing datasets. Both are free to use, free to build on, and maintained by open communities. This server stands on that foundation.

Who is this for? Everyone. Journalists looking for data to verify a story. Researchers exploring public datasets. Public servants checking what data their administration publishes. Developers building data pipelines. No CKAN knowledge required.

Two ways to use it โ€” pick the one that suits you:

Option A: Install locally Option B: No install
How npm install -g @aborruso/ckan-mcp-server Point your tool to the hosted HTTP endpoint
Best for Runs on your machine, works with any local tool Quick start, zero setup
Limits None 100k requests/day shared quota

Hosted endpoint: https://ckan-mcp-server.andy-pr.workers.dev/mcp

Recommendation: Option B is a great way to get started and try things out without any setup. Once you're familiar with what the server can do, switching to Option A (local install) gives you unlimited usage with no shared quotas.

๐Ÿ‘‰ Want to explore the codebase? The AI-generated DeepWiki is a great starting point.

License: MIT โ€” see LICENSE for complete details. Third-party notices: NOTICE.md.

CKAN MCP Server demo


๐Ÿ”Œ Use it in your favorite tool

ChatGPT | Claude Desktop | Claude Code | Le Chat (Mistral) | Perplexity Pro | Gemini CLI | VS Code | Codex CLI

This server works with any MCP-compatible client. The sections below cover some of the most popular ones โ€” if your tool isn't listed, check its documentation for MCP configuration and use the same endpoint URL or command.

All examples below work with both the local installation and the hosted endpoint. Where both options differ, both are shown.

Using local installation? You need to install the server first โ€” see Run locally.

ChatGPT

Requires a ChatGPT Plus, Team, or Enterprise plan.

  1. Open the profile menu and go to Settings โ†’ Apps โ†’ Advanced settings
  2. Enable Developer mode
  3. Click Create app (top-right)
  4. Fill in the form:
    • Name: CKAN MCP Server
    • Description: Search datasets on CKAN open data portals
    • MCP Server URL: https://ckan-mcp-server.andy-pr.workers.dev/mcp
    • Authentication: No Auth
    • Check the confirmation box, then click Create
  5. In a new chat, click + โ†’ More and select CKAN MCP Server

For a step-by-step walkthrough with screenshots, see the full ChatGPT guide.

Claude Desktop

Using the hosted endpoint (no install) โ€” via connector UI:

  1. Open Claude Desktop and go to Settings โ†’ Integrations
  2. Click Add custom integration
  3. Fill in the details:
    • Name: CKAN MCP Server
    • MCP Server URL: https://ckan-mcp-server.andy-pr.workers.dev/mcp
  4. Click Add to save
  5. Open a new chat, click +, select Integrations, and enable CKAN MCP Server
  6. When Claude asks to use a tool, click Allow (or Always allow)

For a detailed walkthrough with screenshots, see the full Claude guide.

Using the hosted endpoint (no install) โ€” via config file:

Configuration file location:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "ckan": {
      "url": "https://ckan-mcp-server.andy-pr.workers.dev/mcp"
    }
  }
}

Using local installation:

{
  "mcpServers": {
    "ckan": {
      "command": "npx",
      "args": ["@aborruso/ckan-mcp-server@latest"]
    }
  }
}

Claude Code

Using the hosted endpoint (no install):

claude mcp add -s user -t http ckan https://ckan-mcp-server.andy-pr.workers.dev/mcp

Using local installation:

claude mcp add -s user ckan npx @aborruso/ckan-mcp-server@latest

--scope user makes the server available globally across all your projects, not just the current one.

To add it only for a specific project, run from the project folder without the --scope user flag:

claude mcp add --transport http ckan https://ckan-mcp-server.andy-pr.workers.dev/mcp

Le Chat (Mistral)

  1. In the left sidebar, click Intelligence, then select Connectors
  2. Click + Add Connector
  3. Select the Custom MCP Connector tab and fill in the details:
    • Name: CKAN
    • Connector Server: https://ckan-mcp-server.andy-pr.workers.dev/mcp
  4. Click Connect to save
  5. Open a new chat, click +, then Connectors, and enable CKAN

For a step-by-step walkthrough with screenshots, see the full Le Chat guide.

Perplexity Pro

Requires a Perplexity Pro account.

  1. Click the "+" (Attach) icon in the message input bar and select Connectors & sources
  2. Click Connect external app
  3. Fill in the details:
    • Name: CKAN MCP Server
    • MCP Server URL: https://ckan-mcp-server.andy-pr.workers.dev/mcp
    • Authorization Type: No Authentication
    • Connection Type: HTTP Streamable
  4. Check the confirmation box and click Save
  5. In a new chat, click + โ†’ Connectors & sources and enable ckan_mcp_server

For a step-by-step walkthrough with screenshots, see the full Perplexity guide.

Gemini CLI

gemini mcp add -s user -t http ckan https://ckan-mcp-server.andy-pr.workers.dev/mcp

Or add manually to ~/.gemini/settings.json:

{
  "mcpServers": {
    "ckan": {
      "httpUrl": "https://ckan-mcp-server.andy-pr.workers.dev/mcp"
    }
  }
}

VS Code

Add to your User Settings or .vscode/settings.json:

Using the hosted endpoint (no install):

{
  "mcpServers": {
    "ckan": {
      "url": "https://ckan-mcp-server.andy-pr.workers.dev/mcp",
      "type": "http"
    }
  }
}

Using local installation:

{
  "mcpServers": {
    "ckan": {
      "command": "npx",
      "args": ["@aborruso/ckan-mcp-server@latest"]
    }
  }
}

Codex CLI

Add to ~/.codex/config.toml:

Using the hosted endpoint (no install):

[mcp_servers.ckan]
url = "https://ckan-mcp-server.andy-pr.workers.dev/mcp"

Using local installation:

[mcp_servers.ckan]
command = "npx"
args = ["-y", "@aborruso/ckan-mcp-server@latest"]

๐Ÿ–ฅ๏ธ Run locally

Option 1 โ€” Install via npm

The quickest way. Install the package globally and it's immediately available as a command:

npm install -g @aborruso/ckan-mcp-server

The server will be available as ckan-mcp-server, or you can run it without installing via:

npx @aborruso/ckan-mcp-server@latest

Option 2 โ€” Clone and build

For development or if you want to run the latest unreleased code:

git clone https://github.com/ondata/ckan-mcp-server.git
cd ckan-mcp-server
npm install
npm run build
node dist/index.js

Option 3 โ€” Docker

Thanks to @piersoft, you can also run the server via Docker:

git clone https://github.com/ondata/ckan-mcp-server.git
cd ckan-mcp-server
docker compose up --build -d

The MCP server will be available at http://localhost:3000/mcp. See docker/README.md for full details, including how to connect Claude Desktop to the container.


๐Ÿ› ๏ธ Available Tools

Search and Discovery

  • ckan_package_search: Search datasets with Solr queries
  • ckan_find_relevant_datasets: Rank datasets by relevance score
  • ckan_package_show: Complete details of a dataset
  • ckan_tag_list: List tags with counts

Organizations

  • ckan_organization_list: List all organizations
  • ckan_organization_show: Details of an organization
  • ckan_organization_search: Search organizations by name

Groups

  • ckan_group_list: List groups
  • ckan_group_show: Show group details
  • ckan_group_search: Search groups by name

DataStore

  • ckan_datastore_search: Query tabular data
  • ckan_datastore_search_sql: SQL queries on DataStore

Quality Metrics

  • ckan_get_mqa_quality: Get MQA quality score and metrics for dati.gov.it datasets (accessibility, reusability, interoperability, findability)
  • ckan_get_mqa_quality_details: Get detailed MQA quality reasons and failing flags for dati.gov.it datasets

Portal Discovery

  • ckan_find_portals: Discover CKAN portals worldwide by country, language, or topic (uses datashades.info live registry of ~950 portals)

Catalog Analysis

  • ckan_analyze_datasets: Search datasets and inspect DataStore schemas of queryable resources
  • ckan_catalog_stats: Statistical overview of a portal (totals, breakdown by category, format, organization)

SPARQL

  • sparql_query: Execute SPARQL SELECT queries against any public SPARQL endpoint

Utilities

  • ckan_status_show: Verify server status

๐Ÿ“Ž MCP Resource Templates

Direct data access via ckan:// URI scheme:

  • ckan://{server}/dataset/{id} - Dataset metadata
  • ckan://{server}/resource/{id} - Resource metadata and download URL
  • ckan://{server}/organization/{name} - Organization details
  • ckan://{server}/group/{name}/datasets - Datasets by group (theme)
  • ckan://{server}/organization/{name}/datasets - Datasets by organization
  • ckan://{server}/tag/{name}/datasets - Datasets by tag
  • ckan://{server}/format/{format}/datasets - Datasets by resource format (res_format + distribution_format)

Examples:

ckan://dati.gov.it/dataset/vaccini-covid
ckan://demo.ckan.org/resource/abc-123
ckan://data.gov/organization/sample-org
ckan://dati.gov.it/group/ambiente/datasets
ckan://dati.gov.it/organization/regione-toscana/datasets
ckan://dati.gov.it/tag/turismo/datasets
ckan://dati.gov.it/format/csv/datasets

๐Ÿ’ก Usage Examples

A natural language conversation

Once connected, just ask in plain language. No query syntax needed:

"Search dati.gov.it for datasets about air quality in Milan, then summarize what each contains โ€” time coverage, license, and best download format."

The server finds 31 datasets, groups them by structural pattern, and returns a clear summary โ€” including series names, years covered, publisher, and format. No CKAN knowledge required.


The examples below show natural language requests alongside the actual tool call the LLM will generate internally and send to the CKAN portal. You never write these queries yourself โ€” they are shown here to illustrate how your question gets translated under the hood.

Search datasets (natural language: "search for population datasets")

ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  q: "popolazione",
  rows: 20
})

Force text-field parser for long OR queries (natural language: "find hotel or accommodation datasets")

ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  q: "hotel OR alberghi OR \"strutture ricettive\" OR ospitalitร  OR ricettivitร ",
  query_parser: "text",
  rows: 0  // returns only the total count, no dataset records โ€” useful to check how many results match before fetching them
})

Note: when query_parser: "text" is used, Solr special characters in the query are escaped automatically.

Rank datasets by relevance (natural language: "find most relevant datasets about urban mobility")

ckan_find_relevant_datasets({
  server_url: "https://www.dati.gov.it/opendata",
  query: "mobilitร  urbana",
  limit: 5
})

Filter by organization (natural language: "show recent datasets from Tuscany Region")

ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  fq: "organization:regione-toscana",
  sort: "metadata_modified desc"
})

Get statistics with faceting (natural language: "show statistics by organization, tags and format")

ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  facet_field: ["organization", "tags", "res_format"],
  rows: 0  // skip dataset records, return only the facet counts
})

List tags (natural language: "show top tags about health")

ckan_tag_list({
  server_url: "https://www.dati.gov.it/opendata",
  tag_query: "salute",
  limit: 25
})

Search groups (natural language: "find groups about environment")

ckan_group_search({
  server_url: "https://www.dati.gov.it/opendata",
  pattern: "ambiente"
})

DataStore Query (natural language: "query tabular data filtering by region and year")

What is DataStore? CKAN DataStore is an optional extension that imports tabular resources (CSV, Excel) into a queryable database. It allows filtering, sorting, and field selection directly on the data โ€” without downloading the file. Not all portals have it enabled, and not all datasets use it even when the portal supports it. Check datastore_active: true on a resource to confirm availability.

// Ordinanze viabili del Comune di Messina โ€” resource with datastore_active: true
ckan_datastore_search({
  server_url: "https://dati.comune.messina.it",
  resource_id: "17301b8b-2a5b-425f-80b0-5b75bb1793e9",
  filters: { "tipo": "lavori" },
  sort: "data_pubblicazione desc",
  limit: 10
})

๐Ÿ‘ A shout-out to Comune di Messina and all public administrations that enable the DataStore extension: by doing so, they make their data dramatically easier to query and explore โ€” including through AI tools like this one.

DataStore SQL Query (natural language: "count road orders by type")

// Count ordinanze viabili by tipo โ€” Comune di Messina
ckan_datastore_search_sql({
  server_url: "https://dati.comune.messina.it",
  sql: "SELECT tipo, COUNT(*) AS total FROM \"17301b8b-2a5b-425f-80b0-5b75bb1793e9\" GROUP BY tipo ORDER BY total DESC LIMIT 5"
})

๐Ÿง  AI Skill for smarter multi-step queries

The MCP server provides the raw tools โ€” the skill teaches your AI assistant how to use them intelligently.

Out of the box, an AI assistant knows each tool individually. The skill adds higher-level reasoning: which portal to query for a given country, what to do when a portal is unreachable, how to fall back to the European open data portal, and how to construct queries that actually return results.

What the skill adds:

  • Country routing โ€” automatically identifies the most authoritative CKAN portal for a country (national > regional > local)
  • Fallback chain โ€” if a portal is unreachable or returns 0 results, tries alternatives and, for European countries, falls back to data.europa.eu with correct country filters
  • Query construction โ€” bilingual queries, parser selection, fq syntax, wildcard handling
  • Correct API patterns โ€” the European portal (data.europa.eu) requires specific facets+facetOperator+facetGroupOperator parameters that are undocumented and easy to get wrong; the skill encodes this correctly

Examples of what the skill enables:

"Find road accident data in Portugal"
โ†’ ckan_find_portals(country="Portugal")          # finds 3 regional portals
โ†’ ckan_package_search on each โ†’ 0 results
โ†’ [tells user] "No results on Portuguese CKAN portals. Trying data.europa.eu..."
โ†’ curl "https://data.europa.eu/api/hub/search/search?q=acidentes+rodoviarios
         &facetOperator=AND&facetGroupOperator=AND&facets={"country":["pt"]}"
โ†’ 157 datasets found โ€” reported with source and filter details
"Find French open data about energy"
โ†’ [knows data.gouv.fr is NOT CKAN โ€” redirects to data.europa.eu]
โ†’ curl "...?q=energie+energy&facets={"country":["fr"]}..."
โ†’ Results filtered strictly to France

Install the skill

The skill folder lives at skills/ckan-mcp/ in this repository and is listed on skills.sh. Use the Skills CLI to install it:

# Install globally (available in all your projects)
npx skills add -g ondata/ckan-mcp-server --skill ckan-mcp

# Or for a single project (run from your project folder)
npx skills add ondata/ckan-mcp-server --skill ckan-mcp

๐ŸŒ Supported CKAN Portals

Some examples of supported portals:

Discover CKAN portals worldwide

Datashades.info/portals maintains a live registry of ~950 CKAN portals from around the world, with metadata on version, plugins, dataset counts, and geographic coordinates. Thanks to Sara Petti for bringing it to our attention.

The ckan_find_portals tool queries this registry directly. You can filter by country, language, minimum dataset count, or DataStore availability:

ckan_find_portals({ country: "Italy", has_datastore: true, limit: 5 })
ckan_find_portals({ language: "fr", min_datasets: 500 })
ckan_find_portals({ query: "transport" })

The portal data is also available as a public JSON API โ€” no authentication required:

Endpoint Description
GET https://datashades.info/api/portal/list Full list of portals with CKAN version, plugins, dataset/resource/organization counts, and country coordinates
GET https://datashades.info/api/portal/stats Aggregate statistics across all monitored portals
GET https://datashades.info/api/portal/historical/stats Historical trend data for the monitored portals

๐Ÿ” Advanced Solr Queries

CKAN uses Apache Solr as its default search engine. Understanding Solr syntax unlocks the full power of dataset search โ€” from simple keywords to complex boolean expressions, fuzzy matching, proximity searches, and date math.

Basic syntax

# Basic search
q: "popolazione"

# Field search
q: "title:popolazione"
q: "notes:sanitร "

# Boolean operators
q: "popolazione AND sicilia"
q: "popolazione OR abitanti"
q: "popolazione NOT censimento"

# Filters (fq) โ€” single value
fq: "organization:comune-palermo"
fq: "tags:sanitร "
fq: "res_format:CSV"

# Filters (fq) โ€” OR on same field: use field:(val1 OR val2)
fq: "res_format:(CSV OR JSON)"
fq: "organization:(comune-palermo OR comune-roma)"

# โš ๏ธ Wrong OR syntax โ€” silently ignored, returns entire catalog:
# fq: "res_format:CSV OR res_format:JSON"   โ† DO NOT USE

# Filters on CKAN extras fields โ€” use extras_ prefix
fq: "extras_hvd_category:\"http://data.europa.eu/bna/c_ac64a52d\""
fq: "extras_hvd_category:(\"http://data.europa.eu/bna/c_ac64a52d\" OR \"http://data.europa.eu/bna/c_dd313021\")"

# Wildcard
q: "popolaz*"

# Date range
fq: "metadata_modified:[2023-01-01T00:00:00Z TO *]"

Advanced Query Examples

These real-world examples demonstrate powerful Solr query combinations tested on the Italian open data portal (dati.gov.it):

1. Fuzzy Search + Date Math + Boosting (natural language: "find healthcare datasets modified in last 6 months")

Find healthcare datasets (tolerating spelling errors) modified in the last 6 months, prioritizing title matches:

ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  q: "(title:sanitร ~2^3 OR title:salute~2^3 OR notes:sanitร ~1) AND metadata_modified:[NOW-6MONTHS TO *]",
  sort: "score desc, metadata_modified desc",
  rows: 30
})

Techniques used:

  • sanitร ~2 - Fuzzy search with edit distance 2 (finds "sanita", "sanitรก", minor typos)
  • ^3 - Boosts title matches 3x higher in relevance scoring
  • NOW-6MONTHS - Dynamic date math for rolling time windows
  • Combined boolean logic with multiple field searches

Results: 949 datasets including hospital units, healthcare organizations, medical services

2. Proximity Search + Complex Boolean (natural language: "find air pollution datasets excluding water")

Environmental datasets where "inquinamento" and "aria" (air pollution) appear close together, excluding water-related datasets:

ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  q: "(notes:\"inquinamento aria\"~5 OR title:\"qualitร  aria\"~3) AND NOT (title:acqua OR title:mare)",
  facet_field: ["organization", "res_format"],
  rows: 25
})

Techniques used:

  • "inquinamento aria"~5 - Proximity search (words within 5 positions)
  • ~3 - Tighter proximity for title matches
  • NOT (title:acqua OR title:mare) - Exclude water/sea datasets
  • Faceting for statistical breakdown

Results: 305 datasets

3. Wildcard + Field Existence + Date Math (natural language: "regional datasets with any format from last month")

Regional datasets published in the last month that have at least one resource format declared:

ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  q: "organization:regione* AND metadata_created:[NOW-1MONTH TO *] AND res_format:*",
  sort: "metadata_modified desc",
  facet_field: ["organization"],
  rows: 10
})

Techniques used:

  • regione* - Wildcard matches all regional organizations
  • res_format:* - Field existence check (has at least one resource format declared)
  • NOW-1MONTH - Rolling 30-day window

Results: 293 datasets

4. Explicit Date Range + Facets (natural language: "Ministry of Labour datasets updated in 2025")

Datasets from the Italian Ministry of Labour modified during 2025, with facets by format and tags:

ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  q: "organization:ministero-del-lavoro AND metadata_modified:[2025-01-01T00:00:00Z TO 2025-12-31T23:59:59Z]",
  sort: "metadata_modified desc",
  facet_field: ["res_format", "tags"],
  rows: 10
})

Techniques used:

  • [2025-01-01T00:00:00Z TO 2025-12-31T23:59:59Z] - Explicit date range (full year)
  • organization:ministero-del-lavoro - Filter by specific organization
  • Multiple facets for format and topic breakdown

Results: 83 datasets

Solr Query Syntax Reference

Boolean Operators: AND, OR, NOT, +required, -excluded Wildcards: * (multiple chars), ? (single char) - Note: left truncation not supported Fuzzy: ~N (edit distance), e.g., health~2 Proximity: "phrase"~N (words within N positions) Boosting: ^N (relevance multiplier), e.g., title:water^2 Ranges:

  • Inclusive: [a TO b], e.g., num_resources:[5 TO 10]
  • Exclusive: {a TO b}, e.g., num_resources:{0 TO 100}
  • Open-ended: [2024-01-01T00:00:00Z TO *]

Date Math: NOW, NOW-1YEAR, NOW-6MONTHS, NOW-7DAYS, NOW/DAY Field Existence: field:* (field exists), NOT field:* (field missing)


๐Ÿ“… Understanding date fields

CKAN portals can be source catalogs (data published directly by the organization) or harvesting aggregators (data collected from many other portals). This distinction matters a lot when filtering by date.

Field Meaning on source portal Meaning on aggregator
issued When the publisher released the dataset When the publisher released the dataset
metadata_created When the record was first created When the record was first harvested
metadata_modified When the record was last updated When the record was last re-harvested

On an aggregator like dati.gov.it, metadata_modified is updated every time the portal re-harvests โ€” even if the dataset content hasn't changed. This makes it unsuitable for finding "recently updated content".

Example โ€” same dataset, three different timestamps on dati.gov.it (aggregator):

{
  "issued": "2024-12-10",
  "metadata_created": "2024-12-16",
  "metadata_modified": "2026-02-28"
}

metadata_modified is February 2026 only because the portal re-harvested it then โ€” not because the data changed.

Which date fields are filterable on dati.gov.it?

All three fields are Solr-indexed and usable in queries:

Field Solr-indexed What queries return
issued โœ… Datasets by publisher release date โ€” most meaningful, but ~14% of datasets lack it
metadata_created โœ… Datasets by first harvesting date on dati.gov.it
metadata_modified โœ… Datasets by last re-harvesting date โ€” often noisy

Query examples (dati.gov.it):

# Datasets about road accidents published by the original source in 2025
ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  q: "incidenti stradali",
  fq: "issued:[2025-01-01T00:00:00Z TO 2025-12-31T23:59:59Z]"
})
// โ†’ ~121 results (only datasets where publisher filled in `issued`)

# Datasets first appearing on dati.gov.it in 2025
ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  q: "incidenti stradali",
  fq: "metadata_created:[2025-01-01T00:00:00Z TO 2025-12-31T23:59:59Z]"
})
// โ†’ ~164 results (includes older datasets harvested for the first time in 2025)

Note on issued coverage: ~59,700 of 69,000+ datasets on dati.gov.it have issued populated. Queries on issued are accurate but incomplete โ€” datasets without the field are silently excluded. Prefer issued for content-date queries; use metadata_created only as a fallback for "when did this appear on the portal".

Recommendation: use issued to find datasets by publication date. Use metadata_created to find datasets that appeared on the portal recently.


๐Ÿ‘ฉโ€๐Ÿ’ป Developer Reference

Project Structure

ckan-mcp-server/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ index.ts            # Entry point
โ”‚   โ”œโ”€โ”€ server.ts           # MCP server setup
โ”‚   โ”œโ”€โ”€ worker.ts           # Cloudflare Workers entry
โ”‚   โ”œโ”€โ”€ types.ts            # Types & schemas
โ”‚   โ”œโ”€โ”€ utils/
โ”‚   โ”‚   โ”œโ”€โ”€ http.ts         # CKAN API client
โ”‚   โ”‚   โ”œโ”€โ”€ formatting.ts   # Output formatting
โ”‚   โ”‚   โ””โ”€โ”€ url-generator.ts
โ”‚   โ”œโ”€โ”€ tools/
โ”‚   โ”‚   โ”œโ”€โ”€ package.ts      # Package search/show
โ”‚   โ”‚   โ”œโ”€โ”€ organization.ts # Organization tools
โ”‚   โ”‚   โ”œโ”€โ”€ datastore.ts    # DataStore queries
โ”‚   โ”‚   โ”œโ”€โ”€ status.ts       # Server status
โ”‚   โ”‚   โ”œโ”€โ”€ tag.ts          # Tag tools
โ”‚   โ”‚   โ””โ”€โ”€ group.ts        # Group tools
โ”‚   โ”œโ”€โ”€ resources/          # MCP Resource Templates
โ”‚   โ”‚   โ”œโ”€โ”€ index.ts
โ”‚   โ”‚   โ”œโ”€โ”€ uri.ts
โ”‚   โ”‚   โ”œโ”€โ”€ dataset.ts
โ”‚   โ”‚   โ”œโ”€โ”€ resource.ts
โ”‚   โ”‚   โ””โ”€โ”€ organization.ts
โ”‚   โ”œโ”€โ”€ prompts/            # MCP Guided Prompts
โ”‚   โ”‚   โ”œโ”€โ”€ index.ts
โ”‚   โ”‚   โ”œโ”€โ”€ theme.ts
โ”‚   โ”‚   โ”œโ”€โ”€ organization.ts
โ”‚   โ”‚   โ”œโ”€โ”€ format.ts
โ”‚   โ”‚   โ”œโ”€โ”€ recent.ts
โ”‚   โ”‚   โ””โ”€โ”€ dataset-analysis.ts
โ”‚   โ””โ”€โ”€ transport/
โ”‚       โ”œโ”€โ”€ stdio.ts
โ”‚       โ””โ”€โ”€ http.ts
โ”œโ”€โ”€ tests/                  # Test suite
โ”œโ”€โ”€ dist/                   # Compiled output (generated)
โ”œโ”€โ”€ package.json
โ””โ”€โ”€ README.md

Build & Test

# Build (esbuild, ~4ms)
npm run build

# Watch mode
npm run watch

# Run all tests
npm test

# Watch mode for tests
npm run test:watch

# Coverage report
npm run test:coverage

Explore with MCP Inspector

The MCP Inspector lets you browse tools, test calls interactively, and debug responses in a web UI:

npm install -g @modelcontextprotocol/inspector
npm run build
npx @modelcontextprotocol/inspector node dist/index.js

Opens at http://localhost:5173.

Manual HTTP Testing

# Start server
TRANSPORT=http PORT=3001 node dist/index.js

# List available tools
curl -s -X POST http://localhost:3001/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'

# Call a tool
curl -s -X POST http://localhost:3001/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{
    "jsonrpc":"2.0","method":"tools/call",
    "params":{"name":"ckan_package_search","arguments":{"server_url":"https://www.dati.gov.it/opendata","q":"ambiente","rows":3}},
    "id":1
  }' | jq -r '.result.content[0].text'

Portal View URL Templates

Some CKAN portals expose non-standard web URLs for viewing datasets or organizations. To support those cases, this project ships with src/portals.json, which maps known portal API URLs (and aliases) to custom view URL templates.

When generating a dataset or organization view link, the server:

  • matches the server_url against api_url and api_url_aliases in src/portals.json
  • uses the portal-specific dataset_view_url / organization_view_url template when available
  • falls back to the generic defaults ({server_url}/dataset/{name} and {server_url}/organization/{name})

Troubleshooting

Wrong URL for Italian portal โ€” use https://www.dati.gov.it/opendata (not https://dati.gov.it).

Connection error

Error: Server not found: https://example.gov

Verify the URL is reachable and use ckan_status_show to confirm the portal is responding.

No results โ€” broaden your query or check what's available with facets:

ckan_package_search({
  server_url: "https://www.dati.gov.it/opendata",
  q: "*:*",
  facet_field: ["tags", "organization"],
  rows: 0
})

LLM uses external data when no results are found โ€” when a tool returns no results, some LLMs (e.g. ChatGPT) may supplement the answer with information from their training data without warning. This is a known LLM behavior, not a server issue. To avoid it, instruct the model in your system prompt to only use data returned by the MCP tools and not rely on external sources.


๐Ÿ†˜ Support

For issues or questions, open an issue on GitHub.


Privacy Policy

This server collects no personal data. It is read-only and stateless โ€” queries are forwarded directly to the public CKAN API you specify, and no data is stored or logged.

See the full Privacy Policy.


๐Ÿ”— Useful Links


Created with โค๏ธ by onData for the open data community

Release History

VersionChangesUrgencyDate
v0.4.106## Security Fix ### GHSA-g84h-j7jj-x32p โ€” SSRF bypass via `ip6-localhost`/`ip6-loopback` Hostname aliases such as `ip6-localhost` and `ip6-loopback` โ€” present in `/etc/hosts` on many Linux systems mapping to `::1` โ€” bypassed the existing SSRF filter (GHSA-3xm7-qw7j-qc8v). The filter checked for `localhost`, dotted IPv4 literals, and bracketed IPv6 literals, but not these string aliases. **Fix**: replaced the single `hostname === 'localhost'` check with a blocked-hostname `Set` covering `ip6-lHigh5/31/2026
v0.4.105## What's New ### Bug Fix: `ckan_find_relevant_datasets` on federated CKAN catalogs Thanks to [@piersoft](https://github.com/piersoft) for identifying and fixing this bug (PR [#34](https://github.com/ondata/ckan-mcp-server/pull/34)). On federated portals like `dati.gov.it`, `organization` is the harvesting catalog (e.g. Regione Puglia), not the actual data owner. Queries like "datasets from Comune di Lecce" previously scored 0 on the owner field for datasets harvested via aggregator catalogs.High5/25/2026
v0.4.104## What's New ### Source Portal DataStore Fallback - `ckan_list_resources` now probes the source CKAN portal when a resource has `datastore_active=false` and its download URL belongs to a different CKAN instance (harvested dataset pattern) - New output fields: `source_datastore_active`, `source_portal_url` - New parameter: `check_source_portal` (default `true`) to skip extra HTTP calls - New utility: `extractSourcePortal()` in `url-generator.ts` ### LLM Error Hints - New `CkanApiError` class iHigh5/20/2026
v0.4.103## What's New ### Security Hardening (CERT-AgID MCP recommendations) - **Domain allowlist**: optional `CKAN_ALLOWED_DOMAINS` env var to restrict which CKAN portals can be reached. Set to a comma-separated list of hostnames (e.g. `CKAN_ALLOWED_DOMAINS=dati.gov.it,demo.ckan.org`). Default: no restriction. - **Audit logging**: every `makeCkanRequest` call now writes a JSON line to stderr in Node modes (stdio + http). Fields: `ts`, `server`, `action`, `cache_hit`, plus relevant query params (`q`, High4/22/2026
v0.4.102## What's New - `cache_hit: true/false` field added to every worker telemetry log entry - Log is now written **after** the response so the flag reflects the actual cache outcome - Enables cache hit rate analysis in `worker_events_flat.jsonl` ### No Breaking Changes - Log format is additive (new field only) **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.101...v0.4.102 High4/14/2026
v0.4.101## What's New ### Features - Per-portal upstream rate limiter in `makeCkanRequest` via new `src/utils/rate-limiter.ts` - Token bucket algorithm: one independent bucket per CKAN portal hostname - Cache hits bypass the limiter entirely โ€” no token consumed if response is cached - `RateLimitError` thrown when required wait exceeds `CKAN_RATE_LIMIT_MAX_WAIT_MS` ### Configuration | Env var | Default | Notes | |---|---|---| | `CKAN_RATE_LIMIT_ENABLED` | `true` | Set `false` to disable | | `CKAN_RATE_Medium4/14/2026
v0.4.100## What's New ### Features - Read-through HTTP cache in `makeCkanRequest` with action-based TTL (metadata 300s, datastore 60s, status 3600s) - Runtime-aware backend: Cloudflare Cache API on Workers, bounded in-memory LRU on Node - Configurable via env vars: `CKAN_CACHE_ENABLED`, `CKAN_CACHE_TTL_DEFAULT`, `CKAN_CACHE_MAX_ENTRIES`, `CKAN_CACHE_MAX_ENTRY_BYTES` - Per-call bypass via `makeCkanRequest(..., { cache: false })` ### Safety - Errors and `success=false` responses are never cached - PayloMedium4/14/2026
v0.4.99## What's New ### Bug Fix - `resolveSearchQuery` no longer wraps `*:*` and fielded queries (e.g. `title:X`) in `text:(...)` when auto-detected parser override is "text" - Previously, `escapeSolrQuery` turned `*:*` into `\*\:\*`, causing 0 results on portals like dati.comune.messina.it with Sitelock anti-bot ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.98...v0.4.99 High4/9/2026
v0.4.98## What's New ### Bug Fix - **`ckan_package_search`**: quoted phrases like `"aree protette"` or `"rischio idrogeologico"` now work correctly when combined with `fq` filters - Root cause: `escapeSolrQuery` was escaping `"` to `\"`, breaking phrase queries inside `text:(...)` wrapping used on dati.gov.it ### No Breaking Changes - All existing functionality preserved - 327 tests passing **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.97...v0.4.98 High4/5/2026
v0.4.97## What's New ### Improvements - Added `.describe()` to all parameters in `ckan_group_list`, `ckan_group_show`, `ckan_group_search` - Added `.describe()` to all parameters in `ckan_tag_list` - Improved `ckan_package_show` parameter descriptions (server_url example URL, id UUID/slug hint) ### Why Better parameter descriptions improve usability in Cloudflare Code Mode, where tool schemas are converted to TypeScript API definitions with JSDoc comments. Each `.describe()` becomes a parameter-levelMedium4/3/2026
v0.4.96## What's New - Add `dati.regione.sicilia.it` (Sicily open data portal) to `portals.json` with `force_text_field: false` โ€” CKAN 2.6.8 does not support the `text:(...)` query wrapper ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.95...v0.4.96 Medium3/26/2026
v0.4.95## What's New ### Improvements - `ckan_status_show` now shows **Portal Locale** (`locale_default`) in the output โ€” models can use this to auto-detect the portal's language before searching - `ckan_package_search` description includes an explicit hint: check locale via `ckan_status_show` and translate query terms to the portal's language - Skill query construction rule updated: replaces hardcoded portal/language table with a dynamic rule based on `locale_default` ### Why Searching in English onMedium3/26/2026
v0.4.94## What's New ### Portal Support - Added `data.gov.ua` (Ukraine open data portal) to known portals ### Fix - Explicit `force_text_field: false` prevents the auto-detection probe from incorrectly wrapping Solr queries in `text:(...)`, which caused 0 results on this portal ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.93...v0.4.94 Medium3/26/2026
v0.4.93## What's New ### Bug Fix - **fix(worker)**: return `405 Method Not Allowed` immediately when bots/scanners send `GET /mcp` ### Problem Bot scanners were sending `GET /mcp` requests at ~4 req/sec (316k in 24h). The Worker was hanging waiting for a JSON-RPC body that never arrived, consuming CPU until Cloudflare's runtime killed it โ€” causing 98.7% error rate. ### Fix 9-line guard at the top of the `/mcp` handler: any method other than `POST` or `OPTIONS` now gets an instant `405` response withMedium3/24/2026
v0.4.92## What's New ### Fix - Updated HTTP transport for SDK 1.26.0 security fix: transport is now created per request (stateless mode requirement, CVE GHSA-345p-7cg4-v4c7) **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.91...v0.4.92 Medium3/23/2026
v0.4.91## What's New ### Fix - Updated for SDK 1.27.1 compatibility: transport is now created per request (stateless mode requirement) **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.90...v0.4.91 Medium3/23/2026
v0.4.90## What's New ### Fix - Update `@modelcontextprotocol/sdk` 1.25.2 โ†’ 1.27.1 โ€” fixes Claude Desktop crash with new MCP protocol version `2025-11-25` (Claude Desktop โ‰ฅ 1.1.7714) ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.89...v0.4.90 Low3/22/2026
v0.4.89## What's New ### Fix - `ckan_organization_search`: pattern is now lowercased before querying Solr โ€” CKAN org name slugs are always lowercase, so searching "Roma", "ROMA", or "roma" now all return the same correct results ### No Breaking Changes - Existing behavior preserved for lowercase patterns **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.88...v0.4.89 Low3/19/2026
v0.4.88## What's New ### Fix - `ckan_organization_search`: link column in markdown table, `view_url` field in JSON output - `ckan_organization_show`: `view_url` field in JSON output - Both tools use `portals.json` custom URL patterns (e.g. dati.gov.it uses `/view-dataset?organization={name}` instead of the default CKAN path) ### No Breaking Changes - All existing fields preserved; `view_url` is additive **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.87...v0.4.88 Low3/19/2026
v0.4.87## What's New ### Bug Fix - **`sparql_query`**: add `; charset=utf-8` to POST `Content-Type` header โ€” fixes corruption of accented characters (e.g. `รฉ`, `ร `) in SPARQL string literals when querying Wikidata and other endpoints. Queries like `?item rdfs:label "Nestlรฉ"@en` now return correct results. ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.86...v0.4.87 Low3/17/2026
v0.4.86## Changes - Add security note to `ckan_datastore_search_sql` tool description โ€” clarifies that SQL queries are forwarded to the CKAN DataStore API (CKAN enforces its own access controls, no local DB exposed) ### No Breaking Changes All existing functionality preserved. **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.85...v0.4.86 Low3/16/2026
v0.4.85## Security Fix ### SSRF Prevention Extended to `sparql_query` - `validateServerUrl()` now applied to `sparql_query` endpoint parameter - Blocks private/internal IPs (RFC 1918, link-local 169.254.x.x) on SPARQL tool - Previously only non-HTTPS was blocked; private IPs could bypass validation - 1 new test added for SSRF prevention via private IP ### Context This patch closes a gap identified in GHSA-3xm7-qw7j-qc8v. The core SSRF fix (blocking private IPs on CKAN tools) was shipped in v0.4.84.Low3/16/2026
v0.4.84## Security Fix ### SSRF Prevention in `validateServerUrl()` Added URL validation in `makeCkanRequest()` to block Server-Side Request Forgery attacks. **Blocked**: - Non-HTTP/S protocols (`file://`, `ftp://`, etc.) - Loopback addresses (`localhost`, `127.x.x.x`, `::1`) - Private IP ranges (`10.x.x.x`, `172.16-31.x.x`, `192.168.x.x`) - Link-local / AWS metadata (`169.254.x.x`) - IPv6 private/local (`fc00::`, `fd00::`, `fe80::`) ### Tests - 15 new unit tests covering all blocked ranges and valLow3/15/2026
v0.4.81## What's New ### Bug Fix - `ckan_find_portals` calls now log search criteria (`country`, `language`, `has_datastore`, `min_datasets`) in worker telemetry โ€” previously always `null` unless `query` param was used ### Files Changed - `src/worker.ts`: added 4 missing fields to request logging - `scripts/worker_telemetry_flatten.py`: `extract_query` builds combined criteria string for `ckan_find_portals` ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://gLow3/10/2026
v0.4.80## What's New ### Bug Fix - **`worker.ts` telemetry**: `sparql_query` now correctly logs the SPARQL endpoint in the `server` field โ€” was always `""` because logging read `server_url` but SPARQL tool uses `endpoint_url` ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.79...v0.4.80 Low3/9/2026
v0.4.79## What's New ### Feature: Auto-detect Solr parser mode Many CKAN portals silently return 0 results for OR queries (e.g. `water OR environment`) due to a known Solr `df` field bug in older CKAN versions (see [ckan/ckan#4376](https://github.com/ckan/ckan/pull/4376)). The server now auto-detects this on first use of any unknown portal: - Runs 2 parallel `rows=0` probe calls (`data OR dati`) โ€” default vs `text:(...)` parser - If text parser returns >2ร— more results โ†’ marks portal as needing `texLow3/8/2026
v0.4.78## What's New ### Bug Fix - **`issued`/`modified` date math**: `NOW` syntax (e.g. `issued:[NOW-30DAY TO *]`) returned 0 results on all portals tested โ€” these fields are CKAN extras, not native Solr date fields, so they don't support `NOW` expressions - Server now auto-converts `NOW` date math to ISO dates in `q` and `fq` when the field is `issued` or `modified`; `metadata_modified` and `metadata_created` are unaffected (they are native Solr fields) - Fixed `content_recent` feature which had theLow3/8/2026
v0.4.77## What's New ### Bug Fix - Removed `Referer`, `Sec-Fetch-Site`, `Sec-Fetch-Mode`, `Sec-Fetch-Dest`, `Upgrade-Insecure-Requests` from axios request headers - These headers triggered "Request Rejected" on portals with strict WAF rules (e.g. BA Data โ€” data.buenosaires.gob.ar) - All previously working portals (dati.gov.it, open.canada.ca, data.gov.uk, etc.) unaffected ### No Breaking Changes - All existing functionality preserved - 310 tests passing **Full Changelog**: https://github.com/ondata/Low3/7/2026
v0.4.76## What's New ### Bug Fix - `ckan_find_portals`: deduplicate portals by hostname, prefer https over http when both exist ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.75...v0.4.76 Low3/6/2026
v0.4.75## What's New ### New Tool: `ckan_find_portals` Discover CKAN portals worldwide from the [datashades.info](https://datashades.info/portals) live registry (~950 portals). **Parameters** (all optional, all LLM-extractable from natural language): - `country` โ€” country name in English (LLM translates from any language) - `query` โ€” keyword matched against portal title - `min_datasets` โ€” minimum dataset count - `language` โ€” portal default locale (e.g. `"it"`, `"pt_BR"`) - `has_datastore` โ€” filter poLow3/6/2026
v0.4.74## What's New ### Bug Fix - `z.coerce.number()` for all numeric tool parameters โ€” fixes `invalid_type` validation errors when MCP clients (e.g. Claude Desktop) pass numeric values as JSON strings instead of numbers ### Affected parameters `rows`, `start`, `page`, `page_size`, `facet_limit`, `content_recent_days`, `limit`, `offset`, boost weights โ€” across `package.ts`, `organization.ts`, `datastore.ts` ### No Breaking Changes All existing functionality preserved. Coercion is transparent when vLow3/6/2026
v0.4.73## What's New ### Improvements - `package_show` JSON now includes `api_json_url` at dataset level and for each resource โ€” direct links to raw CKAN API metadata (`package_show?id=...` and `resource_show?id=...`) - Markdown format also shows **Full JSON metadata** links for dataset and each resource - Uses portal-specific API path (via `getPortalApiPath`) instead of hardcoded `/api/3/action` ### No Breaking Changes - All existing fields preserved **Full Changelog**: https://github.com/ondata/ckLow3/5/2026
v0.4.72## What's New ### Improvements - `package_show` JSON format now exposes 6 new fields: `hvd_category`, `applicable_legislation`, `frequency`, `language`, `publisher_name`, `holder_name` - `fq` parameter documentation now warns about correct Solr OR syntax (`field:(a OR b)`) and the `extras_` prefix required for CKAN extras fields ### No Breaking Changes - All existing fields preserved; new fields are additions only **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.71..Low3/5/2026
v0.4.71## What's New ### HVD Dataset Support - `ckan_status_show` now shows **HVD dataset count** when the portal has `hvd.category_field` configured in `portals.json` (e.g. dati.gov.it: 445 HVD datasets) - New MCP prompt **`ckan-search-hvd`**: guided search for High-Value Datasets using the correct filter field from portal config; falls back to keyword search for unconfigured portals ### No Breaking Changes - All existing functionality preserved - HVD fields read from existing `portals.json` configuLow3/4/2026
v0.4.69## What's New ### Features - `ckan_package_search` JSON output now includes `view_url` โ€” direct link to the dataset page on the source portal - `ckan_package_show` JSON output now includes `view_url` โ€” same field for consistency ### No Breaking Changes - All existing functionality preserved; `view_url` is additive only **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.68...v0.4.69 Low3/4/2026
v0.4.68## What's New ### SPARQL endpoint per portal - `portals.json` now supports a `sparql` field with `endpoint_url` and optional `method` (`GET`/`POST`) - First configured portal: Italy (`lod.dati.gov.it/sparql`, GET-only due to AWS WAF) ### ckan_status_show improvement - Now shows **SPARQL Endpoint** when the portal has one configured โ€” clients can discover and use it automatically ### sparql_query fixes - GET fallback on 403/405 for endpoints that reject POST - User-Agent changed to `Mozilla/5.Low3/4/2026
v0.4.67## What's Changed ### Removed - `europa_dataset_search` tool โ€” interacted with data.europa.eu proprietary API (non-standard CKAN). Use `sparql_query` against `https://data.europa.eu/sparql` for equivalent queries. ### Improved - `sparql_query`: SELECT-only validation (rejects CONSTRUCT, ASK, DESCRIBE, write operations) - `sparql_query`: auto-injects `LIMIT` if not present in query (default 25, max 1000) - `sparql_query`: output truncated at CHARACTER_LIMIT (50k chars) for consistency with otheLow3/4/2026
v0.4.66## What's New ### New Tool: `sparql_query` Execute SPARQL SELECT queries against any public HTTPS SPARQL endpoint directly from ckan-mcp. Supported endpoints include: - `https://data.europa.eu/sparql` โ€” EU open data portal (publisher aggregations, HVD analysis, DCAT-AP queries) - `https://publications.europa.eu/webapi/rdf/sparql` โ€” EU controlled vocabularies - `https://dbpedia.org/sparql` โ€” DBpedia - `https://query.wikidata.org/sparql` โ€” Wikidata - Any other public HTTPS SPARQL endpoint **WhyLow3/4/2026
v0.4.65## What's New ### Changes - `europa_dataset_search` now includes a **Publisher** facet in results โ€” shows top publishers with dataset counts ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.64...v0.4.65 Low3/4/2026
v0.4.64## What's New ### Bug Fix - **fix(europa)**: `q=*` now correctly returns all 1.7M+ datasets from the European Data Portal - Root cause: Europa's Elasticsearch API returns only ~6k results when `q=*` is sent; omitting `q` returns all datasets - Match-all queries (`*`, `*:*`) now omit the `q` parameter entirely ### No Breaking Changes - All existing functionality preserved - Tool interface unchanged **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.63...v0.4.64 Low3/4/2026
v0.4.63## What's New ### Changes - **Filtered facets**: Europa search now returns only 8 useful facets (country, categories, format, is_hvd, scoring, language, subject, hvdCategory) โ€” heavy ones discarded - **Multilingual resolve**: subject, hvdCategory, and categories titles resolved to requested `lang` (was returning all 27 EU languages) - **Smaller output**: JSON response 52KB โ†’ 12KB, always valid (no more truncation) ### No Breaking Changes - All existing functionality preserved **Full ChangelogLow3/4/2026
v0.4.62## What's New ### Features - **Europa facets**: `europa_dataset_search` now returns facets (country, format, categories, and 15 more) in both markdown (tables) and JSON (compact objects, top 15 items per facet) - **HVD filter**: New `is_hvd` boolean parameter to search only High Value Datasets on the European Data Portal ### Example ```json { "q": "transport", "is_hvd": true, "country": ["IT"], "page_size": 5 } ``` ### No Breaking Changes - All existing functionality preserved **Full ChangelLow3/4/2026
v0.4.61## What's New ### New Tool - **`europa_dataset_search`** โ€” search 1.7M+ datasets on data.europa.eu (European Data Portal) with country filter, multilingual support, and HVD badge ### Compact JSON Output - JSON responses for heavy tools now return only essential fields (~70% token reduction) - Affected tools: `package_search`, `package_show`, `organization_list/show`, `group_list/show`, `datastore_search/search_sql` - New `truncateJson()` function ensures valid JSON when truncating (shrinks arrLow3/4/2026
v0.4.60## What's New ### Bug Fix - **Workers fetch timeout**: Add `AbortController` with 30s timeout to the Cloudflare Workers `fetch` call. Previously, if a CKAN server was slow to respond, the Worker would hang indefinitely until Cloudflare's runtime killed it. Now it times out cleanly after 30 seconds, matching the Node.js axios timeout. ### Root Cause Identified via telemetry analysis: two Worker timeout events on 2026-03-03 were caused by `ckan_find_relevant_datasets` hanging on `dati.gov.it`. TLow3/4/2026
v0.4.59## What's New ### One-click install for Claude Desktop CKAN MCP Server is now available as a Desktop Extension (`.dxt`) โ€” download and double-click to install directly in Claude Desktop, no manual config file editing required. ### Changes - Add `manifest.json` (DXT v0.1 spec) - Add `npm run pack:dxt` build script - Add "One-click install" section to README - Update release workflow docs ### No Breaking Changes - All existing stdio/HTTP transport unaffected - All tools work identically **FulLow3/3/2026
v0.4.58## What's New ### HVD context on portal synthesis queries When querying dati.gov.it with a broad synthesis query (`q=*:*`) combined with organisation/tag/group facets (or `rows=0`), the tool now automatically fetches the real-time count of High Value Datasets and appends a contextual note to the markdown response: > **High Value Datasets (HVD)**: This portal contains **445 datasets** classified as High Value Datasets under EU Regulation 2023/138. This helps users discover the HVD layer of thLow3/2/2026
v0.4.57## What's New ### New Portal - **data.stadt-zuerich.ch** (City of Zurich, ๐Ÿ‡จ๐Ÿ‡ญ) โ€” added to the portal registry. Dataset search and organization tools work out of the box. ### Improved LLM Behavior - All tools now include an explicit note when no results are found, discouraging LLMs from supplementing the response with data from external sources. Thanks to @alexanderguentert for reporting this in [#12](https://github.com/ondata/ckan-mcp-server/discussions/12) โ€” great catch! ### Documentation -Low3/2/2026
v0.4.56## What's New ### Documentation - Add `.readme-npm.md`: short, focused README for the npm package page (intro + essentials + link to full GitHub README) - `prepack`/`postpack` hooks swap README automatically on every `npm publish` - Remove stale `README.bak.md` ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.55...v0.4.56 Low3/1/2026
v0.4.55## What's New ### Bug Fixes - Replace relative paths with absolute GitHub URLs in README - GIF demo now renders correctly on npm package page - Guide links and portals.json links now work on npm ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.54...v0.4.55 Low3/1/2026
v0.4.54## What's New ### Documentation - Bump patch version to republish npm package with updated README - Fix DEPLOYMENT.md: every versioned release always includes `npm publish` ### No Breaking Changes - All existing functionality preserved **Full Changelog**: https://github.com/ondata/ckan-mcp-server/compare/v0.4.53...v0.4.54 Low3/1/2026
v0.4.53## What's New ### New Tools - **`ckan_analyze_datasets`**: search datasets and inspect DataStore schema in one call โ€” returns field names, types, labels and notes (from CKAN DataStore Dictionary), and record count per resource - **`ckan_catalog_stats`**: portal overview in one call โ€” total dataset count + breakdown by category, format, and organization via a single faceted query ### Refactoring - `ckan_get_mqa_quality` and `ckan_get_mqa_quality_details` migrated from deprecated `server.tool()`Low2/28/2026
v0.4.52## What's New ### Bug Fixes - **HTTP transport**: `/.well-known/oauth-authorization-server` now returns a JSON 404 response instead of HTML, fixing Claude Code HTTP transport connection failures (inspired by [datagouv/datagouv-mcp#26](https://github.com/datagouv/datagouv-mcp/issues/26)) - **DataStore column discovery**: `ckan_datastore_search` now accepts `limit=0`, allowing LLMs to retrieve available column names and types without fetching any data rows โ€” prevents filter errors caused by unknLow2/28/2026
v0.4.51## What's New ### Refactoring - **CKAN domain types**: Added `CkanTag`, `CkanResource`, `CkanPackage`, `CkanOrganization`, `CkanField`, `CkanDatastoreResult` to `src/types.ts`; `any` usage reduced from 32 to 1 - **Rendering functions**: Extracted markdown rendering from anonymous handler closures into named exported functions in `datastore.ts`, `organization.ts`, `group.ts`, `status.ts` ### Fixes - **Datastore table**: skip internal `_id` column from display; increase cell truncation from 50โ†’8Low2/27/2026
v0.4.50## What's New Four improvements that make the server more transparent and easier to use, especially when searching portals with large or heterogeneous datasets. ### DataStore status always visible `ckan_package_show` now reports DataStore availability for every resource โ€” even on portals (like dati.gov.it) that don't include the field in their API response: - โœ… **Available** โ€” resource is queryable via `ckan_datastore_search` - โŒ **Not available** โ€” resource exists but DataStore is off - โ“ *Low2/26/2026

Dependencies & License Audit

Loading dependencies...

Similar Packages

flywheel-memoryMCP server giving AI a knowledge graph over Obsidian vaults. 13-layer scoring that learns. Local-first, zero cloud.flywheel-memory-v2.12.16
smartlead-mcp-serverAutomate cold email campaigns effortlessly with SmartLead MCP Server. Integrate with AI tools for streamlined communication. ๐Ÿš€๐Ÿ’ปmain@2026-06-06
autotask-mcpMCP server for Kaseya Autotask PSA โ€” 39 tools for companies, tickets, projects, time entries, and morev2.28.1
website-design-systems-mcp๐ŸŽจ Extract complete design systems from websites and generate AI-ready skill.md files to replicate exact design elements efficiently.main@2026-06-02
segundo-cerebroPersonal knowledge graph MCP server on Cloudflare D1 + Vectorize. Deploy your own sovereign second brain in one click โ€” Claude captures atomic concepts, finds cross-domain analogies, and links them wi0.0.0

More in MCP Servers

agentroveYour own Claude Code UI, sandbox, in-browser VS Code, terminal, multi-provider support (Anthropic, OpenAI, GitHub Copilot, OpenRouter), custom skills, and MCP servers.
node9-proxyThe Execution Security Layer for the Agentic Era. Providing deterministic "Sudo" governance and audit logs for autonomous AI agents.
mcp-compressorAn MCP server wrapper for reducing tokens consumed by MCP tools.
claude-plugins-officialOfficial, Anthropic-managed directory of high quality Claude Code Plugins.