Flux tools server reference
Exact schemas for every tool on the Flux tools server: arguments, return values, the API route behind each one, the tool error objects, and the routing server.
The Flux tools server gives an agent every Flux ability as an MCP tool. To add it to an agent, see Set up the Flux tools server. This page is the exact contract.
Transport and auth
| URL | https://api.fluxrouter.ai/mcp-tools/, with the trailing slash. Without it the server answers 307. |
| Transport | Streamable HTTP, stateless. Each request stands alone: tools/list and tools/call need no initialize first and no session id. |
| Auth | Authorization: Bearer sk-flux... on every request. Flux keys only; no sign-in flow. |
| Replies | Server-sent events: read the JSON-RPC message from the data: line. Send Accept: application/json, text/event-stream. |
| Server name | flux-tools |
| Status | Live |
curl https://api.fluxrouter.ai/mcp-tools/ \
-H "Authorization: Bearer sk-YOUR-FLUX-KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_capabilities","arguments":{}}}'
import json
import requests
resp = requests.post(
"https://api.fluxrouter.ai/mcp-tools/",
headers={
"Authorization": "Bearer sk-YOUR-FLUX-KEY",
"Accept": "application/json, text/event-stream",
},
json={
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {"name": "list_capabilities", "arguments": {}},
},
)
resp.raise_for_status()
# The reply is a server-sent event: read the JSON after "data:".
for line in resp.text.splitlines():
if line.startswith("data:"):
message = json.loads(line[len("data:"):])
print(message["result"]["structuredContent"])
const resp = await fetch('https://api.fluxrouter.ai/mcp-tools/', {
method: 'POST',
headers: {
Authorization: 'Bearer sk-YOUR-FLUX-KEY',
'Content-Type': 'application/json',
Accept: 'application/json, text/event-stream',
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'tools/call',
params: { name: 'list_capabilities', arguments: {} },
}),
});
// The reply is a server-sent event: read the JSON after "data:".
const text = await resp.text();
const line = text.split('\n').find((l) => l.startsWith('data:'));
const message = JSON.parse(line!.slice('data:'.length));
console.log(message.result.structuredContent);
How tools bill
The tools server writes no charge of its own. Each tool calls the matching Flux API route over the server's own network, with your key, so the route authenticates, gates and bills the call exactly as if you had sent it yourself. The bill, the limits and the errors are the route's.
The tools
list_capabilities
Always listed, never billed. Live
- Arguments: none.
- Returns:
tier(your plan),premium_unlocked(whether paid abilities work on this key) andenabled, an object keyed by ability. Each entry haspremium(whether it needs a paid plan) and eitherest_microcents(an advisory cost per call, in millionths of a US dollar) ortools(each tool's billing rule, for abilities billed per unit). Entries may carry other fields; ignore any you do not use.
web_fetch
Live Calls POST /v1/fetch; see the fetch reference.
| Argument | Type | Required | Notes |
|---|---|---|---|
url | string | Yes | A public http or https URL. |
- Returns:
markdown,format,urlandcost_microcents. Always a plain read:renderis API only.
web_search
Rolling out Calls POST /v1/search; see the search reference.
| Argument | Type | Required | Notes |
|---|---|---|---|
query | string | Yes | Up to 2,000 characters. |
- Returns:
answer,citations(URLs),searches,cost_microcentsandcost_usd.
image_generate
Live Calls POST /v1/images/generations; see the images reference.
| Argument | Type | Required | Notes |
|---|---|---|---|
prompt | string | Yes | What to draw. |
- Returns: the generation response (
created,datawith the base64 image) pluscost_microcents. Your agent decodesb64_jsonand saves the file itself. - There is no edit tool. Edits are API only.
transcribe
Shipping Calls POST /v1/audio/transcriptions; see Speech to text.
| Argument | Type | Required | Notes |
|---|---|---|---|
audio_url | string | One of the two | A public https URL. Private addresses are refused. |
audio_base64 | string | One of the two | The file, base64-encoded. Send filename with it. |
filename | string | With audio_base64 | For example note.m4a. |
language | string | No | A language hint, such as en. |
prompt | string | No | Context or spellings to guide it. |
- Audio up to 8 MB.
- Returns:
text,billed_secondsandcost_usd.
speak
Shipping Calls POST /v1/audio/speech; see Text to speech.
| Argument | Type | Required | Notes |
|---|---|---|---|
text | string | Yes | Up to 1,000 characters per call, fewer than the API. |
voice | string | No | A voice id. The tool's schema lists them. |
format | string | No | mp3 (default) or wav. |
speed | number | No | 1.0 is normal. |
- Returns: an audio content block (base64) plus
voice,format,mime_type,bytes,billed_charsandcost_usd. Your agent writes the audio to a file itself.
Apps tools
Shipping apps_list, apps_connect, apps_find_actions and apps_execute connect your Flux account to apps such as Gmail or Slack and run actions in them.
| Tool | Arguments | Billed |
|---|---|---|
apps_list | none | No |
apps_connect | app; optional alias for a second account of the same app | No |
apps_find_actions | task; optional app | No |
apps_execute | action (from apps_find_actions), arguments | Per action |
What they return, and how to chain them, is on the apps page.
Which tools you see
tools/listshows every tool your account can call, including paid tools on a Free plan.- A paid tool called on a Free plan answers
premium_locked. After that refusal it appears once more intools/list, then drops out of that account's list, so the agent stops trying it. It comes back once the plan is paid and cleared. - Each paid tool's description carries your plan and an advisory cost per call.
Tool error objects
A refusal is a normal tool result, never a protocol fault. Its structured content is:
{
"error": "premium_locked",
"capability": "web_search",
"message": "Web search needs a paid, cleared Flux plan. Upgrade at https://fluxrouter.ai/home/billing.",
"upgrade_url": "https://fluxrouter.ai/home/billing",
"retryable": false
}
| Field | When | Meaning |
|---|---|---|
error | always | The code, from the table below. |
capability | always | The ability that refused. |
message | most codes | Plain English your agent can act on. |
reason | capability_unavailable | Plain English, in place of message. |
retryable | always | Whether the same call can work later. |
retry_after_seconds | some rate_limited | How long to wait. |
upgrade_url | premium_locked, payment_required | Where to upgrade or add credit. |
price_microcents | some premium_locked | What the call would have cost. |
error | Retryable | Cause |
|---|---|---|
premium_locked | No | The ability needs a paid, cleared plan. |
payment_required | No | The route asked for payment: out of credit or allowance, or a paid plan is needed. |
ability_disabled | No | The ability is not switched on for this account. Do not retry. |
auth_failed | No | The key is missing, wrong, revoked or expired. |
forbidden | No | This key may not use the ability. |
too_large | No | The input is over a limit. |
invalid_request | No | A bad argument, such as an unknown voice or a private URL. |
rate_limited | Yes | Too many calls; wait and retry. |
capability_unavailable | Usually | A temporary fault. Check retryable. |
Fixes are on Tools server problems.
The routing server
A second MCP server at https://api.fluxrouter.ai/mcp exposes routing, not abilities. Status: Live
| Transport | POST JSON-RPC 2.0. Protocol 2025-11-25; older versions are accepted. |
| Session | Send initialize first. Every later request must carry the MCP-Session-Id header it returns. DELETE ends the session; GET answers 405. |
| Auth | Authorization: Bearer sk-flux... |
| Tool | Arguments |
|---|---|
flux_route | prompt or messages (one is required); optional tier (fast, standard, reasoning or auto, the default), model, max_tokens, temperature. Returns the answer and a decision_id. |
flux_explain | decision_id from flux_route. Returns which model answered, the tier, the cost and the latency. |
flux_models | Optional tier (fast, standard, reasoning, pinned or all, the default). |
Errors on this server are JSON-RPC errors: the standard codes -32700 to -32603, plus these Flux codes:
| Code | Meaning |
|---|---|
-32001 | A header does not match the request |
-32002 | Unauthorised: the key is missing or not accepted |
-32003 | Rate limited |
-32004 | The MCP-Session-Id header is missing |
-32005 | The session has expired; send initialize again |