markitup_credit_balance
Check your MarkItUp credit balance and subscription status to ensure you have available credits before generating marketing visuals.
Instructions
Return the current MarkItUp credit balance and subscription status for the authenticated account. Use this before calling generation tools to verify the account has credits available.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/balance.ts:25-48 (handler)The runBalance function executes the tool logic: it calls the API at /credits/balance, formats the response into a human-readable text string, and returns both content and structured data.
export async function runBalance(api: MarkItUpApiClient): Promise<{ content: Array<{ type: "text"; text: string }>; structuredContent: BalanceResponse; }> { const data = await api.post<BalanceResponse>("/credits/balance", {}); const lines = [ `Credit balance: ${data.balance}`, data.subscriptionCredits !== undefined ? ` • Subscription credits: ${data.subscriptionCredits}` : null, data.topupCredits !== undefined ? ` • Top-up credits: ${data.topupCredits}` : null, data.subscription ? `Subscription: ${data.subscription.planId ?? "unknown"} (${data.subscription.status})` : "Subscription: none", ].filter((s): s is string => s !== null); return { content: [{ type: "text", text: lines.join("\n") }], structuredContent: data, }; } - src/tools/balance.ts:3-13 (schema)The balanceTool object defines the tool name ('markitup_credit_balance'), description, and inputSchema (empty object with no properties).
export const balanceTool = { name: "markitup_credit_balance", description: "Return the current MarkItUp credit balance and subscription status for the authenticated account. " + "Use this before calling generation tools to verify the account has credits available.", inputSchema: { type: "object", properties: {}, additionalProperties: false, }, } as const; - src/index.ts:41-42 (registration)The tool is registered into the tools array for the ListToolsRequestSchema handler.
const tools: Tool[] = [ balanceTool as unknown as Tool, - src/index.ts:55-56 (registration)The tool name is used in a switch-case to dispatch to runBalance when the tool is called.
case balanceTool.name: return await runBalance(api); - src/api/client.ts:19-76 (helper)MarkItUpApiClient.post is used by runBalance to make the HTTP request to the API.
export class MarkItUpApiClient { private apiKey: string; private baseUrl: string; constructor(opts: ApiClientOptions) { if (!opts.apiKey) { throw new Error("MARKITUP_API_KEY is required"); } this.apiKey = opts.apiKey; this.baseUrl = (opts.baseUrl ?? DEFAULT_API_BASE).replace(/\/$/, ""); } async post<T>(path: string, body: Record<string, unknown>): Promise<T> { return this.request<T>("POST", path, body); } async get<T>(path: string): Promise<T> { return this.request<T>("GET", path); } private async request<T>( method: "GET" | "POST", path: string, body?: Record<string, unknown> ): Promise<T> { const url = `${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`; const res = await fetch(url, { method, headers: { "X-API-Key": this.apiKey, "Content-Type": "application/json", "User-Agent": "markitup-mcp-server/0.1.0", }, body: body ? JSON.stringify(body) : undefined, }); const text = await res.text(); let parsed: unknown; try { parsed = text ? JSON.parse(text) : {}; } catch { parsed = { error: text }; } if (!res.ok) { const errorMessage = (parsed as { error?: string }).error ?? `HTTP ${res.status}`; throw new MarkItUpApiError( humanizeError(res.status, errorMessage), res.status, codeForStatus(res.status) ); } const wrapper = parsed as { data?: T }; return (wrapper.data ?? parsed) as T; } }