The MCP server lets an AI agent (Claude Code, Codex, Cursor or your own) read the
catalogue, order machines, drive them and destroy them, through the same API and
the same rules as the console. It lives at https://ffxf.net/mcp,
speaks Streamable HTTP, and relays each call with your API key. It stores nothing
and has no rights of its own.
Install it in one sentence
Create a key, put it in the FFXF_API_KEY environment variable, then
give your agent this sentence:
Set up the FFxF MCP server by following https://ffxf.net/agents.md. My API key is in the FFXF_API_KEY environment variable.
agents.md is written for agents: the command for each client, how to check the connection, and the rules to follow before spending anything. The key never goes through the conversation.
1. Create a key
In the console, Account → API keys. Give it only the scopes the agent needs:
| The agent should | Scopes |
|---|---|
| look only (catalogue, machines, spend) | vms.read, billing.read |
| order and run machines | the above, plus vms.create, vms.action, sshkeys.write |
| clean up after itself | the above, plus vms.destroy |
Then export it in the shell the agent starts from, for example in
~/.bashrc or ~/.zshrc:
export FFXF_API_KEY="ffxf_live_…"
A monthly budget, set in the console, caps what the key can spend: machines stop past 120 % of it. See Credit, hours and budget.
2. Add the server to your client
Claude Code, for every project:
claude mcp add --scope user --transport http ffxf https://ffxf.net/mcp \
--header "Authorization: Bearer $FFXF_API_KEY"
Codex CLI, which reads the key from the environment at each start:
codex mcp add ffxf --url https://ffxf.net/mcp --bearer-token-env-var FFXF_API_KEY
Cursor, or any client configured with JSON, with your key in place of <key>:
{
"mcpServers": {
"ffxf": {
"url": "https://ffxf.net/mcp",
"headers": { "Authorization": "Bearer <key>" }
}
}
}
3. Check the connection
claude mcp list
# ffxf: https://ffxf.net/mcp (HTTP) - ✔ Connected
Then ask the agent for your balance: it calls get_account. A
missing_token or invalid_api_key error means the key did not
reach the server; insufficient_scope names the scope the key lacks.
In continuous integration, without a key
An agent started by GitHub Actions or GitLab CI needs no stored key: the server
relays the Authorization header as is, and an OIDC token of the job
works just as well. It acts with the scopes of the binding declared in the
console, and nothing more.
claude mcp add --transport http ffxf https://ffxf.net/mcp \
--header "Authorization: Bearer $FFXF_TOKEN"
The GitHub token lasts five minutes: request a new one before each step that needs it. The steps are in OIDC: CI without an API key.
Next
The sixty-eight tools and their scopes are in MCP tools. To let the agent rent a machine for a task and hand it back afterwards, read Remote mode.
Keys restricted to a list of addresses are refused through ffxf.net/mcp:
the calls reach the API from FFxF's own server. Use such a key with the API directly.