Skip to main content
Glama
matthewdtowles

iwantmymtg-mcp

update_transaction

Update an existing transaction's details by ID, modifying only specified fields like quantity or price, while preserving card identity and transaction type.

Instructions

Update an existing transaction by ID. Only the fields supplied are changed. Card identity and type (BUY/SELL) cannot be changed via this endpoint - delete and re-create instead. Requires IWMM_API_KEY.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idYesTransaction ID from list_transactions.
patchYes

Implementation Reference

  • The updateTransactionTool definition: name 'update_transaction', input schema (id + patch object), and handler that sends a PATCH to /api/v1/transactions/{id} with the patch body.
    export const updateTransactionTool = {
      name: "update_transaction",
      description:
        "Update an existing transaction by ID. Only the fields supplied are changed. Card identity and type (BUY/SELL) cannot be changed via this endpoint - delete and re-create instead. Requires IWMM_API_KEY.",
      inputSchema: z.object({
        id: z.number().int().min(1).describe("Transaction ID from list_transactions."),
        patch: transactionUpdate,
      }),
      handler: ({ id, patch }: { id: number; patch: z.infer<typeof transactionUpdate> }) =>
        apiFetch({ path: `/api/v1/transactions/${id}`, method: "PATCH", body: patch, authenticated: true }),
    };
  • The 'transactionUpdate' Zod schema defining the optional fields that can be patched: quantity, pricePerUnit, date, source, fees, notes.
    const transactionUpdate = z.object({
      quantity: z.number().int().min(1).optional(),
      pricePerUnit: z.number().min(0).optional(),
      date: z.string().optional(),
      source: z.string().optional(),
      fees: z.number().min(0).optional(),
      notes: z.string().optional(),
    });
  • The 'tools' array in src/tools/index.ts registers updateTransactionTool as one of the available tools. It is also exported via the toolsByName lookup.
    export const tools: ToolDefinition[] = [
      // Read-only (no auth)
      searchCardsTool,
      getCardTool,
      getCardPricesTool,
      getCardPriceHistoryTool,
      searchSetsTool,
      getSetTool,
      listSetCardsTool,
      getSealedProductsTool,
      // Inventory (auth)
      listInventoryTool,
      getInventoryQuantitiesTool,
      addInventoryTool,
      updateInventoryTool,
      removeInventoryTool,
      // Transactions (auth)
      listTransactionsTool,
      recordTransactionTool,
      updateTransactionTool,
      deleteTransactionTool,
      getCostBasisTool,
      // Portfolio (auth; most are Premium-gated)
      getPortfolioSummaryTool,
      getPortfolioHistoryTool,
      getCardPerformanceTool,
      getCashFlowTool,
      getRealizedGainsTool,
      getPortfolioBreakdownTool,
      refreshPortfolioTool,
      // Price alerts (auth)
      listAlertsTool,
      createAlertTool,
      updateAlertTool,
      deleteAlertTool,
      // Notifications (auth)
      listNotificationsTool,
      getUnreadCountTool,
      markNotificationReadTool,
      markAllNotificationsReadTool,
    ];
    
    export const toolsByName: Record<string, ToolDefinition> = Object.fromEntries(
      tools.map((t) => [t.name, t]),
    );
  • The 'toolsByName' map provides runtime lookup by tool name, used by the MCP server to dispatch calls.
    export const toolsByName: Record<string, ToolDefinition> = Object.fromEntries(
      tools.map((t) => [t.name, t]),
    );
  • The apiFetch helper that handles HTTP requests. The update_transaction handler calls this with method PATCH, path /api/v1/transactions/{id}, the patch body, and authenticated=true.
    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;
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so description carries burden. It discloses partial update behavior and immutable fields but lacks details on side effects, return value, or error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no redundancy, front-loaded with core action, efficient use of words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers key aspects (partial update, immutability, auth) despite no output schema; could mention response format or impact but acceptable for a simple update tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50% (id explained), but description adds no additional meaning beyond schema; baseline 3 applies as schema already provides type/constraints for patch fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it updates an existing transaction with partial changes, and explicitly distinguishes itself from related tools like record_transaction and delete_transaction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-not-to-use (card identity/type changes) and alternative action (delete and re-create), plus authentication requirement (IWMM_API_KEY).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/matthewdtowles/iwantmymtg-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server