Circles - Shared Files and Agent Memory
Share files, memory, and context with family or teammates across every AI assistant you each use. Share a document once (manually, by asking your assistant, or automatically) and every member's assistants can read it.

A Circle is a shared space for the people (and agents) you choose: your spouse, your family, a study group, a small team. Create a circle, invite members by email, and connect the AI apps that should have access. Members share three things:
- Files. Any document a member shares (researched, generated, or uploaded) becomes readable by every other member and their assistants.
- Shared memory. A living notes page that every member’s connected assistants can read and update.
- An event log. An append-only activity feed with a full audit trail of who wrote what, and when.
Circles are anchored to email addresses, not to any single app. Join once and the circle works in every circle-enabled assistant you sign into with that email, even assistants from different builders. Your family doesn’t need to use the same app you do: they just need to be members.
Think of a Circle as a shared notebook that every person and agent in the group reads from and writes to.
For people and for agents. Circles work two ways at once: the simplest way for people to share files and context across their AI apps, and a production-grade shared memory surface for Alchemist projects, Builder API clients, and autonomous agents via MCP tools. Everyone reads and writes the same store, so there is nothing to sync.
Circles require the builder to enable the feature in the app’s capabilities. Consumers must have a verified email (OTP-confirmed) to create or join circles.
How Shared Agent Memory Works
Consumer (owner) creates a Circle
|
|- Invites members by email
|
|- Connects App A and Alchemist Project B
|
App A agent appends: "Client meeting rescheduled to Friday"
|
v (same DB row, same circle)
Project B reads memory → includes "Client meeting rescheduled to Friday"
|
Project B appends: "Sent updated proposal via email"
|
v
App A next turn → sees both entries, no manual sync requiredCircles use Postgres as the single source of truth. Appends are atomic (no lost updates under concurrent writes). A full event log preserves history even when the current memory text is replaced. Provenance on every mutation records which actor (consumer, application, Alchemist project) wrote it and when.
Key Concepts
Email-Anchored Identity
Consumers are per-app, but circles are cross-app. All consumer identity is based on verified email — not app-specific user IDs. A consumer’s “Family Circle” works in any circle-enabled app where they provide the same verified email.
Shared Memory
Each Circle has a memory field: a free-form text store any authorized writer can append to or (with admin permission) replace. Memory flows into connected agents’ system prompts automatically, bounded and sanitized. Think of it as the team’s shared context document.
Event Log
Circles have a sequential event log (consumer_circle_events). Every mutation (append, replace, custom publish) writes an event in the same transaction. Apps poll new events via cursor — each connected app tracks its own afterSeq cursor so it only processes events it hasn’t seen yet.
App and Agent Connections
A Circle is not accessible to an app or agent by default. An owner explicitly grants a connection, chooses a permission tier, and can revoke it at any time. No connection = no data, regardless of any other authentication.
Permission Tiers
| Tier | Can do |
|---|---|
| read | Read memory, context, events, files, member list |
| write | Everything in read + append memory + publish events |
| admin | Everything in write + replace memory outright (destructive, requires explicit grant) |
The default when a connection is first created is read. An owner must explicitly upgrade a connection to write or admin.
Provenance
Every mutation records: actor kind (consumer, application, alchemist_project, service_agent), actor identity (email or application/project ID), timestamp, and an optional idempotency key. This audit trail is preserved in consumer_circle_events even when the current memory text is overwritten by a later replace.
For Consumers: Using Circles
Creating a Circle
Verify Your Email
Circles require a verified email. If you have not already, verify your email through the OTP flow.
Create the Circle
Open the menu in the top-right of any chat, choose Circles, and create a new circle with a name and optional description.
Invite Members
Add members by email. They will receive an invite notification and can accept or decline.
Connect to Apps
Once active, any member can connect the circle to any circle-enabled app they use. The connection is per-app.
Invitations
- Only the circle owner can invite or remove members
- Invited members see the circle in their pending invites list
- Members can accept or decline an invitation
- Declined invites can be re-sent by the owner
Roles
| Role | Permissions |
|---|---|
| Owner | Full control: invite/remove members, edit circle, delete circle, manage app connection grants |
| Member | Read/write memory, connect/disconnect apps, view members, share/unshare files |
Each member can have an optional role description (like “Budget manager” or “Trip planner”) that is included in the AI’s context, helping the AI understand each person’s role in the group.
Shared Memory
The circle’s memory field is a shared text document. Any member can read or append to it from a connected app. The AI automatically receives a bounded snapshot of this memory (up to 4,000 characters, plus the 10 most recent events) in its system prompt.
File Sharing
Any document in a member’s My Files library can be shared into a circle — including files an assistant researched or generated for you, not just uploads. Shared files are accessible to every active member across all of their connected apps, always attributed (“shared by Hunter in your Family circle”). Your family doesn’t need to use the same app you do: they just need to be members.
There are three ways to share:
- From My Files. Open My Files from the chat menu, hit the share action on any document, and pick a circle. Every other active member is notified by email.
- Just ask your assistant. In any connected app, say “share the market research report with my family circle.” The assistant finds the file in your library and shares it for you; members get the same email notification.
- Auto-share. In the circle’s detail panel, turn on Auto-share new files. From then on, every new file you save in a connected app (generated reports, researched documents, uploads) is shared to the circle automatically. Auto-shared files deliberately skip the per-file email so a busy research session doesn’t flood anyone’s inbox — members see them in the circle’s file list, and their assistants can read them immediately.
What members can do with shared files:
- Browse and download them from the Circles panel in any connected app (downloads use short-lived signed URLs)
- Ask their own assistant about them. Members’ assistants can list, read, and analyze circle files in conversation — “summarize the retirement research Hunter shared” works from any member’s app
Rules and controls:
- You can only share files you own (files in your own library, matched by your verified email)
- Auto-share is personal and per-circle: it only affects files you create, only in apps you connected to that circle, and only files saved after you turned it on
- Only the original sharer or the circle owner can unshare a file
- Deleting a file from your library also removes it from any circles it was shared into; leaving a circle removes your access to its files
File sharing events (file_shared, file_unshared) are recorded in the circle’s event log; auto-shares carry an autoShared: true marker.
Managing App and Agent Connections (Owner Only)
As the circle owner you control which applications and AI projects can access your circle’s data. From your circle settings:
- View connections — see every connected app/project, its permission tier, who granted it, and whether it has been revoked
- Grant access — connect an app or Alchemist project with a chosen permission tier (read / write / admin)
- Revoke access — immediate. The revoked connection loses all access on the very next call — there is no TTL to wait out
- Re-grant — revoked connections can be re-enabled without creating a duplicate
Revocation is the primary privacy control. If you no longer want an agent or project to see your circle’s context, revoke it and the effect is immediate.
Privacy
- Your circle’s memory, events, members, and files are only accessible to explicitly connected apps and projects with active (non-revoked) connection grants
- A read-tier connection cannot write anything to your circle
- Every write to your circle records the actor’s identity and timestamp (provenance). You can inspect this in your circle’s connection audit view
- Circle content flowing into an AI system prompt is wrapped in explicit delimiters so the AI cannot be tricked into treating circle-authored text as system instructions (structural prompt-injection defense)
For Builders: Enabling Circles in Your App
To enable circles for your app, add circle.enabled: true to your app’s capabilities (currently configured through Build settings).
Once enabled, consumers with verified emails can create circles, invite members, and connect circles to your app. The circle context is automatically injected into the AI’s system prompt for connected circles.
What the AI Sees
When a consumer with connected circles starts a chat, the AI receives bounded circle context including:
- Circle name and description
- Shared memory (capped at 4,000 characters — truncated if longer, not raw dump)
- Up to 10 most recent events (chronological)
- Active member list with names, emails, roles, and role descriptions
Memory and event content are wrapped in <<CIRCLE_UNTRUSTED_CONTENT>> / <<END_CIRCLE_UNTRUSTED_CONTENT>> delimiters in the actual prompt — your system prompt’s instructions take precedence over anything a circle member might write in the shared memory. This is structural, not keyword-based: even if someone writes the delimiter text inside the memory, it is escaped before injection.
Owner-Facing Connection Endpoints
Three routes are added to the consumer-authenticated circle surface (owner only) for managing non-consumer connections:
| Method | Endpoint | Description |
|---|---|---|
GET | /:appNameId/circles/:id/connections | List all connections (including revoked) with permissions + audit provenance |
PATCH | /:appNameId/circles/:id/connections/:appId | Grant or update permission tier ({ permissions, principalKind? }) |
POST | /:appNameId/circles/:id/connections/:appId/revoke | Immediately revoke a connection |
These are separate from the existing member-facing POST /:id/connect (creates a default read-only connection for the current app) and DELETE /:id/connect (removes the connection for the current app) — both unchanged.
For Alchemist Projects: Using Circles as Shared Memory
An Alchemist project’s own agent application can be granted access to a Circle by the circle’s owner. Once connected, the project’s agents can read and write Circle memory using standard MCP tools — the same API surface any other connected app uses, with no separate Alchemist-only memory store.
Setup
-
The circle owner connects your project: In the owner’s app, under circle settings, the owner grants your Alchemist project’s agent application a connection with the desired permission tier. Your project needs to have its agent application provisioned (automatic for most Alchemist Cloud projects).
-
Your project discovers available circles: Use the
list_circlesMCP tool to see which circles your project currently has access to. -
Read and write context: Use
get_circle_contextfor bounded, prompt-safe context retrieval,append_circle_memoryto add context, andread_circle_eventsto poll for new events.
MCP Tools Available to Alchemist Projects
| Tool | Permission | Description |
|---|---|---|
list_circles | read+ | List circles this project has access to |
get_circle | read+ | Circle metadata and active member list |
get_circle_context | read+ | Bounded, prompt-safe context (memory + recent events + members) |
append_circle_memory | write+ | Atomically append to shared memory |
replace_circle_memory | admin | Replace memory outright (CAS-guarded, admin only) |
publish_circle_event | write+ | Publish an explicit event to the event log |
read_circle_events | read+ | Cursor-first read of the event log |
list_circle_files | read+ | List files shared in the circle |
See the Circles Builder API & MCP Reference for full request/response examples, concurrency semantics, and error codes.
Cross-Agent Example
Alchemist Project A (research agent):
- Discovers "Acme Project" circle via list_circles
- Reads shared context via get_circle_context
- Appends findings: "Competitor analysis complete. Key risk: pricing gap."
- Uses idempotency_key: "research-complete-2026-07" to make the write safe to retry
Chipp App B (client-facing agent, same circle):
- Consumer asks: "What's the latest on the Acme project?"
- System prompt receives bounded circle context including the research finding
- Responds with up-to-date context, no manual sync required
Consumer (owner):
- Visits circle settings to inspect connection audit log
- Sees: "2026-07-28 14:32 -- alchemist_project (Project A) appended memory"
- Can revoke Project A's access at any timeAPI Reference
Consumer-Authenticated Routes
All circle endpoints for consumers are mounted at /:appNameId/circles/ and require consumerAuthMiddleware + verified email.
Circle CRUD
| Method | Endpoint | Description |
|---|---|---|
GET | /circles | List your circles + pending invites |
POST | /circles | Create a new circle |
GET | /circles/:id | Circle detail + member list |
PATCH | /circles/:id | Update name/description (owner only) |
DELETE | /circles/:id | Delete circle (owner only) |
Membership
| Method | Endpoint | Description |
|---|---|---|
POST | /circles/:id/invite | Invite a member by email (owner only) |
POST | /circles/:id/accept | Accept a pending invite |
POST | /circles/:id/decline | Decline a pending invite |
DELETE | /circles/:id/members/:email | Remove a member (owner only) |
PATCH | /circles/:id/members/me | Update your own member settings ({ autoShareFiles }) |
Memory
| Method | Endpoint | Description |
|---|---|---|
GET | /circles/:id/memory | Read the circle’s shared memory |
PUT | /circles/:id/memory | Write or append to memory (mode: replace or append) |
Events
| Method | Endpoint | Description |
|---|---|---|
GET | /circles/:id/events | Read events (cursor-based) |
Query parameters: after_seq (cursor), limit (max 100), event_type (filter).
App Connections (Owner Only — Connection Grants)
| Method | Endpoint | Description |
|---|---|---|
POST | /circles/:id/connect | Connect circle to the current app (member action) |
DELETE | /circles/:id/connect | Disconnect the current app (member action) |
GET | /circles/:id/connections | List all connections with permissions + audit (owner only) |
PATCH | /circles/:id/connections/:appId | Grant/update permission tier (owner only) |
POST | /circles/:id/connections/:appId/revoke | Immediately revoke a connection (owner only) |
File Sharing
| Method | Endpoint | Description |
|---|---|---|
GET | /circles/:id/files | List shared files |
POST | /circles/:id/files/:fileId | Share a file to the circle |
DELETE | /circles/:id/files/:fileId | Unshare a file |
GET | /circles/:id/files/:fileId/url | Get a signed download URL |
Non-Consumer (Builder API) Routes
For Alchemist projects, third-party applications, and service agents, see the Circles Builder API & MCP Reference. The Builder API surface uses a separate authentication path (Bearer API key + circle-scoped grant) and never impersonates a consumer email.
Use Cases
| Use Case | Who writes | Who reads | Example |
|---|---|---|---|
| Cross-agent research | Alchemist research project | Chipp consumer-facing agent | Research agent appends findings; chat agent answers “what did we learn?” with up-to-date context |
| Family planning | Any member via connected app | All members’ agents | One member adds “Dad’s birthday is March 15”; gift recommendation app for any member has that context |
| Team collaboration | Multiple Alchemist projects | Shared client-facing agent | Marketing team’s research project and copywriting project share a campaign brief circle |
| Customer handoff | CRM integration (write grant) | Support agent (read grant) | CRM writes updated customer notes; support agent reads them on the next conversation |
| Audit trail | Any writer | Owner reviewing provenance | Owner inspects event log to see exactly which agent appended what, and when |
Safety and Limits
Bounded Context Retrieval
Circle content injected into LLM prompts is deliberately bounded:
- Memory: capped at 4,000 characters by default (configurable up to 20,000 via API). Truncated with a
[truncated]notice if longer - Recent events: last 10 events by default (configurable up to 50)
- Event payload: capped at 4,000 characters per event in the audit log
The bounded context endpoint (GET /:circleId/context via Builder API or get_circle_context via MCP) is what agents should use for prompt injection. The raw memory endpoint returns the full untruncated field.
Prompt-Injection Defense
Circle memory and event content are wrapped with explicit delimiters before injection into any LLM system prompt:
<<CIRCLE_UNTRUSTED_CONTENT: circle-name>>
...circle-authored text...
<<END_CIRCLE_UNTRUSTED_CONTENT>>If the memory itself contains these delimiter strings, they are escaped before wrapping — so a malicious circle member cannot forge the delimiter and break out of the untrusted content zone. This is a structural defense, not keyword-based classification.
Concurrency Safety
Concurrent writes to circle memory are safe by design:
- Append is a single atomic SQL
UPDATE ... SET memory = memory || content. No read-modify-write race. Two concurrent appends both persist — neither is lost - Replace uses Compare-And-Swap: pass
expected_versionto gate the write on the current version. A stale version returns409 version_conflictwith the actual current version instead of silently clobbering a concurrent writer - Idempotency: pass an
idempotency_keyon any write to make a retried call a safe no-op. The second call with the same key returns the original result without re-applying the write
Troubleshooting
“Circles are not enabled for this app” (403)?
- The builder has not enabled circles in the app capabilities
- Contact the app creator to request the feature
“Verified email required” (401)?
- You must verify your email through the OTP flow before using circles
- Check your email for the verification code after signing up
Cannot invite members?
- Only the circle owner can invite or remove members
- Verify the email address is correctly formatted
Circle not showing in another app?
- You must connect the circle to each app separately
- Verify the other app has circles enabled
- Make sure you are using the same verified email in both apps
A member doesn’t see a file you shared?
- Check they accepted their invitation (a pending member has no access yet)
- They should look in the Circles panel of a connected app, or ask their assistant to list circle files
Auto-share didn’t share a file?
- Auto-share only covers files saved AFTER you turned it on, and only in apps connected to that circle
- Share older files manually from My Files (or ask your assistant to share them)
Alchemist project cannot see circle data?
- The circle owner must grant the project’s agent application a connection first
- The connection must not be revoked
- The API key must have
circles:readscope
409 version_conflict on replace?
- A concurrent writer updated the memory between your read and your replace
- Re-read the current memory + version (
GET /:circleId/memory), merge your changes, and retry with the newexpected_version
Circles pair well with Consumer Brain for persistent file sharing across sessions, and User Memory for individual per-user context that complements group memory. For programmatic access by applications and agents, see the Circles Builder API & MCP Reference.