Runtimes & capabilities
Every site carries a runtime — wordpress, static, or wasm — and each
runtime advertises a set of capabilities: the actions it can actually perform. A
client asks a site what it can do and branches
on the answer, instead of hard-coding if runtime == "wordpress". This page is the
reference matrix: which capability each runtime supports, and what “no” means when it
doesn’t.
discover at runtime, don’t hard-code
Section titled “discover at runtime, don’t hard-code”The platform answers the question for you. Call GET /v1/sites/{id}/capabilities for
one site, or GET /v1/runtimes for the catalog of every runtime and its default
capabilities — both need sites:read. In the
CLI that’s mf capabilities <siteID> and mf runtimes; in the Go
SDK, client.Capabilities.ForSite(ctx, siteID) and
client.Capabilities.ListRuntimes(ctx).
{ "data": { "runtime": "wordpress", "capabilities": { "components.plugins": { "supported": true, "actions": ["list", "install", "activate", "update", "delete"] }, "components.themes": { "supported": true, "actions": ["list", "activate", "update", "delete"] }, "components.users": { "supported": true }, "components.content": { "supported": true }, "cron": { "supported": true, "kind": "wp-cron" }, "database": { "supported": true, "engine": "mysql" }, "exec": { "supported": true, "shells": ["wp-cli", "bash"] }, "magic_link": { "supported": true }, "clone_content": { "supported": true, "selectors": ["db", "files"] }, "build": { "supported": true }, "functions": { "supported": false } } }, "request_id": "req_01J7..."}Each capability is an object with one required field and optional detail where it’s useful:
| Field | Type | Meaning |
|---|---|---|
supported |
boolean | Whether this runtime can do it at all. Always present. |
actions |
string[] | The verbs allowed, e.g. a component kind’s install/update. |
kind |
string | A flavor, e.g. wp-cron for the cron capability. |
engine |
string | A database engine, e.g. mysql. |
shells |
string[] | The shells exec can run, e.g. wp-cli, bash. |
selectors |
string[] | What clone_content can copy — db, files. |
Every runtime reports the same capability keys, so a client always sees the same
shape and reads supported: false explicitly rather than probing for missing keys.
the matrix
Section titled “the matrix”Rows are capabilities; columns are runtimes. A cell shows the supported detail, or
false when the runtime can’t do it at all.
| Capability | wordpress |
static |
wasm |
|---|---|---|---|
components.plugins |
list · install · activate · update · delete | false |
false |
components.themes |
list · activate · update · delete | false |
false |
components.users |
supported | false |
false |
components.content |
supported | false |
false |
cron |
wp-cron |
false |
false |
database |
mysql |
false |
false |
exec |
wp-cli · bash |
false |
false |
magic_link |
SSO into wp-admin | false |
false |
clone_content |
db · files | files | false |
build |
supported | supported | supported |
functions |
false |
false |
deploy · rollback · routes · secrets |
The wasm runtime is the functions platform: customer code runs untrusted in a
sandboxed WebAssembly tier, so its serve model is functions — and trusted-tier
capabilities like cron stay unsupported. drupal and node runtimes are on the
roadmap; when they land they appear as new catalog entries in GET /v1/runtimes, not
as new endpoints.
which gated endpoints are live
Section titled “which gated endpoints are live”A capability describes what the runtime can do; an endpoint has to exist to exercise it. Today:
| Capability | Endpoint(s) | Scope | Status |
|---|---|---|---|
exec |
POST /v1/sites/{id}/environments/{envID}/exec |
wp.cli:exec |
live |
| cache purge | POST /v1/sites/{id}/environments/{envID}/cache/purge |
cache:write |
live |
functions |
/v1/functions, /v1/sites/{id}/functions, build/deploy/rollback |
functions:read / functions:write |
live |
magic_link |
POST /v1/sites/{id}/magic-link |
credentials:write (isolated) |
live |
components.plugins / components.themes |
plugin & theme management | wp.plugins:*, wp.themes:* |
Preview |
components.content / components.users |
content & user management | wp.content:*, wp.users:* |
Preview |
cron |
cron management | cron:* |
Preview |
database |
database access | db:* |
Preview |
the two “no” semantics
Section titled “the two “no” semantics”A request that can’t be served is reported one of two ways, and the difference is deliberate — see errors:
- Missing resource →
404. The site (or environment, artifact, …) doesn’t exist, or your key can’t see it:site.not_found— existence hiding. - Site exists, runtime can’t →
409 capability.unsupported. The endpoint is real and you’re allowed to call it, but this runtime can’t perform the action. Executing WP-CLI on astaticsite is a409.
Discover capabilities first and you avoid both — the matrix and the discovery endpoint exist precisely so you never have to guess.
adding a runtime is a catalog entry
Section titled “adding a runtime is a catalog entry”The whole point of this model is that a new runtime inherits the entire platform — auth, jobs, SSE, observability, billing — for free. Bringing one online is two pieces of work, neither of which touches the foundational resources:
- A runtime-catalog entry describing its default capabilities (what
GET /v1/runtimesreturns). - A capability provider on the agent side that implements those capabilities —
e.g. mapping a Drupal runtime’s
exectodrush.
No new endpoints, no new scopes, no foundation change. A static site, a WordPress site, and a wasm site are the same resource type with different advertised capabilities — that’s the entire trick. See build runtimes for how detection and the build pipeline fit in.