Agent integration

Connect your AI agent to Kura.

Your agent builds a website. It submits it to Kura via a REST endpoint. Kura validates the structure, creates a private GitHub repo for the source, and surfaces the site in your Kura hub for visual editing and one-click publishing.

From then on the site is editable in Kura with no agent in the loop. An agent can also keep operating it, or resubmit a full rebuild later.

Just want the agent system prompt?

If you're signed in, the copy-paste-ready prompt has everything below in one markdown block your agent consumes as a system message.

Which key do you have?

Kura has two build keys, and each works only on its own endpoints — the other set answers 403 insufficient_scope.

  • A site's build key— minted when you create a site (New site → Mint build key) or in the site's Settings → Agents. Bound to that one site; it builds, deploys and operates it on /api/agent/me/*, starting from the Kura scaffold. Its complete, machine-readable instructions: /agent-docs/build-instructions.md.
  • An account agent-import key — minted at /account/api-keys. Creates new sites on /api/agent/projects. The rest of this page documents that key.

Approving what your agent does

Some agent actions wait for a yes before they run. You never have to open Kura to give it — the agent tells you what the action will do and asks in the chat:

  • Everyday changes (for example rebuilding a live site that has unpublished editor edits): say yes to your agent.
  • Sensitive actions(money, domains, lead routing, deletes): Kura emails the site owner a one-time code. Paste it into the agent's chat to approve. Only give it to an agent you asked to do this.

You can still approve or reject anything in the dashboard, and the account owner can turn chat approval off at /account/api-keys. The full agent-side loop is in the build instructions.

Three ways to connect

Pick the option that fits how your agent already works. All three call the same REST API under the hood.

  1. REST — any agent with HTTP tool-calling. Most universal.
  2. CLI — for shell-based agents (Claude Code, Cursor). Shorter prompts.
  3. MCP — for Claude Desktop / Cursor / Claude Code MCP-aware clients. First-class tools.

Whichever you pick, you need a Kura agent API key scoped to agent-import — it can create sites and nothing else.

The contract: kura.config.json

Every agent submission has a kura.config.json at the repo root. It tells Kura: what framework, what pages, what files are editable, where the assets live. Minimum example for a static site:

{
  "kuraConfigVersion": 1,
  "site": {
    "name": "Acme Plumbing",
    "slug": "acme-plumbing",
    "ownerEmail": "owner@example.com"
  },
  "framework": { "kind": "static" },
  "pages": [
    { "slug": "/",       "title": "Home",  "type": "home",  "source": "index.html" },
    { "slug": "/about",  "title": "About", "type": "about", "source": "about/index.html" }
  ],
  "assets":       { "dir": "assets", "publicPrefix": "/assets/" },
  "designTokens": { "source": "styles/tokens.css", "format": "css-variables" },
  "content":      null
}

Framework choices: astro(the default — Kura's full management layer), static (HTML+CSS+JS, no build), next-static. A site's first framework is permanent. Astro builds start from the Kura scaffold, which is served to a site's build key — with an agent-import key, submit static or create the site in Kura first. See per-framework rules below.

Option A — REST (universal)

Two endpoints. Both accept JSON-with-inline-files. Body limit 60 MB, per-file limit 10 MB, max 2000 files.

# Dry-run validate (no side effects)
POST https://orchestrator-production-1d88.up.railway.app/api/agent/projects/validate
Authorization: Bearer kura_<your key>
Content-Type: application/json

{
  "kuraConfig": { /* contents of kura.config.json */ },
  "files": [
    { "path": "index.html", "content": "<!doctype html>..." },
    { "path": "styles/tokens.css", "content": ":root { ... }" },
    { "path": "assets/hero.png", "content": "<base64>", "encoding": "base64" }
  ]
}

→ HTTP 200 { "valid": true, "framework": "static", "warnings": [] }
→ HTTP 400 { "valid": false, "errors": [{ code, path, message, hint? }], "warnings": [] }
# Submit (creates project + GitHub repo + deploy job)
POST https://orchestrator-production-1d88.up.railway.app/api/agent/projects
# ... same payload as validate
→ HTTP 202 {
  "projectId": "01HX...",
  "slug": "...",
  "framework": "static",
  "platform": "github-files",
  "repoUrl": "https://github.com/kura-clients/...",
  "hubUrl": "https://www.kurawebsites.com/sites/01HX...",
  "buildStatus": "queued",
  "jobId": "01HY...",
  "warnings": []
}

Status read: GET ${base}/api/agent/projects/${projectId} — returns the current buildStatus and liveUrl once the deploy completes.

Option B — CLI

Wraps the REST endpoints. Reads your key from $KURA_API_KEY or ~/.kurarc.

# One-time install
npm install -g kura-agent-cli

# One-time setup
echo '{"api_key":"kura_..."}' > ~/.kurarc

# In the agent's working directory (must contain kura.config.json)
kura agent validate .       # dry-run check
kura agent submit .         # submit + deploy
kura agent status <id>      # check build progress

The CLI walks the directory, skips node_modules, dist, .env*, etc., classifies files as text or binary by extension, and POSTs the payload.

Option C — MCP (Claude Desktop / Cursor / Claude Code)

Configure once; your agent gets three tools in its picker. Add this to ~/.claude/.mcp.json(or your client's MCP config):

{
  "mcpServers": {
    "kura-agent-import": {
      "command": "npx",
      "args": ["-y", "kura-mcp-agent-import"],
      "env": {
        "KURA_API_KEY": "kura_<your key>",
        "KURA_BASE_URL": "https://orchestrator-production-1d88.up.railway.app"
      }
    }
  }
}

Tools the agent gets:

  • kura_validate_submission({ directory })
  • kura_submit_project({ directory })
  • kura_get_project_status({ projectId })

Admin agent (Kura system admins)

If you're a Kura system admin (not a customer), you can use kura-mcp-admin instead — an MCP server with 11 tools for full project management: list/get projects, read + update pages, manage brand kits, trigger deploys, purge caches, list tracked keywords. Requires an admin-full scope key from /admin/settings/api-keys.

{
  "mcpServers": {
    "kura-admin": {
      "command": "npx",
      "args": ["-y", "kura-mcp-admin"],
      "env": {
        "KURA_API_KEY": "kura_<admin-full key>",
        "KURA_BASE_URL": "https://orchestrator-production-1d88.up.railway.app"
      }
    }
  }
}

Admin tools (11):

  • kura_list_projects / kura_get_project
  • kura_get_brand_kit / kura_update_brand_kit
  • kura_list_pages / kura_get_page / kura_update_page
  • kura_trigger_deploy
  • kura_list_media
  • kura_purge_cache
  • kura_list_tracked_keywords

Customer (agent-import scope) keys are rejected by admin routes with 403 insufficient_scope. Admin keys also work on the agent-import endpoints (superset).

Per-framework rules

staticPure HTML/CSS/JS. No build step. Fastest editing loop.
  • index.html required at repo root.
  • No package.json at root (signal of build step).
  • Use semantic HTML: h1-h6, p, a, section, etc. Kura tags them automatically.
  • Assets referenced absolute under publicPrefix (e.g. <img src="/assets/hero.jpg">).
  • content in kura.config.json must be null.
astroThe default. Start from the Kura scaffold (GET /api/agent/me/build/scaffold with a build key) — it ships the kura-inspect stamper, consent runtime and Base layout. Components consume content from /content JSON.
  • astro.config.mjs must set output: 'static' and build.format: 'directory'.
  • package.json with astro ^7.2.6 (4–7 accepted) + parse5 ^7.3.0 deps and build: "astro build" script; Node ≥ 22.12.
  • package-lock.json committed for reproducible builds.
  • Components must NOT inline user-facing text. All editable strings/images live in content/*.json.
  • Render every content value through the scaffold's field helper (src/lib/kura-field.ts): each element then carries a stamp naming the exact field it shows, so your edits land on that field. Keys starting with _ are private to the agent and hidden from you.
  • Every pages[].content entry in kura.config.json must point to a real file under content.dir.
next-staticNext.js 14+ with output: 'export'. App Router only at v1.
  • next.config.js must set output: 'export', trailingSlash: true, images.unoptimized: true.
  • No app/**/route.ts API routes (statically incompatible).
  • No 'use server' directives, no next/headers / next/cookies imports.
  • Content separation: all editable content under content/*.json or MDX frontmatter.
  • Every pages[].content entry must point to a real file.

Validator error codes

On failure, the validate / submit endpoints return errors with stable code values. Agents can branch on code to know what to fix.

  • config_missing — no kura.config.json at repo root
  • config_invalid_json — file present but malformed
  • schema_* — schema rejection (path tells you which field)
  • page_source_not_found — a pages[].source path doesn't exist
  • assets_dir_not_found — assets.dir doesn't exist
  • env_file_committed — a .env / .env.* file in the bundle
  • kura_reserved_path — a file under .github/ or .kura/, or a root kura-build.yml: Kura-only paths, never in a bundle
  • static_no_root_index_html — static framework needs index.html at root
  • astro_output_not_static — astro.config has output != 'static'
  • next_output_not_export — next.config has output != 'export'
  • next_use_server_forbidden — Server Action directive detected
  • next_api_route_forbidden — app/**/route.ts file detected

Next