# FFxF (remote · ffxf.net)

Create and manage VMs, managed databases, firewalls and load balancers in Montréal, Canada.

- Trust score: 69/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- remote · `ffxf.net`: 69/100 (this document), [markdown](https://verifymcp.io/servers/net-ffxf-cloud/ffxf.md), [page](https://verifymcp.io/servers/net-ffxf-cloud/ffxf)

## Channel facts

- Endpoint: `https://ffxf.net/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.12.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Endpoint Security**: 63/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation check failed: no authorisation is required to call this server, and it exposes a tool marked destructive (reinstall_vm).
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 68/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 8659 tokens (~121/item across 71 items; 71 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 93/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 79% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 11 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 72 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the FFxF MCP server?

FFxF is a hosted endpoint at https://ffxf.net/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http net-ffxf-cloud 'https://ffxf.net/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "net-ffxf-cloud": {
      "url": "https://ffxf.net/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "net-ffxf-cloud": {
      "type": "http",
      "url": "https://ffxf.net/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.net-ffxf-cloud]
url = "https://ffxf.net/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "net-ffxf-cloud": {
      "type": "remote",
      "url": "https://ffxf.net/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add net-ffxf-cloud --url 'https://ffxf.net/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  net-ffxf-cloud:
    url: "https://ffxf.net/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "net-ffxf-cloud": {
      "Transport": "http",
      "Url": "https://ffxf.net/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add net-ffxf-cloud -t streamable-http -u 'https://ffxf.net/mcp'
```

### Other

```json
{
  "mcpServers": {
    "net-ffxf-cloud": {
      "type": "http",
      "url": "https://ffxf.net/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-05 (score 69, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-03 (score 68, +1)

- [security] The server rewrote its instructions, which are the text every model session reads

### 2026-11-01 (score 67, +1)

No change was recorded against any check on this day. Stability & Change Management went from 10 to 13. That category is still filling its 30-day observation window: 3 days of observed history at the previous scan, 4 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-30 (score 66, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-29 (score 65, 0)

- [functional improvement] Stability: unverified → 0.03

### 2026-10-28 (score 65)

First indexed and scored.

## MCP tools (71)

### `list_regions` (~19 tokens)

List regions

Where machines can run. Public, no key needed.

### `list_plans` (~44 tokens)

List plans

Plans with their resources and prices (hourly and monthly, in CAD). Public, no key needed.

Input parameters:

- `region` (string): Keep only plans offered in this region.

### `list_images` (~67 tokens)

List images

Operating systems and ready-to-use application images. The slug is what create_vm expects. Public, no key needed.

Input parameters:

- `category` (string): linux, windows, bsd or app.
- `plan` (string): Keep only images that fit this plan.
- `region` (string)

### `get_account` (~27 tokens)

Get account

Credit balance, hourly burn rate and runway, quota and budget caps. Scope: billing.read.

### `list_vms` (~76 tokens)

List machines

The account's machines with their status, addresses and billing. Scope: vms.read.

Input parameters:

- `billing` (string)
- `cursor` (string): next_cursor from the previous page.
- `limit` (integer)
- `region` (string)
- `status` (string): e.g. running, stopped, provisioning.

### `get_vm` (~74 tokens)

Get a machine

One machine: status, IPv4, IPv6 /64, specs, traffic (Internet only, this traffic month: used_gb, limit_gb, period_ends_at), billing, suspension. Scope: vms.read.

Input parameters:

- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `get_vm_metrics` (~55 tokens)

Get machine metrics

CPU, memory, disk and network as measured from outside the machine. Scope: vms.read.

Input parameters:

- `timeframe` (string)
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `estimate_vm` (~283 tokens)

Estimate an order

Runs every check of create_vm and prices it, without creating anything: would_succeed, hourly rate, monthly price, credit required. Call it before create_vm. Scope: vms.create.

Input parameters:

- `billing` (string, required): Hourly draws on prepaid credit; monthly raises an invoice. Fixed for the life of the machine.
- `hostname` (string, required): Letters, digits, dots and hyphens; no leading, trailing or doubled separator.
- `image` (string, required): Image slug from list_images, e.g. debian-13.
- `ipv4` (boolean): false orders an IPv6-only machine, cheaper; outbound IPv4 goes through NAT64.
- `options` (object): Paid options declared by the plan, by name.
- `plan` (string, required): Plan slug from list_plans, e.g. nano.
- `private_only` (boolean): No public address at all; needs vpc. Reachable only from the private network, Internet through its gateway. Priced like ipv4: false.
- `region` (string, required): Region slug from list_regions, e.g. montreal.
- `ssh_keys` (array): Fingerprints or ids of SSH keys already on the account (see list_ssh_keys).
- `vpc` (integer): Private network id (list_vpcs) to connect the machine to, in the same region.

### `create_vm` (~365 tokens)

Create a machine

Orders a machine and spends credit (hourly) or raises an invoice (monthly). Returns the machine and a provisioning action to poll with get_action. Retrying the same order is safe: it is deduplicated for 24 hours. Scope: vms.create.

Input parameters:

- `billing` (string, required): Hourly draws on prepaid credit; monthly raises an invoice. Fixed for the life of the machine.
- `hostname` (string, required): Letters, digits, dots and hyphens; no leading, trailing or doubled separator.
- `idempotency_key` (string): Your own unique value per order. By default one is derived from the order itself.
- `image` (string, required): Image slug from list_images, e.g. debian-13.
- `ipv4` (boolean): false orders an IPv6-only machine, cheaper; outbound IPv4 goes through NAT64.
- `options` (object): Paid options declared by the plan, by name.
- `password_delivery` (string): email mails a generated password; none needs at least one SSH key.
- `payment` (string): Monthly only. credit pays from the balance when it covers the invoice.
- `plan` (string, required): Plan slug from list_plans, e.g. nano.
- `private_only` (boolean): No public address at all; needs vpc. Reachable only from the private network, Internet through its gateway. Priced like ipv4: false.
- `region` (string, required): Region slug from list_regions, e.g. montreal.
- `ssh_keys` (array): Fingerprints or ids of SSH keys already on the account (see list_ssh_keys).
- `vpc` (integer): Private network id (list_vpcs) to connect the machine to, in the same region.

### `power_vm` (~66 tokens)

Start, stop or reboot

start, shutdown (clean ACPI), reboot, or stop (hard power-off). Returns an action to poll with get_action. Scope: vms.action.

Input parameters:

- `type` (string, required)
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `rename_vm` (~69 tokens)

Rename a machine

Changes the hostname, inside the guest and in the console. Scope: vms.action.

Input parameters:

- `hostname` (string, required): Letters, digits, dots and hyphens; no leading, trailing or doubled separator.
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `reinstall_vm` (~118 tokens)

Reinstall a machine

ERASES THE DISK and redeploys another image. Ask the user first. confirm_hostname must be the machine's exact current hostname. Scope: vms.action.

Input parameters:

- `confirm_hostname` (string, required): The machine's exact hostname, typed back as confirmation.
- `image` (string, required): Image slug from list_images, offered in the machine's region and fitting its plan.
- `password_delivery` (string)
- `ssh_keys` (array)
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `destroy_vm` (~104 tokens)

Destroy a machine

DESTROYS the machine and its disk, with no undo and no backup kept. Ask the user first. confirm_hostname must be the machine's exact hostname. Scope: vms.destroy.

Input parameters:

- `confirm_hostname` (string, required): The machine's exact hostname, typed back as confirmation.
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.
- `when` (string): Monthly machines only: at the end of the paid period, or now.

### `get_action` (~46 tokens)

Get an action

Follows an asynchronous action (create, reinstall, power…). Poll until status leaves running; on error it carries the reason. Scope: vms.read.

Input parameters:

- `action` (integer, required)

### `list_vm_actions` (~48 tokens)

List a machine's actions

History of actions on one machine, from the API and the console. Scope: vms.read.

Input parameters:

- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `get_vm_network` (~53 tokens)

Get machine network

IPv4 and IPv6 addresses of a machine with their reverse DNS, and its private networks. Scope: vms.read.

Input parameters:

- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `set_reverse_dns` (~83 tokens)

Set reverse DNS

Sets the PTR record of one of the machine's addresses; null restores the default. Scope: network.write.

Input parameters:

- `address` (string, required): An IPv4 or IPv6 address of the machine.
- `hostname` (string|null, required): Fully qualified name, or null to clear.
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `list_vpcs` (~33 tokens)

List private networks

The account's private networks with their range, gateway and connected machines, plus the quota. Scope: vms.read.

### `get_vpc` (~51 tokens)

Get a private network

One private network and the machines on it, with their private address. Scope: vms.read.

Input parameters:

- `vpc` (integer, required): Private network id, as returned by list_vpcs or create_vpc.

### `create_vpc` (~129 tokens)

Create a private network

Creates an isolated private network; ready when the call returns. The first usable address (.1) is reserved for the gateway. Scope: network.write.

Input parameters:

- `cidr` (string, required): Private IPv4 range from /16 to /29 in 10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16, e.g. 10.0.0.0/24.
- `name` (string, required)
- `region` (string, required): Region slug from list_regions, e.g. montreal.

### `delete_vpc` (~63 tokens)

Delete a private network

Deletes an empty private network. Refused while a machine is still on it: disconnect or destroy those first. Ask the user first. Scope: network.write.

Input parameters:

- `vpc` (integer, required): Private network id, as returned by list_vpcs or create_vpc.

### `connect_vpc` (~116 tokens)

Connect a machine to a private network

Hot-adds a card on the private network and sets its address in the system, without a restart. configuration: manual means the address must be set by hand in the guest. Connecting again returns the same address. Scope: network.write.

Input parameters:

- `ip` (string): Address wanted in the range; default the next free one.
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.
- `vpc` (integer, required): Private network id, as returned by list_vpcs or create_vpc.

### `disconnect_vpc` (~82 tokens)

Disconnect a machine from a private network

Removes the machine's private address and card, without a restart. Refused for the only network of a machine with no public address. Scope: network.write.

Input parameters:

- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.
- `vpc` (integer, required): Private network id, as returned by list_vpcs or create_vpc.

### `move_vpc` (~85 tokens)

Move a machine to another private network

Joins the target network, then leaves this one, so the machine is never cut off. Keeps the same address ending when free. Scope: network.write.

Input parameters:

- `to` (integer, required): The target network.
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.
- `vpc` (integer, required): The network the machine is on now.

### `list_firewalls` (~34 tokens)

List firewalls

The account's firewalls with their inbound rules and the machines they protect, plus the quota. Scope: vms.read.

### `get_firewall` (~59 tokens)

Get a firewall

One firewall: its rules and the machines it protects, with the status of each (applied, pending, error). Scope: vms.read.

Input parameters:

- `firewall` (integer, required): Firewall id, as returned by list_firewalls or create_firewall.

### `create_firewall` (~73 tokens)

Create a firewall

Creates a reusable set of inbound and outbound rules. Without rules it starts with SSH (TCP 22) and ping open from anywhere; pass rules: [] for none. Nothing is filtered until it is attached to a machine. Scope: network.write.

Input parameters:

- `name` (string, required)
- `rules` (array)

### `update_firewall` (~106 tokens)

Rename a firewall or replace its rules

rules REPLACES the whole list and is applied at once to every attached machine: send every rule to keep, not only the new one (read get_firewall first). Removing the SSH rule can lock the agent out. pending_machines counts machines not updated yet, retried automatically. Scope: network.write.

Input parameters:

- `firewall` (integer, required): Firewall id, as returned by list_firewalls or create_firewall.
- `name` (string)
- `rules` (array)

### `delete_firewall` (~53 tokens)

Delete a firewall

Deletes a firewall attached to no machine. Refused while it protects one: detach it first. Scope: network.write.

Input parameters:

- `firewall` (integer, required): Firewall id, as returned by list_firewalls or create_firewall.

### `attach_firewall` (~107 tokens)

Attach a firewall to a machine

From now on the machine refuses inbound traffic no rule of its firewalls opens; enforced within about ten seconds of the call. Up to 5 firewalls per machine, rules add up. Refused for a machine with no public address. Attaching again is harmless. Scope: network.write.

Input parameters:

- `firewall` (integer, required): Firewall id, as returned by list_firewalls or create_firewall.
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `detach_firewall` (~73 tokens)

Detach a firewall from a machine

Removes the firewall's rules from the machine; with no other firewall it accepts all inbound traffic again. Scope: network.write.

Input parameters:

- `firewall` (integer, required): Firewall id, as returned by list_firewalls or create_firewall.
- `vm` (integer, required): Machine id, as returned by list_vms or create_vm.

### `list_load_balancers` (~42 tokens)

List load balancers

The account's load balancers with their addresses, pools, targets and health, listeners and rules, certificates; plus the quota. Scope: vms.read.

### `get_load_balancer` (~79 tokens)

Get a load balancer

One load balancer in full: status, ipv4/ipv6 to put in DNS, pools with targets (health, sessions, response time), listeners with rules in evaluation order, certificates. Scope: vms.read.

Input parameters:

- `lb` (integer, required): Load balancer id, as returned by list_load_balancers or create_load_balancer.

### `get_load_balancer_metrics` (~88 tokens)

Load balancer statistics

Requests by response class, connections, bytes in/out and peak sessions over 1h (1-minute buckets), 24h (15 minutes) or 7d (1 hour), plus totals. Scope: vms.read.

Input parameters:

- `lb` (integer, required): Load balancer id, as returned by list_load_balancers or create_load_balancer.
- `range` (string)

### `create_load_balancer` (~215 tokens)

Create a load balancer

Orders a load balancer in a private network, billed by the hour from now (the account needs 24 hours of credit), or by the month (7.30 CAD) or the year (73 CAD) with billing. A monthly or yearly period comes out of credit if it covers it; otherwise billing.pending_invoice holds the invoice to pay and it stays hourly until then. Ready within minutes (status pending → active); pools and listeners can be added meanwhile. Retrying the same call is safe. Scope: vms.create.

Input parameters:

- `billing` (string): hourly (default), monthly (the price of 730 hours, paid in advance) or yearly (ten months). Ask the user; monthly or yearly needs credit or an invoice paid by the user.
- `idempotency_key` (string): Your own unique value per order. By default one is derived from the call.
- `name` (string, required)
- `vpc` (integer, required): Private network whose machines will be the targets (list_vpcs).

### `delete_load_balancer` (~66 tokens)

Delete a load balancer

Deletes the load balancer, its address and its configuration; billing stops. Target machines are not touched. Ask the user first. Scope: vms.destroy.

Input parameters:

- `lb` (integer, required): Load balancer id, as returned by list_load_balancers or create_load_balancer.

### `upsert_pool` (~225 tokens)

Create or update a pool

Without pool: creates one (name required, up to 10). With pool: changes only the fields given. Deleting a pool also removes its targets and the rules leading to it. Scope: network.write.

Input parameters:

- `algorithm` (string)
- `health_interval` (integer): Seconds between checks, default 5.
- `health_path`: e.g. /health
- `health_type` (string): http (http pools only): GET health_path, 2xx or 3xx is healthy. Default tcp.
- `lb` (integer, required): Load balancer id, as returned by list_load_balancers or create_load_balancer.
- `name` (string): Letters, digits, spaces, . _ -; unique in the load balancer.
- `pool` (integer): Pool id, from get_load_balancer.
- `protocol` (string): http pools serve http/https listeners, tcp pools tcp listeners. Default http; cannot change once in use.
- `send_proxy` (boolean): tcp pools only: PROXY protocol v2 to the targets.

### `delete_pool` (~65 tokens)

Delete a pool

Removes a pool, its targets and the rules leading to it. Scope: network.write.

Input parameters:

- `lb` (integer, required): Load balancer id, as returned by list_load_balancers or create_load_balancer.
- `pool` (integer, required): Pool id, from get_load_balancer.

### `set_targets` (~112 tokens)

Set the targets of a pool

REPLACES the pool's targets with exactly this list (up to 25): send every target to keep. Each machine must be in the load balancer's private network (connect_vpc first). drain: true stops new connections to a target before maintenance. Scope: network.write.

Input parameters:

- `lb` (integer, required): Load balancer id, as returned by list_load_balancers or create_load_balancer.
- `pool` (integer, required): Pool id, from get_load_balancer.
- `targets` (array, required)

### `upsert_listener` (~196 tokens)

Open or update a listener

An entry port on the load balancer's address. Without listener: opens one (port and protocol required, up to 5; 22 and 8402 are reserved). https gets certificates for its rules' hostnames; redirect_https makes port 80 redirect to it. A tcp listener needs a tcp default_pool. sources restricts who may connect (null: everyone); with an https listener, port 80 stays open to everyone. Scope: network.write.

Input parameters:

- `default_pool`: Pool for traffic no rule matches; none answers 503.
- `lb` (integer, required): Load balancer id, as returned by list_load_balancers or create_load_balancer.
- `listener` (integer): Listener id, from get_load_balancer.
- `port` (integer)
- `protocol` (string)
- `redirect_https` (boolean)
- `sources`: IPv4/IPv6 addresses or ranges allowed in.

### `delete_listener` (~61 tokens)

Close a listener

Closes the port and removes its rules. Scope: network.write.

Input parameters:

- `lb` (integer, required): Load balancer id, as returned by list_load_balancers or create_load_balancer.
- `listener` (integer, required): Listener id, from get_load_balancer.

### `set_rules` (~129 tokens)

Set the routing rules of a listener

REPLACES the http/https listener's rules: each sends a hostname and/or path prefix to an http pool (up to 25). They are evaluated most specific first, whatever the order sent; anything unmatched goes to the default pool. No wildcard hostname on https. Each https hostname gets a certificate once it points to the load balancer. Scope: network.write.

Input parameters:

- `lb` (integer, required): Load balancer id, as returned by list_load_balancers or create_load_balancer.
- `listener` (integer, required): Listener id, from get_load_balancer.
- `rules` (array, required)

### `list_databases` (~42 tokens)

List databases

The account's managed databases with their status, private and public addresses, disk, backups and billing (no passwords), plus the quota. Scope: vms.read.

### `get_database_options` (~62 tokens)

Database options

What can be ordered: engines and versions, extensions, sizes with their hourly, monthly and yearly prices per region, and the price of disk beyond what a size includes. Call it before create_database and show the price to the user. Scope: vms.read.

### `get_database` (~116 tokens)

Get a database

One database: status, connection (host, private ip, port, defaultdb and ffxfadmin; on Valkey no database and default), public access and sources, disk usage and cap, users with their databases (null: all) and read_only, logical databases and extensions, Valkey's eviction policy and data memory, backups and restore window, maintenance window, fork link, warning. No passwords. Scope: vms.read.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.

### `get_database_credentials` (~95 tokens)

Get database credentials

Every user with its password, databases and read_only, and its own connection_uri; ready-made connection strings for the admin (private network, and public when open). Treat the result as a secret: give it to the application through an environment variable or a secret store, never into code, commits or logs. Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.

### `get_database_metrics` (~87 tokens)

Database statistics

CPU, memory, connections and commits per minute (commands per minute on Valkey) over 1h (1-minute buckets), 24h (10 minutes) or 7d (1 hour); only buckets with samples. Scope: vms.read.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `range` (string)

### `get_slow_queries` (~110 tokens)

Most expensive queries

The 20 queries with the most total time (pg_stat_statements, values replaced by $1, $2…; performance_schema on MySQL and MariaDB, values replaced by ?): calls, total and mean time, rows. A starting point for indexes. On Valkey, the commands with the most total time since the engine started (GET, HSET…). Scope: vms.read.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.

### `list_database_backups` (~94 tokens)

List database backups

Completed backups (weekly full, daily differential; the transaction log is archived continuously) and the restore window: any minute in it can be restored with restore_database. On Valkey, snapshots (rdb) every hour when there were writes, all kept 24 hours, then one a day. Scope: vms.read.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.

### `create_database` (~335 tokens)

Create a database

Orders a managed database (PostgreSQL, MySQL, MariaDB or Valkey) in a private network, billed by the hour from now (the account needs 24 hours of credit), or by the month (730 hours) or the year (ten months) with billing; get_database_options gives each price. A monthly or yearly period comes out of credit if it covers it; otherwise billing.pending_invoice holds the invoice to pay and it stays hourly until then. Ready within minutes (status pending → active), with the admin user ffxfadmin and the logical database defaultdb (Valkey: the admin default, no logical database). Retrying the same call is safe. Scope: vms.create.

Input parameters:

- `billing` (string): hourly (default), monthly (the price of 730 hours, paid in advance) or yearly (ten months). Ask the user; monthly or yearly needs credit or an invoice paid by the user.
- `engine` (string): Default postgresql. mysql is Percona Server; valkey is Redis-compatible (key-value, in memory).
- `idempotency_key` (string): Your own unique value per order. By default one is derived from the call.
- `name` (string, required)
- `size_gb` (integer): Memory in GB, one of the sizes of get_database_options for the region. Default: 1, or the source's size.
- `version` (string): Major version from get_database_options; the newest by default.
- `vpc` (integer, required): Private network the database joins (list_vpcs); the machines on it reach the database.

### `restore_database` (~207 tokens)

Restore into a new database

Creates a NEW database, billed like any other, holding the data as it was at a given minute of the source's restore window (list_database_backups; Valkey: the last snapshot before that minute), with the same users and passwords. The source is not touched and may have been deleted in the last 7 days. Retrying the same call is safe. Scope: vms.create.

Input parameters:

- `at` (string, required): ISO 8601 timestamp, UTC unless an offset is given, e.g. 2026-10-14T09:30:00Z.
- `database` (integer, required): The source database.
- `idempotency_key` (string)
- `name` (string, required): Name of the new database.
- `size_gb` (integer): Memory in GB, one of the sizes of get_database_options for the region. Default: 1, or the source's size.
- `vpc` (integer): Default: the source's private network.

### `fork_database` (~177 tokens)

Fork a database

Creates a NEW database, billed like any other, whose data is an instant copy of this one (for a test or staging copy), with the same users and passwords. It stays linked to its source for up to 7 days (no backups of its own, the source cannot be deleted) unless detach_database_fork ends that sooner. Retrying the same call is safe. Scope: vms.create.

Input parameters:

- `database` (integer, required): The source database.
- `idempotency_key` (string)
- `name` (string, required): Name of the new database.
- `size_gb` (integer): Memory in GB, one of the sizes of get_database_options for the region. Default: 1, or the source's size.
- `vpc` (integer): Default: the source's private network; same region either way.

### `detach_database_fork` (~61 tokens)

Make a fork independent

Gives a linked fork its own copy of the data; the database is unavailable for about 30 seconds, then its backups start. Scope: vms.action.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.

### `resize_database` (~164 tokens)

Upgrade a database to a larger size

Moves the database to a LARGER size (more vCPU, memory and included disk; see get_database_options): same data, users, names and addresses. It restarts: one to two minutes of downtime, status maintenance meanwhile (resize.to_gb set), then active with the new size_gb. The new rate applies from the next hour. Larger sizes only, there is no way back: tell the user the new price and the downtime first. Retrying the same call is safe. Scope: vms.create.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `idempotency_key` (string)
- `size_gb` (integer, required): Memory in GB, larger than the current size_gb.

### `delete_database` (~103 tokens)

Delete a database

DELETES the database and its data; billing stops. Ask the user first. confirm_name must be the database's exact name. Its backups stay 7 days (restore_database can bring it back meanwhile). Refused while a linked fork depends on it. Scope: vms.destroy.

Input parameters:

- `confirm_name` (string, required): The database's exact name, typed back as confirmation.
- `database` (integer, required): Database id, as returned by list_databases or create_database.

### `update_database` (~185 tokens)

Update a database

Any of: the name; the weekly maintenance window (day 0 = Sunday, start hour, Montréal time, 2 hours long; minor updates, usually under 2 minutes of downtime); the disk cap (the disk grows by itself at 80 % full, up to the cap; disk beyond what the size includes is billed per GB); on Valkey, the eviction policy. Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `disk_cap_gb` (integer)
- `eviction_policy` (string): Valkey only: what happens when data memory is full. noeviction (default) refuses writes; allkeys-lru removes the least used keys, for a cache.
- `maintenance_day` (integer)
- `maintenance_hour` (integer)
- `name` (string)

### `set_database_public_access` (~117 tokens)

Set public access

Opens the database to the internet at its public host and port (IPv4 and IPv6, TLS and password still required), or closes it. sources restricts who may connect (IPv4/IPv6 addresses or ranges); omitted it is left as is, null or [] means everyone. Prefer listing the user's addresses. Live within about 30 seconds. Scope: network.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `enabled` (boolean, required)
- `sources`

### `backup_database` (~55 tokens)

Back up now

Starts a differential backup within a minute, e.g. before a risky migration. Not available on a linked fork. Scope: backups.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.

### `create_database_user` (~234 tokens)

Add a database user

Creates a user with a generated password, returned here once (also readable with get_database_credentials); live within seconds. Up to 30 users. It connects only to its databases (every logical database, future ones included, when databases is omitted): it reads and writes everything there and creates tables (on PostgreSQL in public too), or only reads with read_only; elsewhere it has no access. Its connection_uri points to defaultdb, or to its first database without access to defaultdb. On Valkey, an ACL user with every key and data command (no databases, no read_only). Treat the password as a secret. Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `databases` (array): Logical databases it may connect to (existing ones, see get_database). Omit for all of them, future ones included.
- `read_only` (boolean): SELECT only (MySQL, MariaDB: SELECT and SHOW VIEW). Default false.
- `username` (string, required): Lowercase letters, digits and _, starting with a letter or _.

### `set_database_user_access` (~168 tokens)

Change a database user's access

Sets the logical databases a user connects to (databases: a list, or null for all of them, future ones included) and whether it only reads; a field left out keeps its value. Applied within seconds; where its access is removed or lowered, its open connections are closed, so tell the user first if an application uses it. Not on the admin (it always has every database) nor on Valkey. Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `databases`: Logical databases it may connect to; null for all of them, future ones included.
- `read_only` (boolean)
- `username` (string, required): Lowercase letters, digits and _, starting with a letter or _.

### `reset_database_password` (~80 tokens)

Reset a database password

Gives the user a new password, returned here; the old one stops working within seconds, so update the application first or right after. Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `username` (string, required): Lowercase letters, digits and _, starting with a letter or _.

### `delete_database_user` (~83 tokens)

Delete a database user

Hands the user's objects to the admin, then drops the user. The admin (ffxfadmin, or default on Valkey) cannot be deleted. Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `username` (string, required): Lowercase letters, digits and _, starting with a letter or _.

### `create_logical_database` (~92 tokens)

Add a logical database

Creates another database inside the managed database (like defaultdb), owned by the admin; up to 30. Not on Valkey (numbered databases, SELECT 0 to 15). Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `name` (string, required): Lowercase letters, digits and _, starting with a letter or _.

### `delete_logical_database` (~77 tokens)

Delete a logical database

DROPS the logical database with everything in it (the backups keep it 7 days). Ask the user first. Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `name` (string, required): Lowercase letters, digits and _, starting with a letter or _.

### `enable_extension` (~93 tokens)

Enable a PostgreSQL extension

PostgreSQL only. Enables an extension from get_database_options (vector for pgvector, postgis, pg_trgm…) in one logical database; installed on demand, live within a minute. Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `extension` (string, required)
- `name` (string, required): The logical database, e.g. defaultdb.

### `disable_extension` (~72 tokens)

Remove a PostgreSQL extension

Drops the extension without CASCADE: if objects depend on it, it stays and get_database shows why in warning. Scope: databases.write.

Input parameters:

- `database` (integer, required): Database id, as returned by list_databases or create_database.
- `extension` (string, required)
- `name` (string, required): The logical database.

### `get_runners` (~103 tokens)

GitHub runners

The runs-on labels with their vCPU, memory and price per minute, the account's concurrency (vCPU of jobs starting or running, and the cap), the linked GitHub organizations and accounts, this month's minutes and cost per repository, the actions cache next to the runners (bytes, entries and last use per repository, price per GB per month), and the Docker cache per repository (enabled in the console, bytes, last successful job). Scope: billing.read.

### `list_runner_jobs` (~122 tokens)

List runner jobs

Jobs that ran or wait on FFxF runners, most recent first: repository, workflow and job, label, status (queued with waiting_reason credit, budget or account; running; succeeded; failed, stopped_for_credit when the credit ran out; cancelled; refused with refusal), times, billed minutes and amount, link to the run. Scope: billing.read.

Input parameters:

- `cursor` (string): meta.next_cursor of the previous page.
- `limit` (integer): Default 25.
- `repository` (string): owner/name
- `status` (string)

### `list_ssh_keys` (~33 tokens)

List SSH keys

SSH keys saved on the account, to pass to create_vm. Scope: sshkeys.write or vms.read.

### `add_ssh_key` (~66 tokens)

Add an SSH key

Saves a public key on the account so new machines can be reached without a password. Scope: sshkeys.write.

Input parameters:

- `name` (string, required)
- `public_key` (string, required): OpenSSH public key, e.g. ssh-ed25519 AAAA… user@host.

### `delete_ssh_key` (~48 tokens)

Delete an SSH key

Removes a key from the account. Machines already deployed with it keep it; only future deployments change. Scope: sshkeys.write.

Input parameters:

- `key` (required): Key id from list_ssh_keys.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/net-ffxf-cloud/ffxf#diagnostics

## Score history

- 2026-11-05: 69
- 2026-11-04: 68
- 2026-11-03: 68
- 2026-11-02: 67
- 2026-11-01: 67
- 2026-10-31: 66
- 2026-10-30: 66
- 2026-10-29: 65
- 2026-10-28: 65

## Common questions

### What is the FFxF MCP server?

FFxF is an MCP server listed in the public MCP registry as net.ffxf/cloud. Create and manage VMs, managed databases, firewalls and load balancers in Montréal, Canada. This page covers its hosted endpoint (https://ffxf.net/mcp).

### Is the FFxF MCP server safe to use?

FFxF scores 69 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the FFxF MCP server expose?

FFxF exposes 71 tools: list_regions, list_plans, list_images, get_account, list_vms, and 66 more. Their descriptions and schemas cost roughly 7,220 tokens of context every time the server is loaded.

### Does the FFxF MCP server require authentication?

No. We connected to FFxF without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

### Is the FFxF MCP server still maintained?

FFxF is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://ffxf.net/mcp
- Website: https://ffxf.net/agents
- Changelog RSS feed: https://verifymcp.io/servers/net-ffxf-cloud/ffxf.xml
- Changelog JSON feed: https://verifymcp.io/servers/net-ffxf-cloud/ffxf.json
- HTML version of this page: https://verifymcp.io/servers/net-ffxf-cloud/ffxf
