@olaservo/scryfall-mcp-server 1.0.0 → 1.0.2

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/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
+ #!/usr/bin/env node
1
2
  export {};
package/dist/index.js CHANGED
@@ -1,25 +1,25 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
- import { registerTools } from "./tools/index.js";
4
- const server = new McpServer({
5
- name: "scryfall-mcp-server",
6
- version: "1.0.0",
7
- }, {
8
- capabilities: {
9
- tools: {},
10
- resources: {},
11
- },
12
- instructions: "Search and fetch Magic: The Gathering card data from Scryfall. " +
13
- "Use the 'search' tool with Scryfall full-text query syntax to find cards, " +
14
- "then use 'fetch' with a card ID to get full details.",
15
- });
16
- registerTools(server);
17
- async function main() {
18
- const transport = new StdioServerTransport();
19
- await server.connect(transport);
20
- console.error("Scryfall MCP server running via stdio");
1
+ #!/usr/bin/env node
2
+ const args = process.argv.slice(2);
3
+ const transportName = args[0] || "stdio";
4
+ async function run() {
5
+ try {
6
+ switch (transportName) {
7
+ case "stdio":
8
+ await import("./transports/stdio.js");
9
+ break;
10
+ case "streamableHttp":
11
+ await import("./transports/streamableHttp.js");
12
+ break;
13
+ default:
14
+ console.error(`Unknown transport: ${transportName}`);
15
+ console.log("Available transports: stdio, streamableHttp");
16
+ process.exit(1);
17
+ }
18
+ }
19
+ catch (error) {
20
+ console.error("Fatal error:", error);
21
+ process.exit(1);
22
+ }
21
23
  }
22
- main().catch((error) => {
23
- console.error("Fatal error:", error);
24
- process.exit(1);
25
- });
24
+ await run();
25
+ export {};
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function createServer(): McpServer;
package/dist/server.js ADDED
@@ -0,0 +1,18 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { registerTools } from "./tools/index.js";
3
+ export function createServer() {
4
+ const server = new McpServer({
5
+ name: "scryfall-mcp-server",
6
+ version: "1.0.0",
7
+ }, {
8
+ capabilities: {
9
+ tools: {},
10
+ resources: {},
11
+ },
12
+ instructions: "Search and fetch Magic: The Gathering card data from Scryfall. " +
13
+ "Use the 'search' tool with Scryfall full-text query syntax to find cards, " +
14
+ "then use 'fetch' with a card ID to get full details.",
15
+ });
16
+ registerTools(server);
17
+ return server;
18
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2
+ import { createServer } from "../server.js";
3
+ const transport = new StdioServerTransport();
4
+ const server = createServer();
5
+ await server.connect(transport);
6
+ console.error("Scryfall MCP server running via stdio");
7
+ process.on("SIGINT", async () => {
8
+ await server.close();
9
+ process.exit(0);
10
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,70 @@
1
+ import express from "express";
2
+ import cors from "cors";
3
+ import { randomUUID } from "node:crypto";
4
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
5
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
6
+ import { createServer } from "../server.js";
7
+ const app = express();
8
+ app.use(cors({ origin: "*", exposedHeaders: ["Mcp-Session-Id"] }));
9
+ app.use(express.json());
10
+ const transports = {};
11
+ app.post("/mcp", async (req, res) => {
12
+ const sessionId = req.headers["mcp-session-id"];
13
+ let transport;
14
+ if (sessionId && transports[sessionId]) {
15
+ transport = transports[sessionId];
16
+ }
17
+ else if (!sessionId && isInitializeRequest(req.body)) {
18
+ transport = new StreamableHTTPServerTransport({
19
+ sessionIdGenerator: () => randomUUID(),
20
+ onsessioninitialized: (id) => {
21
+ transports[id] = transport;
22
+ },
23
+ });
24
+ transport.onclose = () => {
25
+ if (transport.sessionId) {
26
+ delete transports[transport.sessionId];
27
+ }
28
+ };
29
+ const server = createServer();
30
+ await server.connect(transport);
31
+ }
32
+ else {
33
+ res.status(400).json({
34
+ jsonrpc: "2.0",
35
+ error: {
36
+ code: -32000,
37
+ message: "Bad Request: No valid session ID provided",
38
+ },
39
+ id: null,
40
+ });
41
+ return;
42
+ }
43
+ await transport.handleRequest(req, res, req.body);
44
+ });
45
+ app.get("/mcp", async (req, res) => {
46
+ const sessionId = req.headers["mcp-session-id"];
47
+ if (!sessionId || !transports[sessionId]) {
48
+ res.status(400).send("Invalid or missing session ID");
49
+ return;
50
+ }
51
+ await transports[sessionId].handleRequest(req, res);
52
+ });
53
+ app.delete("/mcp", async (req, res) => {
54
+ const sessionId = req.headers["mcp-session-id"];
55
+ if (!sessionId || !transports[sessionId]) {
56
+ res.status(400).send("Invalid or missing session ID");
57
+ return;
58
+ }
59
+ await transports[sessionId].handleRequest(req, res);
60
+ });
61
+ const PORT = Number(process.env.PORT) || 3000;
62
+ app.listen(PORT, () => {
63
+ console.log(`Scryfall MCP HTTP server listening on http://localhost:${PORT}/mcp`);
64
+ });
65
+ process.on("SIGINT", async () => {
66
+ for (const transport of Object.values(transports)) {
67
+ await transport.close();
68
+ }
69
+ process.exit(0);
70
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olaservo/scryfall-mcp-server",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Community MCP server to search and fetch Magic: The Gathering card data from Scryfall with a rich card viewer UI. Not affiliated with or endorsed by Scryfall.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -35,16 +35,22 @@
35
35
  "build": "npm run build:ui && npm run build:server",
36
36
  "prepublishOnly": "npm run build",
37
37
  "start": "node dist/index.js",
38
+ "start:http": "node dist/index.js streamableHttp",
38
39
  "dev": "tsx watch src/index.ts",
40
+ "dev:http": "tsx watch src/index.ts streamableHttp",
39
41
  "inspector": "npx @modelcontextprotocol/inspector node dist/index.js",
40
42
  "pack": "npm run build && rm -rf node_modules && npm install --omit=dev --omit=optional && npx --yes @anthropic-ai/mcpb -- pack . scryfall-mcp-server.mcpb; npm install"
41
43
  },
42
44
  "dependencies": {
43
- "@modelcontextprotocol/ext-apps": "^1.0.1",
45
+ "@modelcontextprotocol/ext-apps": "^1.1.0",
44
46
  "@modelcontextprotocol/sdk": "^1.24.3",
47
+ "cors": "^2.8.6",
48
+ "express": "^5.2.1",
45
49
  "zod": "^3.25.0"
46
50
  },
47
51
  "devDependencies": {
52
+ "@types/cors": "^2.8.19",
53
+ "@types/express": "^5.0.6",
48
54
  "@types/node": "^22.10.0",
49
55
  "cross-env": "^10.1.0",
50
56
  "tsx": "^4.19.2",