@jarib/pxweb-mcp 1.0.2 → 1.0.3

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
@@ -5,10 +5,11 @@ MCP server for accessing statistical data via the PxWeb API v2.
5
5
  ## Quick Start
6
6
 
7
7
  ```bash
8
- npx @jarib/pxweb-mcp
8
+ npx -y @jarib/pxweb-mcp
9
+ npx -y @jarib/pxweb-mcp --transport http --port 3000
9
10
  ```
10
11
 
11
- Server runs at `http://localhost:3000/mcp` using Statistics Norway (SSB) by default.
12
+
12
13
 
13
14
  ## Known PxWeb v2 Instances
14
15
 
package/build/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createServer } from "node:http";
3
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
5
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
5
6
  import { z } from "zod";
6
7
  import yargs from "yargs";
7
8
  import { hideBin } from "yargs/helpers";
9
+ import fs from 'fs';
8
10
  const DEFAULT_API_BASE = "https://data.ssb.no/api/pxwebapi/v2";
9
11
  const DEFAULT_LANGUAGE = "no";
10
12
  const USER_AGENT = "pxweb-mcp/1.0";
@@ -19,6 +21,12 @@ const argv = yargs(hideBin(process.argv))
19
21
  type: "number",
20
22
  description: "Port to listen on",
21
23
  default: DEFAULT_PORT,
24
+ })
25
+ .option("transport", {
26
+ type: "string",
27
+ description: "Transport method (http or stdio)",
28
+ choices: ["http", "stdio"],
29
+ default: "stdio",
22
30
  })
23
31
  .help()
24
32
  .parseSync();
@@ -39,9 +47,10 @@ async function makeRequest(url) {
39
47
  return response;
40
48
  }
41
49
  function createMcpServer(apiBase) {
50
+ const pkg = JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
42
51
  const server = new McpServer({
43
52
  name: "pxweb-mcp",
44
- version: "1.0.0",
53
+ version: pkg.version
45
54
  });
46
55
  // Tool: search_tables
47
56
  server.registerTool("search_tables", {
@@ -306,42 +315,50 @@ Use this to find newly published statistics.`,
306
315
  return server;
307
316
  }
308
317
  async function main() {
309
- const { url, port } = argv;
318
+ const { url, port, transport: transportType } = argv;
310
319
  const mcpServer = createMcpServer(url);
311
- const transport = new StreamableHTTPServerTransport({
312
- sessionIdGenerator: () => crypto.randomUUID(),
313
- });
314
- const httpServer = createServer(async (req, res) => {
315
- const pathname = req.url?.split("?")[0] || "/";
316
- // Health check endpoint
317
- if (pathname === "/health") {
318
- res.writeHead(200, { "Content-Type": "application/json" });
319
- res.end(JSON.stringify({ status: "ok" }));
320
- return;
321
- }
322
- // MCP endpoint
323
- if (pathname === "/mcp") {
324
- try {
325
- await transport.handleRequest(req, res);
320
+ if (transportType === "stdio") {
321
+ const transport = new StdioServerTransport();
322
+ await mcpServer.connect(transport);
323
+ console.error(`PxWeb MCP Server running on stdio`);
324
+ console.error(`Using API: ${url}`);
325
+ }
326
+ else {
327
+ const transport = new StreamableHTTPServerTransport({
328
+ sessionIdGenerator: () => crypto.randomUUID(),
329
+ });
330
+ const httpServer = createServer(async (req, res) => {
331
+ const pathname = req.url?.split("?")[0] || "/";
332
+ // Health check endpoint
333
+ if (pathname === "/health") {
334
+ res.writeHead(200, { "Content-Type": "application/json" });
335
+ res.end(JSON.stringify({ status: "ok" }));
336
+ return;
326
337
  }
327
- catch (error) {
328
- console.error("MCP error:", error);
329
- if (!res.headersSent) {
330
- res.writeHead(500, { "Content-Type": "application/json" });
331
- res.end(JSON.stringify({ error: "Internal server error" }));
338
+ // MCP endpoint
339
+ if (pathname === "/mcp") {
340
+ try {
341
+ await transport.handleRequest(req, res);
342
+ }
343
+ catch (error) {
344
+ console.error("MCP error:", error);
345
+ if (!res.headersSent) {
346
+ res.writeHead(500, { "Content-Type": "application/json" });
347
+ res.end(JSON.stringify({ error: "Internal server error" }));
348
+ }
332
349
  }
350
+ return;
333
351
  }
334
- return;
335
- }
336
- // Not found
337
- res.writeHead(404, { "Content-Type": "application/json" });
338
- res.end(JSON.stringify({ error: "Not found" }));
339
- });
340
- await mcpServer.connect(transport);
341
- httpServer.listen(port, () => {
342
- console.error(`PxWeb MCP Server running on http://localhost:${port}/mcp`);
343
- console.error(`Using API: ${url}`);
344
- });
352
+ // Not found
353
+ res.writeHead(404, { "Content-Type": "application/json" });
354
+ res.end(JSON.stringify({ error: "Not found" }));
355
+ });
356
+ await mcpServer.connect(transport);
357
+ httpServer.listen(port, () => {
358
+ console.error(`PxWeb MCP Server running on http://localhost:${port}/mcp`);
359
+ console.error(`Using API: ${url}`);
360
+ });
361
+ }
345
362
  }
346
363
  main().catch((error) => {
347
364
  console.error("Fatal error:", error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jarib/pxweb-mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "MCP server for accessing statistical data via the PxWeb API v2",
5
5
  "type": "module",
6
6
  "main": "build/index.js",