SSH is a privilege. FTP is a habit. An agent that needs either one can also read .env, rewrite .htaccess, and delete the database. Forma’s Agent API exists so Cursor can do CMS work over HTTPS with a leash.
Create the token
In Admin → Settings → API / Agents, create a token with only the scopes the job needs:
content:read/content:write— pages, posts, snippetsmedia:write— uploadssettings:write— site and SEObackup:read— site packagespodcast:write— if the site is licensed
Give a writing agent content:write and maybe media:write. Do not hand it settings:write because it is drafting a blog post.
Treat the token like a password. HTTPS only. Revoke it when the job is done.
First call
GET /api/v1/help
Authorization: Bearer fx_…
That response is the map: every endpoint, the SEO field names, the scopes, and how pages differ from posts. Read it before improvising. Agents that skip /help invent field names and then wonder why META did not update.
DreamHost-safe alternative header: X-Forma-Token: fx_… if Authorization gets stripped.
What a good session looks like
GET /api/v1/site— confirm you are on the right install.GET /api/v1/postsor/pages— see what exists.GETthe one document you will change.PUTwith the full fields you mean to set. For posts, omitbodyif you are only changing SEO or the featured image.- Hit the public URL. Search for a distinctive phrase. Check
/sitemap.xmlif it is a new published post.
The MCP server (formax_* tools) is the same API with friendlier names. If MCP is down, curl still works. The token is the contract, not the transport.
What the token cannot do
It cannot SSH. It cannot run push.sh. It cannot read some other site’s database. Unpublished posts stay unpublished. /search and /admin stay off the token’s write surface.
That is the point of the leash. An agent that can ship a blog post should not also be able to take the server apart.
