---
summary: Hand an API key to an LLM agent over MCP or REST and let it author content.
title: Connecting an agent
path: tutorials/connecting-an-agent
status: published
---

# Connecting an agent

Goal: spin up a Claude / ChatGPT / custom agent that can read and write
ScaiCMS content.

## 1. Decide what the agent should be able to do

- **Read-only research bot** — `docs:read` is enough.
- **Drafting bot** — needs `docs.write` on a chosen namespace, no manage.
- **Full dev-team bot** — needs `docs.read`, `docs.write`, `docs.manage` on
  one or more namespaces.

## 2. Issue an API key

In the admin UI: **API keys → + New**.

- **Name**: descriptive (e.g. `claude-docs-bot`).
- **Bind to**: a *Group* if multiple humans/agents share it, a *User* if
  it's for one human's automations.
- **Scopes**: comma-separated. Examples:
  - `docs:read` — broad read.
  - `docs:write:scaigrid` — write only to scaigrid.
  - `docs:read, docs:write:scaicms, docs:manage:scaicms` — full control of
    one namespace.

Copy the plaintext from the one-time modal **before closing it**.

## 3a. Connect via MCP

```bash
export SCAICMS_API_KEY=scai_live_…
export SCAICMS_SITE_ID=30847722-…
python -m scaicms.mcp.server
```

Configure your agent to use the resulting `stdio` MCP server. It will see
all `manage_*` tools, including `manage_documentation` for docs writes.

## 3b. Connect via REST + Python SDK

```python
from scaicms_docs import DocsClient

with DocsClient(base_url="https://yourdomain", api_key="scai_live_…") as c:
    page = c.pages.upsert(
        "scaicms", "v1", "concepts/something",
        title="Something",
        body_md="# Something\n\nDrafted by my agent.",
        frontmatter={"author": "claude-bot"},
    )
```

## 4. Verify access matches the scope

Try writing into a namespace the key shouldn't reach:

```bash
curl -X PUT -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"nope","body_md":"x"}' \
  "$API/api/v1/docs/some-other-namespace/v1/intro"
```

You should get `403 SCOPE_DENIED`. Good — that means the scope is
holding.

## What's next

- Drop `docs/agent-bundle/` into the agent's system prompt for full
  read/write coverage in plain English.
- Use [`scaicms-docs` CLI](/docs/scaicms/tutorials/writing-docs-with-an-agent)
  for one-off scripts.
