A Chickpea deployment is one running copy of Chickpea that holds every Agent for one Slack workspace. Where a single bot with every tool attached gives every channel every credential, a deployment keeps each Agent’s accounts, memory, and channels separate and routes each mention to exactly one of them. This page follows one mention from Slack to the reply, states the rules that hold on every turn, and names the layers underneath.
One mention, end to end
Someone in #billing types:
@supportcan we refund order 4821? The customer says the card was charged twice.
- Slack renders the mention.
@supportis a Slack user group with zero members, created when the Agent was. To Slack it is an ordinary handle. To Chickpea it is an address. - Chickpea resolves the turn to one Agent. The mention names
@support, and a stored channel grant says whether@supportmay work in#billing. No grant, no reply. A message that mentions two Agent handles is refused as ambiguous rather than guessed. - The Agent runs as itself. Its own instructions, its own memory, its own skills, and its own connected accounts, say Zendesk and Stripe. Nothing that belongs to
@revopsis in the room. - The reply lands in the thread under
@support’s name and avatar, streamed as it is written. Chickpea posts with Slack’s custom username and icon, so each Agent looks like itself. - The thread now belongs to
@support. Anyone in the channel can follow up in that thread without mentioning it again. Mentioning@financein the same thread hands the work over, in the open.
Written out, a small workspace looks like this. Each row is one Agent in the same deployment; the channels are its grants, the accounts are its connections.
| Agent | Channels it may work in | Accounts it may use |
|---|---|---|
@support |
#billing |
Zendesk, Stripe |
@oncall |
#billing, #eng |
GitHub, Sentry |
@revops |
#finance (private) |
HubSpot, Google Sheets |
@oncall can answer in #billing but has no Zendesk. @support has Zendesk but cannot see #eng. Publishing an Agent to a channel hands that channel’s members everything the Agent can do and reach.
Where DMs fit
Where an Agent is published decides who can message it directly. Published in a public channel, any workspace member can DM it. Published only in private channels, only those members can. Unpublished, only its creator can. The same rule covers the App Home tab.
What never happens
These hold on every turn and are checked in code, not in a prompt.
- No ambient listening. In every channel, a top-level message that mentions no one is dropped before any model is involved. There is no “read the channel and decide if you’re needed” mode.
- Credentials never reach the model. Never in model context, never in the tool arguments the model writes. The model picks a connection by ID; the runtime resolves the secret at the moment of the call and injects it at egress.
- Conversation cannot expand authority. Authority comes from stored grants and saved instructions, read from stored state and re-checked at the moment of each use, never from anything produced during the turn. Message text, retrieved content, and tool output are data, never permission.
- Consequential actions need confirmation. Minor reversible writes may proceed without confirmation. Consequential ones (sending a message or email, deleting, publishing, broad or bulk changes) require confirmation unless the saved Agent instructions explicitly authorize that class of action.
- Two handles are refused, not guessed. A message that mentions two Agents gets private guidance instead of an answer.
Why it works this way
The wall between Agents is the design. A support Agent cannot read finance’s inbox because nobody ever gave it to them; there is no shared pool of credentials to leak across. If you need a wall between two jobs, make a second Agent. Memory is deliberately not a wall: one Agent has one memory across its DMs and every granted channel, so something learned in a private conversation can shape a later channel answer.
Authority lives in stored state rather than in the conversation because the conversation is the one thing an outsider can write to. A pasted instruction, a retrieved web page, or a tool result can say anything; the grant table cannot be edited by talking.
The layers
| Layer | What it does |
|---|---|
| Slack app | Events API, DMs, App Home, message delivery. Transport only. Socket Mode is not used. |
| Chickpea | Routes mentions to Agents, enforces channel grants and confirmation policy, resolves credentials at the moment of each call, renders replies as the Agent, and runs Admin and the management MCP. |
| Flue | The agent runtime: durable sessions that survive crashes and restarts, persistent state, subagents, tools, skills, and MCP. Same code on Cloudflare Workers or Node. |
| Pi | The open agent harness Flue runs on, also behind OpenClaw. Provides the model providers. |
| Model provider | Anthropic, OpenAI, OpenRouter, or Cloudflare Workers AI, pinned per Agent. |
| State | Durable Objects and D1 on Cloudflare. SQLite files on Node. |
Chickpea has no agent loop of its own. That is Flue, the Apache-licensed open agent framework from the Astro team, now part of Cloudflare. Everything above the Flue row is Chickpea’s: the Slack product, the authority model, and Admin.
Three doors, one service
Admin, Slack, and the management MCP are three front doors to one management service, with the same permissions and the same approvals behind each. Ask @Chickpea for a new support Agent in the channel where you want it and it creates the Agent, gives it a handle and an avatar, and publishes it there. Publishing to any other channel comes back as a proposal. The same request over MCP from a coding agent, or by hand in Admin, goes through the same checks. Two kinds of change arrive as a frozen proposal you must approve before anything applies: anything the Agent inferred rather than you stated, and anything that changes what an Agent can do, reach, or delete. Simple reversible single-field edits apply directly, with an undo.
What is not covered
- One deployment serves one Slack workspace. A second workspace is a second deployment.
- Memory is not isolation. If two jobs must not share what they learn, they are two Agents.
- Node runs no scheduler and no coding sandbox. Schedules and the container tier are Cloudflare only; Node uses the in-memory execution path.
- Chickpea is not a hosted service. You deploy it, you update it (the Deploy button clones the repository rather than forking it), and your model traffic goes to the provider you chose.
Next steps
- Get started on Cloudflare: deploy, connect Slack, and get the first reply.
- Start: the rest of this section: what Chickpea is, the Node path, requirements and costs.
- Security model: the guarantees above, with the mechanism behind each.
