CKAN MCP Server
The CKAN MCP Server lets you search, explore, and query any CKAN open data portal through natural language, without needing to know CKAN's API or query syntax.
Search & Discovery
Search datasets using full Solr query syntax (boolean, fuzzy, wildcards, date ranges, boosting)
Find relevant datasets ranked by relevance score with weighted fields (title, tags, notes, organization, publisher)
Get full dataset metadata including resources, organization, tags, and license
List dataset resources with format, size, DataStore availability, and download URLs
List tags with counts, optionally filtered by substring or scoped to a dataset query
Organizations & Groups
List, search, and show details for organizations and thematic groups, including their datasets
Tabular Data Querying (DataStore)
Query DataStore resources with filters, sorting, field selection, full-text search, and pagination
Run SQL queries directly on DataStore resources for aggregations and complex filtering
Discover column schemas (field names and types) before querying
Portal Discovery & Catalog Analysis
Find CKAN portals worldwide from a live registry of ~950 portals, filterable by country, language, dataset count, or DataStore availability
Get portal statistics: total dataset count with breakdowns by category, format, and organization
Analyze datasets and DataStore schemas in one call
Quality Metrics
Retrieve MQA quality scores and detailed metrics (accessibility, reusability, interoperability, findability, contextuality) for datasets on dati.gov.it
SPARQL
Execute SPARQL SELECT queries against any public HTTPS SPARQL endpoint (Wikidata, DBpedia, data.europa.eu, etc.)
Utilities
Check server status and version info (including High-Value Dataset counts)
Access CKAN entities via
ckan://URI templates (datasets, resources, organizations, groups, tags, formats)Works with ChatGPT, Claude, Gemini CLI, VS Code, and any MCP-compatible client, via local install (npm/Docker) or a hosted HTTP endpoint
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@CKAN MCP ServerSearch for datasets about air quality in Italy"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
Adopted by AgID — This project has been reused by AgID, Italy's Agency for Digital Italy, as part of its effort to make public open data more accessible, immediate, and easier to consult through AI.
Two ways to use it — pick the one that suits you:
Option A: Install locally | Option B: No install | |
How |
| Point your tool to the hosted HTTP endpoint |
Best for | Runs on your machine, works with any local tool | Quick start, zero setup |
Request quota | No shared quota | 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.

⚖️ Limits
The local and hosted server use the same tool and output caps. The hosted endpoint also has the shared request quota shown above.
Area | Default | Maximum or configuration |
Tool output | 50,000 characters | Fixed server-wide cap |
| 100 | 32,000 ( |
| 10 | 1,000 |
| 10 | 50 |
Injected | 25 | 1,000 when injected; a query that supplies its own |
| 100 | 1,000 |
| 10 | 50 |
HTTP response body | 32 MiB |
|
Decompressed response body | 64 MiB |
|
Text and Markdown responses that exceed the output cap are cut and include a truncation note. JSON responses stay parseable: the server reduces known result arrays and flags the response with _truncated and _original_count, and if a response still cannot fit it is replaced by a small object carrying _truncated and an explanatory _error. The same capped payload is sent on both channels, so a client reading structuredContent sees exactly what the text shows, truncation flags included. Use pagination or a narrower query when you need the complete result set.
Related MCP server: dados-pt
🔌 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.
Open the profile menu and go to Settings → Apps → Advanced settings
Enable Developer mode
Click Create app (top-right)
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/mcpAuthentication: No Auth
Check the confirmation box, then click Create
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:
Open Claude Desktop and go to Settings → Integrations
Click Add custom integration
Fill in the details:
Name: CKAN MCP Server
MCP Server URL:
https://ckan-mcp-server.andy-pr.workers.dev/mcp
Click Add to save
Open a new chat, click +, select Integrations, and enable CKAN MCP Server
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.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.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/mcpUsing local installation:
claude mcp add -s user ckan npx @aborruso/ckan-mcp-server@latest
--scope usermakes 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/mcpLe Chat (Mistral)
In the left sidebar, click Intelligence, then select Connectors
Click + Add Connector
Select the Custom MCP Connector tab and fill in the details:
Name: CKAN
Connector Server:
https://ckan-mcp-server.andy-pr.workers.dev/mcp
Click Connect to save
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.
Click the "+" (Attach) icon in the message input bar and select Connectors & sources
Click Connect external app
Fill in the details:
Name: CKAN MCP Server
MCP Server URL:
https://ckan-mcp-server.andy-pr.workers.dev/mcpAuthorization Type: No Authentication
Connection Type: HTTP Streamable
Check the confirmation box and click Save
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/mcpOr 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-serverThe server will be available as ckan-mcp-server, or you can run it without installing via:
npx @aborruso/ckan-mcp-server@latestOption 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.jsOption 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 -dThe 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 metadatackan://{server}/resource/{id}- Resource metadata and download URLckan://{server}/organization/{name}- Organization detailsckan://{server}/group/{name}/datasets- Datasets by group (theme)ckan://{server}/organization/{name}/datasets- Datasets by organizationckan://{server}/tag/{name}/datasets- Datasets by tagckan://{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: trueon 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.euwith correct country filtersQuery construction — bilingual queries, parser selection,
fqsyntax, wildcard handlingCorrect API patterns — the European portal (
data.europa.eu) requires specificfacets+facetOperator+facetGroupOperatorparameters 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 FranceInstall 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:
🇮🇹 https://www.dati.gov.it/opendata - Italian National Open Data Portal (CKAN 2.10.3)
🇺🇸 https://catalog.data.gov - United States Open Data (CKAN 2.11.4)
🇨🇦 https://open.canada.ca/data - Canada Open Government (CKAN 2.10.8)
🇦🇺 https://data.gov.au - Australian Government Open Data (CKAN 2.11.4)
🇬🇧 https://data.gov.uk - United Kingdom Open Data
And many more portals worldwide
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 |
| Full list of portals with CKAN version, plugins, dataset/resource/organization counts, and country coordinates |
| Aggregate statistics across all monitored portals |
| 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 scoringNOW-6MONTHS- Dynamic date math for rolling time windowsCombined 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 matchesNOT (title:acqua OR title:mare)- Exclude water/sea datasetsFaceting 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 organizationsres_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 organizationMultiple 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 |
| When the publisher released the dataset | When the publisher released the dataset |
| When the record was first created | When the record was first harvested |
| 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_modifiedis 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 |
| ✅ | Datasets by publisher release date — most meaningful, but ~14% of datasets lack it |
| ✅ | Datasets by first harvesting date on dati.gov.it |
| ✅ | 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
issuedcoverage: ~59,700 of 69,000+ datasets on dati.gov.it haveissuedpopulated. Queries onissuedare accurate but incomplete — datasets without the field are silently excluded. Preferissuedfor content-date queries; usemetadata_createdonly 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.mdBuild & 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:coverageExplore 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.jsOpens at http://localhost:5173.
Security: HTTP transport requires a domain allowlist
The HTTP transport (TRANSPORT=http) is unauthenticated: any client that reaches
POST /mcp can drive requests through it. Since v0.4.109 it binds to 127.0.0.1
(loopback) by default and enforces DNS-rebinding protection, so it is not exposed on
the LAN and cross-origin browser requests are rejected. To prevent SSRF abuse (e.g. a
caller pointing server_url at internal hosts or cloud metadata), it also refuses to
start unless you set a domain allowlist:
Variable | Effect |
| Comma-separated allowlist of hostnames the server may query (default-deny). Required to start the HTTP transport. Example: |
| Explicit opt-out: start the HTTP transport without an allowlist (logs a security warning). Not recommended when network-exposed. |
| Interface to bind (default |
| Extra |
| Allowed |
The default stdio transport is unaffected — it stays open so you can query any portal
locally. Regardless of allowlist, all requests are also validated against private/internal
IP ranges, including hostnames that resolve to internal addresses (DNS-based SSRF, fixed
in v0.4.108). The official Cloudflare Worker is sandboxed by the platform and does not
require this setting.
Manual HTTP Testing
# Start server (HTTP needs an allowlist — see "Security" above)
CKAN_ALLOWED_DOMAINS="www.dati.gov.it" 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_urlagainstapi_urlandapi_url_aliasesinsrc/portals.jsonuses the portal-specific
dataset_view_url/organization_view_urltemplate when availablefalls 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.govVerify 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.
Related tools
opensituas — Codes and history of every Italian territorial unit, from the CLI. The join key for any ISTAT dataset.
opensdmx — Official statistics from Eurostat, ISTAT, OECD, and other SDMX providers — no hallucinations, only published figures.
ISTAT MCP Server — Italian statistical data directly in your AI assistant, via the MCP protocol.
🔗 Useful Links
CKAN — the open-source platform behind most public open data portals
CKAN API Documentation — full reference for the CKAN API v3
DCAT Vocabulary (W3C) — the metadata standard used by CKAN portals to describe datasets
MCP Protocol — Model Context Protocol specification
Created with ❤️ by onData for the open data community
Available Tools
20 toolsckan_analyze_datasetsAnalyze CKAN Datasets and DataStore SchemaARead-onlyIdempotent
Search datasets and inspect the DataStore schema of queryable resources.
For each dataset found, lists all resources. For DataStore-enabled resources, fetches the full field schema (name, type, and label/notes when available) plus total record count — all in one call.
Use this before ckan_datastore_search to understand what fields are available and what data to expect.
Args:
server_url (string): Base URL of CKAN server
q (string): Solr search query (e.g. "incidenti", "title:ambiente")
rows (number): Max datasets to analyze (default 5, max 20)
response_format ('markdown' | 'json'): Output format
Returns: For each dataset: title, ID, organization, and per DataStore resource: field schema with label/notes (when available from DataStore Dictionary) and record count.
Typical workflow: ckan_analyze_datasets → ckan_datastore_search (with known field names)
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Solr search query (e.g. 'incidenti', 'title:ambiente') | |
| rows | No | Max datasets to analyze (default 5, max 20) | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.comune.messina.it) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds transparency by detailing that it lists all resources for each dataset and fetches field schema and record count for DataStore-enabled resources, going beyond annotation basics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with an overview, detail, usage guidance, and parameter list. It is concise but informative, with no unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description thoroughly explains the return structure (dataset details and per-resource info). The typical workflow guidance adds completeness, making it easy for an agent to understand the tool's role.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with all parameters described. The description's Args section largely repeats schema information without adding new semantic meaning, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: searching datasets and inspecting DataStore schema. It distinguishes from sibling tools like ckan_datastore_search by specifying that this tool is used to understand available fields before performing a search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly advises using this tool before ckan_datastore_search, providing a typical workflow. While it does not list when not to use it, the context is clear and helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_catalog_statsGet CKAN Portal StatisticsARead-onlyIdempotent
Get a statistical overview of a CKAN portal: total dataset count and breakdown by category, format, and organization.
Single CKAN call (package_search with rows=0 and facets). No query needed.
Args:
server_url (string): Base URL of the CKAN server
facet_limit (number): Max entries per facet section (default 20)
response_format ('markdown' | 'json'): Output format
Returns: Total dataset count, categories ranked by count, file formats ranked by count, organizations ranked by count.
Typical workflow: ckan_catalog_stats (understand the portal) → ckan_package_search (query specific data)
| Name | Required | Description | Default |
|---|---|---|---|
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.comune.messina.it) | |
| facet_limit | No | Max entries per facet section (default 20) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. The description adds that it performs a single CKAN call (package_search with rows=0 and facets) and returns statistical data, confirming no mutation. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is front-loaded with the key purpose. It includes a usage workflow and return description. It could be slightly more concise by removing the 'Args' repetition, but overall every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only stats tool with 3 parameters and no output schema, the description explains the response structure (total count, ranked breakdowns), provides a typical workflow, and mentions sibling tools. This is adequate for an agent to understand the tool's role.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description lists parameters but adds no new meaning beyond what the schema already provides (e.g., defaults, constraints). The description does not clarify parameter formats or provide examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool returns a statistical overview of a CKAN portal with total dataset count and breakdowns by category, format, and organization. It distinguishes itself from siblings like ckan_package_search, which queries specific data, and ckan_analyze_datasets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description provides a typical workflow showing when to use this tool (for understanding the portal) versus ckan_package_search (for specific queries). It also notes that no query is needed and it's a single CKAN call. However, it doesn't explicitly state conditions where the tool should not be used.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_datastore_searchSearch CKAN DataStoreARead-onlyIdempotent
Query data from a CKAN DataStore resource.
The DataStore allows SQL-like queries on tabular data. Not all resources have DataStore enabled.
The response always includes a Fields section listing all available column names and types. Use limit=0 to discover column names without fetching data — do this before using filters to avoid guessing column names and getting HTTP 400 errors.
Args:
server_url (string): Base URL of CKAN server
resource_id (string): ID of the DataStore resource
q (string): Full-text search query (optional)
filters (object): Key-value filters (e.g., { "anno": 2023 })
limit (number): Max rows to return (default: 100, max: 32000)
offset (number): Pagination offset (default: 0)
fields (array): Specific fields to return (optional)
sort (string): Sort field with direction (e.g., "anno desc")
distinct (boolean): Return distinct values (default: false)
response_format ('markdown' | 'json'): Output format
Returns: DataStore records matching query, always including available column names and types
Examples:
{ server_url: "...", resource_id: "abc-123", limit: 0 } ← discover columns first
{ server_url: "...", resource_id: "abc-123", limit: 50 }
{ server_url: "...", resource_id: "...", filters: { "regione": "Sicilia" } }
{ server_url: "...", resource_id: "...", sort: "anno desc", limit: 100 }
Typical workflow: ckan_package_search → ckan_package_show (find resource_id with datastore_active=true) → ckan_datastore_search (limit=0 to get columns) → ckan_datastore_search (with filters)
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Full-text search across all fields | |
| sort | No | Sort expression (e.g., 'anno desc', 'nome asc') | |
| limit | No | Max rows to return (default 100, max 32000); use 0 to get only column names without data | |
| fields | No | Specific field names to return; omit to return all fields | |
| offset | No | Pagination offset | |
| filters | No | Key-value filters for exact matches (e.g., { "regione": "Sicilia", "anno": 2023 }) | |
| distinct | No | Return only distinct rows | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| resource_id | Yes | UUID of the DataStore resource (from ckan_package_show resource.id where datastore_active is true) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. The description adds value by stating the response always includes a Fields section, and that limit=0 returns only column names, avoiding HTTP 400 errors. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections and examples, but verbose. The docstring-style Args/Returns/Examples adds length; could be more concise. Still organized and front-loaded with the main purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 10 parameters, 2 required, no output schema, the description covers response structure, typical workflow, error avoidance, and example usage. It is comprehensive and leaves little ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds significant meaning: explains the role of limit=0 for column discovery, provides examples with real values, and clarifies the response_format. This goes beyond the schema's basic descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Query data from a CKAN DataStore resource' and explains it allows SQL-like queries. It distinguishes itself from siblings like ckan_package_search or ckan_datastore_search_sql by focusing on DataStore queries with specific workflow steps.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidelines: use limit=0 to discover column names first, typical workflow chaining other tools, and examples. It also implies when not to use (if resource not datastore_active). Does not explicitly mention the sibling ckan_datastore_search_sql but covers usage well.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_datastore_search_sqlSearch CKAN DataStore with SQLARead-onlyIdempotent
Run SQL queries on a CKAN DataStore resource.
This endpoint is only available on CKAN portals with DataStore enabled and SQL access exposed.
Args:
server_url (string): Base URL of CKAN server
sql (string): SQL query (e.g., SELECT * FROM "resource_id" LIMIT 10)
response_format ('markdown' | 'json'): Output format
Returns: SQL query results from DataStore
Examples:
{ server_url: "...", sql: "SELECT * FROM "abc-123" LIMIT 10" }
{ server_url: "...", sql: "SELECT COUNT(*) AS total FROM "abc-123"" }
Typical workflow: ckan_package_show (get resource_id) → ckan_datastore_search_sql (run SQL on it)
Security note: SQL queries are forwarded directly to the CKAN DataStore API. The CKAN server enforces its own access controls and read-only permissions. No local database is exposed. Queries are limited to public DataStore resources on the target portal.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | SQL SELECT query; resource_id is the table name, must be double-quoted (e.g., SELECT * FROM "abc-123" LIMIT 10) | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds context: SQL is forwarded to CKAN API, no local database exposure, CKAN enforces access controls. This adds value beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is structured with sections (Args, Returns, Examples, workflow, security) and is concise for the amount of information provided. No redundant sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, description explains return value as 'SQL query results from DataStore'. Includes examples, workflow, and security note, making it complete for an agent to understand usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 100% coverage, so baseline is 3. Description adds examples with double-quoting for resource_id and explains response_format options, which adds meaning beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Run SQL queries on a CKAN DataStore resource', specifying the verb and resource. It distinguishes from siblings like ckan_datastore_search (which likely performs simpler searches without SQL).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description mentions prerequisites (DataStore enabled, SQL access exposed) and provides a typical workflow (ckan_package_show → ckan_datastore_search_sql). It does not explicitly state when not to use or identify sibling alternatives, but the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_find_portalsFind CKAN PortalsARead-onlyIdempotent
Search the live datashades.info registry of ~950 CKAN portals worldwide.
Use this tool to discover which CKAN portals exist for a country, language, or topic before querying them with other CKAN tools.
IMPORTANT — country parameter: always pass country name in English. If the user writes in another language (e.g. "Italia", "España", "Brasil"), translate to English ("Italy", "Spain", "Brazil") before calling this tool.
Args:
country (string): Country name in English (e.g. "Italy", "Brazil", "France")
query (string): Keyword to match against portal title (e.g. "transport", "health")
min_datasets (number): Minimum number of datasets (e.g. 100)
language (string): Portal default locale code (e.g. "it", "en", "pt_BR", "fr")
has_datastore (boolean): If true, return only portals with DataStore enabled (supports SQL queries)
limit (number): Max results to return (default 10, max 50)
Returns: Ranked list of matching portals with URL, country, CKAN version, dataset count, and DataStore status.
Typical workflow: ckan_find_portals (discover portal URL) → ckan_status_show (verify) → ckan_package_search (search datasets)
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results (default 10, max 50) | |
| query | No | Keyword matched against portal title (case-insensitive) | |
| country | No | Country name in English (e.g. 'Italy', 'Brazil'). Translate from any language before passing. | |
| language | No | Portal default locale code (e.g. 'it', 'en', 'pt_BR') | |
| min_datasets | No | Minimum number of datasets | |
| has_datastore | No | If true, return only portals with DataStore plugin (required for SQL queries) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate read-only, open-world, idempotent, non-destructive behavior. The description adds specific context: searches a live registry, returns ranked list with details, and includes an important note about country parameter translation. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with sections, clear parameter list, and a typical workflow. Every sentence adds value; no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description specifies the return format (ranked list with URL, country, CKAN version, dataset count, DataStore status) and suggests a typical usage workflow, making it complete for agent understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds extra meaning: country translation requirement, has_datastore SQL support, limit defaults/max. However, some parameters (e.g., language) lack additional nuance beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Search the live datashades.info registry of ~950 CKAN portals worldwide' and provides a typical workflow that distinguishes it from dataset-level tools like ckan_package_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains when to use the tool (before querying other CKAN tools) and provides a typical workflow, but does not explicitly mention when not to use it or compare to alternative portal discovery methods.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_find_relevant_datasetsFind Relevant CKAN DatasetsARead-onlyIdempotent
Find and rank datasets by relevance to a query using weighted fields.
Use this instead of ckan_package_search when you want relevance-ranked results with explicit scoring across title, notes, tags, and organization fields. Use ckan_package_search instead when you need Solr filter syntax, facets, or pagination.
Uses package_search for discovery and applies a local scoring model.
Args:
server_url (string): Base URL of CKAN server (e.g., "https://dati.gov.it/opendata")
query (string): Natural language or keyword query (e.g., "mobilità urbana", "air quality")
limit (number): Number of datasets to return (default: 10)
weights (object): Field weights for scoring — higher weight = more influence on rank Default: title=4, tags=3, notes=2, organization=1, holder=4, publisher=2 Note on holder vs organization: on federated catalogs (e.g. dati.gov.it),
organizationis the harvesting catalog (e.g. Regione Puglia), whileholder(DCAT-AP_IT dct:rightsHolder) is the actual data owner (e.g. Comune di Lecce). Queries like "datasets from a specific Comune" matchholdercorrectly; matching onlyorganizationmisses datasets harvested via aggregators.publisher(dct:publisher) is scored separately at lower weight as it can contain technical roles ("Redazione OD") rather than the institutional owner.query_parser ('default' | 'text'): Override search parser behavior
response_format ('markdown' | 'json'): Output format
Returns: Ranked datasets with relevance scores and per-field score breakdowns
Examples:
{ server_url: "https://dati.gov.it/opendata", query: "mobilità" }
{ server_url: "...", query: "trasporti", limit: 5, weights: { title: 5, notes: 2 } }
{ server_url: "...", query: "defibrillatori Comune di Lecce", weights: { holder: 5 } }
Typical workflow: ckan_find_relevant_datasets → ckan_package_show (inspect top results) → ckan_datastore_search (query data)
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of datasets to return | |
| query | Yes | Natural language or keyword query to match against dataset title, notes, tags, organization, holder and publisher | |
| weights | No | Per-field scoring weights; unspecified fields use defaults | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| query_parser | No | Override search parser ('text' forces text:(...) on non-fielded queries) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, which cover safety and side effects. The description adds that it uses package_search for discovery and applies a local scoring model, which is useful but not critical beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (main purpose, when to use, args, returns, examples, workflow). It is somewhat lengthy but every sentence adds value, and key information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, nested weights object, 2 enums) and lack of output schema, the description covers purpose, usage, parameter semantics, examples, and typical workflow comprehensively, making it complete for an AI agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions, but the description adds significant value by explaining the nuanced difference between holder, organization, and publisher weights with domain context, and provides multiple examples showing parameter usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool finds and ranks datasets by relevance using weighted fields, and distinguishes it from ckan_package_search, which is a sibling tool. The verb 'find and rank' and specific resource 'datasets' make the purpose precise.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool versus ckan_package_search, including specific use cases for each. It also provides a typical workflow sequence, giving clear guidance on tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_get_mqa_qualityGet MQA Quality ScoreARead-onlyIdempotent
Get MQA (Metadata Quality Assurance) quality metrics for a dataset on dati.gov.it. Returns quality score and detailed metrics (accessibility, reusability, interoperability, findability, contextuality) from data.europa.eu. Only works with dati.gov.it server. Typical workflow: ckan_package_show (get dataset ID) → ckan_get_mqa_quality → ckan_get_mqa_quality_details (for non-max dimensions)
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | Dataset ID or name | |
| server_url | Yes | Base URL of dati.gov.it (e.g., https://www.dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds behavioral context: returns quality score and detailed metrics (accessibility, etc.) from data.europa.eu, and the server restriction. This enriches transparency without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with a bullet-like workflow, no redundancy, and front-loaded with the core purpose. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 3 parameters, no output schema, but strong annotations, the description adequately covers the purpose, workflow, and server restriction. It could mention output format details but the annotation coverage compensates.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all parameters are already documented. The description does not add new semantics beyond what the schema provides, but it confirms the data source (dati.gov.it) for server_url. This meets the baseline expectation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves MQA quality metrics for a dataset on dati.gov.it, specifying verb, resource, and scope. It contrasts with the sibling tool ckan_get_mqa_quality_details by outlining the typical workflow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly defines the workflow (ckan_package_show → ckan_get_mqa_quality → ckan_get_mqa_quality_details) and notes it only works with dati.gov.it, providing clear context for when to use it versus alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_get_mqa_quality_detailsGet MQA Quality DetailsARead-onlyIdempotent
Get detailed MQA (Metadata Quality Assurance) quality reasons for a dataset on dati.gov.it. Returns dimension scores, non-max reasons, and raw MQA flags from data.europa.eu. Only works with dati.gov.it server. Typical workflow: ckan_get_mqa_quality (get overview scores) → ckan_get_mqa_quality_details (inspect failing metrics)
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | Dataset ID or name | |
| server_url | Yes | Base URL of dati.gov.it (e.g., https://www.dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint. The description adds behavioral details: it returns dimension scores, non-max reasons, and raw MQA flags from data.europa.eu, and is restricted to dati.gov.it. This adds value beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, no wasted words, front-loaded with the key action and resource. It efficiently conveys purpose, return content, server constraint, and workflow.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (3 parameters, no output schema, good annotations), the description covers all necessary aspects: purpose, return values, parameter constraints, server limitation, and relationship to sibling. It is fully complete for an AI agent to decide and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds context: it clarifies that server_url must be a dati.gov.it base URL, explains the purpose of dataset_id, and elaborates on response_format options (markdown vs. json). This provides meaningful additional semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get', the resource 'MQA quality reasons for a dataset', and distinguishes it from the sibling 'ckan_get_mqa_quality' by outlining the typical workflow (overview → details). It also specifies the server constraint (dati.gov.it) and return types.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit context: it is used after ckan_get_mqa_quality to inspect failing metrics, and it only works with dati.gov.it. However, it does not explicitly list when not to use it or alternatives beyond the named sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_group_listList CKAN GroupsARead-onlyIdempotent
List all groups on a CKAN server.
Groups are thematic collections of datasets.
Args:
server_url (string): Base URL of CKAN server
all_fields (boolean): Return full objects vs just names (default: false)
sort (string): Sort field (default: "name asc")
limit (number): Maximum results (default: 100). Use 0 to get only the count via faceting
offset (number): Pagination offset (default: 0)
response_format ('markdown' | 'json'): Output format
Returns: List of groups with metadata. When limit=0, returns only the count of groups with datasets.
Typical workflow: ckan_group_list → ckan_group_show (inspect one) → ckan_package_search with fq="groups:name" (browse its datasets)
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort field and direction (e.g., 'name asc', 'package_count desc') | name asc |
| limit | No | Max groups to return. Use 0 to get only the count via faceting | |
| offset | No | Pagination offset | |
| all_fields | No | Return full group objects (true) or just name slugs (false) | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly/ idempotent/ non-destructive. The description adds behavior details: limit default 100, limit=0 returns only count, and output format options. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is well-structured and concise: purpose, explanation, parameters, returns, workflow. Every sentence adds value, no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given full annotations and schema coverage, the description provides complete context: usage, parameters, return behavior, and typical workflow. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of parameters with descriptions. The description repeats them clearly and adds context for limit=0 returning count. Slight extra value but not significantly beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List all groups on a CKAN server' with specific verb and resource. It distinguishes from siblings like ckan_group_search and ckan_group_show via a typical workflow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a typical workflow (ckan_group_list → ckan_group_show → ckan_package_search) that implies when to use this tool. It could explicitly mention when not to use, but the workflow is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_group_searchSearch CKAN Groups by NameARead-onlyIdempotent
Search for groups by name pattern.
This tool provides a simpler interface than package_search for finding groups. Wildcards are automatically added around the search pattern.
Args:
server_url (string): Base URL of CKAN server
pattern (string): Search pattern (e.g., "energia", "salute")
response_format ('markdown' | 'json'): Output format
Returns: List of matching groups with dataset counts
Typical workflow: ckan_group_search → ckan_group_show (get details) → ckan_package_search with fq="groups:name"
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | Name pattern to search for (wildcards added automatically, e.g., 'energia', 'salute') | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive operations. The description adds behavioral details: wildcards are automatically added around the search pattern, and the response format can be markdown or JSON. This provides useful context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a one-line purpose, brief explanation, clearly labeled arguments and returns, and a typical workflow. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description covers all essential aspects: purpose, parameters, return value (list with dataset counts), and typical workflow. No output schema exists, but the return description is adequate. Annotations provide additional safety context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with each parameter well-documented (e.g., pattern includes 'wildcards added automatically'). The tool description's 'Args' section largely duplicates schema info, adding no new parameter semantics. Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches for groups by name pattern, using a specific verb and resource. It differentiates itself from sibling tool package_search by noting it's a simpler interface, and provides a typical workflow sequence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool (simpler than package_search, wildcards automatically added) and gives a typical workflow. It does not explicitly state when not to use or list alternatives beyond package_search, but the guidance is sufficient for most scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_group_showShow CKAN Group DetailsARead-onlyIdempotent
Get details of a specific group.
Args:
server_url (string): Base URL of CKAN server
id (string): Group ID or name
include_datasets (boolean): Include list of datasets (default: true)
response_format ('markdown' | 'json'): Output format
Returns: Group details with optional datasets
Typical workflow: ckan_group_show → ckan_package_show (inspect a dataset) → ckan_datastore_search (query its data)
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Group ID (UUID) or machine-readable name slug (e.g., 'transport', 'energia') | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
| include_datasets | No | Include the list of datasets belonging to this group |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds minimal extra behavioral context, only mentioning return format. With annotations covering the safety profile, the description doesn't need to repeat but could add more (e.g., auth requirements).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise: two sentences plus a typical workflow line. Every sentence adds value, and the purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 4 parameters, no output schema, but annotations cover safety, the description explains return format (markdown or json) and includes a workflow. It is fairly complete for a read tool, though could mention error handling or default behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description restates parameter names and types but adds little beyond what the schema already provides (e.g., 'Group ID or name' vs schema description). No additional semantics or format details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get details of a specific group', specifying the verb and resource. It distinguishes from sibling tools like ckan_group_list and ckan_group_search, which list or search groups.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a typical workflow (ckan_group_show → ckan_package_show → ckan_datastore_search), giving context for when to use this tool in a sequence. While it doesn't explicitly state when not to use, the workflow guidance is clear and helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_list_resourcesList CKAN Dataset ResourcesARead-onlyIdempotent
List all resources in a dataset with a compact summary.
Returns a focused table of resources showing format, size, DataStore availability, and download URL. Use this to quickly assess what files a dataset contains before deciding how to access the data.
Args:
server_url (string): Base URL of CKAN server
id (string): Dataset ID or name
format_filter (string): Filter resources by format, case-insensitive (e.g., "CSV", "json", "XLSX")
response_format ('markdown' | 'json'): Output format
Returns: Compact resource summary with name, ID, format, size, DataStore flag, and URL
Examples:
{ server_url: "https://dati.gov.it/opendata", id: "dataset-name" }
{ server_url: "...", id: "dataset-name", format_filter: "CSV" }
Typical workflow: ckan_package_search → ckan_list_resources (assess available files) → ckan_datastore_search (for resources with DataStore=true)
When a resource has DataStore=false but its download URL belongs to a different (source) portal, the tool can probe the source portal for DataStore availability and report source_datastore_active and source_portal_url so you can query the data there instead. This probing is OFF by default (it issues extra HTTP requests to hosts taken from the dataset's own resource URLs); set check_source_portal=true to enable it.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Dataset ID or name | |
| server_url | Yes | Base URL of the CKAN server | |
| format_filter | No | Filter resources by format, case-insensitive (e.g., 'CSV', 'json', 'XLSX') | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
| check_source_portal | No | Opt-in (default false): when true, probes the source portal for DataStore availability when a resource URL points to a different CKAN instance. Issues extra HTTP requests to hosts taken from the dataset's resource URLs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses non-obvious probing behavior for source portal when check_source_portal=true, mentions extra HTTP requests, and contrasts with default (off). Annotations already provide readOnly/idempotent; description adds significant context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with front-loaded purpose, then args/returns/examples/workflow/advanced behavior. Some redundancy with schema args, but overall each section serves a purpose. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Very comprehensive given complexity: 5 parameters, no output schema, annotations provided. Covers purpose, parameters, examples, workflow, advanced behavior, and edge cases (source portal probing). Missing only minor details like default filter behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage 100% already documents parameters, but description adds value: case-insensitivity of format_filter, side-effects of check_source_portal, and default values for response_format and check_source_portal. Exceeds baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states verb ('List all resources') and resource ('in a dataset'), specifies output ('compact summary with format, size, DataStore availability, download URL'), and distinguishes from siblings via workflow (after package_search, before datastore_search).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use ('quickly assess what files a dataset contains before deciding how to access the data') and provides typical workflow. Lacks explicit when-not-to-use or direct sibling comparison, but context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_organization_listList CKAN OrganizationsARead-onlyIdempotent
List all organizations on a CKAN server.
Organizations are entities that publish and manage datasets.
Args:
server_url (string): Base URL of CKAN server
all_fields (boolean): Return full objects vs just names (default: false)
sort (string): Sort field (default: "name asc")
limit (number): Maximum results (default: 100). Use 0 to get only the count via faceting
offset (number): Pagination offset (default: 0)
response_format ('markdown' | 'json'): Output format
Returns: List of organizations with metadata. When limit=0, returns only the count of organizations with datasets.
Typical workflow: ckan_organization_list → ckan_organization_show (inspect one) → ckan_package_search with fq="organization:name" (browse its datasets)
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort field and direction (e.g., 'name asc', 'package_count desc') | name asc |
| limit | No | Max organizations to return. Use 0 to get only the count via faceting | |
| offset | No | Pagination offset | |
| all_fields | No | Return full organization objects (true) or just name slugs (false) | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint and idempotentHint, so the description does not need to restate safety. It adds value by disclosing pagination behavior, the special case where limit=0 returns only a count, and the output format options. This goes beyond what annotations provide, though it could mention error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise: a single sentence followed by a bullet list and a one-line workflow. Every sentence serves a purpose, and the structure is front-loaded with the core action. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list tool with no output schema, the description covers return type, pagination, the count special case, and output format. The typical workflow provides broader context. It is nearly complete, though it could be more explicit about the fields in the returned objects when all_fields=true.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with detailed parameter descriptions. The description repeats parameter defaults and options in a bullet list but does not add significant new meaning beyond the schema. It provides a typical workflow that contextually ties parameters together, but for individual parameters, it adds little new.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The title 'List CKAN Organizations' and description 'List all organizations on a CKAN server' clearly state the verb and resource. The included typical workflow distinguishes it from siblings like ckan_organization_search or ckan_organization_show, making the purpose unambiguous and well-differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool versus alternatives. The typical workflow hints at its role (list all → show one → search datasets), but there is no explicit guidance on when not to use it or when to prefer ckan_organization_search for filtered results.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_organization_searchSearch CKAN Organizations by NameARead-onlyIdempotent
Search for organizations by name pattern.
This tool provides a simpler interface than package_search for finding organizations. Wildcards are automatically added around the search pattern.
Args:
server_url (string): Base URL of CKAN server
pattern (string): Search pattern (e.g., "toscana", "salute")
response_format ('markdown' | 'json'): Output format
Returns: List of matching organizations with dataset counts
Examples:
{ server_url: "https://www.dati.gov.it/opendata", pattern: "toscana" }
{ server_url: "https://catalog.data.gov", pattern: "health" }
Typical workflow: ckan_organization_search → ckan_organization_show (get details) → ckan_package_search with fq="organization:name"
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | Name pattern to search for (wildcards added automatically, e.g., 'toscana', 'health') | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive nature. The description adds that wildcards are added automatically and specifies the return format (list with dataset counts), providing behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with Args, Returns, and Examples sections. It is concise, front-loads the purpose, and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 3 parameters, no output schema, and many sibling tools, the description is complete. It specifies output format, provides examples, and suggests a workflow, fully equipping an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds meaning: explains pattern with wildcard behavior and examples, server_url as base URL, and response_format output options. Examples further clarify usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches for organizations by name pattern, specifies it is a simpler interface than package_search, and mentions that wildcards are added automatically. This distinguishes it from siblings like package_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use this tool (searching by name pattern, simpler than package_search) and provides a typical workflow (search, then show, then package_search). It does not explicitly state when not to use, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_organization_showShow CKAN Organization DetailsARead-onlyIdempotent
Get details of a specific organization.
Args:
server_url (string): Base URL of CKAN server
id (string): Organization ID or name
include_datasets (boolean): Include list of datasets (default: true)
include_users (boolean): Include list of users (default: false)
response_format ('markdown' | 'json'): Output format
Returns: Organization details with optional datasets and users
Typical workflow: ckan_organization_show → ckan_package_show (inspect a dataset) → ckan_datastore_search (query its data)
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Organization ID (UUID) or machine-readable name slug (e.g., 'regione-siciliana') | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| include_users | No | Include the list of users belonging to this organization | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
| include_datasets | No | Include the list of datasets published by this organization |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, indicating safe read operations. The description adds context about output format options (markdown/json) and default parameter values for include_datasets and include_users, which go beyond the annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections for Args, Returns, and Typical workflow. It is efficient but slightly verbose by repeating schema information. Overall, every sentence serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich annotations (readOnlyHint, idempotentHint) and high schema coverage, the description adequately covers the tool's behavior. It explains return values ('Organization details with optional datasets and users'), output format options, and provides a typical usage workflow. No output schema exists, but the description compensates sufficiently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 100% schema coverage, the description repeats parameter info from the schema (e.g., 'Organization ID or name') without adding new semantic details. The workflow is helpful but not parameter-specific. Baseline 3 is appropriate as the schema already documents parameters thoroughly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get details of a specific organization', using a specific verb and resource. It distinguishes itself from siblings like ckan_organization_list (which lists all organizations) and ckan_organization_search (which searches).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a typical workflow (ckan_organization_show → ckan_package_show → ckan_datastore_search), providing clear context for when to use this tool and what follows. However, it does not explicitly state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_package_searchSearch CKAN DatasetsARead-onlyIdempotent
Search for datasets (packages) on a CKAN server using Solr query syntax.
Supports full Solr search capabilities including filters, facets, and sorting. Use this to discover datasets matching specific criteria.
Note on parser behavior: Some CKAN portals use a restrictive default query parser that can break long OR queries. For those portals, this tool may force the query into 'text:(...)' based on per-portal config. You can override with 'query_parser' to force or disable this behavior per request.
Important - Date field semantics:
issued: publisher's content publish date when available (best proxy for "created/published")
modified: publisher's content update date when available
metadata_created: CKAN record creation timestamp (publish time on source portals, harvest time on aggregators; fallback for "created" if issued missing)
metadata_modified: CKAN record update timestamp (publish time on source portals, harvest time on aggregators; use for "updated/modified in last X")
Natural language mapping (important for tool callers):
"created"/"published" -> prefer issued; fallback to metadata_created
"updated"/"modified" -> prefer modified; fallback to metadata_modified
For "recent in last X", consider using content_recent (issued with metadata_created fallback)
Content-recent helper:
content_recent: if true, rewrites the query to use issued with a fallback to metadata_created when issued is missing.
content_recent_days: window for content_recent (default 30 days).
Args:
server_url (string): Base URL of CKAN server (e.g., "https://dati.gov.it/opendata")
q (string): Search query using Solr syntax (default: ":" for all)
fq (string): Filter query (e.g., "organization:comune-palermo") IMPORTANT — Solr fq syntax rules:
OR inside a single field: use field:(val1 OR val2), NOT field:val1 OR field:val2. Wrong: fq=type:"A" OR type:"B" → silently ignored, returns entire catalog. Right: fq=type:("A" OR "B")
CKAN extras fields are indexed as extras_fieldname, not fieldname. e.g. to filter on extra field "hvd_category" use fq=extras_hvd_category:""
rows (number): Number of results to return (default: 10, max: 1000)
start (number): Offset for pagination (default: 0)
page (number): Page number (1-based); alias for start. Overrides start if provided.
page_size (number): Results per page when using page (default: 10, max: 1000)
sort (string): Sort field and direction (e.g., "metadata_modified desc")
facet_field (array): Fields to facet on (e.g., ["organization", "tags"])
facet_limit (number): Max facet values per field (default: 50)
include_drafts (boolean): Include draft datasets (default: false)
query_parser ('default' | 'text'): Override search parser behavior
response_format ('markdown' | 'json'): Output format
Returns: Search results with:
count: Number of results found
results: Array of dataset objects
facets: Facet counts (if facet_field specified)
search_facets: Detailed facet information
Query Syntax (parameter q): Boolean operators: - AND / &&: "water AND climate" - OR / ||: "health OR sanità" - NOT / !: "data NOT personal" - +required -excluded: "+title:water -title:sea" - Grouping: "(title:water OR title:climate) AND tags:environment"
Wildcards: - : "title:environment" (matches environmental, environments, etc.) - Note: Left truncation (*water) not supported
Fuzzy search (edit distance):
- : "title:rest" or "title:rest~1" (finds "test", "best", "rest")
Proximity search (words within N positions): - "phrase"~N: "title:"climate change"~5"
Range queries: - Inclusive [a TO b]: "num_resources:[5 TO 10]" - Exclusive {a TO b}: "num_resources:{0 TO 100}" - One side open: "metadata_modified:[2024-01-01T00:00:00Z TO *]"
Date math: - NOW-1YEAR, NOW-6MONTHS, NOW-7DAYS, NOW-1HOUR - NOW/DAY, NOW/MONTH (round down) - Combined: "metadata_modified:[NOW-2MONTHS TO NOW]" - Example: "metadata_created:[NOW-1YEAR TO *]" - IMPORTANT: NOW syntax works on metadata_modified and metadata_created fields - For 'modified' and 'issued' fields, NOW syntax is auto-converted to ISO dates - Manual ISO dates always work: "modified:[2026-01-15T00:00:00Z TO *]"
Field existence: - Exists: "field:" or "field:[ TO ]" - Not exists: "NOT field:" or "-field:*"
Boosting (relevance scoring): - Boost term: "title:water^2 OR notes:water" (title matches score higher) - Constant score: "title:water^=1.5"
Examples:
Search all: { q: ":" }
By tag: { q: "tags:sanità" }
Boolean: { q: "(title:water OR title:climate) AND NOT title:sea" }
Wildcard: { q: "title:environment*" }
Fuzzy: { q: "title:health~2" }
Proximity: { q: "notes:"open data"~3" }
Date range: { q: "metadata_modified:[2024-01-01T00:00:00Z TO 2024-12-31T23:59:59Z]" }
Date math: { q: "metadata_modified:[NOW-6MONTHS TO *]" }
Date math (auto-converted): { q: "modified:[NOW-30DAYS TO NOW]" }
Published in 2025 (content date): { fq: "issued:[2025-01-01T00:00:00Z TO 2025-12-31T23:59:59Z]" }
First appeared on portal in 2025: { fq: "metadata_created:[2025-01-01T00:00:00Z TO 2025-12-31T23:59:59Z]" }
Recent content (issued w/ fallback): { q: ":", content_recent: true, content_recent_days: 180 }
Field exists: { q: "organization:* AND num_resources:[1 TO *]" }
Boosting: { q: "title:climate^2 OR notes:climate" }
Filter org: { fq: "organization:regione-siciliana" }
Filter extras field (correct): { fq: "extras_hvd_category:"http://data.europa.eu/bna/c_ac64a52d"" }
Filter extras OR (correct): { fq: "extras_hvd_category:("http://data.europa.eu/bna/c_ac64a52d" OR "http://data.europa.eu/bna/c_dd313021")" }
Get facets: { facet_field: ["organization"], rows: 0 }
Query language: Before searching a portal, check its locale via ckan_status_show (field: "Portal Locale" / locale_default). Translate query terms to the portal's language — searching in English on a non-English portal returns 0 results. Examples: locale "it" → Italian terms; "uk_UA" → Ukrainian (Cyrillic); "fr_FR" → French. Exception: multilingual portals (e.g. data.europa.eu, open.canada.ca) accept EN + native terms joined with OR.
Typical workflow: ckan_status_show (check locale) → ckan_package_search (query in portal's language) → ckan_package_show (get full metadata + resource IDs) → ckan_datastore_search (query tabular data)
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Search query in Solr syntax | *:* |
| fq | No | Filter query in Solr syntax; applied after scoring, does not affect relevance. CKAN extras fields use prefix 'extras_' (e.g. extras_hvd_category). For OR on same field use field:(val1 OR val2), never field:val1 OR field:val2 (silently breaks). Examples: 'organization:comune-palermo', 'res_format:CSV', 'extras_hvd_category:("uri1" OR "uri2")'. | |
| page | No | Page number (1-based); alias for start. Overrides start if provided. | |
| rows | No | Number of results to return | |
| sort | No | Sort field and direction (e.g., 'metadata_modified desc') | |
| start | No | Offset for pagination | |
| page_size | No | Results per page when using page (default: 10) | |
| server_url | Yes | Base URL of the CKAN server | |
| facet_field | No | Fields to facet on | |
| facet_limit | No | Maximum facet values per field | |
| query_parser | No | Override search parser ('text' forces text:(...) on non-fielded queries) | |
| content_recent | No | Use issued date with fallback to metadata_created for recent content | |
| include_drafts | No | Include draft datasets | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
| content_recent_days | No | Day window for content_recent (default 30) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint, idempotentHint, openWorldHint, and non-destructive. Description adds crucial behavioral details: parser behavior on restrictive portals, date field semantics (issued vs modified vs metadata_created), natural language mapping, and content_recent helper. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Long but well-structured with sections, bullet points, and examples. Front-loaded with purpose. Every section earns its place given complexity (15 params, query language nuances). Minor redundancy in date examples could be trimmed, but overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given high complexity (15 params, no output schema), the description is remarkably complete: covers query syntax, date semantics, parser behavior, locale guidance, workflow, and 13 examples. No gaps for intended use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds significant value: explains fq Solr syntax rules with examples, q query syntax with boolean/wildcard/fuzzy/date math, content_recent behavior, and query_parser override. Goes well beyond what schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Search for datasets (packages) on a CKAN server using Solr query syntax', with specific verb ('search'), resource ('datasets'), and scope. It distinguishes from siblings like ckan_package_show (single dataset) and ckan_list_resources (resources).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides extensive context: when to use (discover datasets), typical workflow (status_show → package_search → package_show → datastore_search), and locale guidance. Lacks explicit 'when not to use', but alternatives like ckan_package_show are implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_package_showShow CKAN Dataset DetailsARead-onlyIdempotent
Get complete metadata for a specific dataset (package).
Returns full details including resources, organization, tags, and all metadata fields.
Notes:
metadata_modified is a CKAN record timestamp (publish time on source portals, harvest time on aggregators), not the content date.
issued/modified are content dates when provided by the publisher.
JSON output adds metadata_harvested_at (same as metadata_modified).
Args:
server_url (string): Base URL of CKAN server
id (string): Dataset ID or name (machine-readable slug)
include_tracking (boolean): Include view/download statistics (default: false)
response_format ('markdown' | 'json'): Output format
Returns (JSON format): id, name, title, notes, organization, tags, state, license_title, metadata_created, metadata_modified, issued, modified, author, maintainer, frequency, language, publisher_name, holder_name, hvd_category, applicable_legislation, resources (id, name, format, url, size, datastore_active, created, last_modified, api_json_url), view_url, api_json_url
Examples:
{ server_url: "https://dati.gov.it/opendata", id: "dataset-name" }
{ server_url: "...", id: "abc-123-def", include_tracking: true }
Typical workflow: ckan_package_show → pick a resource with datastore_active=true → ckan_datastore_search (query its data)
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Dataset ID (UUID) or machine-readable name slug (e.g., 'raccolta-differenziata-comuni') | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
| include_tracking | No | Include tracking statistics |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (read-only, idempotent, non-destructive), description clarifies timestamp semantics (metadata_modified vs content dates) and notes on JSON output. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections for notes, args, returns, example, workflow. Front-loaded purpose, no filler. Every sentence informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, description provides a comprehensive list of returned fields and their meanings (e.g., metadata_modified clarified), plus workflow context. Complete for tool's purpose.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already provides 100% coverage with good descriptions. Description adds usage examples and clarifies output format roles, but adds only marginal value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb+resource ('Get complete metadata for a specific dataset'). Distinguishes from siblings like ckan_package_search and ckan_datastore_search via typical workflow note.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit typical workflow linking to subsequent tool, helping select tool in sequence. Implicitly distinguishes from search/query tools, but no explicit 'do not use when' conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_status_showCheck CKAN Server StatusARead-onlyIdempotent
Check if a CKAN server is available and get version information.
Useful to verify server accessibility before making other requests. Also shows the count of High-Value Datasets (HVD) when the portal supports it.
Args:
server_url (string): Base URL of CKAN server
Returns: Server status, version information, and HVD dataset count (if available)
Typical workflow: ckan_status_show (verify server is up) → ckan_package_search (discover datasets)
| Name | Required | Description | Default |
|---|---|---|---|
| server_url | Yes | Base URL of the CKAN server |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds that it shows HVD count when supported, providing useful behavioral context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short paragraphs front-loaded with main purpose. Every sentence adds value, no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully covers the tool's purpose, usage guidance, return values (status, version, HVD count), and typical workflow. No missing context for this simple tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single parameter (server_url). The description repeats the schema information without adding extra meaning like format or examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb+resource: 'Check if a CKAN server is available and get version information.' Differentiates from sibling search/analysis tools by focusing on server status and accessibility.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states it's useful for verifying server accessibility before making other requests and provides a typical workflow (status show then package search). Does not mention when not to use or alternative tools for similar purposes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ckan_tag_listList CKAN TagsARead-onlyIdempotent
List tags from a CKAN server using faceting.
This returns tag names with counts, optionally filtered by dataset query or tag substring.
Args:
server_url (string): Base URL of CKAN server
q (string): Dataset search query (default: ":")
fq (string): Filter query (optional)
tag_query (string): Filter tags by substring (optional)
limit (number): Max tags to return (default: 100, max: 1000)
response_format ('markdown' | 'json'): Output format
Returns: List of tags with counts (from faceting)
Typical workflow: ckan_tag_list → ckan_package_search with fq="tags:tag_name" (find datasets by tag) → ckan_package_show
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Dataset search query in Solr syntax to scope the tag facet (default: '*:*' for all datasets) | *:* |
| fq | No | Filter query in Solr syntax (e.g., 'organization:comune-palermo') to restrict which datasets contribute to tag counts | |
| limit | No | Max tags to return (default 100, max 1000); tags are sorted by count descending | |
| tag_query | No | Substring filter applied to tag names after faceting (e.g., 'acqua' to keep only tags containing 'acqua') | |
| server_url | Yes | Base URL of the CKAN server (e.g., https://dati.gov.it/opendata) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly, non-destructive, and idempotent. The description adds that it uses faceting, returns tag names with counts, and imposes a limit (default 100, max 1000). This provides additional behavioral context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: a brief summary, bulleted args, return description, and typical workflow. Every sentence adds value, and it is appropriately front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 6 parameters, no output schema, and supportive annotations, the description completely covers the tool's behavior, parameters, return, and integration with other tools. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 100% coverage, describing all 6 parameters. The description's parameter list mirrors the schema closely, adding minimal extra meaning. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists tags from a CKAN server using faceting. It provides a typical workflow mentioning sibling tools, but does not explicitly differentiate from all siblings. Overall, the purpose is well-defined.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a typical workflow showing how this tool fits with others (ckan_package_search, ckan_package_show). It also explains options like filtering by dataset query or tag substring. However, it does not state explicit when-not-to-use scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sparql_querySPARQL QueryARead-onlyIdempotent
Execute a SPARQL SELECT query against any public HTTPS SPARQL endpoint.
Useful for querying open data portals and knowledge graphs that expose SPARQL endpoints, including:
data.europa.eu (European open data portal)
publications.europa.eu (EU Publications Office)
DBpedia, Wikidata
Any DCAT-AP compliant data catalog
Only HTTPS endpoints are allowed. Queries timeout after 15 seconds. Only SELECT queries are supported (read-only).
If the query does not contain a LIMIT clause, one is injected automatically (default: 25, max: 1000).
Args:
endpoint_url (string): HTTPS URL of the SPARQL endpoint
query (string): SPARQL SELECT query to execute
limit (number): Max rows to return (default: 25). Ignored if query already contains LIMIT.
response_format ('markdown' | 'json'): Output format
Examples:
Count Italian HVD datasets by publisher on data.europa.eu
Query Wikidata for entities related to a dataset topic
Explore EU controlled vocabularies on publications.europa.eu
Typical workflow: sparql_query (explore schema) → sparql_query (targeted query) → ckan_package_search (get dataset details)
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max rows to return (default: 25, max: 1000). Injected as SPARQL LIMIT if not already present in query. | |
| query | Yes | SPARQL SELECT query to execute | |
| endpoint_url | Yes | HTTPS URL of the SPARQL endpoint | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and non-destructive. The description adds critical behavioral details: HTTPS-only restriction, 15s timeout, auto LIMIT injection (default 25, max 1000), and that the query must be SELECT. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured: purpose sentence, bullet list of endpoints, constraints block, parameter details, examples, workflow. Every sentence is informative and no redundancy. Ideal length for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Lacks explicit description of return structure (e.g., SPARQL results JSON format) but covers constraints, examples, and workflow. For a read-only query tool with good annotations, this is nearly complete. Minor omission of output format details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed parameter descriptions. The description adds value by explaining the LIMIT injection behavior (ignored if query already has LIMIT) and providing context for response_format. Slightly above baseline due to extra contextual details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Execute a SPARQL SELECT query against any public HTTPS SPARQL endpoint' and lists specific endpoints and use cases. It distinguishes itself from sibling tools (all CKAN-based) by being the sole SPARQL query tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit context: only HTTPS, 15s timeout, only SELECT queries, automatic LIMIT injection. Includes examples and a typical workflow showing when to use in sequence with other tools. No exclusions needed as tool is purpose-specific.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
1 tool update
v0.4.112- Changed
ckan_list_resources1 field changed- changed
Input schema / properties / check_source_portal / descriptionPrevious value: -"When true (default), probes the source portal for DataStore availability when a resource URL points to a different CKAN instance"New value: +"Opt-in (default false): when true, probes the source portal for DataStore availability when a resource URL points to a different CKAN instance. Issues extra HTTP requests to hosts taken from the dataset's resource URLs."
20 tool updates
v0.4.108- First observed
ckan_analyze_datasets - First observed
ckan_catalog_stats - First observed
ckan_datastore_search - First observed
ckan_datastore_search_sql - First observed
ckan_find_portals - First observed
ckan_find_relevant_datasets - First observed
ckan_get_mqa_quality - First observed
ckan_get_mqa_quality_details - First observed
ckan_group_list - First observed
ckan_group_search - First observed
ckan_group_show - First observed
ckan_list_resources - First observed
ckan_organization_list - First observed
ckan_organization_search - First observed
ckan_organization_show - First observed
ckan_package_search - First observed
ckan_package_show - First observed
ckan_status_show - First observed
ckan_tag_list - First observed
sparql_query
TDQS
Most tools have clearly distinct purposes, though ckan_package_search and ckan_find_relevant_datasets both search datasets but with different ranking; similarly, ckan_datastore_search and ckan_datastore_search_sql overlap but differ in query interface. These overlaps are well-documented and complementary, so overall disambiguation is good.
All tools follow a consistent 'ckan_verb_noun' pattern (e.g., ckan_group_list, ckan_package_search). The naming is predictable and logical, making it easy for an agent to infer tool purpose from name.
With 20 tools, the set is comprehensive but not excessive given the breadth of CKAN functionality covered (search, datastore, groups, organizations, tags, SPARQL, MQA). It strikes a good balance between completeness and manageability.
The tool set covers the main use cases for exploring CKAN portals: discovery, search, metadata retrieval, datastore querying, and quality assessment. Some advanced features like user or dataset management are absent, but that aligns with the read-only exploration focus. The surface feels mostly complete for its intended purpose.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Ask data questions in natural language. Get SQL, insights, and charts from your databases.
Provides access to Civic Plus - See Click Fix, allowing you to interact with your data via an LLM.…
Resolve any government entity worldwide and submit service requests. Open civic data for AI agents.
- mcpOAuthcom.keboola
Connect your AI assistants to Keboola and expose your data, transformations, SQL queries, ...
Related MCP Servers
- AlicenseBqualityNot gradedmaintenanceEnables AI assistants and CLI tools to explore and analyze datasets from 600+ global CKAN open-data portals. Provides comprehensive tools for dataset discovery, datastore queries, metadata analysis, and local downloads without writing custom CKAN integrations.14-
- AlicenseNot gradedqualityCmaintenanceEnables querying Portugal's national open data portal (dados.gov.pt) through natural language.15MIT
- AlicenseNot gradedqualityCmaintenanceEnables searching and querying Finland's open data portal (avoindata.fi) via CKAN. Supports dataset search, metadata retrieval, and tabular data queries.16MIT

mcp-data-lvofficial
AlicenseNot gradedqualityCmaintenanceEnables AI agents to search, retrieve metadata, and query tabular resources from Latvia's Open Data portal (data.gov.lv) via CKAN.15MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ondata/ckan-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server