iwantmymtg-mcp 0.0.1 → 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 +26 -1
- package/dist/api-client.js +1 -1
- package/dist/error-formatter.js +45 -0
- package/dist/error-formatter.js.map +1 -0
- package/dist/server.js +2 -12
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,12 @@ Requires Node 20+.
|
|
|
19
19
|
npx iwantmymtg-mcp
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
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 |
|
package/dist/api-client.js
CHANGED
|
@@ -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
|
|
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 {
|
|
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
|
|
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
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,
|
|
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