Knowledge & Memory

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.

|View as Markdown
Hunter Hodnett
Hunter HodnettCPTO at Chipp
|1 min read
#consumer#circles#groups#memory#collaboration#shared-memory#files#sharing#auto-share#alchemist#mcp#agent-memory

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

plaintext
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 required

Circles 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

TierCan do
readRead memory, context, events, files, member list
writeEverything in read + append memory + publish events
adminEverything 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

RolePermissions
OwnerFull control: invite/remove members, edit circle, delete circle, manage app connection grants
MemberRead/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:

  1. 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.
  2. 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.
  3. 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:

MethodEndpointDescription
GET/:appNameId/circles/:id/connectionsList all connections (including revoked) with permissions + audit provenance
PATCH/:appNameId/circles/:id/connections/:appIdGrant or update permission tier ({ permissions, principalKind? })
POST/:appNameId/circles/:id/connections/:appId/revokeImmediately 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

  1. 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).

  2. Your project discovers available circles: Use the list_circles MCP tool to see which circles your project currently has access to.

  3. Read and write context: Use get_circle_context for bounded, prompt-safe context retrieval, append_circle_memory to add context, and read_circle_events to poll for new events.

MCP Tools Available to Alchemist Projects

ToolPermissionDescription
list_circlesread+List circles this project has access to
get_circleread+Circle metadata and active member list
get_circle_contextread+Bounded, prompt-safe context (memory + recent events + members)
append_circle_memorywrite+Atomically append to shared memory
replace_circle_memoryadminReplace memory outright (CAS-guarded, admin only)
publish_circle_eventwrite+Publish an explicit event to the event log
read_circle_eventsread+Cursor-first read of the event log
list_circle_filesread+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

plaintext
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 time

API Reference

Consumer-Authenticated Routes

All circle endpoints for consumers are mounted at /:appNameId/circles/ and require consumerAuthMiddleware + verified email.

Circle CRUD

MethodEndpointDescription
GET/circlesList your circles + pending invites
POST/circlesCreate a new circle
GET/circles/:idCircle detail + member list
PATCH/circles/:idUpdate name/description (owner only)
DELETE/circles/:idDelete circle (owner only)

Membership

MethodEndpointDescription
POST/circles/:id/inviteInvite a member by email (owner only)
POST/circles/:id/acceptAccept a pending invite
POST/circles/:id/declineDecline a pending invite
DELETE/circles/:id/members/:emailRemove a member (owner only)
PATCH/circles/:id/members/meUpdate your own member settings ({ autoShareFiles })

Memory

MethodEndpointDescription
GET/circles/:id/memoryRead the circle’s shared memory
PUT/circles/:id/memoryWrite or append to memory (mode: replace or append)

Events

MethodEndpointDescription
GET/circles/:id/eventsRead events (cursor-based)

Query parameters: after_seq (cursor), limit (max 100), event_type (filter).

App Connections (Owner Only — Connection Grants)

MethodEndpointDescription
POST/circles/:id/connectConnect circle to the current app (member action)
DELETE/circles/:id/connectDisconnect the current app (member action)
GET/circles/:id/connectionsList all connections with permissions + audit (owner only)
PATCH/circles/:id/connections/:appIdGrant/update permission tier (owner only)
POST/circles/:id/connections/:appId/revokeImmediately revoke a connection (owner only)

File Sharing

MethodEndpointDescription
GET/circles/:id/filesList shared files
POST/circles/:id/files/:fileIdShare a file to the circle
DELETE/circles/:id/files/:fileIdUnshare a file
GET/circles/:id/files/:fileId/urlGet 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 CaseWho writesWho readsExample
Cross-agent researchAlchemist research projectChipp consumer-facing agentResearch agent appends findings; chat agent answers “what did we learn?” with up-to-date context
Family planningAny member via connected appAll members’ agentsOne member adds “Dad’s birthday is March 15”; gift recommendation app for any member has that context
Team collaborationMultiple Alchemist projectsShared client-facing agentMarketing team’s research project and copywriting project share a campaign brief circle
Customer handoffCRM integration (write grant)Support agent (read grant)CRM writes updated customer notes; support agent reads them on the next conversation
Audit trailAny writerOwner reviewing provenanceOwner 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:

plaintext
<<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_version to gate the write on the current version. A stale version returns 409 version_conflict with the actual current version instead of silently clobbering a concurrent writer
  • Idempotency: pass an idempotency_key on 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:read scope

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 new expected_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.