@opendata.cat/mcp-server 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,16 +18,18 @@ Un projecte d'**[opendata.cat](https://opendata.cat)** — associacio sense anim
18
18
 
19
19
  ## Portals disponibles
20
20
 
21
- | Portal | Datasets | Queryables | APIs |
22
- |--------|----------|-----------|------|
23
- | [Generalitat de Catalunya](https://analisi.transparenciacatalunya.cat) | 1.058 | 1.058 | Socrata (SoQL) |
24
- | [Ajuntament de Barcelona](https://opendata-ajuntament.barcelona.cat) | 555 | 463 | CKAN datastore |
25
- | [Diputacio de Barcelona](https://dadesobertes.diba.cat) | 90 | 32 | REST + JSON:API (CIDO) |
26
- | [Consorci AOC](https://dadesobertes.seu-e.cat) | ~893 | ~893 | CKAN datastore |
21
+ | Portal | Datasets | APIs |
22
+ |--------|----------|------|
23
+ | [Generalitat de Catalunya](https://analisi.transparenciacatalunya.cat) | 1.058 | Socrata (SoQL) |
24
+ | [Ajuntament de Barcelona](https://opendata-ajuntament.barcelona.cat) | 555 | CKAN datastore |
25
+ | [Diputacio de Barcelona](https://dadesobertes.diba.cat) | 90 | REST + JSON:API (CIDO) |
26
+ | [Consorci AOC](https://dadesobertes.seu-e.cat) | ~893 | CKAN datastore |
27
+ | [Ajuntament de Reus](https://opendata.reus.cat) | 119 | CKAN datastore |
28
+ | [Ajuntament de Girona](https://www.girona.cat/opendata/) | 53 | CKAN datastore |
27
29
 
28
30
  El Consorci AOC inclou datasets de les **diputacions de Tarragona, Girona i Lleida**, ajuntaments, consells comarcals i altres organismes publics catalans.
29
31
 
30
- **~2.400 datasets queryables** amb filtres, cerca i paginacio. La resta ofereix descarrega directa de fitxers.
32
+ **+2.700 datasets** de 6 portals. La majoria queryables amb filtres, cerca i paginacio.
31
33
 
32
34
  El cataleg s'actualitza automaticament cada setmana. Cada endpoint es valida per assegurar que funciona.
33
35
 
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { queryDiba } from "./clients/diba.js";
11
11
  import { queryCido } from "./clients/cido.js";
12
12
  const server = new McpServer({
13
13
  name: "opendata-cat",
14
- version: "0.0.8",
14
+ version: "0.0.9",
15
15
  });
16
16
  // Tool 1: search_datasets
17
17
  server.tool("search_datasets", "Cerca datasets de dades obertes catalanes per text lliure. Retorna nom, descripció, portal i formats.", {
@@ -131,6 +131,36 @@ server.tool("list_categories", "Llista totes les categories i temes de datasets
131
131
  const cats = await getCategories();
132
132
  return { content: [{ type: "text", text: JSON.stringify(cats, null, 2) }] };
133
133
  });
134
+ // Tool 7: related_datasets
135
+ server.tool("related_datasets", "Retorna datasets relacionats d'ALTRES portals. Ideal per descobrir dades complementàries.", {
136
+ dataset_id: z.string().describe("ID del dataset del qual vols trobar relacionats"),
137
+ }, async ({ dataset_id }) => {
138
+ const dataset = await getDatasetInfo(dataset_id);
139
+ if (!dataset) {
140
+ return { content: [{ type: "text", text: `Dataset '${dataset_id}' no trobat.` }] };
141
+ }
142
+ // Fetch related from API (stored in DB by enrichment script)
143
+ const resp = await fetch(`https://opendata.cat/api/dataset.php?id=${encodeURIComponent(dataset_id)}`);
144
+ if (!resp.ok) {
145
+ return { content: [{ type: "text", text: "Error obtenint relacions." }] };
146
+ }
147
+ const full = await resp.json();
148
+ const related = full.related ?? [];
149
+ if (!related.length) {
150
+ return { content: [{ type: "text", text: `No hi ha datasets relacionats per a '${dataset.name}'.` }] };
151
+ }
152
+ // Enrich with names
153
+ const details = await Promise.all(related.slice(0, 5).map(async (r) => {
154
+ const info = await getDatasetInfo(r.id);
155
+ return info ? { dataset_id: r.id, name: info.name, portal: info.portal_id, category: info.category, similarity: r.score } : null;
156
+ }));
157
+ return {
158
+ content: [{
159
+ type: "text",
160
+ text: JSON.stringify({ dataset: dataset.name, related: details.filter(Boolean) }, null, 2),
161
+ }],
162
+ };
163
+ });
134
164
  async function main() {
135
165
  const mode = process.argv.includes("--http") ? "http" : "stdio";
136
166
  const port = parseInt(process.env.MCP_PORT || "3100", 10);
@@ -149,7 +179,7 @@ async function main() {
149
179
  // Health check
150
180
  if (req.url === "/health") {
151
181
  res.writeHead(200, { "Content-Type": "application/json" });
152
- res.end(JSON.stringify({ status: "ok", name: "opendata-cat", version: "0.0.8" }));
182
+ res.end(JSON.stringify({ status: "ok", name: "opendata-cat", version: "0.0.9" }));
153
183
  return;
154
184
  }
155
185
  // MCP endpoint
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.0.8",
6
+ "version": "0.0.9",
7
7
  "description": "Servidor MCP per consultar les dades obertes públiques de Catalunya",
8
8
  "type": "module",
9
9
  "main": "dist/index.js",