Skip to content

Tools reference

The FLORA MCP server exposes exactly two tools: search_docs and execute. Rather than wrapping each API endpoint as a separate tool, the agent writes TypeScript against the @flora-ai/flora SDK inside a single execute call — keeping the interface simple and the agent in full control of sequencing and error handling.

Searches the @flora-ai/flora SDK documentation to find the right method, its parameter shapes, and usage examples. The agent calls this before writing code whenever it is unsure of a method name, argument structure, or return type.

ArgumentTypeDescription
querystringNatural-language question or method name to look up
languagestringTarget language, e.g. "typescript"

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.

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 search_docs 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.

// 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.attachAsset(/* see search_docs for exact args */);
// Retrieve the canvas topology as a Mermaid flowchart
const canvas = await client.projects.canvas.retrieve("prj_...");
// Apply a Mermaid patch to add or connect nodes
await client.projects.canvas.update("prj_...", {
diagram: "...", // Mermaid diff
node_params: { /* optional per-node param overrides */ },
});
// Run generation nodes the diagram created — spends credits, returns a run per node
await client.projects.canvas.runNodes({
workspaceId: "ws_...",
projectId: "prj_...",
node_ids: ["outc"],
});
// 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_...");

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_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. search_docs — look up client.techniques.list and client.techniques.runs.create parameter shapes.
  2. execute — a single function that lists Techniques (filtering by name), retrieves the matching one to confirm its inputs, creates a run, and polls 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. With the new two-tool model you’ll see:

  • Claude Code (/mcp listing): flora:execute, flora:search_docs
  • Cursor: flora.execute, flora.search_docs
  • 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 — top up in FLORA → Settings → Billing.