AI agents (MCP)
@trokky/mcp is a Model Context Protocol server. With it, an AI agent can learn a site’s content model, then list, search, draft, edit, publish and delete documents and upload media. It uses the same API as everything else, with the access the person approving gave it.
It runs on your machine, started by the MCP client, and talks to your sites over HTTPS. Nothing is installed on the server. It needs Node.js 20 or later, and sites on 3.5.2 or later with OAuth2 enabled. For a site you cannot enable that on, pin it with an API token instead.
Connect a client
Section titled “Connect a client”Claude Code
claude mcp add trokky -- npx -y @trokky/mcp@3Claude Desktop, Cursor and other clients take the same thing as JSON, under mcpServers:
{ "mcpServers": { "trokky": { "command": "npx", "args": ["-y", "@trokky/mcp@3"] } }}On Windows, npx is a batch file: use "command": "cmd" with "args": ["/c", "npx", "-y", "@trokky/mcp@3"].
Pin the major version (@3) rather than running whatever is newest. The package runs with your sign-ins at hand, so an upgrade should be something you choose.
Add a site
Section titled “Add a site”Ask the agent: “Add the site cms.example.com with edit access.”
- The agent calls
add_siteand writes the link and the code in its reply. - You open the link, sign in to that site’s Studio if you are not already, and check that the code matches.
- You untick anything you do not want to give, and approve.
- The site is saved the moment you approve. The agent does not need to ask whether you are done: it waits in
finish_add_site, which returns as soon as the approval arrives. If you take longer than about a minute and a half, it reports that it is still waiting and calls again.
If you deny the request, or the code expires (after about ten minutes), the agent tells you, and add_site starts a fresh sign-in. A sign-in in progress survives a restart of the MCP server; its code is kept in mcp-sign-ins.json beside the site list, never a token. This behaviour arrived in @trokky/mcp 3.5.4.
The agent asks for one of four levels. You can always narrow it on the approval screen.
| Level | Asks for |
|---|---|
read | View content and media |
edit | Also create and change content, upload media. The default. |
publish | Also publish and unpublish |
full | Also delete content and media |
Whatever it asks, the site gives the agent no more than you approved, and never more than your own account may do. An agent signed in by an admin is not an admin.
From a terminal instead:
npx @trokky/mcp@3 login https://cms.example.com --access editnpx @trokky/mcp@3 siteslogin takes --name to choose the site’s name and --replace to sign in again to a site you already have. A site is named after the first part of its hostname, with the port when there is one: cms.example.com is cms, localhost:3000 is localhost-3000.
Several sites
Section titled “Several sites”Add as many as you work on. The first becomes the default. Every content tool takes an optional site, so the agent can work on another one without switching:
| Tool | |
|---|---|
list_sites | The sites, which one is the default, and how each is signed in |
add_site, finish_add_site | Sign in to a site, as above |
set_default_site | The site used when a tool is called without site |
remove_site | Forget a site and revoke its sign-in on the site |
Sign-ins renew themselves. A session lasts as long as it is used at least once every 30 days, or whatever the site set as its refresh token lifetime.
The sites are the CLI’s. They live in ~/.trokky/config.yaml, the file the Trokky CLI uses, so a site signed in with either one works in both. The two coordinate their writes, so a token renewal in one is never lost to a save in the other. TROKKY_CONFIG points the MCP server at another file; the CLI always uses ~/.trokky/config.yaml.
What the site sees
Section titled “What the site sees”In the site’s Studio, the agent appears under Preferences > Connected applications as Trokky MCP (AI agent), with the access it holds, when it was last used, and where it signed in from: trokky-mcp/3.5.2 (claude-code; macOS; laptop-name). The name of your machine is shown to the site’s admins, who see every connected application under Users & Access. It is sent with the sign-in only, not with every request.
Revoke there ends the agent’s access at once. The next call tells the agent the session has ended, and it asks you to add the site again.
Every change the agent makes is recorded as yours, via Trokky MCP (AI agent): a document’s history reads “Updated by amen via Trokky MCP (AI agent)”, so its edits can be told from your own.
One site with an API token
Section titled “One site with an API token”For a site without OAuth2, or a shared machine where no one should sign in, pin one site with an API token:
claude mcp add trokky \ --env TROKKY_URL=https://cms.example.com \ --env TROKKY_TOKEN=<token> \ -- npx -y @trokky/mcp@3The site-management tools are then not offered. Create the token for the agent alone, in Studio under Users & Access > API Tokens, with only what it needs and an expiry:
| The agent should | Permissions |
|---|---|
| Answer questions about the content | view content, view media |
| Draft articles for a person to review | view content, edit content, view media, upload media |
| Run the site end to end | add publish content and delete content, only if you mean it |
To limit a token to some collections, create it through the API with per-collection permissions such as posts:read and posts:write (see API tokens); Studio’s dialog offers the site-wide ones only.
Configuration
Section titled “Configuration”| Variable | |
|---|---|
TROKKY_URL | With TROKKY_TOKEN, pins one site. The site (https://cms.example.com means its /api) or the API itself if it is mounted elsewhere. No credentials in the URL. |
TROKKY_TOKEN | The API token for that site. |
TROKKY_CONFIG | Where the site list lives, instead of ~/.trokky/config.yaml. The CLI does not read it, so a file set here is the MCP server’s alone. |
TROKKY_READ_ONLY | 1 registers only the reading tools, and add_site asks for read access whatever the agent requests. |
TROKKY_UPLOAD_DIRS | Absolute paths the agent may upload files from, separated by : (; on Windows). Unset, the agent cannot upload at all. |
TROKKY_MAX_UPLOAD_MB | Largest upload, default 25. |
What the agent can do
Section titled “What the agent can do”| Tool | Needs | |
|---|---|---|
list_collections | Collections, their fields, and the document id of each singleton | any access |
get_schema | One collection’s full schema | any access |
list_documents | A page of documents, with exact-match filter, sort and reference expand | view content |
get_document | One document | view content |
search | Text search over the collections it can read, plus media names when it can view media | any access |
list_media, get_media | Media metadata, with each file’s public URL | view media |
create_document | A new document, draft unless asked otherwise | edit content, plus publish to create it published |
update_document | Change some fields and keep the rest | edit content |
set_status | Publish or unpublish | publish |
delete_document | Delete for good | delete content |
upload_media | Upload a local file | upload media, and TROKKY_UPLOAD_DIRS |
The server hands the agent what it cannot guess from a schema. How a media field and a reference field are written, that a slug is not regenerated when the title changes, and that an array field is replaced whole on update, not merged.
Where the boundary is
Section titled “Where the boundary is”The site. Every call goes through the API, which checks what the sign-in or token may do. The MCP server adds nothing it could get wrong: a tool the agent may not use answers 403, and the agent is told not to retry. A sign-in can never reach the account itself: passwords, passkeys, MFA, users, API tokens, webhooks and settings are refused to it whoever approved it.
Read-only mode goes further and does not register the writing tools at all. One read still writes: reading a singleton that has never been saved creates it empty, as it does for any reader of the site.
Publishing, unpublishing, updating, deleting and removing a site are marked destructive, so clients that honour tool annotations ask you before each one.
Uploads are the one place the agent touches your disk, and uploaded media is public to anyone with its URL. So upload_media only reads from TROKKY_UPLOAD_DIRS (symlinks are resolved, so a link cannot lead out), only file types the server accepts, and the type is judged from the file on disk, so an agent cannot publish .env by calling it notes.txt. SVG is refused, because media is served inline and an SVG can carry script.
Content is input. What the agent reads was written by your editors. The server tells the agent to treat instructions inside content as data, but that is advice to a model, not a control. If people you do not trust can edit the site, approve read access only, or keep a person approving each write.
When it does not work
Section titled “When it does not work”| The agent reports | Cause |
|---|---|
No site is set up yet | Add one with add_site, or set TROKKY_URL and TROKKY_TOKEN. |
does not have sign-in for applications enabled | The site has oauth2.enabled unset. Enable it, or use an API token. |
The site's session has ended | The sign-in was revoked in Studio, lapsed after 30 days unused, or was made before the site ran 3.5.2. Add the site again. |
401 | With an API token: the token is wrong, revoked or expired. |
403 | The sign-in or token lacks that permission. The agent will not retry. |
Could not reach … | Wrong URL, or the site is down. A bare origin gets /api added. |
| A warning about plain http | The site is reached over http:// on a remote host, so sign-ins and tokens cross the network unencrypted. Use https://. |
The server writes its own messages to stderr, which most clients show in their MCP logs. Claude Code lists servers and their state with claude mcp list.