@opendata.cat/mcp-server 0.0.7 → 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 +10 -7
- package/dist/index.js +70 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
6
|
<a href="https://www.npmjs.com/package/@opendata.cat/mcp-server"><img src="https://img.shields.io/npm/v/@opendata.cat/mcp-server?color=c44536&label=npm" alt="npm"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/@opendata.cat/mcp-server"><img src="https://img.shields.io/npm/dm/@opendata.cat/mcp-server?color=c44536&label=downloads" alt="npm downloads"></a>
|
|
7
8
|
<a href="https://github.com/xaviviro/Opendata.cat-MCP-Server"><img src="https://img.shields.io/github/v/tag/xaviviro/Opendata.cat-MCP-Server?label=github&color=1a1a1a" alt="github"></a>
|
|
8
9
|
<a href="https://opendata.cat/mcp"><img src="https://img.shields.io/badge/web-opendata.cat%2Fmcp-c9a227" alt="web"></a>
|
|
9
10
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-green" alt="license"></a>
|
|
@@ -17,16 +18,18 @@ Un projecte d'**[opendata.cat](https://opendata.cat)** — associacio sense anim
|
|
|
17
18
|
|
|
18
19
|
## Portals disponibles
|
|
19
20
|
|
|
20
|
-
| Portal | Datasets |
|
|
21
|
-
|
|
22
|
-
| [Generalitat de Catalunya](https://analisi.transparenciacatalunya.cat) | 1.058 |
|
|
23
|
-
| [Ajuntament de Barcelona](https://opendata-ajuntament.barcelona.cat) | 555 |
|
|
24
|
-
| [Diputacio de Barcelona](https://dadesobertes.diba.cat) | 90 |
|
|
25
|
-
| [Consorci AOC](https://dadesobertes.seu-e.cat) | ~893 |
|
|
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 |
|
|
26
29
|
|
|
27
30
|
El Consorci AOC inclou datasets de les **diputacions de Tarragona, Girona i Lleida**, ajuntaments, consells comarcals i altres organismes publics catalans.
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
**+2.700 datasets** de 6 portals. La majoria queryables amb filtres, cerca i paginacio.
|
|
30
33
|
|
|
31
34
|
El cataleg s'actualitza automaticament cada setmana. Cada endpoint es valida per assegurar que funciona.
|
|
32
35
|
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createServer } from "node:http";
|
|
2
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
6
|
import { z } from "zod";
|
|
5
7
|
import { searchDatasets, getDatasetInfo, getCategories } from "./api.js";
|
|
6
8
|
import { querySocrata } from "./clients/socrata.js";
|
|
@@ -9,7 +11,7 @@ import { queryDiba } from "./clients/diba.js";
|
|
|
9
11
|
import { queryCido } from "./clients/cido.js";
|
|
10
12
|
const server = new McpServer({
|
|
11
13
|
name: "opendata-cat",
|
|
12
|
-
version: "0.0.
|
|
14
|
+
version: "0.0.9",
|
|
13
15
|
});
|
|
14
16
|
// Tool 1: search_datasets
|
|
15
17
|
server.tool("search_datasets", "Cerca datasets de dades obertes catalanes per text lliure. Retorna nom, descripció, portal i formats.", {
|
|
@@ -129,8 +131,73 @@ server.tool("list_categories", "Llista totes les categories i temes de datasets
|
|
|
129
131
|
const cats = await getCategories();
|
|
130
132
|
return { content: [{ type: "text", text: JSON.stringify(cats, null, 2) }] };
|
|
131
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
|
+
});
|
|
132
164
|
async function main() {
|
|
133
|
-
const
|
|
134
|
-
|
|
165
|
+
const mode = process.argv.includes("--http") ? "http" : "stdio";
|
|
166
|
+
const port = parseInt(process.env.MCP_PORT || "3100", 10);
|
|
167
|
+
if (mode === "http") {
|
|
168
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
169
|
+
const httpServer = createServer(async (req, res) => {
|
|
170
|
+
// CORS
|
|
171
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
172
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
173
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
174
|
+
if (req.method === "OPTIONS") {
|
|
175
|
+
res.writeHead(204);
|
|
176
|
+
res.end();
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// Health check
|
|
180
|
+
if (req.url === "/health") {
|
|
181
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
182
|
+
res.end(JSON.stringify({ status: "ok", name: "opendata-cat", version: "0.0.9" }));
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
// MCP endpoint
|
|
186
|
+
if (req.url === "/mcp") {
|
|
187
|
+
await transport.handleRequest(req, res);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
res.writeHead(404);
|
|
191
|
+
res.end("Not found");
|
|
192
|
+
});
|
|
193
|
+
await server.connect(transport);
|
|
194
|
+
httpServer.listen(port, () => {
|
|
195
|
+
console.log(`MCP HTTP server running on port ${port}`);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
const transport = new StdioServerTransport();
|
|
200
|
+
await server.connect(transport);
|
|
201
|
+
}
|
|
135
202
|
}
|
|
136
203
|
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.0.
|
|
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",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"author": "opendata.cat",
|
|
27
27
|
"license": "MIT",
|
|
28
|
+
"mcpName": "io.github.xaviviro/opendata-cat",
|
|
28
29
|
"repository": {
|
|
29
30
|
"type": "git",
|
|
30
31
|
"url": "git+https://github.com/xaviviro/Opendata.cat-MCP-Server.git"
|