fal
This server ("The Orange Box") gives any MCP client full access to fal.ai's 600+ generative AI models, with built-in job management, budget controls, persistent project tracking, and a learning loop.
Run models: Execute any fal.ai model (image, video, audio, text) synchronously (
fal_run_model) or submit slow jobs to an async queue (fal_submit_request).Manage async jobs: Check status, fetch results, or cancel queued requests.
One-call shortcuts: Generate and save media in a single call (
fal_generate_and_save), or submit a slow job and wait for completion with automatic download (fal_wait_for_result).Discover models: Search/browse the 600+ model catalog and fetch any model's exact OpenAPI input/output schema before calling it.
Handle media input: Base64-encode local files as data URIs or upload larger files to fal's CDN for a public URL.
Save outputs: Download result media to a local directory with auto-versioned filenames.
Generate audio by kind: Produce speech, music, or SFX — the server routes to the best model automatically.
Match reference images: Analyze a reference image to suggest the optimal model and prompt for recreating the look (still or video).
Learning loop: Record winner/loser verdicts to improve future model recommendations (
fal_pick_winner).Budget controls: Set daily/monthly spend caps checked before each generation, blocking or warning when limits would be exceeded, with a local run log for auditing costs.
Persistent projects: Organize multi-shot work into named projects that survive session restarts, tracking render state per shot.
Brand resources: Expose local brand documents as read-only MCP resources to bake branding into generation prompts.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fal run fal-ai/flux/dev with prompt 'sunset over mountains'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
The Orange Box
A Model Context Protocol server that puts the full power of fal.ai inside any MCP client — and remembers what you did there.
A tool by Tech with Xavier.
Most generative tooling is stateless. It spends your money, hands you a file, and forgets you — so you end up being the memory. The Orange Box keeps the thread: it prices the work before it runs it, holds a project's shots across sessions, learns which models you actually keep choosing, and refuses the render that would blow your budget.
Free. No gate, no email. Download and setup guide: techwithxavier.com/tools/fal-mcp
fal.ai is a generative-media powerhouse — 600+ image, video, audio, and text models (FLUX, Kontext, Veo, Kling, Suno-style audio, and more) served on some of the fastest inference infrastructure in the industry. This server hands that entire catalog to an MCP client (Claude Code, Claude Desktop, Cursor, etc.) through a small, clean set of tools: run any model by id, manage the async job queue, browse and search the model catalog, and inspect a model's exact input schema before calling it.
Why fal.ai
Breadth that's hard to beat. One API key unlocks 600+ production models across every generative modality — no per-vendor integrations, no juggling SDKs.
Built for speed. fal's inference stack is engineered for low-latency generation, so fast models return in seconds and heavy jobs stream through a robust async queue.
Always current. New state-of-the-art models land on fal continuously — pointing this server at a new
model_idis all it takes to use them.Schema-first, no guesswork. Every model publishes an OpenAPI schema, so
fal_get_model_schemalets your agent discover exact inputs and defaults instead of guessing.Agent-friendly by design. A predictable REST surface and a clean queue model make fal a natural fit for autonomous, multi-step generative workflows.
This MCP server is a thin, faithful bridge to that platform — it stays out of the way and lets fal.ai shine.
Related MCP server: Fal.ai MCP Server
Tools
Tool | Purpose |
| Run a model synchronously and block for the result (best for fast models, <2 min) |
| Submit a job to the async queue and get a |
| Poll a queued request's status ( |
| Fetch the final output of a completed queued request |
| Cancel a request that's still |
| Search/browse the fal.ai model catalog to find the right model id |
| Fetch a model's OpenAPI schema — exact input fields, types, defaults |
| Locally base64-encode a file so it can be passed as an |
| Upload a local file to fal.ai CDN storage and get a hosted URL (preferred over data URIs for anything big) |
| Download result media URLs to a local directory with versioned filenames ( |
| Scan a reference image with a cheap vision model and get the best model + prompt to reproduce that look as a still or a video shot; optional cost-gated compare mode generates candidates on the top 2 models |
| Record which model won/failed a comparison — future recommendations reorder around your verdicts (learning loop) |
| Run a model, download all media with versioned filenames, and log the run — one call |
| Local spend dashboard: estimated spend, runs by model, failure rate, recent entries (today/week/month/all) |
| Daily/monthly spend caps, checked before each generation — stops the next expensive render instead of explaining it afterwards |
| Submit a slow job, poll to completion with backoff, and download the media — one call instead of submit → status → status → result → save |
| Voiceover, music, or sound effects by kind — the router picks the model, runs it, and saves the file |
| Open or create a shot project (a spot, a sequence, a board) and make it active |
| Create or update one shot — description, model, request id, status, notes, files |
| List every shot, and with |
Brand resources
Markdown files in brand/ (or $FAL_BRAND_DIR) are exposed as read-only MCP resources at fal://brand/<name> — clients pull real brand tokens (colors, type, layout, mascot) into any generation. fal_match_reference can also bake them into its recreation prompt via enhance_prompt=true, brand="mx7".
Budget
fal_get_run_log tells you what you spent. fal_budget stops you spending it:
fal_budget(daily_usd=20) # cap today at $20
fal_budget() # status, headroom, projection
fal_budget(enforce="warn") # annotate instead of refusing
fal_budget(clear=true) # back to tracking-onlyOnce a cap is set it's checked before every generation — fal_run_model, fal_submit_request, fal_generate_and_save, fal_wait_for_result, fal_generate_audio, and fal_match_reference compare mode. A call that would cross the line is refused before it reaches the network:
Blocked by budget. Would exceed daily cap $5.00 — spent ~$4.800, this call adds ~$3.024.Deliberate behaviours:
Setting a cap defaults to
block. A budget you can silently blow past is just a dashboard.Resuming a wait is never blocked.
fal_wait_for_result(request_id=...)skips the check — the money is already committed, and a cap must not strand a render you've paid for.An unpriced model isn't treated as free. If the cap is already breached, a call with no price estimate is still refused; if there's headroom it proceeds with an explicit warning that tracked spend understates reality.
submitandresultare never double-counted for the same queued job.todayis the local calendar day, not a rolling 24h — and the projection stays quiet until two hours in, so one early render doesn't extrapolate to a fake emergency.
Caps live in $FAL_BUDGET_FILE (else ~/.fal-mcp/budget.json), or pin one without any state via $FAL_DAILY_BUDGET_USD / $FAL_MONTHLY_BUDGET_USD.
Shot projects — surviving the session
A multi-shot piece is the unit of work that actually spans sessions, and a request_id living only in chat context dies with that context. Projects persist shot state to disk instead:
fal_project_open(name="jackal-intro", dir="C:/.../boards/jackal")
fal_wait_for_result(model_id="fal-ai/kling-video/v2.5-turbo/pro/image-to-video",
arguments={...}, shot="SH-03")fal_wait_for_result records the request_id against the shot before it starts waiting. So if the wait budget runs out, or the session ends mid-render, nothing is lost:
fal_shot_list(refresh=true)polls fal for every shot still outstanding, downloads whatever finished into the project dir, and marks it done. That's the answer to "what was still rendering when I closed the laptop?"
Shot ids sort naturally (SH-2 before SH-10), and fal_shot_list rolls up status counts plus estimated spend on completed shots only — queued work isn't counted as money spent.
State lives in $FAL_PROJECT_DIR (else ~/.fal-mcp/projects/).
Audio
fal_generate_audio takes a kind rather than a model id:
kind | final | draft |
| ElevenLabs v3 | Kokoro (fast scratch VO for timing) |
| ElevenLabs Music | MiniMax Music |
| ElevenLabs SFX v2 | CassetteAI |
Override per-kind with $FAL_SPEECH_MODEL / $FAL_MUSIC_MODEL / $FAL_SFX_MODEL, or pass model_id directly. Alternates are suggested for an A/B, and verdicts are scoped under audio:<kind>.
Video routing
fal_match_reference routes video as a first-class target, not just stills. Pass target="video" and the reference is treated as a start frame, routing image-to-video models instead of image models:
fal_match_reference(image_path="boards/SH-03_hero-walking.png", target="video",
goal="slow push in, coat moves in the wind", duration_seconds=5)Routing axes beyond the style profile:
Flag | Effect |
| Routes reference-to-video models — conditions on the character still, not just frame one, so a look holds across a multi-shot sequence |
| Routes first-last-frame conditioning to lock both the in and the out of a shot |
| Routes models that generate native dialogue/sound (and bills at the higher audio rate) |
| Surfaces the cheapest credible motion first for blocking and timing before the hero render |
| Drives per-second cost estimates |
Video compare mode submits to the queue rather than running synchronously — video renders run for minutes and would time out — and hands back request_ids to poll.
Learning loop
Verdicts accumulate in ~/.fal-mcp/learning.jsonl (override: $FAL_LEARN_LOG), and fal_match_reference reorders its recommendations by your record per style medium. Two kinds of signal feed it:
Explicit —
fal_pick_winnerrecords a win, loss, or outright failure. Failure memory is the rarest and most valuable: it's how the router learns which models can't do a look.Implicit — saving output to disk is counted automatically as a half-weight vote.
fal_save_resultmatches the downloaded URL back through the run log to the model that produced it, so no extra arguments are needed;fal_generate_and_savealready knows its own model. Nobody saves the loser, so the router keeps tuning even when you never stop to record a verdict.
Video verdicts are scoped under their own video:<medium> key, so animating a photo never reorders your still-image routing.
Cost estimates & run log
fal_run_model/fal_submit_requestresponses include a rough cost estimate for common models. Image models are priced per call; video models are priced per second of output and read the requested clip length out of your arguments (duration,duration_seconds, orseconds), falling back to an explicitly-labelled 5s assumption. This matters: a 10s Seedance 2.0 clip is ~$3.02, not pennies.Where a model's real rate varies with resolution or audio (Veo 3.1 ranges $0.20–$0.60/sec), the estimate is the cheapest tier and says so. Unknown models return no estimate rather than a guess — including in compare mode, which names them instead of silently substituting a default.
Every run/submit/upload/save is appended to a JSONL log — one line per event with timestamp, model, prompt (clipped), media URLs, duration, and estimated cost — so you can audit spend with a simple grep.
Log location:
FAL_RUN_LOGenv var if set, else~/.fal-mcp/runs.jsonl.Transient fal errors (5xx / network) are retried automatically with backoff; 4xx and timeouts are not.
Setup
Get an API key from fal.ai/dashboard/keys.
Clone and build the server:
git clone https://github.com/MalcolmXavier7/orange-box.git cd orange-box npm install npm run buildAdd it to your MCP client config (e.g. Claude Code's
.mcp.jsonor Claude Desktop's config), pointing atdist/index.jsand settingFAL_KEY:{ "mcpServers": { "fal": { "command": "node", "args": ["/absolute/path/to/orange-box/dist/index.js"], "env": { "FAL_KEY": "your-fal-api-key" } } } }
Typical workflows
Quick image generation:
fal_run_model(model_id="fal-ai/flux/dev", arguments={"prompt": "a sunset over mountains"})Not sure what a model accepts?
fal_get_model_schema(model_id="fal-ai/flux-pro/kontext")Slow model (video) — fire and check back later:
fal_submit_request(model_id="fal-ai/minimax/video-01", arguments={"prompt": "a rocket launch"})
-> fal_check_status(model_id=..., request_id=...)
-> fal_get_result(model_id=..., request_id=...) # once COMPLETEDUsing a local image as input:
fal_encode_file_as_data_uri(file_path="/path/to/photo.jpg")
-> pass the returned data: URI as image_url in fal_run_model / fal_submit_requestFind a model for a task:
fal_list_models(query="background removal")Notes
Base64 data URIs work directly as file inputs anywhere fal expects a URL —
fal_encode_file_as_data_urihandles this locally (no fal upload API call needed). For files already hosted publicly, just pass the URL directly.fal_run_modelhas a 5-minute timeout; anything slower should go throughfal_submit_request.All tools support
response_format: "json"for structured output or"markdown"(default) for readability.
What else is in here
Path | What it is |
| How to talk to it. Direction over orders — the habits that decide whether a session lands or drifts. |
| End-to-end run through a real piece. |
| The operator agent. Drop it in |
| Local run dashboard — every generation with its model, duration, cost, and prompt. |
| Markdown brand docs, exposed as read-only MCP resources at |
| QA pairs for the schema tool. |
Evaluation
evaluation.xml contains 10 read-only QA pairs testing fal_get_model_schema against known model defaults. Run with the harness described in the mcp-builder skill's evaluation guide. Since fal.ai model schemas can change as models are updated, spot-check these against the live API before relying on them.
Available Tools
8 toolsfal_cancel_requestCancel fal.ai Queue RequestADestructiveIdempotent
Cancel a queued request before it finishes processing. Only works while status is IN_QUEUE — requests already IN_PROGRESS or COMPLETED cannot be cancelled and this will return an error.
Args:
model_id (string): The same model id used when submitting, e.g. "fal-ai/minimax/video-01"
request_id (string): The request_id returned by fal_submit_request
Returns: A confirmation message once the cancellation is accepted.
Examples:
Use when: "Actually, cancel that video job I just started" -> cancel while still IN_QUEUE
Don't use when: the job is already IN_PROGRESS or COMPLETED (use fal_check_status to confirm first)
Error Handling:
Returns "Not found (404)" if the request_id is wrong
Returns an error if the request already started processing or completed (cannot be cancelled)
Inputs: model_id (required), request_id (required).
fal_check_statusCheck fal.ai Queue Request StatusARead-onlyIdempotent
Check the status of a request previously submitted with fal_submit_request. Does NOT return the final output — once status is COMPLETED, call fal_get_result to fetch it.
Args:
model_id (string): The same model id used when submitting, e.g. "fal-ai/minimax/video-01"
request_id (string): The request_id returned by fal_submit_request
include_logs (boolean): Include runner logs (default: false)
response_format ('markdown' | 'json'): Output format (default: markdown)
Returns: Status object with fields: { "status": "IN_QUEUE" | "IN_PROGRESS" | "COMPLETED", "request_id": string, "queue_position": number, // present while IN_QUEUE "logs": array | null // present if include_logs=true }
Examples:
Use when: "Is my video ready yet?" -> check status, then fal_get_result if COMPLETED
Don't use when: you haven't submitted a request yet — use fal_submit_request first
Don't use when: you want the actual output — use fal_get_result after status is COMPLETED
Error Handling:
Returns "Not found (404)" if the request_id is wrong or the request has expired
Returns "Authentication failed" if FAL_KEY is missing or invalid
Inputs: model_id (required), request_id (required), include_logs, response_format.
fal_encode_file_as_data_uriEncode Local File as Data URIARead-onlyIdempotent
Reads a local file and returns it as a base64 data: URI that can be passed directly into fal model arguments (e.g. as an image_url field) wherever a hosted file URL is expected. fal's API accepts base64 data URIs anywhere it accepts a file URL — no separate upload step is required.
This is a local, offline operation — it does not contact fal.ai or any network service.
Args:
file_path (string): Absolute path to a local file (e.g. an image to use in an image-to-image model)
Returns: A data: URI string, e.g. "data:image/png;base64,iVBORw0KG...". Use this string directly as the value of an image_url (or similar) field in fal_run_model / fal_submit_request arguments.
Examples:
Use when: "Use this local screenshot as input for the kontext model" -> encode it, then pass the result as image_url
Don't use when: the file is already hosted at a public URL — just pass that URL directly
Don't use when: the file is very large (>10MB) — large data URIs slow down requests; host the file publicly instead
Error Handling:
Returns "File not found" if the path doesn't exist
Returns "File too large" if the file exceeds 15MB (data URI overhead makes this impractical)
Inputs: file_path (required).
fal_get_model_schemaGet fal.ai Model Input/Output SchemaARead-onlyIdempotent
Fetch the OpenAPI schema for a specific fal.ai model, showing exactly which input fields it accepts (names, types, defaults, enums) and what its output looks like. Call this before fal_run_model or fal_submit_request whenever you're unsure of a model's required arguments.
Args:
model_id (string): The fal.ai model id, e.g. "fal-ai/flux-pro/kontext"
response_format ('markdown' | 'json'): Output format (default: markdown)
Returns: For JSON format: the raw OpenAPI document for that model endpoint. For markdown format: a summary of the request/response schemas.
Examples:
Use when: "What parameters does fal-ai/flux-pro/kontext take?" -> model_id="fal-ai/flux-pro/kontext"
Use when: you got a 422 error from fal_run_model and need to see the correct field names
Don't use when: you already know the model's arguments from prior use
Error Handling:
Returns "Not found (404)" if the model_id doesn't exist
Returns "Authentication failed" if FAL_KEY is missing or invalid
Inputs: model_id (required), response_format.
fal_get_resultGet fal.ai Queue Request ResultARead-onlyIdempotent
Fetch the final output of a queued request submitted with fal_submit_request. Only call this once fal_check_status reports status COMPLETED — calling it earlier will error.
Args:
model_id (string): The same model id used when submitting, e.g. "fal-ai/minimax/video-01"
request_id (string): The request_id returned by fal_submit_request
response_format ('markdown' | 'json'): Output format (default: markdown)
Returns: The model's result payload (structure is model-specific — images/video/audio/text). For JSON format: the complete raw result object. For markdown format: a summary with any generated media URLs surfaced up top.
Examples:
Use when: fal_check_status just reported "COMPLETED" for this request_id
Don't use when: status is still IN_QUEUE or IN_PROGRESS — check status again instead
Error Handling:
Returns "Not found (404)" if the request_id is wrong, expired, or not yet completed
Returns "Authentication failed" if FAL_KEY is missing or invalid
Inputs: model_id (required), request_id (required), response_format.
fal_list_modelsSearch fal.ai Model CatalogARead-onlyIdempotent
Search or browse fal.ai's catalog of 600+ hosted models to find the right model id for a task. Does NOT run any model — this is discovery only.
Args:
query (string, optional): Keyword search, e.g. "flux", "upscale", "text to speech"
category (string, optional): Category filter, e.g. "text-to-image", "image-to-video"
limit (number): Maximum results to return, 1-100 (default: 20)
cursor (string, optional): Pagination cursor from a previous response's next_cursor
response_format ('markdown' | 'json'): Output format (default: markdown)
Returns: For JSON format: { "count": number, "models": [ { "endpoint_id": string, "title": string, "category": string, "short_description": string } ], "has_more": boolean, "next_cursor": string | null } For markdown format: a readable list of matching models with their ids.
Examples:
Use when: "What model should I use to generate a video?" -> query="video" or category="text-to-video"
Use when: "Find a background removal model" -> query="background removal"
Don't use when: you already know the exact model_id — go straight to fal_run_model or fal_submit_request
Error Handling:
Returns "No models found matching ''" if the search returns empty
Returns "Authentication failed" if FAL_KEY is missing or invalid
Inputs: limit, query, cursor, category, +1 more.
fal_run_modelRun fal.ai Model (Synchronous)A
Run a fal.ai model and block until the result is ready. Best for fast models (a few seconds up to ~2 minutes) like most image generation, image editing, and short text/audio models.
This does NOT use the queue — there is no request_id to check later. For slow models (video generation, training jobs) or when you want to fire off a job and check back later, use fal_submit_request instead.
Args:
model_id (string): The fal.ai model id, e.g. "fal-ai/flux/dev"
arguments (object): Model-specific input, e.g. { "prompt": "a cat astronaut" }
response_format ('markdown' | 'json'): Output format (default: markdown)
Returns: The model's result payload (structure is model-specific — images/video/audio/text). For JSON format: the complete raw result object. For markdown format: a summary with any generated media URLs surfaced up top.
Examples:
Use when: "Generate an image of a sunset" -> model_id="fal-ai/flux/dev", arguments={"prompt": "a sunset over mountains"}
Use when: "Edit this image to add snow" -> model_id="fal-ai/flux-pro/kontext", arguments={"prompt": "add snow", "image_url": "https://..."}
Don't use when: the model is slow (video, training) — use fal_submit_request instead
Don't use when: you don't know the model's required fields — call fal_get_model_schema first
Error Handling:
Returns "Authentication failed" if FAL_KEY is missing or invalid
Returns "Invalid input (422)" if arguments don't match the model's schema — check fal_get_model_schema
Returns "Request timed out" if the model takes longer than 5 minutes — use fal_submit_request instead
Inputs: model_id (required), arguments (required), response_format.
fal_submit_requestSubmit fal.ai Request to QueueA
Submit a job to fal.ai's async queue and return immediately with a request_id. Use this for slow models (video generation, training jobs) or whenever you don't want to block waiting for a result.
After submitting, use fal_check_status to poll progress and fal_get_result once status is COMPLETED. This does NOT wait for or return the final result — see fal_run_model if you want a single blocking call instead.
Args:
model_id (string): The fal.ai model id, e.g. "fal-ai/minimax/video-01"
arguments (object): Model-specific input, e.g. { "prompt": "a cat astronaut" }
webhook_url (string, optional): URL fal should POST the result to on completion
response_format ('markdown' | 'json'): Output format (default: markdown)
Returns: For JSON format: { "request_id": string, "status": string, "status_url": string, "response_url": string, "cancel_url": string, "queue_position": number } For markdown format: the same fields, human-readable, plus next-step guidance.
Examples:
Use when: "Generate a video of a rocket launch" -> model_id="fal-ai/minimax/video-01", arguments={"prompt": "a rocket launch"}
Use when: "Kick off this training job and let me know status later" -> submit, then poll with fal_check_status
Don't use when: the model is fast and you want the result immediately — use fal_run_model instead
Error Handling:
Returns "Authentication failed" if FAL_KEY is missing or invalid
Returns "Invalid input (422)" if arguments don't match the model's schema — check fal_get_model_schema
Returns "Not found (404)" if the model_id doesn't exist
Inputs: model_id (required), arguments (required), webhook_url, response_format.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Each tool has a distinct, non-overlapping purpose: cancelling requests, checking status, encoding files, fetching schemas, retrieving results, listing models, running synchronously, and submitting asynchronously. No confusion possible.
All tools follow a consistent fal_verb_noun pattern (e.g., fal_cancel_request, fal_get_result, fal_list_models). Even compound verbs like encode_file_as_data_uri maintain the structure.
8 tools is ideal for this scope: covering discovery, synchronous and asynchronous execution, result handling, and a utility. Neither too few nor too many.
The set covers the full lifecycle: model discovery (list_models, get_model_schema), execution (run_model, submit_request), status tracking (check_status), result retrieval (get_result), cancellation (cancel_request), and a local file encoding helper. No obvious gaps.
Maintenance
Related MCP Connectors
AI video, image and audio generation with 150+ AI models from any MCP agent
Generate images, video, audio and short films with 140+ AI models from any MCP client.
Use AI models for chat, image, and video generation from Claude Code and other MCP hosts.
214 tools for AI agents over one MCP endpoint: image, video, audio, 3D, data, storage, mail, GPUs.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables Claude Desktop and other MCP clients to generate images, videos, music, and audio using Fal.ai models. Supports text-to-image generation, video creation, music composition, text-to-speech, audio transcription, and image enhancement through natural language prompts.1861MIT
- AlicenseBqualityFmaintenanceEnables seamless integration with Fal.ai's 600+ image generation models including Flux and Stable Diffusion. Supports real-time streaming, workflow execution, and unified access to AI image generation through natural language.558 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables interaction with fal.ai AI models through MCP, supporting model discovery, content generation, queue management, and file uploads to the fal.ai platform.MIT
- AlicenseNot gradedqualityDmaintenanceProvides access to over 600 AI models on fal.ai for generating and editing images, videos, music, and speech directly within Claude. It supports high-performance models like FLUX, Kling, and Whisper for various creative and analytical tasks.1,462 npm1MIT