Skip to main content
Glama

⚡ pixio-mcp ⚡

554+ generative models. One MCP server. Zero chances to nuke your credit balance.

Tests Python MCP Spend Safety License

Prompt in. File on disk. Four tool calls. Every model Pixio ships — the day it ships.


🔥 What is this

pixio-mcp hands any MCP client — Claude Desktop, Claude Code, or your own agent swarm — the entire Pixio media generation arsenal: text-to-image, image-to-video, text-to-video, video-to-video, lipsync, text-to-audio, and a stack of utility ops. All of it metered in credits, all of it behind guardrails that make it safe to hand the keys to a fully autonomous agent and walk away.

discover → inspect schema → price it → generate → poll → download. done. 💅

The cheat code: this server hardcodes zero model knowledge. Every parameter schema is pulled live from the API at call time. Pixio drops 50 new models tomorrow? They work here tomorrow. No update. No redeploy. No waiting on anybody.

Related MCP server: universal-image-mcp

🧨 Why it goes hard

The old way

The pixio-mcp way

Coverage

Hand-rolled HTTP for a handful of models

All 554+ models, discovery-driven

New models

Wait for someone to update the wrapper

Day-zero support, automatically

Spend control

Vibes 💸

Two hard caps + estimate-before-spend

Long video jobs

Hang or lose the job

Resumable ids — timeout ≠ dead job

Local files

Figure out uploads yourself

upload_mediapermanent public URL

Errors

A stack trace and a prayer

9-code machine-actionable taxonomy

Battle-tested: 121 offline tests, two full multi-agent validation rounds (security audit, adversarial review, live protocol checks), and a real end-to-end run — prompt → generated image → verified bytes on disk.

🚀 Quick start

You need: Python 3.11+, uv, and a Pixio API key (pxio_live_...).

git clone https://github.com/RealDealCPA-VR/Pixio-MCP.git
cd Pixio-MCP
uv sync
# PowerShell — fire it up (stdio transport; it waits for an MCP client)
$env:PIXIO_API_KEY = "pxio_live_..."
uv run pixio-mcp
# bash / zsh — same thing
export PIXIO_API_KEY="pxio_live_..."
uv run pixio-mcp

You'll almost never run it by hand — register it with your client (next section) and let your agent cook. 👨‍🍳 No key set? The server still boots (warning on stderr) and every tool politely returns an AUTH error until you feed it one.

🔌 Plug it in

🌍 Any MCP host

One JSON shape rules them all:

{
  "mcpServers": {
    "pixio": {
      "command": "uv",
      "args": ["run", "--directory", "<path-to-repo>", "pixio-mcp"],
      "env": { "PIXIO_API_KEY": "pxio_live_..." }
    }
  }
}

This exact block works in Claude Desktop, LM Studio (~/.lmstudio/mcp.json), Cursor (.cursor/mcp.json), Windsurf, Cline (cline_mcp_settings.json), and LibreChat (librechat.yaml, mcpServers section). Swap <path-to-repo> for wherever you cloned this — and once pixio-mcp hits PyPI, swap the whole command for "command": "uvx", "args": ["pixio-mcp"].

Claude Desktop

Drop the block above into %APPDATA%\Claude\claude_desktop_config.json (Windows) or ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) under mcpServers, restart Claude Desktop. Done.

Claude Code

One-liner. That's it. That's the setup.

# <path-to-repo> = your clone, e.g. C:\Users\you\projects\Pixio-MCP
claude mcp add pixio -e PIXIO_API_KEY=pxio_live_... -- uv run --directory <path-to-repo> pixio-mcp

# Published package
claude mcp add pixio -e PIXIO_API_KEY=pxio_live_... -- uvx pixio-mcp

Or drop the same JSON block into your project's .mcp.json.

Continue

In config.yaml, add a stdio entry under mcpServers:

mcpServers:
  - name: pixio
    command: uv
    args: ["run", "--directory", "<path-to-repo>", "pixio-mcp"]
    env:
      PIXIO_API_KEY: pxio_live_...

Zed

In settings.json, under context_servers:

{
  "context_servers": {
    "pixio": {
      "command": {
        "path": "uv",
        "args": ["run", "--directory", "<path-to-repo>", "pixio-mcp"],
        "env": { "PIXIO_API_KEY": "pxio_live_..." }
      }
    }
  }
}

Open WebUI

Open WebUI speaks OpenAPI, not MCP — bridge with mcpo:

export PIXIO_API_KEY="pxio_live_..."
uvx mcpo --port 8000 --api-key <secret> -- uvx pixio-mcp

Then add http://localhost:8000 as an OpenAPI tool server in Open WebUI (Settings → Tools), using <secret> as the bearer token.

🐍 Roll your own agent

No host at all? The vanilla mcp SDK gets you a working client in ~15 lines:

import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main() -> None:
    server = StdioServerParameters(
        command="uv",
        args=["run", "--directory", "<path-to-repo>", "pixio-mcp"],
        env={"PIXIO_API_KEY": "pxio_live_..."},
    )
    async with stdio_client(server) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            print([t.name for t in tools.tools])
            result = await session.call_tool("list_models", {"query": "flux", "limit": 5})
            print(result.content[0].text)

asyncio.run(main())

🏠 Built for local models too

This server isn't just tuned for frontier models — it's deliberately friendly to a 7B running on your laptop:

  • Self-describing schemas. Every tool parameter carries its own description in the MCP schema — small models don't have to guess what confirm or offset mean.

  • Lenient inputs. String numbers, string bools, params passed as a JSON string, backtick-wrapped ids — all quietly normalized instead of rejected. Local models fumble formats; the server doesn't punish them for it.

  • Compact by default. list_models returns 20 models per call unless you ask for more, and descriptions are truncated — a 554-model catalog never floods a small context window. Filter with type/query instead of paging.

  • HTTP transport built in. LM Studio, Ollama-backed hosts, or anything that prefers HTTP over stdio — see Transports below.

🎛️ Configuration

Everything tunes through env vars:

Env var

Required

Default

Purpose

PIXIO_API_KEY

yes

Bearer token (pxio_live_...). Never logged, never echoed. Ever.

PIXIO_BASE_URL

no

https://beta.pixio.myapps.ai/api/v1

Override if the API moves off beta. Trailing slash / missing /api/v1 normalized for you.

PIXIO_MAX_CREDITS_PER_JOB

no

60

Per-job credit cap. Estimates above this get refused without confirm=true.

PIXIO_SESSION_BUDGET

no

300

Cumulative credit ceiling per server process.

PIXIO_DEFAULT_TIMEOUT_S

no

180

Default wait for generate(wait=true) / wait_for_generation.

PIXIO_DOWNLOAD_DIR

no

~/pixio-outputs

Where download_output drops the goods.

PIXIO_LOG_LEVEL

no

INFO

Logs go to stderr as JSON lines (stdout carries the MCP protocol).

PIXIO_TRANSPORT

no

stdio

stdio, streamable-http, or sse. See Transports.

PIXIO_HOST

no

127.0.0.1

Bind address for the HTTP transports.

PIXIO_PORT

no

8000

Bind port for the HTTP transports.

Fat-finger an integer (PIXIO_SESSION_BUDGET=lots)? The server refuses to boot — one clean stderr line naming the exact variable, no traceback. No silent misconfigs.

🚦 Transports

Default is stdio — the classic spawn-me-as-a-subprocess mode every desktop host uses. For hosts that talk HTTP instead (web UIs, remote agents, LM Studio-style local stacks), flip one env var:

export PIXIO_TRANSPORT=streamable-http   # or "sse" for legacy SSE hosts
uv run pixio-mcp                          # serves on http://127.0.0.1:8000

⚠️ SECURITY: this server holds a spending API key. Anyone who can reach the port can burn your credits. Keep it bound to 127.0.0.1 (the default) — if you must expose it beyond localhost via PIXIO_HOST, put it behind a reverse proxy with auth, a firewall rule, or a VPN. Never bind 0.0.0.0 on an untrusted network.

🧰 The toolkit — 9 tools, full lifecycle

Tool

What it does

Key inputs

list_models

Filterable catalog of all 554+ models (cached 10 min). Id, name, type, per-run credits, company, description.

type (exact, e.g. "text-to-image"), query (substring), limit (1–200, default 20), offset

get_model_params

The exact live input schema for one model — names, types, required flags, defaults, allowed options. Verbatim API passthrough.

model_id

estimate_cost

Price the job before a single credit moves. Falls back to catalog cost if the estimate endpoint flakes.

model_id, params

upload_media

Local file or remote URL → permanent public Pixio URL (pixiomedia.nyc3.digitaloceanspaces.com).

source

generate

The main event: rejects local paths, estimates, enforces caps, submits, waits for the result.

model_id, params, wait=true, timeout_s, confirm=false

get_generation

One-shot status + output URLs.

generation_id

wait_for_generation

Poll to succeeded/failed or timeout. Resumes jobs that outlived a generate timeout.

generation_id, timeout_s

download_output

Every output file of a succeeded job → your disk. Returns absolute paths.

generation_id, dest_dir

get_credits

Balance breakdown (total, recurring, permanent) + optional spend ledger tail.

include_ledger_tail, ledger_limit

Every tool returns clean JSON. Failures come back as structured error dicts (see taxonomy) — tools never throw raw exceptions at your agent.

🎯 The three-call contract

The server ships knowing nothing about any model. Your LLM discovers everything at runtime:

  1. list_models — find the weapon 🎯

  2. get_model_params — read the manual 📖

  3. generate — send it 🚀

Add download_output and a text prompt becomes a file on your machine in four calls flat:

>>> list_models(type="text-to-image", query="flux")
{
  "models": [
    {"id": "pixio/flux-1/schnell", "name": "FLUX.1 Schnell", "type": "text-to-image",
     "credits": 1, "company": "Black Forest Labs", "description": "Fast text-to-image..."},
    ...
  ],
  "total_matching": 6, "returned": 6, "offset": 0
}

>>> get_model_params(model_id="pixio/flux-1/schnell")
{
  "model": {"id": "pixio/flux-1/schnell", ...},
  "params": [
    {"name": "prompt", "type": "string", "label": "Prompt", "required": true, "defaultValue": ""},
    {"name": "image_size", "type": "select", "label": "Image size", "required": false,
     "defaultValue": "landscape_4_3",
     "options": [{"value": "square_hd", "label": "Square HD"},
                 {"value": "landscape_4_3", "label": "Landscape 4:3"}, ...]}
  ]
}

>>> generate(model_id="pixio/flux-1/schnell",
             params={"prompt": "a crimson arc reactor on black velvet, studio lighting",
                     "image_size": "square_hd"})
{
  "generation_id": "b7e2f9c1-4a06-4d2e-9c1e-0f3a7d5e8b21",
  "status": "succeeded",
  "output_urls": ["https://pixiomedia.nyc3.digitaloceanspaces.com/outputs/...png?X-Amz-Expires=3600&..."],
  "outputs": {"imageUrl": "https://pixiomedia.nyc3.digitaloceanspaces.com/outputs/...png?..."},
  "model_id": "pixio/flux-1/schnell",
  "credits_spent": 1,
  "remaining_balance": 999,
  "elapsed_s": 6.4,
  "error": null
}

>>> download_output(generation_id="b7e2f9c1-4a06-4d2e-9c1e-0f3a7d5e8b21")
{
  "generation_id": "b7e2f9c1-4a06-4d2e-9c1e-0f3a7d5e8b21",
  "files": ["~/pixio-outputs/b7e2f9c1-0.png"],
  "dest_dir": "~/pixio-outputs"
}

Models that eat media (image-to-video, lipsync, ...)? upload_media first, pass the returned URL in params. generate is URLs-only and swats local paths before a single credit is spent.

🛡️ Spend safety (the flex)

This is the part that lets you point an autonomous agent at a credit balance and sleep at night. All guardrails are server-side and on by default:

  • 💰 Estimate before spend. Every job is priced first (estimate endpoint, catalog fallback). Nothing submits until the price is known — or explicitly flagged unknown via a warning.

  • 🧱 Per-job cap (PIXIO_MAX_CREDITS_PER_JOB, default 60). One job over the line → BUDGET_EXCEEDED. Denied.

  • 🏦 Session budget (PIXIO_SESSION_BUDGET, default 300). Cumulative ceiling for the whole server process. The meter never lies.

  • 🔑 Explicit override only. A refusal tells you the estimate, which cap tripped, and the cap value — and only a re-call with confirm=true gets through. The server never overrides itself.

  • 📊 Balance on every receipt. Every terminal result reports credits_spent + remaining_balance. Spend drift has nowhere to hide.

  • 🚫 Zero auto-retry on submission. POST /generate fires exactly once — a network blip can never double-spend you. (Reads and estimates retry 3x, because those are free.)

🚨 Error taxonomy

Failed tool calls return {"error": {"code": ..., "message": ..., "details": {...}}}. Nine codes, all machine-actionable:

⚠️ Telling failures apart from successes: successful job results also carry an error key — it's the provider's failure reason, null on success (see the generate example above). Don't test "error" in result; test whether result["error"] is a dict with a code (failure envelope) vs null/string (job-result field).

Code

Meaning

Your move

AUTH

401, or PIXIO_API_KEY missing/empty.

Set a valid pxio_live_... key in the server's env, restart the client.

INSUFFICIENT_CREDITS

402 — balance can't cover the job. details has availableCredits, requiredCredits, shortfall when the API provides them.

Top up, or pick a cheaper model (list_models shows per-run credits).

VALIDATION

Bad/missing param — or a local file path in generate params. Message surfaces the API's error body verbatim (e.g. Missing required parameter: X) or names the offending field.

Re-read get_model_params, fix the payload. Local paths → upload_media first.

BUDGET_EXCEEDED

The server's own guardrail said no (per-job cap or session budget). Nothing was spent.

If the estimate's acceptable, re-call with confirm=true — or raise the caps via env.

CONCURRENCY

429 — account's in-flight limit reached. details carries concurrencyLimit when reported.

Wait for in-flight jobs (wait_for_generation on their ids), then resubmit. Don't hammer.

GENERATION_FAILED

Terminal failed status. details.provider_reason has the provider's reason string.

Read the reason, adjust, submit fresh (a retry spends credits again).

TIMEOUT_PENDING

Wait window elapsed but the job is still cooking — not cancelled. details has generation_id + a hint.

wait_for_generation(generation_id) to resume; the job finishes server-side either way.

NOT_FOUND

404 — unknown model or generation id.

Check the id; discover real ones via list_models.

UPSTREAM_ERROR

5xx, network failure, or unparseable response.

Retry later — GETs/estimates already retried 3x with backoff before this surfaced.

💀 Gotchas (learned so you don't have to)

Hard-won quirks of the live Pixio gateway. The server stays schema-agnostic and does not enforce these — your agent must respect them:

  • Select values are strings. Send options[].value exactly as given. "5", not 5. Even when it looks numeric. Especially when it looks numeric.

  • "Optional" is sometimes a lie. Some optional-with-default params get rejected when omitted. First attempt: send every param from get_model_params at its defaultValue.

  • Output URLs can die in ~1 hour. outputUrl may be signed with a short fuse. download_output promptly; never stash URLs for later. (upload_media URLs are the exception — permanent and public.)

  • Concurrency is account-wide. 1 in-flight by default, 3 on Maker — across all your API keys. Parallel fan-outs will eat CONCURRENCY errors; serialize your jobs.

  • There is no cancel button. Once submitted, a job runs to the end; DELETE /generations/{id} isn't a thing. A TIMEOUT_PENDING job keeps holding a concurrency slot until it finishes — budget timeout_s accordingly and resume, don't resubmit.

  • No list-generations endpoint. The generation_id from every submission is the only handle you get. Guard it with your life.

🧪 Development

uv sync
uv run pytest

121 tests, fully offline — a mocked Pixio gateway, no API key, no network, zero credits harmed. 🌱

📜 License

MIT — go build something loud.

Built for agents. Guarded like a vault. Fresh models on day zero.

Available Tools

9 tools
download_outputA

Download every output file of a succeeded generation to a local directory.

Call this after generate(wait=true) or wait_for_generation reports status succeeded. Output URLs may be signed and expire (~1 hour), so download promptly. If the generation is still processing this returns a VALIDATION error — call wait_for_generation(generation_id) first and retry once it succeeds. Any non-succeeded status (including failed) returns a VALIDATION error stating the current status; for a failed generation the provider's reason is included in the details.

Args: generation_id: The id returned by generate. dest_dir: Target directory, created if missing (~ is expanded). Defaults to the server's configured download directory (PIXIO_DOWNLOAD_DIR, default ~/pixio-outputs).

Returns: {"generation_id": str, "files": [absolute file paths], "dest_dir": str} — files are named {generation_id[:8]}-{index}{ext} (id prefix sanitized to filesystem-safe characters) with the extension inferred from each URL or the downloaded content.

ParametersJSON Schema
NameRequiredDescriptionDefault
dest_dirNo
generation_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

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

No annotations provided, so description carries full burden. It discloses that output URLs may be signed and expire, behavior for error states (processing vs failed), that dest_dir is created if missing, ~ expansion, default directory, and file naming convention. Comprehensive behavioral disclosure.

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?

Description is multi-paragraph but well-structured: starts with main purpose, then usage instructions, then parameter details, then return value. Every sentence provides value. No fluff.

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

Completeness5/5

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

Given output schema exists (context: true), description explains return format with example and file naming convention. It also provides enough context for an agent to use correctly with siblings. Complete for this tool's complexity.

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

Parameters5/5

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

Schema describes parameters but without descriptions (coverage 0%). Description adds critical meaning: generation_id is 'id returned by generate', dest_dir is 'Target directory, created if missing (~ expanded), defaults to server's configured download directory'. Fully compensates for lack of schema descriptions.

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 the tool downloads every output file of a succeeded generation. It specifies the verb 'download', resource 'output files', and context 'after generation succeeds', distinguishing it from siblings like generate, wait_for_generation, etc.

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?

Explicitly states when to use: after generate(wait=true) or wait_for_generation reports succeeded. Provides warnings about URL expiration (~1 hour) and explains error conditions (VALIDATION error if processing, failed status with details). Gives clear guidance on when not to use and what alternatives to use (wait_for_generation).

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

estimate_costA

Estimate the credit cost of a generation BEFORE spending anything.

Call this after get_model_params and before generate (the three-call contract is list_models -> get_model_params -> generate; this tool is the recommended pre-flight between steps 2 and 3). Costs come from the gateway estimate endpoint when available ("source": "estimate"), else from the catalog-listed per-generation cost ("source": "catalog"), else the cost is reported as unknown.

Args: model_id: Catalog model id, e.g. "pixio/flux-1/schnell". params: The exact params object you intend to pass to generate(), built from the get_model_params response.

Returns: {"model_id": str, "estimated_credits": int | null, "source": "estimate" | "catalog" | "unknown"}, plus a "warning" string only when the cost could not be determined ("estimated_credits" is null and "source" is "unknown").

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes
model_idYes

TDQS

A4.6/5.0
Behavior4/5

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

No annotations provided, so description carries full burden. Details cost determination logic, return structure, and warning conditions. Lacks some side-effect info, but as a read-only estimation tool, this is sufficient.

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

Conciseness4/5

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

Well-structured with paragraphs and bullet points. Front-loaded with purpose. Every sentence adds value, though slightly verbose in cost source enumeration.

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

Completeness5/5

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

Given no output schema and low schema coverage, description thoroughly explains return format, three cost sources, and warning conditions. Covers workflow context and parameter details completely.

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

Parameters4/5

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

Schema coverage is 0%, but description provides clear explanations: model_id with example, params as the intended generate object. This adds significant meaning beyond the bare schema.

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?

Clearly states the tool estimates credit cost before spending. Positions it in a workflow between get_model_params and generate, distinguishing it from siblings like generate and list_models.

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?

Explicitly says to call after get_model_params and before generate, referencing the three-call contract. Explains cost source hierarchy (estimate > catalog > unknown) and when warning appears.

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

generateA

Run a media generation job on Pixio, with spend guardrails.

This is the final step of the 3-call discovery contract: list_models -> get_model_params -> generate. Build params from the live get_model_params(model_id) response — this server embeds no model schemas. On a first attempt send EVERY param the schema lists, at its default value (some params marked optional are actually required by the gateway), and send select-option values as STRINGS (e.g. "5", not 5).

URLs-only contract: every media input inside params must be an http(s) or data: URL. Any value that looks like a local filesystem path (~, ./, ../, file://, X:\, UNC \\, or an existing file) is rejected with a VALIDATION error naming the offending field(s) — before any credits are spent. Call upload_media first and pass the permanent URL it returns.

Spend guardrails: the job cost is estimated up front and refused with BUDGET_EXCEEDED if it exceeds the per-job cap or would exceed the session budget — no credits are spent on a refusal. Pass confirm=true to explicitly override both caps for this one job.

Waiting: with wait=true (default) this call polls until the job is terminal or timeout_s elapses (default: PIXIO_DEFAULT_TIMEOUT_S, 180s). On timeout you get a TIMEOUT_PENDING error whose details carry the generation_id — the job KEEPS RUNNING server-side; resume with wait_for_generation(generation_id). With wait=false the call returns immediately (status "processing", plus estimated_credits); check later with get_generation or wait_for_generation.

Output URLs may be signed and expire after roughly an hour — call download_output(generation_id) promptly.

Args: model_id: Pixio model id, e.g. "pixio/flux-1/schnell". params: Generation inputs built from get_model_params (URLs only for media fields). wait: Poll to completion (True, default) or return immediately. timeout_s: Max seconds to wait when wait=true; None uses the server default. confirm: Set True to override the per-job and session credit caps.

Returns: On success: {"generation_id", "status", "output_urls", "outputs", "model_id", "credits_spent", "remaining_balance", "elapsed_s", "error"}. With wait=false: the same shape with status "processing", credits_spent None, and estimated_credits added. On failure: {"error": {"code", "message", "details"}} with code VALIDATION, BUDGET_EXCEEDED, INSUFFICIENT_CREDITS, CONCURRENCY, GENERATION_FAILED, TIMEOUT_PENDING, NOT_FOUND, AUTH, or UPSTREAM_ERROR. NOTE: success results also contain an "error" key (the provider reason, null on success) — a call failed only when result["error"] is a dict carrying a "code".

ParametersJSON Schema
NameRequiredDescriptionDefault
waitNo
paramsYes
confirmNo
model_idYes
timeout_sNo

TDQS

A4.9/5.0
Behavior5/5

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

Despite no annotations, the description thoroughly discloses behavioral traits: spend guardrails (BUDGET_EXCEEDED), URL-only input requirement, validation errors, waiting/polling mechanisms, timeout handling, output URL expiration, and error codes. No contradictions with annotations since none exist.

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

Conciseness4/5

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

The description is well-structured with a summary, step-by-step instructions, parameter details, and return format. While it's fairly long, every sentence adds value given the tool's complexity. A slight reduction could improve conciseness, but it remains efficient.

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

Completeness5/5

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

Given the tool's complexity (5 parameters, nested objects, no output schema), the description is remarkably complete. It explains return values for success and failure, all possible error codes, and the behavior of wait=true/false, leaving no major gaps.

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

Parameters5/5

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

Schema description coverage is 0%, but the description compensates fully with an 'Args:' section explaining each parameter's purpose, defaults, and constraints. For 'params', it provides critical context about building from get_model_params and URL-only media fields, which the schema lacks.

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 that the tool runs a media generation job on Pixio with spend guardrails. It distinguishes itself from siblings by being the final step of a 3-call discovery contract (list_models -> get_model_params -> generate), making its purpose very specific.

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?

The description explicitly explains when to use the tool (as the final step of the discovery contract) and provides alternatives for waiting behavior (e.g., using wait_for_generation if timeout occurs). It also gives detailed instructions on how to build params from get_model_params and URL requirements.

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

get_creditsA

Report the Pixio account's current credit balance.

Use to check affordability before a job or to audit spend after one. Every terminal generate / wait_for_generation result already includes "remaining_balance", so this tool is mainly for standalone balance checks and recent-spend review.

Args: include_ledger_tail: When true, also return the most recent credit ledger entries (spend and top-up history). ledger_limit: Maximum ledger entries to include (default 10; only used when include_ledger_tail is true; negative values are treated as 0).

Returns: {"total": , "recurring": {"current", "quota", "lastTopOffAt"}, "permanent": }, plus "ledger_tail": [{"id", "reason", "deltaRecurring", "deltaPermanent", "sourceId", "createdAt"}, ...] when include_ledger_tail is true.

ParametersJSON Schema
NameRequiredDescriptionDefault
ledger_limitNo
include_ledger_tailNo

TDQS

A5/5.0
Behavior5/5

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

With no annotations provided, the description fully discloses behavior: it returns a detailed JSON structure, explains the effect of arguments, and specifies how ledger_limit handles negative values. No contradictions present.

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?

The description is well-organized with a summary, usage context, args, and returns sections. Every sentence adds value without redundancy, achieving efficiency and clarity.

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

Completeness5/5

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

For a tool with two optional parameters and no output schema, the description covers all necessary aspects: purpose, usage, parameters, and return format. It is fully complete.

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

Parameters5/5

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

Schema has 0% description coverage, but the description thoroughly explains both parameters: include_ledger_tail triggers ledger entries, ledger_limit controls count with default 10 and negative treated as 0.

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 'Report the Pixio account's current credit balance' and distinguishes the tool from siblings like 'estimate_cost' and mentions that other generation tools include 'remaining_balance', making its unique purpose evident.

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?

Explicitly provides when to use (check affordability before a job, audit spend after) and when not to use (since generation results already include remaining_balance), with clear alternatives.

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

get_generationA

Fetch the current status and outputs of one generation (no polling).

A single GET /generations/{id} snapshot. Use this to check on a job started with generate(wait=false) or after a TIMEOUT_PENDING; use wait_for_generation instead if you want to block until it finishes.

Statuses: "processing" -> "succeeded" | "failed". remaining_balance is only fetched (best-effort) once the job is terminal; while processing it is None, as is credits_spent.

Args: generation_id: Id returned by generate.

Returns: {"generation_id", "status", "output_urls", "outputs", "model_id", "credits_spent", "remaining_balance", "elapsed_s", "error"} — error carries the provider reason when status is "failed". On failure: {"error": {"code", "message", "details"}} (e.g. NOT_FOUND for an unknown id).

ParametersJSON Schema
NameRequiredDescriptionDefault
generation_idYes

TDQS

A4.9/5.0
Behavior5/5

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

Despite no annotations, description discloses that remaining_balance is best-effort and None while processing, explains error structure, and notes it's a snapshot. Fully transparent.

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?

Concise but complete. Every sentence adds value, front-loaded with purpose. Structured with use case, status info, args, returns.

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

Completeness5/5

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

No output schema, but description provides detailed return fields including error structure. For a single-param tool, it's fully complete.

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

Parameters4/5

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

Only one parameter, and the description adds meaning by stating that generation_id is the Id returned by generate, which is beyond the schema's minimal 'Generation Id'.

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 the tool fetches status and outputs of a generation (snapshot). It uses specific verb 'Fetch' and resource 'generation', and distinguishes from sibling 'wait_for_generation' by stating no polling.

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?

Explicitly says when to use this tool (check on job with wait=false or after timeout) and when to use alternative (wait_for_generation for blocking). Also explains status progression.

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

get_model_paramsA

Fetch the exact input schema for one Pixio model.

Step 2 of the three-call contract: list_models -> get_model_params -> generate. Build the params object for generate() strictly from this response — the server embeds no per-model knowledge.

Critical gotchas when building params for generate():

  • For select-type params the allowed values are options[].value (there is no ".values" array). Send select values as STRINGS even when they look numeric — e.g. "5", not 5.

  • Some params marked optional-with-default are still required by the gateway. On your first attempt send EVERY listed param, using each param's defaultValue where you have no better value.

Args: model_id: Catalog model id from list_models, e.g. "pixio/flux-1/schnell".

Returns: The gateway /params response verbatim: {"model": {...}, "params": [{"name", "type", "label", "required", "defaultValue", "placeholder"?, "options"?: [{"value", "label"}]}, ...]}. An unknown model id yields a NOT_FOUND error dict.

ParametersJSON Schema
NameRequiredDescriptionDefault
model_idYes

TDQS

A4.4/5.0
Behavior4/5

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

No annotations provided, so description carries full burden. It describes the return format verbatim, gotchas about select-type params and optional-with-default params, and error condition. It does not mention destructive actions or auth, but as a read-only fetch, that is implied.

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

Conciseness4/5

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

The description is well-structured with overview, step context, gotchas, args, and returns. It is slightly verbose but each sentence adds value given the need to explain gotchas and contract.

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

Completeness5/5

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

Given no output schema, the description provides return structure. One param is well explained. The tool is part of a sequence, and the description explains its role fully. No missing critical information.

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

Parameters4/5

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

Only one parameter (model_id) with 0% schema description coverage. The description adds meaning: 'Catalog model id from list_models, e.g. "pixio/flux-1/schnell".' This provides useful context beyond the schema.

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 'Fetch the exact input schema for one Pixio model' and positions it as step 2 of a three-call contract (list_models -> get_model_params -> generate). This distinguishes it from siblings like list_models and generate.

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

Usage Guidelines4/5

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

The description explicitly says 'Step 2 of the three-call contract' and provides critical gotchas for building params for generate(). It does not explicitly state when not to use it, but the contract implies its specific role. It also mentions error behavior for unknown model_id.

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

list_modelsA

Browse the Pixio model catalog (550+ models) with optional filters.

Step 1 of the three-call contract for running any generation:

  1. list_models — find a model id (filter by type and/or query).

  2. get_model_params(model_id) — fetch that model's exact input schema.

  3. generate(model_id, params) — run the job.

Args: type: Exact model type to match, e.g. "text-to-image", "image-to-image", "image-to-video", "text-to-video", "video-to-video", "text-to-audio". query: Case-insensitive substring matched against each model's id, name, and description (e.g. "flux", "background removal"). limit: Maximum number of models to return; clamped to 1..200 (default 50). offset: Number of matching models to skip, for pagination (negative values are treated as 0).

Returns: {"models": [{"id", "name", "type", "credits", "company", "description"}, ...], "total_matching": , "returned": <len of "models">, "offset": }. "credits" is the catalog-listed cost per generation; descriptions are truncated to 200 characters. The catalog is cached for ~10 minutes.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNo
limitNo
queryNo
offsetNo

TDQS

A5/5.0
Behavior5/5

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

Discloses caching behavior (~10 minutes), truncation of descriptions to 200 characters, clamping on limit parameter, and handling of negative offset. Provides detailed return structure without contradicting any annotations (none provided).

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?

Well-structured: summary sentence, contract overview, bulleted Args, Returns section. Every sentence adds value without unnecessary verbosity. Ideal length for an AI agent.

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

Completeness5/5

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

Comprehensive for a tool with 4 parameters, no output schema, and no annotations. Covers parameter constraints, return format, caching, and positions within the tool ecosystem (sibling tools). No gaps.

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

Parameters5/5

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

Despite 0% schema description coverage, the description thoroughly explains each parameter: type examples, query as case-insensitive substring matching with examples, limit clamped to 1-200 with default 50, offset with negative handling. Adds significant meaning beyond the bare schema.

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 the tool browses the Pixio model catalog with optional filters. It identifies the resource and action, and distinguishes itself from siblings by being step 1 of a three-call contract.

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?

Explicitly describes the three-call contract for running generations, positioning list_models as the first step to find a model ID. Provides clear when-to-use guidance with alternatives (get_model_params and generate) listed.

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

upload_mediaA

Upload a local file or mirror a remote URL to Pixio, returning a permanent public media URL.

Use this before generate whenever a model parameter needs media (image_url, video_url, audio_url, ...): generate accepts http(s) URLs only and rejects local filesystem paths. The returned url (hosted on pixiomedia.nyc3.digitaloceanspaces.com) is permanent and publicly readable, and is exactly what generate's media params (e.g. image_url) expect — pass it through verbatim.

Args: source: An http(s) URL (mirrored server-side into Pixio storage) or a local file path (~ is expanded; uploaded as multipart). Directories are rejected.

Returns: {"url": str, "source_kind": "local_file" | "remote_url", "file_name": str, "size_bytes": int | None}size_bytes is None for remote URLs (the file never transits this machine).

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

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

No annotations provided, so description fully handles transparency. Discloses behavior: source can be URL (mirrored) or local file (uploaded with ~ expansion), directories rejected, returns a detailed dict. Notes that size_bytes is None for remote URLs.

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?

Well-structured: brief intro, usage context, then clearly formatted Args and Returns sections. Every sentence is informative and earns its place.

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

Completeness5/5

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

With one parameter and an output schema present, the description fully covers what the tool does, when to use it, input details, and output structure. No gaps.

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

Parameters5/5

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

Schema coverage is 0%, so description must compensate. It thoroughly explains the 'source' parameter: accepts http(s) URL or local file path, with ~ expansion, and that directories are rejected. Adds significant value beyond the schema's minimal type info.

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 the tool's purpose: uploading a local file or mirroring a remote URL to Pixio for a permanent public media URL. It distinguishes itself by explaining why it's necessary before the 'generate' tool, which only accepts http(s) URLs.

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?

Explicitly states to use this tool before 'generate' when media parameters like image_url, video_url, audio_url are needed. Provides clear context on what it returns and how to pass the result to generate.

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

wait_for_generationA

Block until a generation reaches a terminal status, or time out.

Resumes waiting on any in-flight job — most usefully after generate returned TIMEOUT_PENDING, or for a job started with wait=false. Polls with backoff (2s growing to a 10s cap, jittered) until the job is "succeeded" or "failed", or until timeout_s elapses (default: PIXIO_DEFAULT_TIMEOUT_S, 180s). Budget actuals are reconciled from the job's real creditsCost when it completes.

On timeout the TIMEOUT_PENDING error again carries the generation_id — the job keeps running server-side and this tool can be called as many times as needed.

Args: generation_id: Id returned by generate. timeout_s: Max seconds to wait; None uses the server default.

Returns: On success the job-result shape: {"generation_id", "status", "output_urls", "outputs", "model_id", "credits_spent", "remaining_balance", "elapsed_s", "error"}. On failure: {"error": {"code", "message", "details"}} with code GENERATION_FAILED (details include the provider reason), TIMEOUT_PENDING (details include generation_id and a resume hint), NOT_FOUND, AUTH, or UPSTREAM_ERROR.

ParametersJSON Schema
NameRequiredDescriptionDefault
timeout_sNo
generation_idYes

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations provided, the description fully covers behavioral traits: polling with backoff (2s to 10s jittered), timeout handling, credit reconciliation, and return shapes on success and failure. No contradictions.

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?

The description is well-organized into logical sections (purpose, usage, behavior, Args, Returns) with no unnecessary words. Every sentence provides value.

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

Completeness5/5

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

Given the tool's complexity (polling, timeout, error handling), the description covers return types, error codes, and usage patterns comprehensively. No output schema exists, but the description includes the return shape.

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

Parameters5/5

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

Schema description coverage is 0%, but the description's 'Args' section adds clear meaning: 'generation_id' is the ID from 'generate', and 'timeout_s' is max wait with server default. This fully compensates for missing schema descriptions.

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 'Block until a generation reaches a terminal status, or time out,' providing a specific verb and resource. It distinguishes from siblings by mentioning its use after 'generate' returns TIMEOUT_PENDING or for jobs with 'wait=false'.

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

Usage Guidelines4/5

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

The description explicitly notes when to use the tool (after TIMEOUT_PENDING or wait=false) and explains that it can be called multiple times on timeout. However, it does not explicitly contrast with alternatives like 'get_generation' for non-blocking scenarios.

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

TDQS

A4.7/5.0
Disambiguation5/5

Each tool targets a distinct action (listing, param fetching, cost estimation, generation, status polling, download, upload, credit checking) with no overlap. The descriptions clearly differentiate their purposes.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case (e.g., list_models, get_model_params, upload_media). No mixing of conventions.

Tool Count5/5

With 9 tools covering the full generation workflow (discovery, parameter retrieval, cost estimation, run, status, download, upload, credits), the count is well-scoped and each tool serves a necessary role.

Completeness4/5

The tool surface covers the essential lifecycle: list, params, estimate, generate, poll, download, upload, and credit check. A minor gap is the absence of cancel or delete operations, but these are not critical for the core use case.

Maintenance

ActivitySlowing
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

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/RealDealCPA-VR/Pixio-MCP'

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