get_portfolio_breakdown
Break down your MTG collection value by dimension like set, rarity, type, format, or cost-basis to see portfolio distribution and gain/loss buckets.
Instructions
Get the user's collection value broken down by a dimension. Premium-gated. Requires IWMM_API_KEY.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| by | Yes | Dimension to break down by. 'cost-basis' buckets are gain/loss/at-cost. |
Implementation Reference
- src/tools/portfolio.ts:51-62 (handler)The handler function that executes get_portfolio_breakdown logic. It validates the 'by' parameter (enum: set, rarity, type, format, cost-basis) and calls apiFetch to GET /api/v1/portfolio/breakdown with the query parameter.
export const getPortfolioBreakdownTool = { name: "get_portfolio_breakdown", description: "Get the user's collection value broken down by a dimension. Premium-gated. Requires IWMM_API_KEY.", inputSchema: z.object({ by: z .enum(["set", "rarity", "type", "format", "cost-basis"]) .describe("Dimension to break down by. 'cost-basis' buckets are gain/loss/at-cost."), }), handler: ({ by }: { by: string }) => apiFetch({ path: "/api/v1/portfolio/breakdown", query: { by }, authenticated: true }), }; - src/tools/portfolio.ts:55-58 (schema)Input schema defining the 'by' parameter as a zod enum restricted to 'set', 'rarity', 'type', 'format', or 'cost-basis'.
inputSchema: z.object({ by: z .enum(["set", "rarity", "type", "format", "cost-basis"]) .describe("Dimension to break down by. 'cost-basis' buckets are gain/loss/at-cost."), - src/tools/index.ts:76-77 (registration)Tool is registered in the tools array (index 76), making it discoverable via ListToolsRequestSchema and callable via CallToolRequestSchema.
getPortfolioBreakdownTool, refreshPortfolioTool, - src/tools/index.ts:90-92 (registration)A name-to-tool lookup map (toolsByName) is built from the tools array, enabling fast dispatch when a tool is called by name.
export const toolsByName: Record<string, ToolDefinition> = Object.fromEntries( tools.map((t) => [t.name, t]), ); - src/api-client.ts:26-67 (helper)Helper apiFetch function that constructs the URL, adds auth headers, and performs the HTTP request. Used by the handler to call the external API.
export async function apiFetch<T = unknown>(req: ApiRequest): Promise<T> { const url = new URL(req.path, config.baseUrl); if (req.query) { for (const [k, v] of Object.entries(req.query)) { if (v !== undefined && v !== null && v !== "") { url.searchParams.set(k, String(v)); } } } const headers: Record<string, string> = { Accept: "application/json", "User-Agent": "iwantmymtg-mcp/0.0.1", }; if (req.authenticated) { const { requireApiKey } = await import("./config.js"); headers["Authorization"] = `Bearer ${requireApiKey()}`; } if (req.body !== undefined) { headers["Content-Type"] = "application/json"; } const res = await fetch(url, { method: req.method ?? "GET", headers, body: req.body !== undefined ? JSON.stringify(req.body) : undefined, }); if (!res.ok) { const text = await res.text(); throw new ApiError(res.status, text, { limit: res.headers.get("X-RateLimit-Limit") ?? undefined, remaining: res.headers.get("X-RateLimit-Remaining") ?? undefined, reset: res.headers.get("X-RateLimit-Reset") ?? undefined, }); } if (res.status === 204) return undefined as T; return (await res.json()) as T; }