Control-plane MCP
Connect an external agent (Claude Code, Cursor, MCP Inspector) into RetinueOS.
How to connect an external agent (Claude Code, Cursor, MCP Inspector) into RetinueOS so it can inspect personas, run jobs, manage routines, and resolve approvals. Architecture is ADR 0005. This doc is the operator how-to.
This is the opposite of Connectors. Connections lets a
RetinueOS persona call an outbound MCP server (Gmail, Calendar, …). This
page is the inbound control plane. Personas never call /mcp/control; they
use native tools.
Endpoint
${BACKEND_URL}/mcp/controlBACKEND_URL is the backend origin — the same host as NEXT_PUBLIC_BACKEND_URL.
Transport is Streamable HTTP. There is no stdio server.
| Setup | App (frontend) | MCP URL |
|---|---|---|
| Local Compose | http://localhost:3000 | http://localhost:8080/mcp/control |
| Split-origin production | https://retinue.example.com | https://api.retinue.example.com/mcp/control |
Use the API host, not the app host. Pointing Claude Code or Cursor at the frontend origin returns Next.js HTML 404. Clients report that as "Couldn't connect to the server. Check that the URL points to a valid MCP server."
On the personal deploy that is:
- App:
https://retinue.sissingh.me - MCP:
https://api.retinue.sissingh.me/mcp/control
The Access page (/settings/access) shows the correct URL for the running
instance.
Quick check that you hit the backend, not Next.js:
curl -sS -D - -o /dev/null https://api.retinue.sissingh.me/mcp/controlExpect HTTP 401 with Content-Type: application/json and
{"error":"invalid or missing bearer token"}. HTML 404 means the frontend
host.
Create a token
- Open Access (
/settings/access). - Name the client (for example
Claude Code on my laptop). - Select scopes. Choosing a write scope also selects its matching read scope in the form; the server still enforces each scope independently.
- Click Create token and copy it immediately. RetinueOS shows the plaintext once.
Token shape: rtn_live_<12-character-prefix>_<43-character-secret>.
Every MCP request needs:
Authorization: Bearer rtn_live_…Do not put the token in the query string. Missing, invalid, or revoked
credentials return HTTP 401. Revoke from the same Access page; the next
request fails.
Scopes
Discovery returns only tools the token is allowed to call. A jobs:write
token can create a job but cannot inspect it unless it also has jobs:read.
| Scope | Tools |
|---|---|
personas:read | retinue_personas_list, retinue_personas_get |
jobs:read | retinue_jobs_list, retinue_jobs_get |
jobs:write | retinue_jobs_create, retinue_jobs_continue, retinue_jobs_cancel |
routines:read | retinue_routines_list |
routines:write | retinue_routines_create, retinue_routines_update, retinue_routines_pause, retinue_routines_resume, retinue_routines_run, retinue_routines_delete |
approvals:read | retinue_approvals_list |
approvals:write | retinue_approvals_resolve |
audit:read | retinue_audit_list |
A useful Claude/Cursor default is personas + jobs + routines + approvals (read and write) if the agent should operate the control plane. Use read-only scopes when it should only inspect.
Claude Code
claude mcp add --transport http retinueos https://api.retinue.sissingh.me/mcp/control \
--header "Authorization: Bearer rtn_live_your_token"Replace the URL with your BACKEND_URL plus /mcp/control.
Cursor
In ~/.cursor/mcp.json or the project .cursor/mcp.json:
{
"mcpServers": {
"retinueos": {
"url": "https://api.retinue.sissingh.me/mcp/control",
"headers": {
"Authorization": "Bearer rtn_live_your_token"
}
}
}
}Reload MCP (or restart Cursor) after saving.
MCP Inspector
Connect Inspector to the same URL with the same Authorization header. That
is the fastest way to confirm handshake, scope-filtered discovery, and that a
read-only token cannot see write tools.
Constraints
- HTTPS outside localhost. A non-local
BACKEND_URLmust behttps://. - Origin. CLI clients that omit
Originare fine. If a client sendsOrigin, it must matchFRONTEND_ORIGINor the origin ofBACKEND_URL. A browser page from some other host gets403 untrusted Origin. - No OAuth yet. Hosted Claude.ai connector onboarding is not in this release. Manual bearer tokens work for Claude Code, Cursor, and other HTTP MCP clients.
- No stdio. Clients that can only spawn a local process cannot connect without their own HTTP bridge.
- No query credentials.
token,access_token, andpasswordquery parameters are rejected before the header is read.