Skip to content

Tools reference

The FLORA MCP server exposes execute, flora_discover_skills, and a set of flora_* endpoint tools. The endpoint tools map directly to the FLORA API, while execute runs TypeScript against the @flora-ai/flora SDK and flora_discover_skills provides reusable workflow instructions.

Runs TypeScript in a sandboxed environment with a pre-authenticated @flora-ai/flora client. The agent defines a function async function run(client) { ... } and the server invokes it, returning whatever the function returns plus any console.log output.

ArgumentTypeDescription
codestringTypeScript code defining async function run(client) { ... }

Discovers reusable FLORA workflow skills. Omit name to list available skills; pass an exact skill name to retrieve its instructions.

ArgumentTypeDescription
namestring, optionalExact skill name from a previous discovery result

These tools expose the current FLORA API surface directly. Their argument shapes are available in the API Reference and the SDK’s TypeScript types.

Read-only tools carry readOnlyHint. flora_update_project_sharing, flora_remove_from_canvas and flora_update_canvas_node_document carry destructiveHint because they revoke links people already hold, delete nodes for good, or replace a whole document, so a host can ask before running them.

  • flora_list_workspaces — List the workspaces available to the account.
  • flora_list_projects — List projects in a workspace, most recently active first.
  • flora_get_project — Get one project’s metadata.
  • flora_list_canvas_nodes — List a project’s media nodes and asset URLs.
  • flora_open_project — Open a project canvas in a browser session with WebMCP tools.
  • flora_create_project — Create an empty project canvas in a workspace.
  • flora_share_project — Share a project by link and return the link.
  • flora_get_project_sharing — Read a project’s link sharing mode, share link, owner, and members.
  • flora_update_project_sharing — Change a project’s link sharing, including unsharing it.
  • flora_get_canvas — Read a project’s canvas: every node with its position and size, every edge, and a revision marker.
  • flora_add_to_canvas — Add nodes and edges to a project canvas.
  • flora_update_canvas_nodes — Edit existing nodes in place (label, prompt, model, params, position, a note’s text) and remove edges.
  • flora_remove_from_canvas — Delete nodes from a project canvas, with their edges and group members.
  • flora_run_canvas_nodes — Run generation nodes already on a project canvas.
  • flora_get_canvas_node_document — Read a document-bearing node’s full content: a timeline’s tracks, items and assets, a deck’s slides and layers, or a note’s whole text body.
  • flora_update_canvas_node_document — Replace a timeline node’s document, guarded by base_revision.
  • flora_arrange_canvas — Arrange nodes on a project canvas: Tidy (edge-following), or a row, column, or grid of named nodes with a chosen gap and origin.
  • flora_add_action — Add a prebuilt action node to a project canvas.
  • flora_list_models — List generation models available to the account.
  • flora_view_model3d — Open a read-only 3D viewer for a run.
  • flora_list_generations — List generation history or read a set of runs by run_ids.
  • flora_create_generations — Start 1–20 generations; pass a one-item generations array for a single request.
  • flora_list_lora_trainers — Discover families, training defaults and limits, and compatible inference models with strength parameters.
  • flora_train_lora — Train and save a Style through the same flow as the web Train dialog; this spends usage. Persist client_token before submitting.
  • flora_get_lora — Check saved Style readiness and compatible base-model family. Poll training with flora_list_generations using run_ids: [run_id].

Use the ready style_id as params.lora_id in an item of flora_create_generations. See LoRA training for captions, recovery and SDK examples. These are remote MCP endpoint tools; the browser’s project WebMCP surface is separate.

  • flora_list_techniques — List saved techniques with inputs, outputs, and run cost.
  • flora_get_technique — Get a technique’s declared inputs and outputs.
  • flora_list_technique_runs — List past technique runs with status, cost, and outputs.
  • flora_run_technique — Run a saved technique; this spends credits.
  • flora_search_actions — Search the credit-free prebuilt action registry.
  • flora_run_action — Run a prebuilt action on inline inputs without touching the canvas.
  • flora_run_canvas_action — Run an action node already on a canvas.
  • flora_list_assets — List assets in a workspace or project.
  • flora_get_asset — Get one asset’s metadata.
  • flora_create_asset — Bring a file into a workspace from a URL or signed upload.
  • flora_complete_asset — Finish a signed upload and return the asset’s final URL.
  • flora_attach_asset — Put an existing asset onto a project canvas.

Listed only for accounts with Brand OS.

  • flora_brand — Read a published brand: list (brands with their release and task profiles), context (the rules for one task profile), module, assets, package, and render_text for exact text and logos in the brand’s fonts.
  • flora_brand_edit — Set up and edit a brand’s draft, then publish it: create, add_source and complete_source (public HTTPS URL or signed upload), extract, set_specs (palette, type styles, grids, logo lockups), import_templates (Figma slots.json or specs.json), set_asset_use (intent, imagery bank tags and usage notes, display names; up to 100 assets per call), save_rule and publish. It needs Brand OS edit access in the workspace. Agents read the changes through flora_brand after a publish.
  • flora_brand_status — Read-only progress for that setup: extraction (a run’s status) and publish_preview (what would ship, and the latest release).

execute constraints:

  • Variables and imported state do not persist between execute calls — each call is isolated.
  • Individual HTTP requests inside the sandbox time out at 30 seconds.
  • Total code execution times out at approximately 5 minutes.

The sections below describe every client.* namespace available inside execute, grouped by resource.

The agent uses these methods to discover Techniques and create Technique runs.

// List all techniques (supports async iteration)
const { techniques } = await client.techniques.list({ query: "thumbnail" })
// Inspect a specific technique's inputs, outputs, and cost
const technique = await client.techniques.retrieve("tech_...")
// → { technique_id, name, description, inputs[], outputs[], run_cost }
// Create a technique run
const run = await client.techniques.runs.create("tech_...", {
mode: "async",
inputs: [{ id: "image_in", type: "imageUrl", value: "https://..." }],
callback_url: "https://yourserver.com/webhook", // optional
})
// → { run_id, status, progress, outputs? }
// List past technique runs (newest first, paginated; supports async iteration)
const { runs } = await client.techniques.runs.list({
workspace_id: "ws_...",
status: "completed",
limit: 20,
})
// Poll a technique run
const status = await client.techniques.runs.retrieve("run_...", {
techniqueId: "tech_...",
})
// → { status: 'pending'|'running'|'completed'|'failed', progress,
// outputs: [{ output_id, type, url }], error_code?, error_message? }

→ API Reference: Techniques

For one-off model generations that don’t require a saved Technique, the agent calls client.generations.create. This is the preferred path for plain image, video, audio, or text generation.

// Create a generation
const run = await client.generations.create({
type: "image",
prompt: "a fox in the snow",
workspace_id: "ws_...",
project_id: "prj_...",
model: "model_id_from_list", // optional
params: { width: 1024, height: 768 }, // optional, model-specific
})
// → { run_id, type, charged_cost, estimated_seconds, model?, project_id? }
// List past generations (newest first, paginated; supports async iteration)
for await (const gen of client.generations.list({ workspace_id: "ws_..." })) {
console.log(gen.run_id, gen.status)
}

→ API Reference: Generations

For workflows that need user-supplied images or videos, the agent follows a 3-step signed-upload flow: create an asset slot → upload bytes via the signed URL → mark it complete. The resulting asset URL can then be passed as a Technique input.

// Step 1: create a signed upload slot
const asset = await client.assets.create(/* see the API Reference and SDK types for full args */)
// Step 2: upload bytes via the signed URL (the agent uses curl or fetch)
// Step 3: mark the upload complete
await client.assets.complete(asset.asset_id)
// Retry if the signed URL expired
await client.assets.retry(asset.asset_id)
// List assets
const { assets } = await client.assets.list({ workspace_id: "ws_..." })
// Retrieve a specific asset
const a = await client.assets.retrieve("asset_...")

→ API Reference: Assets

Projects organize runs and assets inside a workspace. The canvas and actions methods let the agent read and modify a project’s node graph.

Video-generation nodes require the workspace video entitlement; a changeset that adds one without access is rejected. Static video uploads using content_url are exempt. If rejected, ask the user to enable video access or build the workflow with image nodes; do not retry the unchanged request.

// List and create projects
const { projects } = await client.projects.list({ workspace_id: "ws_..." })
const project = await client.projects.create({ name: "My Campaign", workspace_id: "ws_..." })
// Retrieve a project and its nodes
const p = await client.projects.retrieve("prj_...")
for await (const node of client.projects.listNodes("prj_...")) {
/* ... */
}
// Attach an asset to a project canvas
await client.projects.assets.attach(/* see the API Reference and SDK types for exact args */)
// Read the full canvas graph: nodes, edges, and a revision marker
const graph = await client.projects.canvas.getGraph({ workspaceId: "ws_...", projectId: "prj_..." })
// Add and connect nodes in one changeset; created maps each ref to its assigned ids
const { created } = await client.projects.canvas.applyChangeset({
workspaceId: "ws_...",
projectId: "prj_...",
add: [{ ref: "outc", type: "image", prompt: "Editorial campaign image" }],
connect: [{ from: "n1", to: "outc" }],
})
// Run generation nodes the changeset created — spends credits, returns a run per node
await client.projects.canvas.runNodes({
workspaceId: "ws_...",
projectId: "prj_...",
node_ids: [created.outc.id],
})
// Add a prebuilt action node from a raw action slug
await client.projects.actions.create("prj_...", {
action_id: "rotate-image",
params: {
/* optional */
},
})
// Run an existing canvas action node
await client.projects.actions.run("prj_...", "node_...")
// Share the project by link, the way the canvas Share tab does. Escalate-only:
// sharing for "view" never downgrades a project already shared for "edit".
// "edit" needs a plan with editable sharing (403 paid_plan_required otherwise).
const { url } = await client.projects.sharing.share({ projectId: "prj_...", access: "view" })
// → { url, role: "guest" | "editor", sharing_mode, created, canvas_url }
// Read the sharing state; the link appears only when the user may manage sharing
const state = await client.projects.sharing.get({ projectId: "prj_..." })
// → { sharing_mode, is_private, can_manage_sharing, link | null, owner, members[] }
// Change it explicitly — "restricted" unshares; passphrase: null clears the passphrase
await client.projects.sharing.update({
projectId: "prj_...",
sharing_mode: "restricted",
})

Agents that prefer the flora_* tools get the same three operations as flora_share_project, flora_get_project_sharing (read-only), and flora_update_project_sharing. A link returned by any of them grants access to whoever holds it, so the agent should hand it to the user rather than post it elsewhere.

→ API Reference: Projects

const { workspaces } = await client.workspaces.list()
// → [{ workspace_id, name, role, created_at }]

The agent typically calls this first after OAuth, or when the user has access to multiple workspaces and needs to resolve the right workspace_id.

→ API Reference: Workspaces

For generation workflows that accept a model parameter, the agent lists models to discover available IDs and their parameter schemas.

const { models } = await client.models.list({ type: "image" }) // type optional
// → [{ model_id, name, provider, type, estimated_credits, estimated_cost_usd, estimated_seconds,
// params: [{ name, required, type, default, min, max, options }] }]

→ API Reference: Models

await client.feedback.record({
/* ... */
})

The agent calls this when the user wants to send feedback to the FLORA team — e.g. “tell FLORA the MCP keeps disconnecting”, “send feedback that I’d love a Technique for X”, “let FLORA know this worked great”.

→ API Reference: Feedback


You don’t call tools directly. You describe what you want, and the agent handles the sequence. For example, “Run the Thumbnail Technique on this image” typically resolves to:

  1. flora_list_techniques — find matching Techniques and their declared inputs.
  2. flora_get_technique — confirm the selected Technique’s input schema.
  3. flora_run_technique — start the run with an inputs map keyed by those input ids.
  4. flora_list_generations — pass run_ids: [run_id] and technique_id to poll the run until complete:
async function run(client) {
// 1. Find the technique
const { techniques } = await client.techniques.list({ query: "thumbnail" })
const tech = techniques[0]
console.log("Using technique:", tech.technique_id, tech.name)
// 2. Create a run
const run = await client.techniques.runs.create(tech.technique_id, {
mode: "async",
inputs: [{ id: "image_in", type: "imageUrl", value: "https://example.com/photo.jpg" }],
})
console.log("Run created:", run.run_id)
// 3. Poll until complete
let result
do {
await new Promise((r) => setTimeout(r, 3000))
result = await client.techniques.runs.retrieve(run.run_id, {
techniqueId: tech.technique_id,
})
console.log("Status:", result.status, result.progress)
} while (result.status === "pending" || result.status === "running")
return result.outputs
}

Different prompts produce different sequences. The Recipes section walks through several end-to-end examples.


Most clients namespace tools by server. You’ll see the current server tools under names like:

  • Claude Code (/mcp listing): flora:execute, flora:flora_discover_skills, and flora:flora_*
  • Cursor: flora.execute, flora.flora_discover_skills, and flora.flora_*
  • Other MCP clients: similar namespacing depending on the client

You almost never need to type these directly — describe what you want and the agent picks the right tool.


  • Calls that create runs (client.techniques.runs.create(...), client.generations.create(...)) are billed in USD against your workspace. The cost is shown in client.techniques.retrieve(...) under run_cost and on the completed run as charged_cost.
  • Rate limits apply at the workspace level and match the REST API. See the API Reference for current limits.
  • A 402 insufficient_credits error means the workspace balance is too low — see About FLORA credits.