# Agents

Connecting Claude, Cursor or any MCP client, and what an agent key cannot do

Claude, Cursor and other AI assistants can work in your workspace through our MCP server:
read your contacts and results, build segments, write campaigns, templates and journeys.
They cannot send anything until a person in your team says so.

## 1. Create an agent key

In the dashboard, open **Developer → Agent access → Create agent key** and pick what it
may read (contacts, campaigns and their reports, templates, journeys) and build
(campaigns, templates, journeys). Copy the key; it is shown once.

An agent key cannot send, schedule or activate anything, nor change contacts or their
consent: a campaign or journey it wrote or edited waits for an admin or owner to send or
activate it in the dashboard. The API enforces this, whatever client holds the key; see
[Authentication](/docs/api/authentication#key-kinds) for the details.

## 2. Connect your assistant

The MCP server is at `https://api.kirora.io/mcp`, over
Streamable HTTP, with the key as a bearer token.

**Claude Code**

```sh
claude mcp add --transport http kirora https://api.kirora.io/mcp \
  --header "Authorization: Bearer kirora_..."
```

**Cursor** (`.cursor/mcp.json`) and other clients that take a URL and headers:

```json
{
  "mcpServers": {
    "kirora": {
      "url": "https://api.kirora.io/mcp",
      "headers": { "Authorization": "Bearer kirora_..." }
    }
  }
}
```

Add `?redactContactFields=true` to the URL to replace contacts' names and custom
attributes with a placeholder in everything the assistant reads. Those fields are typed by
the public into your signup forms, so they are the one place a stranger's text could reach
the model; personalisation still works, because merge tags are filled in at send time.

## 3. Ask it

Paste this to start:

> [!PROMPT]
> You are connected to our Kirora workspace through the `kirora` MCP server. First
> list the API endpoints, then read our recent campaigns, how they performed, and our
> templates. Draft a win-back email campaign from the template that fits best, written in
> the voice of our best-performing campaign. Use merge tags such as
> `{{ contact.firstName | default: "there" }}`, never invented ones. Leave the audience for
> me to choose and do not try to send; tell me when the draft is ready for review.

## What the server offers

- **Every `/v1` operation**, through `list_api_endpoints`, `describe_api_endpoint`,
  `read_api`, `write_api` and `delete_api`, so nothing the API can do is out of reach, and an invented path is refused with a usable message.
- **A few named tools** where guidance matters: `create_campaign` and `update_campaign`
  (they explain the merge-tag rules and take a `templateId`), `find_contact`, and
  `preview_segment` to count an audience before proposing a campaign.

Failures come back with the HTTP status and the [error](/docs/api/errors) body, so an assistant
can correct a request and try again.

## Reading the docs

These guides are published as plain Markdown, each page at its own `.md` address, with an
index for language models at [`/llms.txt`](/llms.txt). Point an assistant at the index when
it needs to know how something works.