Manage Statamic content through a safe, authenticated tool execution gateway. Supports managing multiple Statamic sites from a single agent installation.
Before first use, follow the setup in INSTALL.md. For the endpoint contract, see references/api.md.
Credentials are stored in ~/.config/ai-gateway/sites.json (override with AI_GATEWAY_SITES_CONFIG).
{
"sites": {
"marketing": { "base_url": "https://marketing.example.com", "token": "token-aaa..." },
"docs": { "base_url": "https://docs.example.com", "token": "token-bbb..." }
}
}
Look up base_url and token by site name before every request.
| Method | Path | Purpose |
|---|---|---|
| -------- | ----------------------------------- | ---------------------------------------- |
| POST | /ai-gateway/execute | Execute a tool |
| GET | /ai-gateway/capabilities | List all tools and their enabled state |
| GET | /ai-gateway/capabilities/{tool} | Get full usage docs for a specific tool |
All requests require Authorization: Bearer {token}.
Do not guess tool arguments. Always discover before executing:
GET /capabilities — see which tools are enabled on this siteGET /capabilities/{tool.name} — get the argument schema, validation rules, example request/response, allowed targets, denied fields, and behavioral notes for that tool/execute requestThis is the primary way to learn how to use any tool. The capabilities endpoints are the source of truth.
{
"tool": "tool.name",
"arguments": { },
"request_id": "optional-tracking-id",
"idempotency_key": "optional-dedup-key",
"confirmation_token": "optional-if-confirming"
}
Success: { "ok": true, "tool": "...", "result": { ... }, "meta": { ... } }
Error: { "ok": false, "tool": "...", "error": { "code": "...", "message": "..." }, "meta": { ... } }
> ⛔ CRITICAL — Structured field values are READ-ONLY structures.
> Bard, Replicator, Grid, and similar fields store values as deeply nested ProseMirror/TipTap JSON. When reading these back from entry.get or global.get, you will see arrays of node objects with type, attrs, content, and marks keys.
>
> You MUST NOT alter the structure. Never add, remove, reorder, or rename nodes, attributes, or marks. You may only change the literal text strings inside leaf nodes — nothing else.
>
> To update a rich-text field: (1) fetch with entry.get/global.get, (2) change only text values, (3) send back structurally identical. Violating this corrupts content.
base_url and token from sites.json before every request./capabilities then /capabilities/{tool} before using any tool for the first time on a site.enabled: true. Only target allowlisted resources. forbidden means off-limits.data must be a JSON object, never an array or string. Don't send unknown argument keys.entry.upsert over entry.create — safer and idempotent.navigation.update is a full tree replacement. Always fetch with navigation.get first.requires_confirmation: true in capabilities: (1) send the request, (2) receive confirmation_required with a token, (3) show the user the operation_summary and ask permission, (4) only if approved, resend with confirmation_token. Never auto-confirm.rate_limited, back off and retry.request_id (e.g. marketing:upsert-about).stache.warm rebuilds content indexes, static.warm regenerates static pages.| Code | HTTP | Action |
|---|---|---|
| ------------------------ | ------ | ------------------------------------------------- |
unauthorized | 401 | Check token in sites.json |
forbidden | 403 | Target not in allowlist |
tool_not_found | 404 | Check name against /capabilities |
tool_disabled | 403 | Tool is off on this site |
validation_failed | 422 | Read error.message and error.details |
resource_not_found | 404 | Collection/entry/global/nav/taxonomy missing |
conflict | 409 | Entry exists — use entry.upsert |
rate_limited | 429 | Wait and retry |
confirmation_required | 200 | Resend with confirmation_token (after user OK) |
execution_failed | 500 | Retry or report |
internal_error | 500 | Retry or report |
共 1 个版本