FFxF
Create and manage VMs, managed databases, firewalls and load balancers in Montréal, Canada.
Hosted MCP Server
npx add-mcp 'https://ffxf.net/mcp'Installs into Claude Code, Codex, Cursor and more
Documentation
Connect your agent
The FFxF MCP server lives at https://ffxf.net/mcp. It speaks Streamable HTTP and relays each call to the FFxF API with your API key. It stores nothing and has no rights of its own: the agent can do exactly what the key allows, and nothing more.
The quickest way: put your API key in the FFXF_API_KEY environment variable, then give your agent this sentence.
prompt
Set up the FFxF MCP server by following https://ffxf.net/agents.md. My API key is in the FFXF_API_KEY environment variable.
Or by hand, in two steps (details in the MCP documentation):
- Create an API key at console.ffxf.net/account/api-keys. Give it only the scopes the job needs:
vms.read,vms.create,vms.actionandbilling.readcover ordering and running machines. Leavevms.destroyout unless the agent should delete them. - Add the server to your client. With Claude Code:
bash Copy
In Cursor, or any client configured with JSON: json Copyclaude mcp add --transport http ffxf https://ffxf.net/mcp \ --header "Authorization: Bearer ffxf_live_…"{ "mcpServers": { "ffxf": { "url": "https://ffxf.net/mcp", "headers": { "Authorization": "Bearer ffxf_live_…" } } } }
Any client that supports Streamable HTTP and a custom header works the same way. The catalogue tools answer without a key, so an agent can compare plans and images before you create one.
What the agent can do
71 tools, each mapped to one endpoint of the public API and to the scope it needs: machines, private networks, firewalls, load balancers, managed databases and GitHub runners.
| Tool | What it does | Scope |
|---|---|---|
| list_regions, list_plans, list_images | Catalogue: regions, plans with hourly and monthly prices, operating systems and application images. | none |
| get_account | Credit balance, hourly burn rate, runway, quota and budget. | billing.read |
| list_vms, get_vm, get_vm_metrics | Machines, their status, addresses, traffic and usage graphs. | vms.read |
| estimate_vm | Runs every check of an order and prices it, without creating anything. | vms.create |
| create_vm | Orders a machine, billed by the hour from credit or by the month. | vms.create |
| power_vm, rename_vm | Start, clean shutdown, reboot, hard stop; change the hostname. | vms.action |
| reinstall_vm | Erases the disk and deploys another image. | vms.action |
| destroy_vm | Destroys the machine and its disk. | vms.destroy |
| get_action, list_vm_actions | Follows provisioning, reinstalls and power changes, which run in the background. | vms.read |
| get_vm_network, set_reverse_dns | IPv4 and IPv6 addresses; reverse DNS records. | vms.read, network.write |
| list_ssh_keys, add_ssh_key, delete_ssh_key | SSH keys saved on the account, to reach new machines without a password. | sshkeys.write |
| list_vpcs, get_vpc | Private networks, their range and the machines on them. | vms.read |
| create_vpc, delete_vpc, connect_vpc, disconnect_vpc, move_vpc | Creates or deletes a private network; adds, removes or moves a machine without restarting it. | network.write |
| list_firewalls, get_firewall | Firewalls, their rules and the machines they protect. | vms.read |
| create_firewall, update_firewall, delete_firewall, attach_firewall, detach_firewall | Inbound and outbound rules, attached to a machine and enforced within about ten seconds. | network.write |
| list_load_balancers, get_load_balancer, get_load_balancer_metrics | Addresses, pools and target health, listeners, certificates, requests and traffic. | vms.read |
| create_load_balancer, delete_load_balancer | Orders a load balancer in a private network, or deletes it. | vms.create, vms.destroy |
| upsert_pool, delete_pool, set_targets, upsert_listener, delete_listener, set_rules | Pools and their targets, ports (HTTPS with certificates), routing by hostname and path. | network.write |
| list_databases, get_database, get_database_options, get_database_metrics, get_slow_queries, list_database_backups | Managed PostgreSQL, MySQL, MariaDB and Valkey: status, prices, usage, slowest queries, backups and restore window. | vms.read |
| create_database, restore_database, fork_database, resize_database | Orders a database, restores one to any minute of its window, makes an instant copy, or moves it to a larger size. | vms.create |
| detach_database_fork | Gives a copy its own data and backups. | vms.action |
| delete_database | Deletes the database; its backups stay 7 days. | vms.destroy |
| get_database_credentials, update_database, create_database_user, set_database_user_access, reset_database_password, delete_database_user, create_logical_database, delete_logical_database, enable_extension, disable_extension | Users and passwords, access per database and read-only users, logical databases, PostgreSQL extensions, maintenance window and disk cap. | databases.write |
| set_database_public_access | Opens the database to the internet, optionally to some addresses only, or closes it. | network.write |
| backup_database | Starts a backup within a minute, before a risky migration for instance. | backups.write |
| get_runners, list_runner_jobs | GitHub Actions runners: labels and prices, concurrency, minutes and cost per repository, jobs. | billing.read |
A real run, call by call, from order to destruction: an AI agent that rents its own VPS.
Limits that hold when the agent gets it wrong
The rules live in the API, not in the agent's good behaviour:
- A key only does what its scopes allow. Anything else is refused with
403, naming the missing scope. - Hourly machines draw on prepaid credit. An order needs the first 24 hours covered, and the balance never goes negative.
- A monthly budget set in the console warns at 50, 80 and 100 % of spend, and stops machines past 120 %.
estimate_vmprices an order before anything is created, and the server tells the agent to show that price to you first.- An order retried after a timeout is deduplicated for 24 hours instead of creating a second machine.
destroy_vmandreinstall_vmrequire the machine's exact hostname, typed back.- Per key: 120 reads a minute, 20 actions a minute, 10 creations or reinstalls an hour.
Keys restricted to a list of addresses: through ffxf.net/mcp, calls reach the API from FFxF's own server, so such a key is refused there. Use it with the API directly.
Without MCP
The MCP server is a thin layer over the public API. Scripts and agents that prefer plain HTTP can call it directly.
Base URL
https://api.ffxf.net/v1
OpenAPI contract
Documentation
ffxf.net/docs, with recipes such as an ephemeral runner
For language models
If you are an agent reading this page
A short briefing to keep in context:
text
FFxF rents KVM virtual machines in Montréal, Canada.
MCP server: https://ffxf.net/mcp (Streamable HTTP, header Authorization: Bearer <key>)
API: https://api.ffxf.net/v1, contract https://ffxf.net/public/api/openapi.v1.json
1. Read the catalogue without a key: list_regions, list_plans, list_images.
2. Ask the user for an API key; never invent one.
Keys are created at https://console.ffxf.net/account/api-keys
3. Call estimate_vm and show the price before create_vm.
4. Poll get_action until the provisioning action leaves "running".
5. Ask the user before destroy_vm or reinstall_vm: both erase the disk.
Money is a decimal string with a currency code. Quote request_id to support.