Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the Flux MCP server

Vendor MCP
Open markdown

The Flux MCP connector routes your AI agent's tool calls to Flux's own MCP server through Scalekit. Each user signs in to Flux once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 10 tools.

Tools
10
What they doRead · write · destructive
3 · 7 · 03 read7 write0 destructive
Users sign in with
OAuth app
Scalekit's or your own

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the Flux MCP connection

    In AgentKit > Connections, create a Flux MCP connection. The name you give it is the connection_name your code passes. See Configure connections.

    Scalekit credentials are available for Flux MCP server, so you don't need to register an OAuth app.

  4. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'fluxmcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize Flux MCP:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'fluxmcp_get_credits',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • fluxmcp_get_creditsCheck the user's remaining BFL API credits AND welcome-bonus free-generation balance.Read-only

    GetCredits

    Check the user's remaining BFL API credits AND welcome-bonus free-generation balance. The free pool is a one-time grant of N generations issued when the user first connects MCP (counted in generations, not dollars — every model decrements 1 from the pool regardless of cost). Free generations are consumed automatically before paid credits; when the free pool hits zero, gens charge the user's paid balance. Returns `{credits, free_generations, free_generations_total_granted}` on success. `free_generations` may be 0 — surface that explicitly to the user so they know the bonus is exhausted (it's a one-time grant, not a refill).

    Inputs

    This tool takes no inputs.

  • fluxmcp_get_historyList the user's recent FLUX generations as a grid of thumbnails.Read-only

    GetHistory

    List the user's recent FLUX generations as a grid of thumbnails. Each item carries the original prompt, model, seed, dimensions, plus `image_url` (full-res, 24h signed). The viewer offers per-tile Variations (regenerate via `generate_variations`) and Use (use the image as an `input_medias` entry on a follow-up `generate_image`), plus copy / download. Pagination is keyset on `created_at`. Pass `cursor=<next_cursor>` to page back in time; combine with `before` / `after` for date ranges. Returns the standard `{data, message}` shape. Errors: UNAUTHENTICATED, STORAGE_NOT_CONFIGURED, HISTORY_LIST_FAILED.

    Inputs

    afterstring
    Optional date filter: only return items strictly newer than this ISO-8601 timestamp.
    beforestring
    Optional date filter: only return items strictly older than this ISO-8601 timestamp. Combine with `cursor` for keyset pagination over a fixed range.
    cursorstring
    Pagination cursor. Pass `data.next_cursor` from a previous response to fetch the next (older) page. ISO-8601 timestamp; omit for the first page.
    limitinteger
    DO NOT pass this argument. The viewer paginates with a Load more button — extra rows aren't useful in a single response. Omit so the server's default of 8 is used. Only override if the user literally said a number. Hard cap 16.default 8
    statusstring
    Filter by generation lifecycle status. Defaults to `ready`: completed generations only. Use `all` to include in-flight and failed rows.one of readypendingmoderated_inputmoderated_outputfailedalldefault ready
  • fluxmcp_get_resultDO NOT CALL FROM THE LLM.Read-only

    GetResult

    DO NOT CALL FROM THE LLM. The image-viewer iframe handles all result polling automatically. Internal tool: the iframe invokes this per pending item via `app.callServerTool` after `generate_image` returns with items in `pending` status. Each call inline-polls BFL up to `INLINE_POLL_TIMEOUT_SECONDS`; if the request is still running when the budget expires, the response is `{status: "pending", request_id, ...}` and the iframe just calls again. Returns the same shape as a single-image `generate_image` result: `{data: {status, image_url, image_path, seed, cost, remaining_credits, ...}, message}` on ready, or `{error: {code, ...}, message}` on terminal failure.

    Inputs

    request_idstringrequired
    The `request_id` returned by a previous `generate_image` call. The image-viewer iframe calls this tool per item to poll BFL until that item reaches a terminal state.
  • fluxmcp_enhance_videoRender a prior DRAFT video at full quality.Write

    Enhance Video

    Render a prior DRAFT video at full quality. The draft's cached generation plan is replayed with more denoising steps — same composition, seed, and prompt plan, sharper detail — on an `fhd` (1080p-class) canvas by default, or `hd` via `resolution`. Everything else is pinned by the draft. Only works on a draft (`draft: true`) generation that has reached `status: "ready"`. Use when the user picks a draft they like ("make this one full quality", "finalize it", "enhance it"). To change the CONTENT instead, submit a new `generate_video` call. Returns immediately with a pending item, exactly like `generate_video`; the full-quality render takes minutes and the widget (or `get_result`) resolves it.

    Inputs

    request_idstringrequired
    The `request_id` of a READY draft generation (submitted with `draft: true` on `generate_video`).
    resolutionstring
    Output canvas for the enhanced render. Defaults to `fhd` (1080p-class, upsampled) when omitted; pass `hd` only when the user wants to keep the draft's 704p-class canvas.
  • fluxmcp_generate_imageSubmit one or more FLUX.2 image generations.Write

    GenerateImage

    Submit one or more FLUX.2 image generations. Returns immediately after BFL accepts each submit; the iframe streams the actual images in as they finish. Reference images go in `input_medias: InputMedia[]`. Two shapes: • `{id: <string>}` — for content already in our bucket. • `{url: <https URL>}` — ONLY for URLs the user typed from the open web. For user-attached files, call `request_upload_url` FIRST and pass `{id: data.media_id}` from the tool's response. Each `requests` entry is one image. Pass a single-item list for one image, or up to 8 entries to produce a batch in parallel.

    Inputs

    requestsarrayrequired
    List of image generation requests. Pass a single-item list for one image; pass multiple to generate a batch in one call (each entry is submitted to BFL in parallel and the iframe renders the results as a clickable grid). Cap is 8 entries per call.
  • fluxmcp_generate_variationsGenerate N more images "in the same direction" as a previously completed generation.Write

    GenerateVariations

    Generate N more images "in the same direction" as a previously completed generation. Use this tool whenever the user asks for variations of an existing generation — "more like that one", "give me variations", "another version", "show me alternatives", and similar. Reads the original request from the DB (prompt, model, dimensions, safety, Flex knobs, AND input_image slots), and for models that support it sets `prompt_upsampling=True` so each call rephrases the prompt diversely before generation — combined with BFL's auto-picked seeds this produces compositionally distinct outputs in the same direction. Pass ONLY the `request_id` (and optionally `count`) — every other field is sourced from the DB row. Returns the same shape as `generate_image`: `{data: {items: [{status: "pending", request_id, ...}, ...]}, message}`.

    Inputs

    request_idstringrequired
    The `request_id` of an existing ready generation to vary. The server reads its prompt, model, dimensions, safety_tolerance, Flex knobs, and any input_image slots and submits `count` fresh-seed clones in parallel.
    countinteger
    Number of variations to generate. Defaults to 4. Pass a different value only if the user specifically asked for it. Hard cap 8.default 4
  • fluxmcp_generate_videoGenerate videos with FLUX.3.Write

    Generate Video

    Generate videos with FLUX.3. Each `requests` entry picks an explicit `mode`: * `t2v` — text-to-video, prompt only. * `i2v` — image-to-video via `keyframes`: 1 keyframe animates a still (it becomes the opening frame); 2 keyframes transition/morph from the first to the second; 3-10 form a storyboard spread across the clip (needs explicit `duration`). Per-keyframe `timestamp` (seconds, all-or-none) pins exact positions. * `v2v` — video continuation via `start_video`: the output picks up from the source clip's final seconds (video AND audio). Chain results for longer sequences. When the user PROVIDES media, it MUST go into `keyframes` or `start_video` — never describe provided images/videos in prose and call with `t2v` (the output would look unrelated to the user's media). Media uses the same `{id}` / `{url}` shapes as `generate_image`; upload user-attached files via `request_upload_url` first (`kind: "video"` for MP4s). Reference-based conditioning (keep a subject's identity from reference images / borrow motion from a reference video) is NOT available on this endpoint yet — tell the user so instead of faking it with t2v. Clips are 5-20s at 24fps, `hd` or `fhd`, with synchronized audio by default. The harness reasons about the prompt before rendering and picks `duration` / `aspect_ratio` itself when they're `auto`. DRAFT WORKFLOW: pass `draft: true` for a fast, cheap preview of the exact planned generation. When the user likes a draft, call `enhance_video(request_id=<draft's id>)` to re-render the SAME clip (same composition, seed, and prompt plan) at full quality. Prefer drafts when the user is exploring ideas or wants variants — submit a batch of drafts, let them pick, enhance the winner. Drafts render at hd; `enhance_video` finishes the winner at `fhd` (default) or `hd`. VIDEO TAKES TIME: minutes for short clips, up to ~an hour for long ones. The response returns IMMEDIATELY with pending items. In hosts with the video-viewer widget the widget polls and renders automatically — do not poll yourself; tell the user the video is rendering. In text-only hosts, call `get_result(request_id=...)` per item to check progress (each call waits up to ~45s and returns `pending` again with a `progress` fraction until done). Results survive chat closes — the same `request_id` resumes from the server even days later.

    Inputs

    requestsarrayrequired
    List of video generation requests. Pass a single-item list for one video; pass up to 4 to generate a batch in one call (each entry is submitted to BFL in parallel). Each entry carries its own mode / prompt / media, so a batch can mix variations of one idea or entirely different clips.
  • fluxmcp_refresh_image_urlMint a fresh 24h signed URL for an image already stored in this server's bucket.Write

    RefreshImageUrl

    Mint a fresh 24h signed URL for an image already stored in this server's bucket. Internal: used by the iframe viewers to recover from expired URLs in older chats. You normally do not need to call this from the LLM. Every fresh `generate_image` / `get_history` response includes a usable URL already. Call this only when the user explicitly asks for a refreshed link to an image they generated previously. Returns `{data: {url, expires_in_seconds}, message}` on success, or an `error` payload (UNAUTHENTICATED, STORAGE_NOT_CONFIGURED, INVALID_IMAGE_PATH, REFRESH_FAILED).

    Inputs

    image_pathstringrequired
    Storage path of the image to renew, e.g. `<user_id>/generations/<request_id>.jpg`. Returned as `data.image_path` by `generate_image`, `get_result`, and `get_history`. Only paths owned by the calling user are accepted.