# Heilo MCP server

A workspace's AI assistant (Claude Code, Claude Desktop, Cursor, VS Code, or any client that supports remote MCP servers) can look up the workspace's chats, contacts, tickets and reports.

- **Address**: `https://<your Heilo server>/mcp` (Streamable HTTP, stateless, JSON responses; `GET` and `DELETE` answer 405).
- **Auth**: `Authorization: Bearer <REST API key>` (Integrations → REST API). Missing or wrong key: `401` with `WWW-Authenticate: Bearer`. A revoked key stops working at once.
- **Plans**: the `api` feature (Pro, Business, the trial), like the REST API. Otherwise `402 upgrade_required`.
- **Read only**: every tool has `readOnlyHint: true`; nothing sends, edits or deletes.
- **Rate limit**: 60 requests a minute per key.
- **Output**: JSON text; epoch-ms fields (`createdAt`, `lastMessageAt`…) become ISO 8601 UTC strings and file links become absolute, because models read those better.

## Tools

| Tool | Arguments | Returns |
| --- | --- | --- |
| `get_overview` | none | live numbers (visitors online, teammates online, open, unassigned, waiting), today, last 7 days, the 5 chats waiting longest |
| `list_websites` | none | websites with id, name, domain |
| `list_team` | none | members with role and online |
| `search_conversations` | `status` open/closed/all, `unassigned`, `waiting`, `websiteId`, `query`, `since`, `before`, `limit` ≤ 50, `cursor` | conversations (newest activity first) + `nextCursor` (`null` on the last page) |
| `get_conversation` | `conversationId`, `messageLimit` ≤ 200 | the conversation and its latest messages, internal notes included (`type: "note"`) |
| `search_contacts` | `query`, `scope` identified/all, `seenWithinDays`, `notSeenForDays`, `websiteId`, `limit`, `cursor` | contacts + `total`, `nextCursor` |
| `get_contact` | `contactId` | details, labels, custom fields, conversations |
| `search_tickets` | `status` active/open/pending/solved/closed/all, `priority`, `query`, `overdue`, `limit`, `cursor` | tickets + counts (needs the `tickets` feature) |
| `get_ticket` | `ticketId` | the ticket and its timeline |
| `get_analytics` | `days` (capped by the plan), `websiteId`, `timeZone` (IANA) | totals (with `csat`: after-chat ratings `good`, `bad`, `score` = % good), daily (with `good` / `bad` ratings), hours, per teammate (with `ratings`, `csat`) |

## Client setup

Claude Code:

```
claude mcp add --transport http heilo https://app.heilo.chat/mcp --header "Authorization: Bearer YOUR_API_KEY"
```

Claude Desktop (`claude_desktop_config.json`, needs Node.js):

```json
{ "mcpServers": { "heilo": { "command": "npx", "args": ["-y", "mcp-remote", "https://app.heilo.chat/mcp", "--header", "Authorization:${AUTH_HEADER}"], "env": { "AUTH_HEADER": "Bearer YOUR_API_KEY" } } } }
```

Cursor (`~/.cursor/mcp.json`):

```json
{ "mcpServers": { "heilo": { "url": "https://app.heilo.chat/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } }
```

VS Code (`.vscode/mcp.json`):

```json
{
  "servers": { "heilo": { "type": "http", "url": "https://app.heilo.chat/mcp", "headers": { "Authorization": "Bearer ${input:heilo-api-key}" } } },
  "inputs": [{ "type": "promptString", "id": "heilo-api-key", "description": "Heilo API key", "password": true }]
}
```

The dashboard shows the same snippets with the server's own address under Integrations → MCP server.
