{"name":"io.github.maginaryai/maginary-mcp","slug":"maginaryai-maginary-mcp","title":null,"description":"AI image + video generation for agents: --flag prompt DSL, async generate/poll, x402 pay-per-use.","url":"https://mcp.market/server/maginaryai-maginary-mcp","rating":null,"grade":"B","score":83,"certified":false,"status":"active","category":"ai","tags":["ai","media"],"presence":{"score":41,"stars":1,"forks":0,"downloads_week":1177,"last_push_at":"2026-09-15T15:48:24.000Z","license":"MIT"},"uptime":{"percent":100,"checks":2,"ok":2,"last_checked_at":"2026-09-19T23:31:12.259Z","last_ok_at":"2026-09-19T23:31:12.259Z","latency_ms":477},"claimed":false,"transport":"mixed","callable_via_gateway":true,"default_price_micros":0,"repository":"https://github.com/maginaryai/maginary-mcp","website":"https://maginary.ai/mcp","version":"0.3.18","remotes":[{"type":"streamable-http","url":"https://mcp.maginary.ai/mcp"}],"packages":[{"registryType":"pypi","registryBaseUrl":"https://pypi.org","identifier":"maginary-mcp","version":"0.3.18","runtimeHint":"uvx","transport":{"type":"stdio"},"environmentVariables":[{"description":"Bearer token from https://app.maginary.ai/dashboard#api-keys. Optional: without it the server offers in-chat signup (create_account) or wallet signup (create_wallet_account); catalog tools always work.","isSecret":true,"name":"MAGINARY_API_KEY"}]}],"tools":[{"name":"check_account_status","description":"Check account verification status, credit balance, and API key count.\n\n    Use this after ``create_account`` to poll whether the user has clicked the\n    verification link. Pass ``email`` + ``password`` (from ``create_account``)\n    for Basic auth, or omit both to use the configured API key.\n\n    Args:\n        email: Account email (for Basic auth).\n        password: Account password (for Basic auth).\n\n    Returns:\n        Dict with ``verified`` (bool), ``email``, ``api_key_count``,\n        ``credits_remaining``, ``uploads_remaining``.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"email":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Account email (for Basic auth). Omit to use API key.","title":"Email"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Account password (for Basic auth).","title":"Password"}},"title":"check_account_statusArguments"}},{"name":"checkout","description":"Create a Stripe checkout session for purchasing a product.\n\n    Returns a ``checkout_url`` — the user must open it in a browser to\n    complete payment. After payment, credits are provisioned automatically\n    via webhook. **Present the URL exactly as returned, including the\n    ``#fragment`` — do not truncate, reformat, or strip any part of it.**\n\n    If the agent has a USDC wallet, skip this entirely — just call\n    ``generate`` and the x402 protocol handles payment on-chain.\n\n    Args:\n        product_id: Product ID from ``get_products``.\n        email: Account email (for Basic auth during onboarding).\n        password: Account password (for Basic auth during onboarding).\n\n    Returns:\n        Dict with ``checkout_url``. On failure, an ``isError`` result — e.g.\n        ``error: \"email_not_verified\"`` until the user clicks the\n        verification link, or ``\"auth\"`` / ``\"failed\"``.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"product_id":{"description":"Product ID from get_products.","title":"Product Id","type":"integer"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Account email (for Basic auth during onboarding).","title":"Email"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Account password (for Basic auth).","title":"Password"}},"required":["product_id"],"title":"checkoutArguments"}},{"name":"configure_api_key","description":"Activate an API key. Local (stdio) servers persist it; hosted does not.\n\n    Call this after ``manage_api_key(action='create')`` returns a ``raw_key``.\n    On a local server the key is saved to ``~/.config/maginary/api_key``\n    (chmod 600) and survives restarts. On the hosted server\n    (mcp.maginary.ai) nothing can be stored — auth is per-request: the\n    response will say ``persisted: false`` and the key must be sent as an\n    ``Authorization: Bearer <key>`` header on every request (set it in the\n    MCP client's connection config).\n\n    Args:\n        api_key: The full API key string returned by ``manage_api_key``.\n\n    Returns:\n        Confirmation dict.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"api_key":{"description":"Full API key string from manage_api_key.","title":"Api Key","type":"string"}},"required":["api_key"],"title":"configure_api_keyArguments"}},{"name":"create_account","description":"Create a new Maginary account for the given email address.\n\n    Returns the auto-generated password — display it to the user ONCE so they\n    can save it. A verification email is sent; the user must click the link\n    before the account can generate images.\n\n    After verification, use ``manage_api_key(action='create')`` with\n    ``email`` + ``password`` to get an API key, then ``configure_api_key``\n    to activate it.\n\n    Args:\n        email: The user's email address.\n\n    Returns:\n        Dict with ``email``, ``password``, and ``message``. On failure, an\n        ``isError`` result — e.g. ``error: \"already_exists\"`` (email taken:\n        ask the user for their password or a different email),\n        ``\"rate_limited\"``, or ``\"failed\"``.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"email":{"description":"Email address for the new account.","title":"Email","type":"string"}},"required":["email"],"title":"create_accountArguments"}},{"name":"create_wallet_account","description":"Create (or access) a Maginary account using a wallet signature.\n\n    Sign the message ``Maginary: authenticate <address> at <timestamp>.\n    This does not move funds.`` with EIP-191 ``personal_sign`` and pass all\n    three values. On success, an API key is returned immediately — no email\n    verification needed.\n\n    Use this when you have a wallet but no email. The returned ``api_key``\n    should be passed as ``Authorization: Bearer <key>`` in the MCP client\n    config, or via ``configure_api_key`` (stdio) / ``_meta[\"maginary/api_key\"]``\n    (hosted, per-call).\n\n    If the wallet already has an account, returns the existing account with\n    a fresh API key.\n\n    Args:\n        address: EVM wallet address (0x..., 42 chars).\n        signature: Hex-encoded EIP-191 personal_sign of the auth message.\n        timestamp: Unix epoch seconds used in the signed message (must be\n            within the last 5 minutes).\n\n    Returns:\n        Dict with ``address``, ``api_key`` (full key — show once),\n        ``key_prefix``, ``created`` (bool), ``message``.\n        On failure: ``isError`` with ``error`` = ``\"validation\"``,\n        ``\"signature_failed\"``, or ``\"rate_limited\"``.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"address":{"description":"EVM wallet address (0x..., 42 chars).","title":"Address","type":"string"},"signature":{"description":"Hex EIP-191 personal_sign of the auth message.","title":"Signature","type":"string"},"timestamp":{"description":"Unix epoch seconds used in the signed message.","title":"Timestamp","type":"integer"}},"required":["address","signature","timestamp"],"title":"create_wallet_accountArguments"}},{"name":"execute_action","description":"Run a follow-up action on a completed generation's image.\n\n    After ``generate`` → ``wait_for_generation``, the response's\n    ``processing_result.available_actions`` lists what's possible per slot.\n    Call this tool with one of those action types.\n\n    Args:\n        generation_uuid: UUID of the parent generation (from ``generate``).\n        action_type: One of the values from ``available_actions`` — e.g.\n            ``\"upscale_2x\"``, ``\"upscale_1_5x\"``, ``\"vary_strong\"``,\n            ``\"vary_subtle\"``, ``\"pan_left\"``, ``\"pan_right\"``,\n            ``\"pan_up\"``, ``\"pan_down\"``, ``\"zoom_out_2x\"``,\n            ``\"zoom_out_1_5x\"``, ``\"img2vid_basic\"``, ``\"reroll\"``.\n        parent_image_index: The slot index of the image to act on (0, 1,\n            2, or 3 for a 4-image grid). Required for per-slot actions;\n            omit for ``\"reroll\"`` (global action).\n        prompt: Optional replacement prompt. For ``vary_*`` you can steer\n            the variation with a new prompt; for ``img2vid_basic`` you can\n            describe the desired motion.\n        callback_url: Optional webhook URL (same as ``generate``).\n\n    Returns:\n        The newly created child generation record (same shape as\n        ``generate``'s return — poll it with ``wait_for_generation``).\n\n        On failure, same ``isError`` contract as ``generate``:\n        ``\"auth\"``, ``\"payment_required\"`` (with x402 challenge),\n        or ``\"failed\"``.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"generation_uuid":{"description":"UUID of the parent generation.","title":"Generation Uuid","type":"string"},"action_type":{"description":"Action from available_actions, e.g. upscale_2x, vary_strong, img2vid_basic, reroll.","title":"Action Type","type":"string"},"parent_image_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Slot index (0-3) of the image to act on. Omit for global actions like reroll.","title":"Parent Image Index"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Optional replacement prompt for vary/img2vid actions.","title":"Prompt"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"HTTPS webhook URL for done/failed notifications.","title":"Callback Url"}},"required":["generation_uuid","action_type"],"title":"execute_actionArguments"}},{"name":"generate","description":"Kick off a generation via POST /api/gens/.\n\n    Args:\n        prompt: The user's words, passed through as-is. Do NOT add flags the\n            user did not ask for — no ``--ar``, no ``--flagship``, no model\n            flags. Every extra flag costs credits; adding them unrequested is\n            wrong. Standard quality is the default and is cheap; ``--flagship``\n            is ~4× more expensive and must only be used when the user\n            explicitly asks for best quality.\n\n            If the user asks about quality or aspect ratio: ask them first\n            (standard vs flagship, landscape vs portrait) before generating.\n\n            Flags go at the END, only when the user asked:\n            ``--1``/``--2``/``--3``/``--4`` = image count (default 4),\n            ``--ar 16:9`` = aspect ratio, ``--flagship`` = best quality.\n            Unknown flag: call ``get_parameter(name)`` first — never guess.\n\n            Examples — user says \"a fox\": prompt is ``\"a fox\"``.\n            User says \"a fox, landscape, best quality\":\n            prompt is ``\"a fox --ar 16:9 --flagship\"``.\n\n            **Image-to-image (img2img):** Place one or more public image URLs\n            in the prompt, followed by editing instructions:\n            ``\"https://cdn.example.com/photo.webp reimagine as oil painting --ar 16:9\"``\n            The engine extracts URLs automatically and switches to img2img mode.\n            Multiple URLs trigger multi-input mode (compositing/combining).\n            Use ``upload_image`` first if images aren't already hosted.\n\n            **Image-to-video:** Place an image URL in the prompt AND add\n            ``--mp4`` plus video flags (``--5sec``, ``--1080p``). Or use\n            ``execute_action`` with ``action_type=\"img2vid_basic\"`` on a\n            completed generation's image.\n\n            **Style reference (--sref) is NOT img2img:** ``--sref <url>``\n            copies the visual *style* of a reference image (colors, mood,\n            composition) without using the image content as input. A bare URL\n            in the prompt edits the actual image; ``--sref`` transfers style.\n\n        callback_url: Optional HTTPS URL that will receive a webhook when the\n            generation reaches done / failed. See\n            https://maginary.ai/blog/webhooks-guide for signature verification.\n\n    Returns:\n        On success, the created generation record. Key fields: ``uuid`` (use\n        to poll), ``action_type``, ``processing_state``,\n        ``expected_output_count``.\n\n        On failure, an ``isError`` result instead (nothing is raised), with a\n        JSON body whose ``error`` field is one of:\n\n        - ``\"auth\"`` — no/invalid API key. Surface the message directly to\n          the human.\n        - ``\"payment_required\"`` — out of credits. The body carries\n          ``billing_url`` and top-level x402 fields (``accepts``,\n          ``resource``): either send the human to ``billing_url`` to top up,\n          or pay programmatically via x402 (settle ``accepts[0]`` with USDC\n          on Base and retry).\n        - ``\"demo_not_found\"`` — ``--demo`` prompt has no matching seeded\n          generation. ``available_demos`` lists valid prompts.\n        - ``\"failed\"`` — anything else (invalid prompt, rate limit, backend\n          or network error); see ``message``.\n\n        x402 over MCP: a ``payment_required`` result also carries the x402\n        fields at the top level (``accepts``, ``resource``); an x402-capable\n        client signs ``accepts[0]`` and calls this tool again with the payment\n        in ``_meta[\"x402/payment\"]``. The settled call returns the generation\n        with ``x402_receipt`` (and ``_meta[\"x402/payment-response\"]``); a\n        wallet's first settlement creates its account. Subsequent requests\n        use wallet-signed auth headers (X-Wallet-Address/Signature/Timestamp)\n        or pass an API key as ``_meta[\"maginary/api_key\"]``.\n\nEvery flag that exists, and its state: Flags, live (35): --ar, --output-count (--1/--2/--3/--4), --seed, --transparent, --sref, --sw, --png, --jpg, --webp, --svg, --2k, --4k, --upscale, --vary, --varysubtle, --varystrong, --panleft, --panright, --panup, --pandown, --zoomout, --mp4, --video-resolution (--480p/--540p/--720p/--1024p/--1080p/--2160p / --4k (4k, Seedance 2 Pro)/--480p24 / --480p24fps/--540p24 / --540p24fps/--720p24 / --720p24fps/--1024p30 / --1024p30fps/--1080p24 / --1080p24fps), --video-fps (--24fps/--30fps/--50fps/--60fps), --video-duration (--4s / --4sec/--5s / --5sec/--6s / --6sec/--8s / --8sec/--10s / --10sec/--12s / --12sec), --flagship, --sora, --soralite, --nanobananapro, --nb2, --gpt2, --gpt2high, --seedance2, --seedance2pro, --demo. Partial (4, only some models honour them): --no, --zoomout2x, --zoomoutexpand, --zoomoutexpand2x. Reserved (2, the parser rejects them): --cref, --cw. Any other --flag is rejected with `Unrecognized parameter`. Details: `get_parameter(name)`.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"prompt":{"description":"The user's words as-is, flags at the end. Do NOT add flags the user did not ask for.","title":"Prompt","type":"string"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"HTTPS webhook URL for done/failed notifications.","title":"Callback Url"}},"required":["prompt"],"title":"generateArguments"}},{"name":"get_balance","description":"Check remaining credits and uploads for the authenticated account.\n\n    Args:\n        email: Account email (for Basic auth).\n        password: Account password (for Basic auth).\n\n    Returns:\n        Dict with ``credits_remaining`` and ``uploads_remaining``.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"email":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Account email (for Basic auth).","title":"Email"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Account password (for Basic auth).","title":"Password"}},"title":"get_balanceArguments"}},{"name":"get_generation","description":"Fetch a generation by UUID (GET /api/gens/{uuid}/).\n\n    Args:\n        uuid: The UUID returned by ``generate``.\n\n    Returns:\n        The full generation record. If terminal, ``image_urls[]`` holds the\n        finished outputs and ``processing_result.slots[]`` the per-slot detail.\n        NOTE: a generation that failed server-side is a SUCCESSFUL tool call\n        returning ``processing_state: \"failed\"`` — always check the state,\n        never infer success from the absence of a tool error.\n\n        **Follow-up actions:** A completed generation's\n        ``processing_result.available_actions`` maps slot indices to valid\n        action types. E.g. ``{\"0\": [\"upscale_2x\", \"vary_strong\", ...],\n        \"global\": [\"reroll\"]}``. Use ``execute_action`` with the ``uuid``,\n        a chosen ``action_type``, and the ``parent_image_index`` (the slot\n        key as an int) to run an action.\n\n        Hosted: a key obtained mid-session may be passed as\n        ``_meta[\"maginary/api_key\"]``.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"uuid":{"description":"Generation UUID from generate or execute_action.","title":"Uuid","type":"string"}},"required":["uuid"],"title":"get_generationArguments"}},{"name":"get_parameter","description":"Return the full record for a single parameter (canonical name or alias).\n\n    Args:\n        name: Parameter name with or without leading ``--`` (e.g. ``ar``,\n            ``--ar``, ``aspect``). Case-insensitive.\n\n    Returns:\n        The parameter dict. Not-found is an ``isError`` result — surface it\n        rather than fabricating a param.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"name":{"description":"Parameter name with or without --, e.g. ar, --ar, aspect.","title":"Name","type":"string"}},"required":["name"],"title":"get_parameterArguments"}},{"name":"get_products","description":"List available Maginary products/plans with pricing.\n\n    No authentication required. Use this to present purchase options to the\n    user. The ``novice_pack`` ($10, 150 credits) is the recommended starting\n    point.\n\n    Returns:\n        Dict with ``count`` and ``products`` — each product carries ``id``,\n        ``short_name``, ``title``, ``description``, ``price_cents``,\n        ``credits``, ``uploads``, ``is_subscription``. (The backend sends a\n        bare array; it is wrapped here because FastMCP validates tool output\n        against the dict annotation and rejects a top-level list.)\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"title":"get_productsArguments"}},{"name":"list_parameters","description":"List Maginary prompt-DSL parameters.\n\n    Args:\n        category: Restrict to one category (e.g. ``composition``, ``video``,\n            ``model``, ``outpaint``). Call with no filters once — the response's\n            ``categories`` / ``statuses`` maps are the full taxonomy.\n        status: Restrict to one status (``live``, ``mostly-dead``,\n            ``unimplemented``).\n        include_reserved: When False (default) drop ``unimplemented``\n            (recognized-but-blocked) parameters from the result.\n\n    Returns:\n        A dict with ``count``, ``source`` (``live`` vs. ``bundled-snapshot``),\n        ``categories`` / ``statuses`` (the filter taxonomy), and ``parameters``\n        (the array of matching entries).\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"category":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Filter by category, e.g. composition, video, model, outpaint.","title":"Category"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Filter by status: live, mostly-dead, or unimplemented.","title":"Status"},"include_reserved":{"default":false,"description":"Include unimplemented (blocked) parameters.","title":"Include Reserved","type":"boolean"}},"title":"list_parametersArguments"}},{"name":"manage_api_key","description":"Create, list, or revoke Maginary API keys (up to 10 per account).\n\n    Auth: pass ``email`` + ``password`` for Basic auth (onboarding), or omit\n    both to use the configured API key (normal operation).\n\n    Args:\n        action: One of ``create``, ``list``, ``revoke``.\n        name: Key name (required for ``create``).\n        key_prefix: 8-char prefix of the key to revoke (required for ``revoke``).\n        email: Account email (for Basic auth).\n        password: Account password (for Basic auth).\n\n    Returns:\n        For ``create``: dict with ``raw_key`` (the full key — show once, then\n        use ``configure_api_key`` to activate it), ``key_prefix``, ``name``.\n        For ``list``: dict with ``keys`` array.\n        For ``revoke``: success/error message.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"action":{"description":"One of: create, list, revoke.","title":"Action","type":"string"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Key name (required for create).","title":"Name"},"key_prefix":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"8-char prefix of key to revoke (required for revoke).","title":"Key Prefix"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Account email (for Basic auth).","title":"Email"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Account password (for Basic auth).","title":"Password"}},"required":["action"],"title":"manage_api_keyArguments"}},{"name":"search_parameters","description":"Text-search over parameter names, aliases, descriptions, values, examples.\n\n    Args:\n        query: Substring match, case-insensitive.\n        category: Optional single-category restriction.\n        include_reserved: Whether to include ``unimplemented`` parameters.\n\n    Returns:\n        Dict with ``count``, ``source`` (``live`` vs. ``bundled-snapshot``),\n        and ``parameters`` (ordered as they appear in the catalog).\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"query":{"description":"Search term (case-insensitive substring match).","title":"Query","type":"string"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Filter by category, e.g. composition, video, model.","title":"Category"},"include_reserved":{"default":false,"description":"Include unimplemented (blocked) parameters.","title":"Include Reserved","type":"boolean"}},"required":["query"],"title":"search_parametersArguments"}},{"name":"upload_image","description":"Upload a local image and get a CDN URL for img2img or ``--sref``.\n\n    Only available on local (stdio) connections.  On hosted/remote\n    connections, place an existing image URL directly in the prompt.\n\n    Place the returned ``url`` in a ``generate`` prompt:\n    ``generate(\"https://cdn.maginary.ai/…/photo.webp reimagine as oil painting\")``\n\n    Args:\n        file_path: Path to an image file on disk (JPEG, PNG, WebP, HEIC).\n        filename: Original filename.  Inferred from ``file_path`` if omitted.\n\n    Returns:\n        Dict with ``url`` (the public CDN URL), ``exists`` (deduplicated),\n        ``credits_deducted``, and ``message``.\n    ","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"file_path":{"description":"Path to a local image (JPEG, PNG, WebP, HEIC).","title":"File Path","type":"string"},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Override filename. Inferred from file_path if omitted.","title":"Filename"}},"required":["file_path"],"title":"upload_imageArguments"}},{"name":"wait_for_generation","description":"Poll ``get_generation`` on a backoff until it reaches done / failed.\n\n    Args:\n        uuid: The UUID returned by ``generate``.\n        timeout_s: Return after this many seconds even if still running.\n            Default 45 stays under the 60 s per-call limit most MCP clients\n            enforce; a ``timeout`` result just means \"call again\". Only raise\n            it (e.g. for video) on clients you know allow long tool calls.\n\n    Returns:\n        The terminal generation record — which includes generations that\n        failed server-side: those are SUCCESSFUL tool calls returning\n        ``processing_state: \"failed\"`` with empty ``image_urls``, so always\n        check the state. On tool failure, an ``isError`` result whose\n        ``error`` field is ``\"timeout\"`` (``message`` names the last\n        observed state — the generation keeps running server-side and can be\n        re-fetched with ``get_generation`` later), ``\"auth\"``, or\n        ``\"failed\"``.\n\n        **Follow-up actions:** A ``done`` generation's\n        ``processing_result.available_actions`` maps slot indices to valid\n        action types — e.g. ``{\"0\": [\"upscale_2x\", \"vary_strong\",\n        \"pan_left\", \"zoom_out_2x\", \"img2vid_basic\", ...], \"global\":\n        [\"reroll\"]}``. Use ``execute_action`` with the ``uuid``, a chosen\n        ``action_type``, and the ``parent_image_index`` (the slot key as an\n        int) to run an action on a specific output image.\n    ","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"uuid":{"description":"Generation UUID to poll.","title":"Uuid","type":"string"},"timeout_s":{"default":45,"description":"Max seconds to wait before returning a timeout result.","title":"Timeout S","type":"number"}},"required":["uuid"],"title":"wait_for_generationArguments"}}],"scan":{"score":83,"grade":"B","scanned_at":"2026-09-19T19:49:05.723Z","report":{"scannerVersion":"0.1.5","scannedAt":"2026-09-19T19:49:05.614Z","components":{"code":{"score":25,"max":25,"notes":["15 source files scanned"]},"reliability":{"score":20,"max":20,"notes":["remote reachable in 663ms"]},"poisoning":{"score":13,"max":15,"notes":["16 tool descriptions checked"]},"auth":{"score":3,"max":15,"notes":["open endpoint exposes 6 write-action tools with no auth"]},"maintenance":{"score":15,"max":15,"notes":["last push 4 days ago"]},"identity":{"score":7,"max":10,"notes":["registry namespace matches repository owner"]}},"findings":[{"id":"auth.open-write","severity":"high","component":"auth","title":"Write-action tools reachable without authentication"},{"id":"poison.long-description","severity":"low","component":"poisoning","title":"Unusually long tool description (over 2,000 characters)","evidence":"tool generate: …Kick off a generation via POST /api/gens/. Args: prompt: The user's words, passed through as-is. Do NOT add flags the user did not ask for — no ``--ar``, no ``--flagship``, no model flags. Every extra flag costs credits; adding them unrequested is wrong. Standard quality is the default and is cheap; ``--flagship`` is ~4× more expensive and must only be used when the user explicitly asks for best quality. If the user asks about quality or aspect ratio: ask them first (standard vs flagship, landscape vs portrait) before generating. Flags go at the END, only when the user asked: ``--1``/``--2``/``--3``/``--4`` = image count (default 4), ``--ar 16:9`` = aspect ratio, ``--flagship`` = best quality. Unknown flag: call ``get_parameter(name)`` first — never guess. Examples — user says \"a fox\": prompt is ``\"a fox\"``. User says \"a fox, landscape, best quality\": prompt is ``\"a fox --ar 16:9 --flagship\"``. **Image-to-image (img2img):** Place one or more public image URLs in the prompt, followed by editing instructions: ``\"https://cdn.example.com/photo.webp reimagine as oil painting --ar 16:9\"`` The engine extracts URLs automatically and switches to img2img mode. Multiple URLs trigger multi-input mode (compositing/combining). Use ``upload_image`` first if images aren't already hosted. **Image-to-video:** Place an image URL in the prompt AND add ``--mp4`` plus video flags (``--5sec``, ``--1080p``). Or use ``execute_action`` with ``action_type=\"img2vid_basic\"`` on a completed generation's image. **Style reference (--sref) is NOT img2img:** ``--sref <url>`` copies the visual *style* of a reference image (colors, mood, composition) without using the image content as input. A bare URL in the prompt edits the actual image; ``--sref`` transfers style. callback_url: Optional HTTPS URL that will receive a webhook when the generation reaches done / failed. See https://maginary.ai/blog/webhooks-guide for signature verification. Returns: On success, the created generation record. Key fields: ``uuid`` (use to poll), ``action_type``, ``processing_state``, ``expected_output_count``. On failure, an ``isError`` result instead (nothing is raised), with a JSON body whose ``error`` field is one of: - ``\"auth\"`` — no/invalid API key. Surface the message directly to the human. - ``\"payment_required\"`` — out of credits. The body carries ``billing_url`` and top-level x402 fields (``accepts``, ``resource``): either send the human to ``billing_url`` to top up, or pay programmatically via x402 (settle ``accepts[0]`` with USDC on Base and retry). - ``\"demo_not_found\"`` — ``--demo`` prompt has no matching seeded generation. ``available_demos`` lists valid prompts. - ``\"failed\"`` — anything else (invalid prompt, rate limit, backend or network error); see ``message``. x402 over MCP: a ``payment_required`` result also carries the x402 fields at the top level (``accepts``, ``resource``); an x402-capable client signs ``accepts[0]`` and calls this tool again with the payment in ``_meta[\"x402/payment\"]``. The settled call returns the generation with ``x402_receipt`` (and ``_meta[\"x402/payment-response\"]``); a wallet's first settlement creates its account. Subsequent requests use wallet-signed auth headers (X-Wallet-Address/Signature/Timestamp) or pass an API key as ``_meta[\"maginary/api_key\"]``. Every flag that exists, and its state: Flags, live (35): --ar, --output-count (--1/--2/--3/--4), --seed, --transparent, --sref, --sw, --png, --jpg, --webp, --svg, --2k, --4k, --upscale, --vary, --varysubtle, --varystrong, --panleft, --panright, --panup, --pandown, --zoomout, --mp4, --video-resolution (--480p/--540p/--720p/--1024p/--1080p/--2160p / --4k (4k, Seedance 2 Pro)/--480p24 / --480p24fps/--540p24 / --540p24fps/--720p24 / --720p24fps/--1024p30 / --1024p30fps/--1080p24 / --1080p24fps), --video-fps (--24fps/--30fps/--50fps/--60fps), --video-duration (--4s / --4sec/--5s / --5sec/--6s / --6sec/--8s / --8sec/--10s / --10sec/--12s / --12sec), --flagship, --sora, --soralite, --nanobananapro, --nb2, --gpt2, --gpt2high, --seedance2, --seedance2pro, --demo. Partial (4, only some models honour them): --no, --zoomout2x, --zoomoutexpand, --zoomoutexpand2x. Reserved (2, the parser rejects them): --cref, --cw. Any other --flag is rejected with `Unrecognized parameter`. Details: `get_parameter(name)`.…"}],"inputs":{"probes":[{"url":"https://mcp.maginary.ai/mcp","reachable":true,"authRequired":false,"latencyMs":663,"serverInfo":{"name":"maginary","version":"1.30.0"}}],"packages":[{"registryType":"pypi","identifier":"maginary-mcp","version":"0.3.18","found":true,"license":"MIT","dependencyCount":5,"publishedAt":"2026-09-15T15:49:00.054048Z","repositoryUrl":"https://github.com/maginaryai/maginary-mcp"}],"repo":{"found":true,"owner":"maginaryai","repo":"maginary-mcp","archived":false,"pushedAt":"2026-09-15T15:48:24Z","stars":1,"forks":0,"openIssues":0,"ownerType":"Organization","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/325287092?v=4","ownerCreatedAt":"2026-09-05T13:16:34Z","license":"MIT"},"icon":{"url":"https://avatars.githubusercontent.com/u/325287092?v=4&s=128","source":"registry","width":128,"height":128},"presence":{"stars":1,"forks":0,"downloadsWeek":1177,"license":"MIT","lastPushAt":"2026-09-15T15:48:24.000Z","score":41}}}},"grade_history":[],"reviews":[]}