# Set up Caly for an AI coding agent

These are official instructions from Caly to set up an AI development environment for Caly, a scheduling tool: connect calendars, share one booking link, and let the API create, reschedule and cancel bookings for you. All commands are validated by Caly. Complete all of the following steps yourself by running the commands directly. Do not ask the user to run any of these commands.

Steps:

1. Get credentials
2. Configure your agent (use the section for the agent you are)
3. Connect the MCP server (same section for your agent)
4. Verify
5. Report back to the user

## 1. Get credentials

Caly authenticates with a personal API key. First check whether `CALY_API_KEY` is already set, in the environment or in the project's `.env` file, using whatever shell or file tools you have. Check only that it exists; never print its value. In a POSIX shell, for example:

```sh
test -n "$CALY_API_KEY" && echo "CALY_API_KEY is set" || echo "CALY_API_KEY is missing"
```

If it is missing, ask the user ONCE for a key using exactly this message, word for word, then wait:

> I need a Caly API key. Create one at https://app.trycaly.com/settings/developer/api-keys (Settings → Developer → API keys → Add), copy it, and paste it here. It is stored in this project's git-ignored .env file and in your agent's own config outside the repository.

Never write a key into code, commits, instructions files or any file inside the repository other than the git-ignored `.env`. Never print it back to the user.

## 2. Configure your agent

Use the correct section for your agent. If your agent is not listed, follow the Codex steps: they only rely on an `AGENTS.md` file and a `.env` file.

### Claude Code

1. Store the key in `.env` as `CALY_API_KEY=<key>` (create the file if needed; append if it exists).
2. Append the block under "Instructions block" below to `CLAUDE.md` (create it if it does not exist; skip if a "## Caly" heading is already there).
3. Add `.env` to `.gitignore` if it is not already there, so the key never lands in a commit.
4. Tell the user they can start a Caly task in this project with plain language now, e.g. "list my event types".

### Codex

1. Store the key in `.env` as `CALY_API_KEY=<key>` (create the file if needed; append if it exists).
2. Append the block under "Instructions block" below to `AGENTS.md` (create it if it does not exist; skip if a "## Caly" heading is already there).
3. Add `.env` to `.gitignore` if it is not already there, so the key never lands in a commit.

### Cursor

1. Store the key in `.env` as `CALY_API_KEY=<key>` (create the file if needed; append if it exists).
2. Append the block under "Instructions block" below to `.cursor/rules/caly.mdc` (create it if it does not exist; skip if a "## Caly" heading is already there).
3. Start `.cursor/rules/caly.mdc` with four frontmatter lines — `---`, `description: Caly scheduling API`, `alwaysApply: true`, `---` — so the rule loads in every chat.
4. Add `.env` to `.gitignore` if it is not already there, so the key never lands in a commit.

### OpenCode

1. Store the key in `.env` as `CALY_API_KEY=<key>` (create the file if needed; append if it exists).
2. Append the block under "Instructions block" below to `AGENTS.md` (create it if it does not exist; skip if a "## Caly" heading is already there).
3. Add `.env` to `.gitignore` if it is not already there, so the key never lands in a commit.

### Instructions block

```markdown
## Caly

Caly is the scheduling tool this project talks to.

- MCP server: `caly` at https://mcp.trycaly.com/mcp. Prefer it for event types, availability, bookings and schedules: call `search_tools` first, then run one `execute_typescript` program. Cancelling a booking is two-step: show the user what will be cancelled and only confirm after they agree.
- REST API for everything else: base URL https://api.trycaly.com — every endpoint lives under /v2
- Auth: send the key from the CALY_API_KEY environment variable as `Authorization: Bearer <key>`
- Booking endpoints are versioned: send `cal-api-version: 2024-08-13` on /v2/bookings requests
- OpenAPI spec (source of truth for paths and payloads): https://trycaly.com/docs/openapi.json
- Human reference: https://trycaly.com/docs/api/
- Outbound webhooks (booking created / rescheduled / cancelled) are configured at https://app.trycaly.com/settings/developer/webhooks

Never print the key. Prefer reading the spec over guessing an endpoint.
```

## 3. Connect the MCP server

Caly's MCP server is https://mcp.trycaly.com/mcp (Streamable HTTP). It takes the same API key as a bearer token. Use the section for your agent. If your agent is not listed but supports remote MCP servers, register https://mcp.trycaly.com/mcp with the header `Authorization: Bearer <key>` in its user-level config.

### Claude Code

Config: ~/.claude.json (local scope: private to this user and this project)

1. Run the commands below from the project root. The default local scope keeps the key out of `.mcp.json` and out of the repository.
2. Tell the user to restart Claude Code (or open `/mcp`) so the `caly` server loads.

```sh
set -a; . ./.env; set +a
claude mcp add --transport http caly https://mcp.trycaly.com/mcp --header "Authorization: Bearer $CALY_API_KEY"
```

### Codex

Config: ~/.codex/config.toml

1. Append the block below to `~/.codex/config.toml` (create the file if needed; skip if a `[mcp_servers.caly]` table is already there). It names the variable, never the key.
2. This agent reads `CALY_API_KEY` from the environment it was started in, not from `.env`. Tell the user to add `export CALY_API_KEY=<key>` to their shell profile, or to start the agent from this project with `set -a; . ./.env; set +a` first.
3. Tell the user to restart Codex so the `caly` server loads.

```toml
[mcp_servers.caly]
url = "https://mcp.trycaly.com/mcp"
bearer_token_env_var = "CALY_API_KEY"
```

### Cursor

Config: ~/.cursor/mcp.json (user level, outside the repository)

1. Merge the `caly` entry below into `~/.cursor/mcp.json` (create the file if needed; keep any servers already there), with the key in place of `<key>`. Never put this entry in the project's `.cursor/mcp.json`: that file can be committed.
2. Tell the user to reload MCP servers in Cursor Settings → MCP so `caly` shows up.

```json
{
  "mcpServers": {
    "caly": {
      "url": "https://mcp.trycaly.com/mcp",
      "headers": { "Authorization": "Bearer <key>" }
    }
  }
}
```

### OpenCode

Config: ~/.config/opencode/opencode.json (global, outside the repository)

1. Merge the `caly` entry below into `~/.config/opencode/opencode.json` (create the file if needed; keep everything already there). It names the variable, never the key.
2. This agent reads `CALY_API_KEY` from the environment it was started in, not from `.env`. Tell the user to add `export CALY_API_KEY=<key>` to their shell profile, or to start the agent from this project with `set -a; . ./.env; set +a` first.
3. Tell the user to restart OpenCode so the `caly` server loads.

```json
{
  "mcp": {
    "caly": {
      "type": "remote",
      "url": "https://mcp.trycaly.com/mcp",
      "enabled": true,
      "headers": { "Authorization": "Bearer {env:CALY_API_KEY}" }
    }
  }
}
```

## 4. Verify

Run both, from the project root:

```sh
set -a; . ./.env; set +a
curl -s -H "Authorization: Bearer $CALY_API_KEY" https://api.trycaly.com/v2/me
curl -s -X POST https://mcp.trycaly.com/mcp -H "Authorization: Bearer $CALY_API_KEY" -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

The first succeeds with `{"status":"success","data":{...,"email":"..."}}`, the profile of the key's owner. The second succeeds with a JSON-RPC result whose `tools` list includes `search_tools`. A 401 from either means the key is missing, expired or mistyped; ask the user for it again.

## 5. Report back to the user

Print this, filled in:

> Caly is set up. I stored your API key in <env file> (git-ignored), connected the Caly MCP server (https://mcp.trycaly.com/mcp) in <MCP config>, and added a "## Caly" section to <instructions file> pointing at the API reference and OpenAPI spec. I verified the key against https://api.trycaly.com/v2/me as <email> and the MCP server answered with its tools. <Any restart or export the user still needs to do.> Webhooks for booking events can be added at https://app.trycaly.com/settings/developer/webhooks whenever you want them.

## Resources

- Docs home: https://trycaly.com/docs/
- FAQ: https://trycaly.com/docs/faq/
- API reference: https://trycaly.com/docs/api/
- OpenAPI spec: https://trycaly.com/docs/openapi.json
- MCP server: https://mcp.trycaly.com/mcp
- Agent setup guides: https://trycaly.com/agent-setup/
- llms.txt: https://trycaly.com/llms.txt
- Pricing: https://trycaly.com/pricing/
- Support: hello@devino.ca
