{"serverId":"mcp-registry/io.github.cnghockey/sats4ai","tools":[{"name":"analyze_image","fixed":{"name":"analyze_image","description":"Analyze and describe image content, answer visual questions, extract information from screenshots or photos. Uses Qwen VL — multimodal vision-language model with strong OCR, chart reading, and spatial reasoning. 21 sats per image. Pay per request with Bitcoin Lightning — no API key or signup needed. Requires create_payment with toolName='analyze_image'.","inputSchema":{"type":"object","required":["paymentId","prompt","imageBase64"],"properties":{"prompt":{"type":"string","description":"Question or analysis prompt for the image"},"modelId":{"type":"number","description":"Optional. Omit for default model."},"paymentId":{"type":"string","description":"Valid payment ID (must be paid)"},"imageBase64":{"type":"string","description":"Base64 encoded image to analyze. Single images only — for PDFs or multi-page document text use extract_document (a PDF sent here is treated as an image and may return a wrong/hallucinated result with no error)."}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":276,"tokensAfter":276},{"name":"check_job_status","fixed":{"name":"check_job_status","description":"Poll the status of an async job. Use this after calling any async tool (generate_video, animate_image, generate_3d_model, transcribe_audio, epub_to_audiobook, ai_call) that returns a requestId. Returns JSON: { status: 'IN_PROGRESS' | 'COMPLETED' | 'FAILED', requestId, jobType }. For epub-audiobook, also includes progress (0-100) and chapterProgress array. Poll every 5-10 seconds. When status is 'COMPLETED', call get_job_result to retrieve the output. When status is 'FAILED', the response include","inputSchema":{"type":"object","required":["requestId","jobType"],"properties":{"jobType":{"enum":["video","video-image","video-fal-standard","video-fal-pro","image-3d","transcription","transcribe-translate","translate-epub","epub-audiobook","ai-call"],"type":"string","description":"Must match the async tool: video=generate_video, video-image=animate_image, image-3d=generate_3d_model, transcription=transcribe_audio, epub-audiobook=epub_to_audiobook, ai-call=ai_call. video-fal-standard/video-fal-pro = the fallback jobType generate_video returns when the primary video model is at capacity."},"requestId":{"type":"string","description":"The requestId returned by the async tool (e.g., from generate_video, animate_image, generate_3d_model, transcribe_audio, epub_to_audiobook, ai_call)"}}},"annotations":{"idempotentHint":true,"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":372,"tokensAfter":372},{"name":"convert_file","fixed":{"name":"convert_file","description":"Convert files between 200+ formats: documents (PDF, DOCX, XLSX, HTML→PDF), images (PNG, JPG, WEBP, SVG), PDF first page to image (PDF→JPG, PDF→PNG), audio (MP3, WAV, FLAC), video (MP4, AVI, MOV). Industrial-grade conversion engine — preserves formatting and quality. Returns download URL. 100 sats. Pay per request with Bitcoin Lightning — no API key, no account, no subscription needed. Requires create_payment with toolName='convert_file'.","inputSchema":{"type":"object","required":["paymentId","extensionFrom","extensionTo"],"properties":{"fileUrl":{"type":"string","description":"Public URL to the file (provide this OR fileBase64)"},"paymentId":{"type":"string","description":"Valid payment ID (must be paid)"},"fileBase64":{"type":"string","description":"Base64-encoded file (provide this OR fileUrl)"},"extensionTo":{"type":"string","description":"Target format without dot (e.g., 'pdf', 'docx')"},"extensionFrom":{"type":"string","description":"Source format without dot (e.g., 'pdf', 'docx')"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":290,"tokensAfter":290},{"name":"convert_html_to_pdf","fixed":{"name":"convert_html_to_pdf","description":"Convert HTML or Markdown to a pixel-perfect PDF. Returns JSON: { url } — a temporary download URL (valid ~1 hour). Great for generating invoices, reports, receipts, or formatted documents programmatically. Supports full HTML/CSS including tables, images (base64 or URL), and inline styles. For Markdown input, set format='markdown'. 50 sats per conversion. Use convert_file instead for converting existing files between formats (e.g., DOCX→PDF). Pay per request with Bitcoin Lightning — no API key or","inputSchema":{"type":"object","required":["paymentId","html"],"properties":{"html":{"type":"string","description":"HTML or Markdown content to convert"},"format":{"enum":["html","markdown"],"type":"string","default":"html","description":"Input format (default: html)"},"paymentId":{"type":"string","description":"Valid payment ID (must be paid)"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":250,"tokensAfter":250},{"name":"create_cart","fixed":{"name":"create_cart","description":"Pay for 2 to 10 calls with ONE Lightning invoice, up to 2,000 sats in all. Each item is { toolName, ...the same inputs create_payment takes for that tool }. The server checks and prices EVERY item first: one bad item refuses the whole cart, with no invoice, and the error names the item by its index. Returns JSON: { cartId, lightningInvoice, totalSats, expiresAt, items: [{ index, toolName, paymentId, amountSats }] }. Pay the ONE invoice. Then call each item's tool with that item's own paymentId, ","inputSchema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"type":"object","required":["toolName"],"properties":{"text":{"type":"string","description":"For text_to_speech and translate_text: the exact text (priced per character, locked to the item)."},"prompt":{"type":"string","description":"For generate_text and translate_text: the exact text you will send (the price is its character count, locked to the item)."},"modelId":{"type":["number","string"],"description":"Optional. AI model id or name, as for create_payment."},"quantity":{"type":"number","description":"For extract_document and extract_receipt: the pages. Default 1."},"toolName":{"enum":["generate_text","translate_text","generate_image","edit_image","analyze_image","remove_background","upscale_image","restore_face","detect_nsfw","detect_objects","remove_object","colorize_image","deblur_image","estimate_depth","render_card","convert_file","merge_pdfs","convert_html_to_pdf","extract_document","extract_receipt","text_to_speech"],"type":"string","description":"The tool this item pays for."},"resolution":{"type":"string","description":"For image tools priced by size: the resolution, as for create_payment."},"fileContext":{"type":"string","description":"For generate_text: attached file text, if any (it is part of the price)."},"systemPrompt":{"type":"string","description":"For generate_text: the system prompt, if you use one (it is part of the price)."},"targetLanguage":{"type":"string","description":"For translate_text: the target language (it picks the engine and so the price)."}},"additionalProperties":true},"maxItems":10,"minItems":2,"description":"The calls to pay for. Each item is an object with toolName and the inputs create_payment takes for that tool (for example prompt for generate_text, text and targetLanguage for translate_text)."}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":670,"tokensAfter":670},{"name":"create_payment","fixed":{"name":"create_payment","description":"Create a Lightning invoice to pay for one AI service call. Returns JSON: { paymentId, invoice (BOLT11), amount (sats), expiresAt }. Each payment covers exactly one tool call — call this once per operation. Typical flow: list_models → create_payment → check_payment_status → call tool. The invoice expires in 10 minutes. Call list_models first to discover modelId values. modelId is optional — omit it to use the default (best) model. Some tools require extra params at payment time because pricing de","inputSchema":{"type":"object","required":["toolName"],"properties":{"ocr":{"type":"boolean","description":"For receive_fax: include the OCR text-extraction add-on (+200 sats). Must be set HERE at payment time — receive_fax refuses ocr=true at execution unless the charge covered it."},"mode":{"enum":["standard","pro"],"type":"string","description":"Legacy alias for generate_video: 'standard'→768p, 'pro'→2K. Prefer 'resolution'."},"text":{"type":"string","description":"Required for text_to_speech: the exact text to synthesize (price is per-character by tier, locked to payment)"},"prompt":{"type":"string","description":"Required for generate_text: the exact prompt (price calculated from char count, locked to payment)"},"message":{"type":"string","description":"Required for send_sms: message text (max 1544 chars; billed per SMS segment, so longer or accented messages cost more)"},"modelId":{"type":"number","description":"Optional. AI model ID from list_models. Omit for default (best) model."},"duration":{"type":"number","description":"Required for generate_video / animate_image: duration in seconds (5-15)"},"quantity":{"type":"number","description":"Units to pay for when the price scales: passes for boardingpass_wallet, pages for extract_document / extract_receipt / send_fax. Default 1 — under-counting is rejected at execution with the exact price to re-pay."},"toolName":{"type":"string","description":"Tool name to pay for (e.g., 'generate_text', 'generate_image', 'generate_video', 'send_sms', 'place_call')"},"resolution":{"enum":["768p","2K","480p","720p","1080p","1K","4K"],"type":"string","description":"768p (default) or 2K for generate_video / animate_image — priced by resolution × duration, native audio free; 2K is upscaled from a 768p render. 480p/720p/1080p are retired Seedance rungs, still accepted (480p/720p→768p, 1080p→2K). For edit_image: a flat 200 sats per edit, so resolution does not change the price."},"fileContext":{"type":"string","description":"For generate_text: include extracted file text if attaching a file (affects price)"},"phoneNumber":{"type":"string","description":"Required for send_sms and place_call: phone in E.164 format (e.g., +14155550100)"},"systemPrompt":{"type":"string","description":"For generate_text: include if using a custom system prompt (affects price)"},"characterCount":{"type":"number","description":"Required for epub_to_audiobook: total text characters in the book (price is per-character by voice tier, minimum 500 sats). Send the count, not the book — the file goes to epub_to_audiobook itself. Execution re-derives the price from the real file and rejects a short-pay with the exact amount to re-pay."},"generate_audio":{"type":"boolean","description":"Accepted and IGNORED — H3 audio is native and always on, at no extra cost. There is no way to request a silent render."},"durationMinutes":{"type":"number","description":"Minutes of audio/call. Required for place_call with audioUrl (1-30); for transcribe_audio / transcribe_translate it sets the per-minute price (10 sats/min) — declare your audio length (default 1). Audio longer than paid is rejected + refunded at execution."}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":1031,"tokensAfter":1031},{"name":"estimate_depth","fixed":{"name":"estimate_depth","description":"Estimate per-pixel depth from a single photo. Depth Anything V2 (NeurIPS 2024, 3.8M+ runs) returns BOTH the raw greyscale depth map — what a ControlNet, AR or 3D reconstruction pipeline consumes — and a colour visualization for humans. Structured geometry a vision LLM cannot produce. 5 sats per image, pay per request with Bitcoin Lightning — no API key or signup needed. Requires create_payment with toolName='estimate_depth'.","inputSchema":{"type":"object","required":["paymentId","imageBase64"],"properties":{"paymentId":{"type":"string","description":"Valid payment ID (must be paid)"},"model_size":{"enum":["Small","Base","Large"],"type":"string","description":"Model size — larger is more accurate, price is the same (default Large)"},"imageBase64":{"type":"string","description":"Base64-encoded image (PNG, JPEG, WEBP) or data URI"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":246,"tokensAfter":246},{"name":"merge_pdfs","fixed":{"name":"merge_pdfs","description":"Merge multiple PDF files into a single document. Preserves bookmarks, links, and formatting. Returns JSON: { url } — a temporary download URL (valid ~1 hour). Minimum 2 files, no maximum. Files are concatenated in array order. 100 sats per merge regardless of file count. Use convert_file instead if you need format conversion (e.g., DOCX→PDF). Pay per request with Bitcoin Lightning — no API key, no account needed. Requires create_payment with toolName='merge_pdfs'.","inputSchema":{"type":"object","required":["paymentId","files"],"properties":{"files":{"type":"array","items":{"type":"string"},"description":"Array of base64-encoded PDF files (minimum 2)"},"paymentId":{"type":"string","description":"Valid payment ID (must be paid)"}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":216,"tokensAfter":216},{"name":"remove_background","fixed":{"name":"remove_background","description":"Remove background from any image, returning transparent PNG. Uses BiRefNet (state-of-the-art, Papers with Code — Sm 0.901 on DIS5K). Handles hair, fur, glass, transparency, and complex edges. Stable endpoint — model upgrades automatically as SOTA evolves. 44 sats per image, pay per request with Bitcoin Lightning — no API key or signup needed. Requires create_payment with toolName='remove_background'.","inputSchema":{"type":"object","required":["paymentId","imageBase64"],"properties":{"paymentId":{"type":"string","description":"Valid payment ID (must be paid)"},"imageBase64":{"type":"string","description":"Base64-encoded image (PNG, JPEG, WEBP) or data URI"}}},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: true, idempotentHint: true (inferred from the name).","verify":true}],"tokensBefore":198,"tokensAfter":198},{"name":"remove_object","fixed":{"name":"remove_object","description":"Remove unwanted objects from images by describing what to remove — no mask needed. Combines Grounding DINO detection (ECCV 2024) with Bria Eraser inpainting. Just say 'person', 'car', or 'watermark' and the object is erased and filled convincingly. 130 sats per image, pay per request with Bitcoin Lightning — no API key or signup needed. Requires create_payment with toolName='remove_object'.","inputSchema":{"type":"object","required":["paymentId","imageBase64","query"],"properties":{"query":{"type":"string","description":"What to remove (e.g. 'person', 'car', 'watermark', 'text')"},"paymentId":{"type":"string","description":"Valid payment ID (must be paid)"},"imageBase64":{"type":"string","description":"Base64-encoded image (PNG, JPEG, WEBP) or data URI"},"box_threshold":{"type":"number","description":"Detection confidence threshold (0-1, default 0.25)"},"text_threshold":{"type":"number","description":"Text matching threshold (0-1, default 0.25)"}}},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: true, idempotentHint: true (inferred from the name).","verify":true}],"tokensBefore":279,"tokensAfter":279},{"name":"request_refund","fixed":{"name":"request_refund","description":"Open a MANUAL 48-hour refund review ticket for a service that FAILED (error, timeout, wrong output). Sends an email to the operator. DO NOT call this for unused-minute refunds on metered services (ai_call, voice_bridge) — those are returned automatically as an LNURL-withdraw link in the service's own response under `refund.lnurl_withdraw`, no manual ticket needed. If you call this on a metered payment that already has a pending LNURL refund, this tool will detect it and return the existing LNURL","inputSchema":{"type":"object","required":["paymentId","invoice"],"properties":{"email":{"type":"string","description":"Optional email address for follow-up"},"invoice":{"type":"string","description":"Lightning address (e.g., user@wallet.com) or bolt11 invoice for the refund"},"feedback":{"type":"string","description":"Optional description of what went wrong (max 2000 chars)"},"paymentId":{"type":"string","description":"The payment ID from a failed service call"}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":282,"tokensAfter":282}],"toolsChanged":11,"tokensSaved":0,"todo":[],"note":"Deterministic fixes. Changes marked verify need a human look before shipping (renames, inferred annotations, inferred types, removed text). Parameter descriptions in `todo` need to be written by someone who knows the API."}