MCP server overview
What flux start mcp exposes — separate process, FastMCP-based, fixed generic toolset over a running Flux server.
What it is
flux start mcp runs a separate process that bridges a running Flux server to MCP-compatible clients (Claude Desktop, Cursor, custom agents, any client speaking the Model Context Protocol). It does not execute workflows. It proxies every call to the Flux HTTP API and returns the JSON result.
The implementation lives in flux/mcp_server.py and is built on FastMCP.
Process model
The MCP server is a distinct process from flux start server. You run both:
| Process | Holds | Started by |
|---|---|---|
flux start server | Workflow catalog, execution state, scheduler, workers | Operator |
flux start worker | Workflow code, runs executions, checkpoints to server | Operator |
flux start mcp | MCP protocol surface, no state of its own | Operator (or an MCP client, for stdio) |
The MCP server keeps a single httpx.AsyncClient pointed at server_url (default http://localhost:8000) and uses it for every tool call.
Transports
flux/mcp_server.py accepts three transports via the transport argument:
| Transport | When to use |
|---|---|
streamable-http | Server-to-server connections and newer MCP clients. This is the CLI default for flux start mcp. |
sse | Older clients that only speak Server-Sent Events, including some Claude Desktop builds. |
stdio | Client-launched subprocess. The MCP client (e.g. Claude Desktop’s local-server model) spawns flux start mcp and talks to it over stdin/stdout. |
The default transport is streamable-http. The flux start mcp CLI and the underlying MCPConfig (in flux/config.py) agree on it — whether you start the process via the CLI or instantiate MCPServer programmatically without passing a transport, you get streamable-http.
When started with streamable-http or sse, the server binds to host:port and serves at the path /mcp.
Exposed toolset
The MCP server registers a fixed set of tools at startup. It does not generate one MCP tool per workflow. Workflows are addressed by name through generic tools like list_workflows, execute_workflow_sync, and execute_workflow_async.
If you want a per-workflow MCP tool with its own name and input schema, expose the workflow as a service. See flux service create --mcp and Workflows as services. That is the only path to bespoke MCP tools.
For the full list of generic tools and their parameters, see MCP tool reference.
CLI invocation
Usage: flux start mcp [OPTIONS]
Start the Flux MCP server that exposes API endpoints as tools.
Options:
-h, --host TEXT Host to bind the MCP server to.
-p, --port INTEGER Port to bind the MCP server to.
-n, --name TEXT Name for the MCP server.
-surl, --server-url TEXT Server URL to connect to.
-t, --transport [stdio|streamable-http|sse] Transport protocol for MCP.
Default: streamable-http.
When a flag is omitted, the CLI passes None to MCPServer, which then falls back to the corresponding MCPConfig value. Defaults from flux/config.py:
| Field | Default |
|---|---|
name | flux-workflows |
host | localhost |
port | 8080 |
server_url | http://localhost:8000 |
transport | streamable-http |
Authentication
The MCP server talks to the Flux HTTP server like any other client. It needs an API key whose role permits the operations its tools perform.
The base httpx.AsyncClient in flux/mcp_server.py does not attach an Authorization header explicitly. The API key must reach the server through the standard configuration path — env var FLUX_API_KEY, the configured key for the running principal, or whatever auth scheme your deployment uses. If the Flux server has [flux.security.auth] enabled = false (the default for local dev), no key is required.
For production, give the MCP server a dedicated API key with the operator role or a narrower custom role. admin grants full surface and is rarely the right choice.
Configuration
Settings under [flux.mcp] in flux.toml, or FLUX_MCP__* env vars:
[flux.mcp]
name = "flux-workflows"
host = "localhost"
port = 8080
server_url = "http://localhost:8000"
transport = "streamable-http"
Equivalent environment variables:
FLUX_MCP__NAME=flux-workflows
FLUX_MCP__HOST=localhost
FLUX_MCP__PORT=8080
FLUX_MCP__SERVER_URL=http://localhost:8000
FLUX_MCP__TRANSPORT=streamable-http
CLI flags override env vars, which override flux.toml, which overrides defaults.
What goes wrong
Three common failure modes:
MCP server can’t reach the Flux HTTP server. Every tool returns {"success": false, "error": "Could not connect to Flux server at <server_url>"}. Check that flux start server is running, that --server-url matches the actual bind address, and that no firewall or TLS misconfiguration is blocking the call. The MCP server logs Flux server at: <url> at startup — verify the URL there.
MCP client rejects the transport. Symptoms: the client connects but every request hangs or returns a protocol error. Reconfigure both sides to agree on transport. Claude Desktop’s “local server” entries expect stdio; remote MCP entries in newer clients expect streamable-http. Restart the MCP server with --transport matching what the client sends.
Auth failures on execute_workflow_* and admin tools. Symptoms: tools return {"success": false, "error": "HTTP error: 401 - ..."} or 403. The MCP server’s API key lacks permission on that workflow or schedule. Either grant the key the required permission (workflow:<namespace>:<name>:run, schedule:*:create, etc.) or assign it a broader role. The full permission matrix is in REST API: authentication.