---
name: circles-whatsapp
description: Read the WhatsApp chats a person opened to agents through Circles, and send only where they allowed it and only after they agree. Use when the person asks about their WhatsApp groups or chats, what they missed, who said what (voice notes included), a file someone sent, or asks you to reply on WhatsApp.
---

# Using Circles

Circles gives you the WhatsApp chats this person chose to open, from their own personal number, and nothing else. Each chat is hidden, read, or read and send. A hidden chat does not exist for you. Only the person can open a chat or change a level, in Circles at https://app.usecircles.app.

- MCP endpoint: `https://app.usecircles.app/api/mcp` (remote MCP over HTTP; OAuth 2.1 with PKCE, or a bearer token that starts `circ_`)
- HTTP API: `https://app.usecircles.app/api/v1/agent/...`, OpenAPI at `https://app.usecircles.app/api/openapi.json`
- Docs: https://usecircles.app/en/docs

## The order that works

1. **`allowed_chats` first** when you do not know what is open. It is the whole world: a chat missing from it cannot be read, searched or sent to. It also tells you if no number is linked (`not_linked`) or the subscription ended (`subscription_ended`); say so plainly.
2. **`activity`** with `since` for "what did I miss?". Counts per chat, last time, last sender, no text. Cheap. Start of today or 24 hours ago are good defaults.
3. **`catch_up`** to read. With `chat`: one chat (default 50 messages, max 200). Without `chat`: every chat that moved, newest chat first (default 20 per chat, max 50, 150 in total); a chat that had more says `more`, so go back for it by name.
4. **`search`** with `query` for "did anyone mention...?", in one chat or all. It also matches what was said in voice notes. Leave out `days` to search all the history kept.
5. **`people`** to map who is who across open chats (family, work, the kids' class). **`group_members`** for one group, by name.
6. **`documents`** to find PDFs, Word files and sheets. **`get_media`** with one `ref` to fetch a file, only when you need its content.
7. **`send`** last, and only as described below.

Use `catch_up` for "what happened" and `search` for "did anyone say X". Do not read every chat when `activity` can tell you where to look.

## Name chats the way the person would

Pass the chat's name, never an id: `"chat": "Oak Street parents"`. Names are often in Hebrew; pass them as written. If several chats match, the answer lists them: ask the person which one. If none match, the refusal lists what IS open. Do not guess, and do not try variations to find a chat that was not listed.

## Refusals are answers

A refusal comes back as plain text with `isError: false`. Read it and act on it, and do not retry it:

- "No chat named ... is open to agents. What IS open: ..." Pick from the list, or tell the person the chat is not open to you. You cannot tell whether it exists, by design.
- "... is open for reading only." Tell the person they can turn on sending for that chat in Circles if they want. Do not look for another way to send.
- A tool you expected is missing (for example `send` or `get_media`): the person did not grant it, or, for `send`, no chat is open for sending. Tell them; they can connect you again with it ticked, or open a chat for sending in Circles.
- A `coverage` note means you asked for more history than is kept. Say your answer covers only what is there; nothing was hidden.

## Voice notes and files

- A voice note has `media.kind` `voice`; an audio file has `audio`. Both carry `transcript`, so you can read what was said without fetching the audio. `transcript_state`: `done`, `pending` (still being transcribed, check later), `empty` (nothing said) or `failed`. Transcripts are Hebrew and English. To find recordings, use `kind: "recording"` (either) on `catch_up` or `search`.
- Photos, PDFs, documents and video are announced with filename, type, size, a `ref` and a `state`. Fetch one with `get_media`; the file comes back base64 in `bytes_base64`. You read it yourself: a PDF's text, what a photo shows.

Every announced file has a `state`:

- `available`: `get_media` returns it now.
- `downloading`: arriving by itself. Ask again shortly.
- `on_request`: WhatsApp no longer has it, so `get_media` asks the person's phone to re-upload it and waits about 25 seconds. The phone must be online.
- `fetching`: the phone has not answered yet. It is NOT gone. Ask again with the same `ref` in about a minute.
- `gone`: the phone could not re-upload it. Say so. Do not retry.
- `too_large`: over 50 MB, the limit for one call. Tell the person.
- `failed`: could not be downloaded yet. Nothing for the person to do.

One `ref` per call. Fetch only the files you need.

## Times are UTC

`at` is milliseconds since 1970 and `at_iso` the same moment in ISO 8601 ending in Z. Circles does not know where the person is and converts nothing. Give `since` with a Z or an offset. Before telling the person a local time, use the time zone they told you, or ask.

## Sending

- **Ask first, every time.** Show the person the exact text (and file) and the exact chat, and send only after they agree to that message. Then set `confirmed: true`. Never set it on your own judgment. Circles records it as your own statement.
- `send` exists only if you hold the send permission and a chat is open for sending. The message appears as the person, in their name.
- **Never retry a send.** Circles never does, and neither should you. If a send fails or its outcome is unknown, check the chat with `catch_up` before deciding anything, and tell the person what you saw.
- There is a daily cap for the whole number, across all agents (default 5), counted per UTC day. If you hit it, tell the person; do not try another route.
- One message to one chat per call. Never send to many chats, never broadcast.
- Limits: text up to 65,536 characters; a file up to about 3 MB with an optional caption up to 4,096. A JPEG, PNG or WebP goes as a photo, an MP4 as a video, anything else as a named document.
- To someone with no chat yet: only when the person's number allows it, by phone number with country code (`+972501234567`) or a saved contact's exact name.
- Native quoted replies and emoji reactions exist only in the HTTP API.

## Privacy

- Members and senders come back by name. Group member lists never include phone numbers. A sender nobody has a name for may appear as a number: do not repeat it to anyone.
- Do not quote private messages to people who were not in that chat unless the person asked you to.
- Every call you make, including refused ones, is in the person's activity log under your name.
- The person can disconnect you at any time. A 401 means your access ended: tell them.
