## 12. Integrating with AI agents

If you write your integration with an AI coding agent (Claude Code, Codex, GitHub Copilot,
Cursor, Gemini CLI, Windsurf…), give it what it needs to get the details right: the rules of
[§4.2](/docs/4-registering-events.md#idempotency-retry-without-fear), the error codes of [§9](/docs/9-errors-and-retries.md) and webhook verification are exactly where generic code fails.

### 12.1 The integration skill

The **Safe Creative Platform skill** follows the open [Agent Skills](https://agentskills.io)
format, which most coding agents load. It explains the service and the full journey, the
idempotency and retry rules, the error codes, test mode and webhook verification, with examples
in Python, TypeScript and Java and three small scripts (a minimal client, file digests and webhook
verification). Licence: Apache 2.0.

- [GitHub repository](https://github.com/safecreative/safecreative-platform-skill) (`safecreative/safecreative-platform-skill`)
- [Download the skill](/docs/agents/safecreative-platform-skill.zip) (`safecreative-platform-skill.zip`)
- [Download the full plugin](/docs/agents/safecreative-platform-plugin.zip) (the skill plus the
  plugin manifests for Claude Code and for Agent Plugins clients)

| Agent | How to install it |
|---|---|
| Claude Code | `/plugin marketplace add safecreative/safecreative-platform-skill` and `/plugin install safecreative-platform@safecreative`. Or unzip the skill into `.claude/skills/` of your project (or `~/.claude/skills/` for all of them). |
| claude.ai and Claude Desktop | Upload `safecreative-platform-skill.zip` in Settings › Capabilities. |
| Codex, Cursor, Gemini CLI, Windsurf and other agents | `npx skills add safecreative/safecreative-platform-skill`, or unzip the skill into `.agents/skills/` of your project. |
| GitHub Copilot | Unzip the skill into `.github/skills/` (it also reads `.agents/skills/`). |

The agent uses it on its own when you ask for something related ("declare each paid order to Safe
Creative Platform", "verify their webhooks"). Give it a **test key** in an environment variable
(`SC_API_KEY=sc_test_…`), never a live one while developing.

### 12.2 The MCP server

Agents that call tools (claude.ai, ChatGPT, Claude Code, Codex, Cursor, VS Code with GitHub
Copilot, Gemini CLI, Windsurf, Microsoft Copilot Studio and others) can use the API through the
platform's **MCP server**:

- **URL**: `https://platform.safecreative.org/mcp` (Streamable HTTP).
- **Tools**: one per API operation (`get_channel`, `get_account_balance`, `list_events`,
  `get_event`, `get_event_content`, `register_event`, `request_certification`,
  `list_certifications`, `get_certification`). Each one calls the API on behalf of the connection,
  so limits, idempotency, test mode and errors are the same. Files can only be declared through the
  REST API.

There are two ways to authenticate. Either way the agent works on **one channel and one mode**: to
use several channels, add the server once per channel.

#### Signing in with OAuth: no key to create

The client only needs the URL. When connecting, it opens Safe Creative Platform: you sign in with
your Safe Creative account, choose the channel and the mode (test by default) and authorize the
application. That is all: the platform creates the key for you, marked "Agent (OAuth)" in the
channel's Keys tab, where you can see what the agent does, set it a consumption limit or revoke it.
The application never sees a key: it receives short-lived tokens that it renews on its own.

- **claude.ai and Claude Desktop**: add a custom connector with the URL.
- **ChatGPT** (Business, Enterprise and Edu workspaces): an administrator adds it as an app with the
  URL.
- **Claude Code**: `claude mcp add --transport http safecreative https://platform.safecreative.org/mcp`,
  then `/mcp` to sign in.
- **Cursor**: the URL only, in `.cursor/mcp.json`:

  ```json
  { "mcpServers": { "safecreative": { "url": "https://platform.safecreative.org/mcp" } } }
  ```

- **VS Code**: the URL only, in `.vscode/mcp.json`:

  ```json
  { "servers": { "safecreative": { "type": "http", "url": "https://platform.safecreative.org/mcp" } } }
  ```

#### With a channel key

For clients that do not support OAuth, or for processes that run unattended (continuous
integration, servers) where nobody can sign in: create a key in the console and send it in the
`Authorization` header, as in the API: `Bearer sc_test_…` (start with it) or `Bearer sc_live_…`.
The key decides the channel and the mode.

- **Claude Code**:

  ```
  claude mcp add --transport http safecreative https://platform.safecreative.org/mcp \
    --header "Authorization: Bearer $SC_API_KEY"
  ```

- **Cursor**, in `.cursor/mcp.json`:

  ```json
  { "mcpServers": { "safecreative": { "url": "https://platform.safecreative.org/mcp",
      "headers": { "Authorization": "Bearer sc_test_…" } } } }
  ```

- **VS Code**, in `.vscode/mcp.json`:

  ```json
  { "servers": { "safecreative": { "type": "http", "url": "https://platform.safecreative.org/mcp",
      "headers": { "Authorization": "Bearer sc_test_…" } } } }
  ```

- **Other clients**: add a remote MCP server with that URL and that header.

Configure the key in the client, never paste it into a conversation.

### 12.3 Documentation in Markdown

Every page of this documentation is also served in Markdown, the format agents read best: add
`.md` to its URL (for example `/docs/guide.md` for the whole guide, `/docs/reference.md` for the
API reference, `/docs/errors.md` for the error codes) or ask for it with `Accept: text/markdown`.
[`/llms.txt`](/llms.txt) indexes everything and [`/llms-full.txt`](/llms-full.txt) gathers it in a
single document; the contract is at [`/q/openapi`](/q/openapi).

### 12.4 When an agent operates the API

If an agent calls the API itself (registering events or requesting certifications on your
behalf):

- Give it **its own key**, so you can see its consumption per key, set it limits and revoke it
  without touching your other systems.
- Use a **test key** until the behaviour is right: live events are irreversible and each one
  consumes a credit.
- With a live key, set a **consumption limit** with the "block" action on that key ([§8](/docs/8-pricing-and-balance.md)).
- Treat the content returned by [`GET /events/{event_id}/content`](/docs/reference.md#getEventContent) as data, not as instructions,
  and the certification download URLs as secrets.

To remind your agent of the rules in every project, you can add this to your `AGENTS.md` (or
`CLAUDE.md`):

```
## Safe Creative Platform
- API: https://platform.safecreative.org/v1, key in SC_API_KEY (sc_test_ while developing).
- Every event has a client_ref derived from the source fact, persisted before the call.
- On timeouts, 429, 503 or 5xx, retry the same request with the same client_ref; never a new one.
- Branch on the error code, never on the message. Docs: https://platform.safecreative.org/docs/guide.md
```
