chickpea
Self-hosted, model-agnostic AI teammates in Slack. Agents with their own @handle, memory, skills, and per-channel permissions. 35 connector presets (Zendesk, Stripe, GitHub, HubSpot), MCP and API connections, scheduled work, coding sandbox. Manage from Slack, Admin, or MCP. Built on Flue. Cloudflare Workers or Node. MIT.
Links
README
From the repo.
AI teammates in Slack that answer questions, take on tasks, and use the accounts you give them, all on infrastructure you own.
Paste one prompt into Claude Code, Codex, or Cursor. Chickpea runs in your own Cloudflare account or on your own Mac.
Already installed? Connect via MCP · Update
Why it exists · Features · How it works · Managing · CLI · Security · Deployment · Good to know · FAQ
Chickpea gives your team AI teammates in Slack. You address them by name. @support answers the billing question in the channel where someone asked it. @revops posts Monday's pipeline numbers from HubSpot on a schedule. @oncall reads the repo before it answers. Each one has its own instructions, memory, connected accounts, and list of channels it's allowed to work in. You set all of that up by asking, in Slack.
The difference is where they work. Chickpea is licensed under Apache 2.0 and you deploy it yourself, to your own Cloudflare account or your own server, pointed at whichever model provider you want. Under the hood every Agent runs on Flue, the open agent framework from the Astro team, now part of Cloudflare. More in How It Works.
Why Chickpea Exists
Your team already uses AI all day, one person at a time in a private tab, and the answer stays in that one person's history. Ask in the channel instead:
@growthwhich pages lost impressions in Search Console last month?
@growth checks Search Console, cross-references Google Analytics, and answers in the thread. @sales pulls the recurring objections out of this week's Gong calls. @eng names the top new Sentry issue since Friday's deploy. Ask any of them to update a HubSpot record or move something on your Google Calendar and they confirm with you first. Everyone in the channel sees the answer, and anyone can pick it up later without starting over.
The hosted versions of this idea run on the vendor's infrastructure, with the vendor's model, on the vendor's schedule. Good products, and for a lot of teams that trade is fine. Some teams can't make it, for reasons of policy or data, and they have mostly gone without.
Chickpea is for those teams. Each Agent keeps its own connected accounts and its own channels, so the support Agent can't read finance's inbox; nobody ever gave it to them. If you need a wall between two jobs, make a second Agent.
What Your Workspace Gets
| Feature | What it does | |
|---|---|---|
| Addressable Agents | Each Agent gets a real Slack handle (a zero-member user group like @support), a distinct generated avatar, and its own name on every reply. | |
| Agent memory | One memory per Agent, shared across its DMs and every granted channel, editable and deletable in Admin. | Details |
| Connection accounts | Team accounts and personal accounts, each owned by one Agent. 35 connector presets, plus native API and MCP for anything custom. | Details |
| Model choice | Anthropic, OpenAI, OpenRouter, or Cloudflare Workers AI, pinned per Agent. | Details |
| Skills | Import from a GitHub repo or a skills.sh link, in Admin or by handing the link to an Agent in Slack. You see which skills were found before anything is installed. | |
| Repositories | Grant GitHub repositories to an Agent through the Chickpea GitHub App (Settings → GitHub). Access uses short-lived installation tokens scoped to the granted repositories. | |
| Coding sandbox | Optional Cloudflare container tier for Agents that need to clone a repo, install packages, and run tests. | Details |
| Browser | Optional. Agents open a real browser in your own Browserbase project to check live pages, sign in with website logins you grant, and attach a screenshot or recording as proof. Connect it in Settings → Browser. | |
| Schedules | Agent-owned recurring or one-time work, set up conversationally in Slack, delivered to a granted channel or a private DM thread. | Details |
| Manage from Slack | Admin, Slack, and an MCP server are three doors to the same controls. Create Agents, install skills, set schedules, and edit memory by asking, with consequential changes gated behind an approval. Connect your coding agent from Settings → MCP or with one pasted line. | Details |
| Slack-native answers | Progressive streaming for long replies, adaptive tables (prose, inline Markdown, or a native sortable Slack table) when the data earns one, and task cards for multi-step work. | |
| Reads attachments | Images, PDFs, UTF-8 text and source files, and Slack's generated previews for docs, slides, and sheets. A file is untrusted reference material: its contents inform the answer, and text inside it never authorizes a tool or a change. | |
| Files | Agents attach final or revised sandbox deliverables, including Markdown, through their Slack reply. Scratch files stay private, and explicit no-attachment requests are respected. Missed exports get one repair attempt; files that cannot be attached are identified in the reply. Files upload straight to Slack on both direct and shared-app installs, up to Slack's 1 GB limit; browser recordings stream, and the shared gateway only issues the upload ticket. Works without a coding sandbox or repository grant on Cloudflare and Node. | |
| Live activity status | Slack's native under-composer status shows real phases as they happen: Checking Gmail…, Drafting the response…. |
How It Works
In Slack
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 checks the grant. One deployment holds every Agent, and a channel grant says which Agent may work in which channel. If
@supporthas no grant for#billing, nothing happens. Two handles in one message get rejected 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's written. The thread now belongs to@support. Anyone in the channel can follow up there without mentioning it again, and mentioning@financein the same thread hands the work over in the open.
Want another teammate? Ask @Chickpea for one, in Slack or in Admin. Managing Chickpea covers what else you can do from each.
Drawn out, a workspace looks like this. Solid lines are channel grants, dotted lines are connected accounts.
flowchart LR
zs["Zendesk · Stripe"] -.- support["@support"]
gh["GitHub · Sentry"] -.- oncall["@oncall"]
hs["HubSpot · Google Sheets"] -.- revops["@revops"]
subgraph cp["Chickpea, one deployment"]
support
oncall
revops
end
subgraph slack["Slack workspace"]
billing["#billing"]
eng["#eng"]
fin["#finance (private)"]
end
support --- billing
oncall --- billing
oncall --- eng
revops --- fin
@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, so think about that before you publish.
Publishing to a public channel joins the bot automatically. Private channels need someone to /invite @Chickpea first, and the grant stays pending until then. Where an Agent is published also decides who can DM it. In a public channel, any workspace member can. Only in private channels, only those members can. Unpublished, only its creator can.
In every channel, a top-level message that mentions no one is dropped before any model is involved. Chickpea is not sitting in your channels forming opinions.
If Slack blocks user-group creation
Agent handles are Slack user groups, which some plans restrict. If Slack blocks the group, Chickpea keeps the Agent and shows the fix:
- A Workspace Owner or Admin opens Roles & permissions → Account types at
slack.com/admin. - Next to Create and edit user groups, choose Edit permission.
- Add Members and save.
- Return to the Agent and choose Retry.
On Enterprise Grid it's the equivalent setting under Organization settings → Roles & permissions. Reconnecting Slack cannot repair a policy, so Chickpea won't suggest it.
Under the hood
| Layer | What it does |
|---|---|
| Slack app | Events API, DMs, App Home, message delivery. Transport only. |
| 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. |
| 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 (@flue/runtime), the Apache-licensed open agent framework from the Astro team, now part of Cloudflare. Everything above the Flue row in the table is Chickpea's: the Slack product, the authority model, and the admin panel.
Connections and Authority
Every connection belongs to one Agent for its lifetime. A team account is shared authority the Agent's editors manage, like the support team's Zendesk. A personal account belongs to one member inside one Agent, like your work Gmail, and runtime use requires both that Agent's connection and your identity. Authorizing the same external account for a second Agent creates a separate connection with its own consent.
Credentials never enter model context or the tool arguments the model writes. The model picks a connection by ID and the secret goes in at egress. An interrupted OAuth flow resumes bound to the provider, the account owner, the Agent, and the Slack task it left. Disconnecting revokes that one connection, tombstones secret access, and retires it from dependent schedules.
Selected connection capabilities authorize the Agent to carry out the requested task. The model uses the conversation and saved instructions to determine intent, without requiring particular words or an extra confirmation merely because a tool can write. Explicit read-only permissions, preview-only requests, and saved confirmation requirements remain in force. Conversation text and API results cannot expand connection grants. The Security Model has the full list.
What you can connect, 35 presets in all. 13 run through a single Composio key; the other 22 go through the vendor's hosted MCP server or a direct API:
| Managed · one Composio key | ||||
|---|---|---|---|---|
| Gong | ||||
| Presets · the vendor's hosted MCP server, with OAuth or an API key | ||||
| Ahrefs | Exa | |||
| Firecrawl | Fireflies | Gamma | Granola | |
| incident.io | LunarCrush | Monday.com | ||
| Neon | ||||
| Presets · direct HTTP API | ||||
| Native · bring your own | ||||
| Any service with an HTTP API or a remote MCP server. Bearer tokens and custom headers supported. | ||||
Gmail, Google Calendar, and Google Drive can also connect through your own Google Cloud OAuth client instead of Composio.
Managed connectors run through one Composio project key, added under Settings → Connectors. Sign-in happens in Composio's hosted UI and Chickpea polls for completion, so a self-hosted install needs no public OAuth callback URL. Opting in means Composio holds OAuth storage, refresh, and API execution for those accounts; Chickpea still owns account selection, capability limits, confirmation policy, and which provider account is used on every call. See the managed connector runbook.
Managing Chickpea
Chickpea has an Admin panel. It is not the only way in. The same controls have three front doors, with the same permissions and the same approvals behind each one.
- Admin, the browser UI on your deployment.
- Slack, by asking
@Chickpea, or asking any Agent about itself. - MCP, from any MCP client you already use, through the management MCP server. Settings → MCP in Admin has the snippet for each client, and
https://<your Chickpea>/connecthas the one-line prompt.
Most days the Slack door is the one you want.
@Chickpeamake me a support agent that answers billing questions and knows our refund policy
That one message creates the Agent, gives it a handle and an avatar, and publishes it to a channel you name. Where each job can be done:
| Slack | Admin | MCP | |
|---|---|---|---|
| Create, edit, archive, and restore Agents | ✓ | ✓ | ✓ |
| Change an Agent's instructions, model, or handle | ✓ | ✓ | ✓ |
| Publish an Agent to a channel, or pull it out | ✓ | ✓ | ✓ |
Import skills from a GitHub repo or a skills.sh link | ✓ | ✓ | ✓ |
| Edit an Agent's memory | ✓ | ✓ | ✓ |
| Set up and manage schedules | ✓ | ✓ | ✓ |
| Connect a service, grant a repository, add a provider key | link | ✓ | link |
| Composio project key, GitHub App, coding sandbox install | ✓ |
"Link" means the Agent hands back a Chickpea link and the rest finishes in the browser, because OAuth sign-in and secrets never pass through a Slack message. When you hand an Agent a GitHub link for skills, it reads the SKILL.md files and shows you which skills it found before importing any of them.
What keeps a chat window from being a loophole:
- Who can change what.
@Chickpeacan create Agents and edit any Agent you're permitted to edit. A routed Agent can inspect and edit only itself, still bound by your permissions. - Proposals before consequences. Two kinds of change arrive as a frozen read-only proposal: anything the Agent inferred rather than you stated, and anything that changes what an Agent can do, reach, or delete. Nothing applies until you approve it.
- No ceremony for small edits. Simple reversible single-field changes apply directly, and you can undo them.
- MCP gets the same treatment. Requests are scoped to that requester's permissions and held to the same approvals. The authoring guide is published at
chickpea://guide/agent-authoring/v1, and the workspace management MCP runbook covers authority and proposal semantics.
CLI
For scripts, there is a fourth door: the official chickpea-cli package on npm. It signs in with the same OAuth flow an MCP client uses and calls the same management tools, so a deployment can be checked and configured from a shell without building an MCP integration.
npx chickpea-cli doctor https://chickpea.example.com # public checks, no sign-in
npx chickpea-cli mcp config https://chickpea.example.com # client config for Claude Code, Codex, Cursor, and more
npx chickpea-cli login https://chickpea.example.com # browser sign-in, tokens stored 0600
npx chickpea-cli workspace inspect https://chickpea.example.com
npx chickpea-cli call https://chickpea.example.com <tool> --args '{...}'
npx chickpea-cli recipe export https://chickpea.example.com > recipe.json
The CLI never takes a token or key as an argument, never confirms a proposal on its own, and sends no telemetry. Node 24.x, minimum 24.20.0.
Memory
One memory per Agent, no partitions. The same body informs its DMs and every granted channel.
One consequence of that: something learned in a private conversation can influence a later channel answer. If you need isolation, use a separate Agent. Memory is not it.
Memory is advisory, never policy. Live instructions, current permissions, and verified grant state win. Secrets, tokens, sensitive personal data, and untrusted quoted instructions are rejected on the way in.
Schedules
Schedules belong to an Agent, target a granted Slack destination or a private DM thread, and record their creator as Runs as. Ask for one in Slack and the Agent sets it up.
Every run rechecks the whole chain: is the Agent alive, does it still have the channel, is the creator still a member, do the required connections still work, does policy still allow it. If authority disappears, future runs pause. Chickpea never silently reassigns work to someone else. Cloudflare supplies alarms; the production Node launcher checks for due work at startup and every minute while its process is running.
Models and Providers
Bring your own: Anthropic, OpenAI, OpenRouter, or Cloudflare Workers AI. Cloudflare deploys can use the keyless binding provider and skip the API token entirely. Keys go in environment variables or in Settings, whichever you prefer.
Node installations can also connect a ChatGPT subscription in Settings → Model providers → OpenAI for chat. This uses the subscription's shared usage limits. The option is unavailable on Cloudflare. Switching between a subscription and an API key is explicit; Chickpea does not fall back to API billing when the subscription is unavailable.
Every Agent can be pinned to its own model. A cheap fast model for triage, a strong one for the Agent that writes.
Images are a second model role beside chat. The first OpenAI connection sets an unconfigured workspace image default: Flare when you add an API key, or ChatGPT Image when you connect a subscription on Node. Existing choices, including a deliberately cleared default, are preserved. Change the default image model in Settings → Model providers, or override it on any Agent from its Model tab; Agents with the role filled can generate images in a thread, and Agents without it cannot. Flare and Sunburst use your OpenAI API key and support editing images from the conversation. On Node, ChatGPT Image uses the connected ChatGPT subscription independently of the selected chat method; it generates one image per call and does not edit images. ChatGPT chooses its output settings and does not identify a specific underlying image model. When an Agent makes an image, the prompt text it writes and any supported images people posted in that Slack thread are sent to that provider.
With Flare or Sunburst, ask for square, portrait, or landscape output, a quick draft, or a transparent background; the Agent passes explicit output controls. With ChatGPT Image, those preferences travel in the prompt and ChatGPT chooses the output settings. The Agent checks the returned file's dimensions and transparency. For models that support editing, a visual check uses the Agent's configured chat model and may make one corrective edit within the four-image response budget. Visual inspection can miss defects; it does not establish pixel-identical logos or typography, and unavailable checks are reported.
Chickpea attempts to retain generated files up to 8 MiB privately for up to 24 hours. The installation shares a 64 MiB cache; each file is accessible only in its workspace, Agent, channel, and thread. Cache pressure may remove files earlier. Ask to resend a retained image to retry its delivery without generating it again. Oversized files are compressed. For Flare and Sunburst, explicitly requested dimensions are preserved unless you accept a smaller resend. An image already shared in the conversation is resent using its original Slack file, avoiding another upload that Slack may re-encode. A new name labels the link; the existing download filename stays unchanged. Generated outputs and their references are also sent to the configured chat provider for the visual check. Transparent images are shown against a neutral checkerboard for inspection only; this does not alter the delivered file. Image generation and inspection costs are not yet included in Usage.
Coding Sandbox
The default Cloudflare deploy is the core profile: no container, no image build, small and fast. Normal Slack replies, administration, GitHub browsing, and repository-aware model work need none of it.
Install the coding sandbox when an Agent needs a real checkout, package installation, tests, or a dev server. Open Settings → Coding sandbox, request installation, redeploy. It requires Workers Paid. The container application and its Ubuntu-based image live in your Cloudflare account and may incur costs on it, and the first image build takes several minutes. Node installations always use the standard in-memory bash sandbox and never touch the host filesystem or host git and SSH. Full procedure in the coding sandbox runbook.
Security Model
What the design guarantees:
- No ambient listening. Unmentioned root messages never trigger classification, model spend, memory writes, or work. 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.
- Connection permissions, enforced through selected tools, resource scopes, and argument restrictions. Saved confirmation requirements and preview-only requests guide the model's behavior.
- Per-Agent isolation. Connections, memory, skills, repositories, and reach all stop at the Agent. Nothing is reused across Agents implicitly.
- Slack OIDC is the only human sign-in. No passwords. The first installer becomes the first Owner, bound to an exact workspace and user tuple. Email is mutable contact information, not the identity key. See authentication.
- An editor may publish only to a channel they belong to. Chickpea Admin status does not bypass Slack channel membership.
- Self-hosted state. Runtime, model traffic, configuration, memory, and connector credentials stay in infrastructure you operate. The exception is opting into Composio-managed connectors, which delegates OAuth storage, refresh, and API execution for those accounts to Composio. Native API and MCP connections keep their credentials with you.
- Minimal product telemetry. Chickpea sends six content-free, anonymous product events to measure adoption. It sends no messages, prompts, tool data, customer identity, or error text; it creates no person profile and can be disabled completely. The exhaustive field list and opt-out instructions are in Product telemetry.
The other exception is the optional shared Slack-app gateway, which exists so you can skip Slack app configuration entirely. It stores encrypted installation credentials and sanitized health metadata, but does not durably store Slack message or event bodies. If it cannot hand an event to your deployment, it returns a failure so Slack can retry; with Slack's Delayed Events setting enabled, those retries can continue hourly for 24 hours. Cloudflare and Node deployments durably admit the event before acknowledging it, then scrub the body as soon as processing reaches a terminal state and keep only a content-free deduplication record for 48 hours. Node stores its inbox in the installation's SQLite state and receives deliveries over an outbound socket. Read the exact retention and recovery boundaries in Shared Slack gateway data handling. If you'd rather not have the gateway in the path at all, pick the customer-owned Slack app lane, which talks directly to your deployment and never loads the gateway client.
Get started with your coding agent
Install on Cloudflare
Copy this prompt into a coding agent with terminal and browser access:
Install Chickpea for my Slack workspace on my Cloudflare account using this guide:
https://chickpea.co/install.md
The address serves the installation guide,
which stays current on main. It has your agent pick the latest stable
release, walk you through the Cloudflare, Slack, and model-provider choices,
verify a real Slack reply and Admin sign-in, connect itself to your new
Chickpea over MCP, and report the installed release and local project path.
Install on your Mac
Copy this prompt into a coding agent running on the Mac:
Install Chickpea on this Mac using this guide:
https://chickpea.co/install-mac.md
The address serves the Mac installation guide. It handles Node, the build, private state, and starting Chickpea. You choose a stable HTTPS address and complete Slack and provider authorization in your browser, and the agent connects itself over MCP before it finishes. Prefer a shell to an agent? The one-line installer does the same job.
Connect via MCP
Chickpea includes a built-in MCP server. Connect your coding agent to create Chickpea Agents, update their instructions, manage connections, edit memory, and set up schedules.
You need an existing Chickpea installation and permission to manage the Agents
you want to work with. Every address below uses your installation's address:
the same one you use for Admin, without /admin. Ask whoever installed
Chickpea if you don't know it.
The quickest way is to paste one line into your coding agent:
Connect my coding agent to my Chickpea using https://<your Chickpea>/connect.md
The agent reads that guide from your own deployment, writes its own client configuration, signs in through Slack, and proves the connection with one read-only call. Two places give you that prompt with the real address filled in, plus the exact snippet for every client:
- Settings → MCP in Admin (
https://<your Chickpea>/admin/settings/agents-clients). The Coding agents page lists Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, claude.ai and Claude Desktop, ChatGPT, and a generic JSON block, each with a Copy button, plus one-click Add to Cursor and Add to VS Code. Every member can open it. https://<your Chickpea>/connect, a public page on your deployment, for anyone who is not signed in to Admin yet. It works before Slack setup is finished, although/mcpanswers 404 until setup completes.
Prefer to type it yourself? One example, for Claude Code, with
chickpea.example.com standing in for your address:
claude mcp add --transport http --scope user chickpea https://chickpea.example.com/mcp
Then open Claude Code, run /mcp, select chickpea, and follow the browser
sign-in steps. The Settings page has the equivalent for every other client.
Sign in and try it
Sign in with your Slack account for the workspace where Chickpea is installed, then approve access to manage your Chickpea workspace. Authentication uses OAuth; no API key or separate MCP package is needed, and you never create or paste a token.
Start a conversation in your coding agent and ask:
Use Chickpea to show me the Agents I can manage and their connected services.
Then try:
Create a Chickpea Agent named Support that helps our team answer billing questions.
In Claude Code, /mcp__chickpea__new-agent opens the same guided flow from the
slash menu; /mcp__chickpea__status, /mcp__chickpea__edit-agent, /mcp__chickpea__connect,
/mcp__chickpea__schedule, and /mcp__chickpea__import-skill cover the rest.
These are MCP prompts, not installed local skills. In Codex, ask for the same
work in plain language; they do not appear in the $ skills picker. No separate
skills installation is required in either client.
Chickpea applies your existing permissions. Changes that expand access or require confirmation produce a proposal for you to approve. Connecting an account opens a browser setup flow.
Other MCP clients can connect to the same /mcp URL using Streamable HTTP
and OAuth.
See Managing Chickpea for available controls and the MCP guide for details.
Update Chickpea
Open your Chickpea folder in your coding agent and paste:
Update this Chickpea installation to the latest stable release. Follow:
https://chickpea.co/update.md
The address serves the update guide, which stays current on main. Your
coding agent preserves the existing installation settings, deploys the latest
release, and verifies Admin access. It does not send test messages to Slack.
Deploy it yourself
Cloudflare
The compressed Worker fits within the Workers Free size limit; only the optional coding sandbox requires Workers Paid. See Good to Know.
The installation guide is written for a coding agent, but every step in it is an ordinary command or browser action you can carry out yourself: clone a release tag, install dependencies, authorize Wrangler, deploy, and open the private setup link it prints.
Then pick a Slack lane:
- Add to Slack installs the unlisted shared Chickpea app through the private gateway. No configuration token, client secret, signing secret, public Events URL, or app-level token required from you.
- Use your own Slack app creates and installs a customer-owned app from the reviewed manifest. Paste a configuration token and it's done; a manual manifest path with screenshots is the fallback. Step-by-step in SETUP_AGENT.md.
Setup then runs four steps: connect Slack, choose a provider, choose a model, and try it. The last step has you message Chickpea in Slack. A real reply is the proof.
App installation and browser sign-in are two different OAuth jobs. Installation grants bot scopes; sign-in requests openid profile email and binds you as the first Owner.
Uses Cloudflare Workers, Durable Objects, D1, and Workers AI.
Node
On a Mac, run:
curl -fsSL https://chickpea.co/install.sh | bash
The installer prepares a private Node 24.20.0 runtime, builds a stable application release, creates persistent SQLite state, and opens setup. It leaves system Node and existing Chickpea installations alone. Guided ngrok setup can provide a stable HTTPS address without buying a domain or using Cloudflare. It saves your assigned domain and privately entered token, and runs the tunnel alongside Chickpea. Cloudflare Tunnel and externally managed HTTPS remain options. You need permission to install a Slack app and a model provider account. The Mac installation guide explains the HTTPS options, start/stop/restart commands, and optional start at login. ngrok Free has usage limits and a browser warning; check its current account allowance before relying on it for ongoing traffic.
The installer uses the latest stable application release. Mac installation is supported starting with v0.1.21. Guided ngrok setup and support for the shared Chickpea Slack app on Node are available starting with v0.1.22.
For an existing manual installation, keep using
npm run start:node -- --env-file <path>. For Linux hosting, backups, restores,
and upgrades, use
Operating and upgrading Chickpea.
Configuration
Chickpea is offline-safe by default. Left unset, most variables take a local path. These are the ones worth knowing:
| Variable | When | Purpose |
|---|---|---|
CHICKPEA_AUTH_SECRET | required on Node, managed on Cloudflare | Stable internal signing authority. |
SLACK_SIGNING_SECRET | customer-owned Slack lane | Verifies direct Events API requests. Setup can store it instead. |
SLACK_BOT_TOKEN | customer-owned Slack lane | Direct Slack Web API credential. Setup can store it instead. |
CHICKPEA_GATEWAY_URL | optional | Shared-app gateway origin. Defaults to the Chickpea-operated service; override only for a compatible private gateway. |
ANTHROPIC_API_KEY / OPENAI_API_KEY / OPENROUTER_API_KEY | optional | Enable the matching provider. Can be stored in Settings instead. |
CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_API_TOKEN | optional | Enable REST Workers AI. Cloudflare deploys can use the keyless binding provider instead. |
COMPOSIO_API_KEY | optional | Deployment-managed alternative to adding the project key in Settings → Connectors. Never enters a runtime plan or model context. |
DO_NOT_TRACK / CHICKPEA_DISABLE_TELEMETRY | optional | Set either to 1, true, or yes to disable anonymous product telemetry completely. |
CHICKPEA_TELEMETRY_ENVIRONMENT | optional | Label telemetry as production, development, or test; defaults to production on Cloudflare and development on Node. |
TAG_DB_PATH / SLACK_STATE_DB_PATH | optional, Node | SQLite paths for durable transcripts and app-owned state. |
CHICKPEA_RECOVERY_TOKEN | optional break-glass | One short-lived repair capability. Not a login credential. |
The full list, including per-connector Composio auth config IDs and the Google Ads and YouTube quota and policy assertions, is documented in .env.example, with setup procedures in the managed connector runbook and repair steps in the Slack auth recovery runbook.
Good to Know
- One deployment currently serves one Slack workspace.
- The shared gateway is private infrastructure. Its implementation and Slack credentials are not in this public repository, and it does not durably queue Slack event bodies. Delivery recovery relies on Slack retries plus deployment-owned admission; the data-handling contract spells out what is stored, where, and for how long.
- Updates are manual. The update guide walks a coding agent through them; your installation is a clone of a release tag, not a fork.
- Node durability is single-host SQLite. Multi-instance Node needs a shared state service.
- The compressed Worker upload is about 2.5 MiB, under the Workers Free plan's 3 MiB limit;
npm run buildfails if it grows past the budget inscripts/verify-worker-size.mjs. Public images and the Admin application's browser code use Static Assets in the same deployment, which do not count toward that limit. - Anonymous, content-free product telemetry is enabled by default and has a complete operator opt-out.
- The coding sandbox is Cloudflare-only. Node uses the in-memory execution path and runs scheduled work only while its production process is active; startup applies the same eligible missed-run policy after downtime.
- Earlier experimental schemas may be incompatible. Never reset production state to upgrade; follow the compatibility and recovery policy.
Contributions go through GitHub pull requests; see CONTRIBUTING.md. Report vulnerabilities privately using SECURITY.md. Maintainers use the release checklist.
Attachment limits
Per turn: 4 files, 8 MiB each, 12 MiB total, 100 PDF pages, 32,000 characters per file and 48,000 total. Images use Slack's bounded thumbnails when available. Anything over a limit, or without a safe conversion, gets a file-specific next action instead of a quiet partial read. Slack installations predating the files:read scope must reconnect once.
FAQ
"Why not just run one bot with every tool connected?" Because then every channel that bot is in has every credential that bot holds, and everything it learns anywhere it can say anywhere. Agents exist so you can put a wall between support's Zendesk and finance's spreadsheets without running a second deployment.
"What does this cost to run?" Chickpea itself is licensed under Apache 2.0 with no per-seat pricing and no metering. You pay your model provider directly for API usage. The Worker fits the Workers Free size limit; the optional coding sandbox requires Workers Paid. Workers, Durable Objects, D1, Workers AI, and optional coding sandbox usage run in your own Cloudflare account and may incur costs. Running on your own Node host, the infrastructure bill is whatever that host costs you.
"How do I see what an Agent actually did?" Most of it is already visible: work happens in Slack threads, in the open, under the Agent's own name. In Admin, the Memory tab shows exactly what an Agent retained (and lets you edit or delete it), and the Schedules tab shows status, last run, next run, and a run-history and activity inspector for scheduled work. One deliberate gap: activity telemetry is fixed-schema and content-free, and Admin has no searchable conversation archive. The conversation itself lives in Slack and in your deployment's transcript store.
"What is Flue?"
The open agent framework Chickpea runs on: @flue/runtime · flueframework.com · github.com/withastro/flue. Apache-2.0, from the Astro team, now part of Cloudflare. Flue is the TypeScript harness; Chickpea is the Slack product on top of it. More in How It Works.
Development
npm install
npm test # typecheck + node --test over tests/
npm run dev # local Node lane
npm run build # Cloudflare build
Targeted checks worth knowing:
npm run verify:admin-ui
npm run verify:cf-smoke
npm run verify:providers
npm run verify:management-mcp
npm run verify:oss-export
Node 24.20.0 is pinned in .nvmrc for development, builds, and verification. Node 24.x is the only supported major, with engine range >=24.20.0 <25. Later Node 24 updates are supported; update the pin for patch/security releases and verify the new baseline once. Other Node majors are outside this release's support policy. Several verify:*:live variants exist for provider- and Slack-touching evaluations; they are opt-in because they spend real quota. Live Slack acceptance should run against a disposable paid workspace so user-group policy, handle collisions, public auto-join, private invitation, App Home, avatar updates, archive, and restore all get exercised for real.
Live Slack verification is available through the repo-scoped $chickpea-live-verification skill. Codex discovers it automatically in this repository. The thin entry point routes to the canonical operator workflow and runbook, so the operating instructions remain in one place.
verify:slack-streaming-policy validates the content-free model-decision fixture corpus. A
provider evaluation is deliberately separate and opt-in: run
npm run verify:slack-streaming-policy:live -- --live --lane <lane> --model <id> only when
quota use has been approved. It exercises the shipped stream_answer name, description,
instruction, and acknowledgement against clear positive, clear negative, and ambiguous Slack
requests under a reduced prompt and tool surface. Its paired timings are provider-boundary
proxies: they show whether the declaration round trip can beat terminal model completion, but
they do not include durable persistence or Slack transport. The command never calls Slack or
prints model output. Actual first-visible Slack latency remains a separate, approved disposable-
workspace launch gate. Re-run both checks for each supported model when the model, system
instruction, or tool protocol changes.
License
Apache License 2.0. Use it, fork it, run it for your company, sell what you build on it, subject to the license terms.
Copyright (c) 2026 Pejman Pour-Moezzi. See NOTICE.
Version and updates
Installation Owners can open Settings → About & updates to review the current version, check releases, and copy an exact upgrade command. Updates are manual. Start with the Cloudflare update guide. The updater runbook documents its compatibility and recovery boundaries. Node deployments follow the operations guide.
Collected info
- ★ 5 stars
- Language: TypeScript
- Source updated: 9/25/2026
Config for your environment
Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.
Tool
OS
Config file: ~/.cursor/mcp.json
{
"mcpServers": {
"mcp-server": {
"url": "{MCP_ENDPOINT_URL}"
}
}
}Paste into mcpServers in the config file. Restart Cursor after saving.
If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.