iwantmymtg-mcp 0.1.0 → 0.2.0

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
@@ -19,7 +19,12 @@ Requires Node 20+.
19
19
  npx iwantmymtg-mcp
20
20
  ```
21
21
 
22
- (Until published to npm, use the local install instructions below.)
22
+ Or install globally if you prefer:
23
+
24
+ ```bash
25
+ npm install -g iwantmymtg-mcp
26
+ iwantmymtg-mcp
27
+ ```
23
28
 
24
29
  ## Claude Desktop
25
30
 
@@ -57,6 +62,24 @@ Add to `.mcp.json` in your project (or `~/.claude/.mcp.json` globally):
57
62
  }
58
63
  ```
59
64
 
65
+ ## Cursor
66
+
67
+ Add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` in your project:
68
+
69
+ ```json
70
+ {
71
+ "mcpServers": {
72
+ "iwmm": {
73
+ "command": "npx",
74
+ "args": ["-y", "iwantmymtg-mcp"],
75
+ "env": { "IWMM_API_KEY": "iwm_live_..." }
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ After saving, restart Cursor and confirm `iwmm` appears under **Settings -> Features -> MCP Servers**.
82
+
60
83
  ## Example prompts
61
84
 
62
85
  - "Search for Lightning Bolt printings and show me the cheapest one."
@@ -64,6 +87,8 @@ Add to `.mcp.json` in your project (or `~/.claude/.mcp.json` globally):
64
87
  - "Add 4 copies of Lightning Bolt LEA to my inventory."
65
88
  - "What sealed products are available for MH3?"
66
89
 
90
+ See [`examples/`](https://github.com/matthewdtowles/iwantmymtg-mcp/tree/main/examples) for walkthroughs of common flows (card lookup, inventory, transactions, portfolio insights, price alerts).
91
+
67
92
  ## Configuration
68
93
 
69
94
  | Env var | Default | Purpose |
@@ -22,7 +22,7 @@ export async function apiFetch(req) {
22
22
  }
23
23
  const headers = {
24
24
  Accept: "application/json",
25
- "User-Agent": "iwantmymtg-mcp/0.0.1",
25
+ "User-Agent": "iwantmymtg-mcp/0.2.0",
26
26
  };
27
27
  if (req.authenticated) {
28
28
  const { requireApiKey } = await import("./config.js");
@@ -0,0 +1,45 @@
1
+ import { ApiError } from "./api-client.js";
2
+ export function formatError(err) {
3
+ if (err instanceof ApiError) {
4
+ return formatApiError(err);
5
+ }
6
+ return err instanceof Error ? err.message : String(err);
7
+ }
8
+ export function formatApiError(err) {
9
+ const apiMessage = extractApiMessage(err.body);
10
+ if (err.status === 401) {
11
+ return `Not authenticated. Set IWMM_API_KEY to your iwm_live_... key from https://iwantmymtg.net/user/api-keys.`;
12
+ }
13
+ if (err.status === 402 || err.status === 403) {
14
+ const detail = apiMessage ?? "Premium subscription required.";
15
+ return `${detail} This feature requires an active IWMM Premium subscription. Upgrade at https://iwantmymtg.net/pricing.`;
16
+ }
17
+ if (err.status === 429) {
18
+ const rl = err.rateLimit;
19
+ const resetNote = rl?.reset ? ` Resets at ${rl.reset}.` : "";
20
+ return `Rate limit exceeded.${resetNote} ${apiMessage ?? ""}`.trim();
21
+ }
22
+ const rl = err.rateLimit;
23
+ const rateNote = rl?.remaining !== undefined
24
+ ? ` (rate limit: ${rl.remaining}/${rl.limit} remaining, resets ${rl.reset ?? "?"})`
25
+ : "";
26
+ return `IWMM API responded ${err.status}${rateNote}: ${apiMessage ?? err.body}`;
27
+ }
28
+ export function extractApiMessage(body) {
29
+ if (!body)
30
+ return undefined;
31
+ try {
32
+ const parsed = JSON.parse(body);
33
+ if (typeof parsed?.message === "string")
34
+ return parsed.message;
35
+ if (Array.isArray(parsed?.message))
36
+ return parsed.message.join("; ");
37
+ if (typeof parsed?.error === "string")
38
+ return parsed.error;
39
+ }
40
+ catch {
41
+ // Body wasn't JSON; fall through.
42
+ }
43
+ return undefined;
44
+ }
45
+ //# sourceMappingURL=error-formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-formatter.js","sourceRoot":"","sources":["../src/error-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAa;IAC1C,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAE/C,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,OAAO,yGAAyG,CAAC;IACnH,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,UAAU,IAAI,gCAAgC,CAAC;QAC9D,OAAO,GAAG,MAAM,wGAAwG,CAAC;IAC3H,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC;QACzB,MAAM,SAAS,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,OAAO,uBAAuB,SAAS,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IACvE,CAAC;IAED,MAAM,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC;IACzB,MAAM,QAAQ,GACZ,EAAE,EAAE,SAAS,KAAK,SAAS;QACzB,CAAC,CAAC,iBAAiB,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,KAAK,sBAAsB,EAAE,CAAC,KAAK,IAAI,GAAG,GAAG;QACnF,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,sBAAsB,GAAG,CAAC,MAAM,GAAG,QAAQ,KAAK,UAAU,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,OAAO,MAAM,EAAE,OAAO,KAAK,QAAQ;YAAE,OAAO,MAAM,CAAC,OAAO,CAAC;QAC/D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;YAAE,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,IAAI,OAAO,MAAM,EAAE,KAAK,KAAK,QAAQ;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
package/dist/server.js CHANGED
@@ -3,11 +3,11 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
3
3
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
4
4
  import { zodToJsonSchema } from "zod-to-json-schema";
5
5
  import { tools, toolsByName } from "./tools/index.js";
6
- import { ApiError } from "./api-client.js";
6
+ import { formatError } from "./error-formatter.js";
7
7
  export async function startServer() {
8
8
  const server = new Server({
9
9
  name: "iwantmymtg-mcp",
10
- version: "0.0.1",
10
+ version: "0.2.0",
11
11
  }, {
12
12
  capabilities: {
13
13
  tools: {},
@@ -53,14 +53,4 @@ export async function startServer() {
53
53
  const transport = new StdioServerTransport();
54
54
  await server.connect(transport);
55
55
  }
56
- function formatError(err) {
57
- if (err instanceof ApiError) {
58
- const rl = err.rateLimit;
59
- const rateNote = rl?.remaining !== undefined
60
- ? ` (rate limit: ${rl.remaining}/${rl.limit} remaining, resets ${rl.reset ?? "?"})`
61
- : "";
62
- return `IWMM API responded ${err.status}${rateNote}: ${err.body}`;
63
- }
64
- return err instanceof Error ? err.message : String(err);
65
- }
66
56
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;QACE,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;SACV;KACF,CACF,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAA4B;SAC/F,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC5D,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;aACtE,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,yBAAyB,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;qBAClE;iBACF;aACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7C,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aACnE,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QAChF,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iwantmymtg-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "MCP server for I Want My MTG - query cards/sets and manage your collection from Claude Desktop, Claude Code, Cursor, and other MCP clients.",
5
5
  "type": "module",
6
6
  "bin": {