CopilotKit/OpenBot
Open-source AI coworkers that each get a computer of their own: a browser, files and tools, with every action decided before it happens and recorded after. Bring any AG-UI agent.
About CopilotKit/OpenBot
CopilotKit/OpenBot is an open-source project on GitHub, mainly written in TypeScript. Open-source AI coworkers that each get a computer of their own: a browser, files and tools, with every action decided before it happens and recorded after. It currently holds 7,759 stars and 1,030 forks with 45 open issues, and was last pushed on 2026-10-29 (repository created 2026-08-17).
Project Overview
Git Homed tracks it on the Today's Trending board, currently at rank #36 with 247 new stars today.
GitHub Repository Details
README
OpenBot
The AI assistant your company can actually own. Same shape as ChatGPT, Claude or Grok, with one difference that matters: it runs on your infrastructure and you can change anything about it. Any agent stack, through AG-UI.
Each coworker gets a computer of its own: a real browser with its own logins, its own files, and only the tools you grant. Every action decided before it happens and recorded after.
Talk to an engineer · Have us build it with you · copilotkit.ai/openbot · Quick start · Docs
https://github.com/user-attachments/assets/535ef7ee-1631-4a69-b839-564c56cf90b4
Bring any AG-UI agent, written on a framework or by hand, and it arrives as a coworker with a channel of its own. Watch it work on its own screen, take the wheel when it reaches something it should not do alone, then hand it back. It answers with components rather than only prose, and the whole thing runs on your own machine.
A template, not a product. OpenBot is meant to be cloned and made your own. There is no hosted version to sign up for, and nothing here is published as a package to depend on: every workspace in this repository is private. You take the repository, replace the example tenant package under examples/ with your own coworkers, channels and skills, and run it. Everything below describes a starting point, not a finished thing somebody operates for you.
Beta, and under active development. OpenBot is early. Expect rough edges and bugs, and expect things to move. Issues and pull requests are welcome.
Runs on your machine. Everything below is written for a laptop..env.examplecarriesOPENBOT_SINGLE_USER=true, which admits every request as one administrator, so a fresh clone reaches the product without registering an OAuth client first. Sign-in turns that off, and is required before anybody else can reach the deployment.
We can build this for you, or with you, at your company. Our engineers will stand OpenBot up
inside your infrastructure, customize it into something that looks like your own product, and hand it
back to you to keep changing. Start the conversation.
> In the meantime, run all of it on your laptop, Intelligence included: CopilotKit's free Developer plan
covers running Intelligence locally in Docker on a Mac.
What it is
An agent platform that runs inside your own infrastructure. Docker Compose brings up every part of it, the data sits in your PostgreSQL, and the model is yours to choose: no model ships in the box, and an administrator supplies the credential, which is encrypted at rest and never logged.
A deployment starts with two coworkers, and they are configuration rather than code: General Assistant for everyday work and Knowledge for company questions. A Risk Analyst joins them once its endpoint is configured, and ten more wait in examples/fintech/catalog/, each doing one job — reading an expense claim against the policy as written, turning a meeting note into the follow-ups actually in it, drafting release notes from what shipped, triaging a ticket, answering a new starter from the handbook, writing a brief that names what it could not find, writing up an interview, handing an on-call shift over, assembling what is known before a renewal, and grouping customer feedback into themes it can cite. Copy one into examples/fintech/agents/ to add it, write your own there or in agents.yaml, or make one from /bots in the UI.
Anything a Bot does to a computer, a file, an MCP server or a component goes through one gateway that decides and records it. That is the difference between an agent that can use your tools and an agent you can let near them.
More at copilotkit.ai/openbot.
Built on AG-UI
A Bot is any endpoint speaking AG-UI, the open protocol for agent-to-user interaction, so OpenBot is not tied to a framework and neither are you. Agents built with LangGraph, Mastra, CrewAI, Pydantic AI, Google ADK or written by hand all arrive the same way, and the governance rides the protocol rather than the framework.
Requirements
- Docker, for PostgreSQL and the shipped Bots.
- Bun 1.4+, for the app, the API server and the tests (some tests fail on 1.3).
- A CopilotKit Intelligence project and license. A free plan is available, and Intelligence can be self-hosted.
- A model key. The proof-of-concept Bot uses OpenAI; the LangGraph Bot can use OpenAI, Anthropic, or Google.
Quick start
Setting up with an AI assistant? Paste prompt.txt into it first. It carries the
same steps as below plus the things that are easy to get wrong: which of the blank keys in
.env.example are actually yours to fill (the CopilotKit key and a model key), which the start
script fills for you, and what each start-up refusal means. Every claim in it is checked against
this repository.
1. Create .env:
cp .env.example .env
bun install
2. Connect a fresh managed Intelligence project:
npx --yes copilotkit@latest login
npx --yes copilotkit@latest project select
bun scripts/setup-learning.ts
The helper provisions the selected project's runtime key, creates or reuses its
openbot Learning container, then writes both settings to .env. It preserves
custom container assignments and never replaces an existing OpenBot key; with one
set, it only creates openbot in that key's project if it is missing.
For fresh self-hosted setup, set INTELLIGENCE_API_URL to that deployment's
HTTPS API origin (or http://localhost for a local one) and run the helper
without the two npx commands. It opens an isolated Chrome or Edge window for
your usual sign-in and project choice; install either browser first. For CLI-managed
local evaluation installs, it discovers the matching dashboard with the newest installed or
cached CopilotKit CLI and uses that dashboard for login and session requests. Discovery
runs offline with Bun, without downloading the CLI or requiring npx on your PATH.
If no CLI is available, manually hosted deployments use their API origin for sign-in. Complete the local auth
approval shown in the browser when prompted. The runtime API URL stays unchanged. It writes
the API URL, the key and the container, not INTELLIGENCE_GATEWAY_WS_URL, so
set that one to the same deployment yourself. Once openbot exists, the server assigns it
as the default by itself unless Admin → Automatic Learning
has a saved setting.
Managed Intelligence needs no separate licence token.
3. Fill the remaining required values:
OPENAI_API_KEY
.env.example unless you run Intelligence yourself. The example KEY_ENCRYPTION_KEY is public and fine locally; generate your own with:
openssl rand -base64 32
4. Run:
bash scripts/start.sh
5. Open .
scripts/start.sh starts Docker services, applies migrations, starts the API server on port 3001, starts the routine worker, starts the app on port 3010, and checks that the services answer their own health routes before printing next steps.
scripts/stop.sh takes the same things down, including each Bot's computer, which compose does not own; --keep-computers leaves the computers running. Nothing is deleted: the database, the Bots' files and their browser profiles are volumes.
Intelligence on your own machine
To try Intelligence on one Mac instead of the managed service, follow
Evaluate Intelligence locally. The free
Developer plan qualifies. The local licence lasts 30 days and
npx copilotkit@latest local renew renews it as often as you need, while your account is in good
standing. It is a preview for macOS with Docker Desktop,
not a production installation. Run its
npx copilotkit@latest local connect from the OpenBot root, where .env is.
That command writes INTELLIGENCE_API_URL, INTELLIGENCE_GATEWAY_WS_URL and
CPK_INTELLIGENCE_API_KEY to .env. OpenBot reads those settings directly; no key
copying or renaming is needed. INTELLIGENCE_API_KEY remains supported for older
configurations. When both are set, the non-empty CLI key takes precedence so
reconnecting uses the new project's key.
To give the Bots a Learning container on that stack, see Automatic Learning.
Deploy it
One image carries the app, the API, the browser the Bots drive, and optionally PostgreSQL. Same
.env, no Kubernetes.
# The published image. Nothing to clone and nothing to build.
docker run -p 3001:3001 --env-file .env \
-e EMBEDDED_POSTGRES=on -v openbot-data:/var/lib/postgresql \
ghcr.io/copilotkit/openbot:latest
Or the tree you have in front of you.
docker build -t openbot .
docker run -p 3001:3001 --env-file .env \
-e EMBEDDED_POSTGRES=on -v openbot-data:/var/lib/postgresql openbot
Everything is on 3001 here, the app included, rather than the 3010 the clone uses. latest is the
most recent release and a version tag such as :v0.0.9 pins one.
Leave EMBEDDED_POSTGRES off and set DATABASE_URL to point at a database you already run.
docs/deployment.md has the minimum sizes, the platform notes, and how it behaves behind more than one replica.
Try it
- Open
/botand ask:Open news.ycombinator.com and tell me the top story. - Ask the Bot to fill out , then inspect
/admin/audit. - Open
/admin/boundaries, add a deny rule or preset, and retry the same browser action. - Create a Bot from
/bots, give it a standing role, and start a channel with it.
Main surfaces
| Route | Purpose |
| --------------------------- | ------------------------------------------------------------------ |
| / | Start and browse channels. |
| /channel/new | Start a conversation; two or more Bots in To: start a group. |
| /channel/:id | Converse with one coworker, watch its screen, and see what it ran. |
| /bot | Direct chat with a Bot; ?agent= selects one. |
| /bots | Every Bot you can reach; create one, and open its page to change it. |
| /bots/:id | One Bot: what it waits on you for, what it is doing, and how it is set up. |
| /bots/:id/responsibilities | Give the Bot a lasting goal, follow its progress, and decide when it should work. |
| /bots/:id/reach | Continue a conversation with the Bot in Slack, Microsoft Teams, or by text message. |
| /bots/:id/memory | Which connected apps feed the Bot facts, and its background research. |
| /bots/:id/approvals | What the Bot may do without asking you first. |
| /connections | Connect your apps so your Bots can work with them. |
| /capabilities/skills | Create and enable personal skills. |
| /capabilities/memory | What your Bots remember about you, and facts you tell them. |
| /routines | See the routines that are standing, and stop one. |
| /settings | User preferences. |
| /settings/passwords | Logins you saved when signing a Bot in to a website. |
| /settings/notifications | Where updates go, your devices, and recent deliveries. |
| /settings/approvals | Whether your Bots ask before acting, and rules for every Bot. |
| /admin/credentials | Store write-only encrypted credentials. |
| /admin/approvals | Team approval settings, team rules, and shared account requests. |
| /admin/computers | View, stop, and reset Bot computers. |
| /admin/boundaries | Configure browser/file/MCP action policy. |
| /admin/components | Publish components and govern which Bots may use them. |
| /admin/playground | Draft and publish sandboxed components in the browser. |
| /admin/plugins | Configure MCP servers and grant their tools to Bots. |
| /admin/skills | Write deployment skills and grant them to Bots. |
| /admin/learning | Assign Learning containers to Bots, or pause Automatic Learning. |
| /admin/people | List, promote, demote, and remove people who have signed in. |
| /admin/identity-providers | Register a company SAML or OIDC provider, routed by email domain. |
| /admin/enterprise | What members may use, how Bot computers reach the network, and what is recorded about it. |
| /admin/audit | Review permitted, refused, and failed actions. |
Features
- A computer per Bot: the supervisor gives each Bot its own container, its own
/workspacevolume and its own browser profile. SetCOMPUTER_RUNTIME=runscto run them under gVisor where the host supports it. - A shell, not just a browser: a Bot can run a command in its workspace, install what it needs, and process a file it saved. Through the same gate as everything else, so a rule can refuse a shell outright or refuse particular commands, and the command is on the record either way. The command inherits PATH, locale, terminal and proxy variables, not the rest of the deployment's environment.
- The gateway is the only way in: it resolves the target from a server-held snapshot, evaluates the policy, writes the audit row, and only then calls the computer. There is no path that acts without the record existing first.
- CEL policy, fail closed: rules can inspect
tool.name,intent,bot.id,actor.id,page.url,page.host,element.,key,command,file.,mcp.andinitiator.(what started the run, so a rule can refuse a scheduled routine what it would allow a person). Deny is evaluated before allow, a missing policy permits nothing, and a broken rule refuses rather than opens. - Watch what it is doing: the screen shows what a Bot is looking at, and the Activity tab beside it shows what it ran, read and saved, with the output. A command line in the transcript opens to the same thing. A saved file shows its path and size, never its contents.
- Take the wheel: a Bot that hits a login wall or a 2FA prompt asks for help. Control is handed over in the same panel and recorded as
computer.help_requested,computer.control_takenandcomputer.control_released. While a person is driving, Bot actions are refused rather than queued. - Secrets never enter the transcript: the trail records that a secret was requested and how long it was, not what it said.
- Bring your own agent: any AG-UI endpoint is a Bot, on a framework or hand-written. Endpoints are validated with the same target checks used for browser navigation, and an auth header is stored write-only.
- Components instead of prose: compiled React components live in
app/src/components/gallery/, sandboxed ones are authored in/admin/playgroundand published with no deployment. Every call asks the server whether the component exists, is published, and is not withheld from that Bot. Data functions are granted per component. - Governed MCP: Google Drive, Notion and the public-web research providers Parallel, Exa and Firecrawl ship in the catalogue, and Composio brokers a few hundred more apps behind one account, each reached as the person asking. The catalogue carries only vendors this deployment stands behind, so adding one is a review of that vendor. Custom servers must pass URL checks; unknown tools and custom-server tools are treated as writes, and a catalogue tool the server advertises but does not name as a write classifies as a read. A Bot is told which connectors exist here and which it holds, so it says it has not been granted one rather than browsing to the vendor's website.
- Skills are instructions, not capabilities: personal skills attach only to Bots their author owns, deployment skills are admin-owned, and both are invoked with
/in the composer. A Bot granted the shippedskill-creatorskill can write one with you in the conversation, and saves it only when you press the button on the card. - Sign in with what your company already has: Google, Microsoft or Okta from the environment, or a company's own SAML or OpenID Connect provider registered while the deployment runs and routed by email domain. Any one turns sign-in on; several may be configured at once.
- Decide who gets in:
/admin/peoplelists everybody who has signed in, promotes and demotes them, and removes access, which ends the session they are using and stops the next sign-in. Every change is on the audit trail. - An audit trail you can read:
/admin/auditlists what was permitted, what was refused and what failed, and every refusal carries the rule that caused it. - Credentials encrypted at rest: stored through
/admin/credentials, never returned by an API, and redacted from audit events. - Loopback by default: computers bind to
127.0.0.1and require a per-container token, so nothing reaches a logged-in browser by knowing its port. The supervisor binds there too, because it holds the Docker socket and its token is a shared secret rather than a network boundary. - Durable threads and memory: conversations survive restarts through CopilotKit Intelligence, and each deployment stamps the threads it owns.
- Routines: ask a Bot to do something on a schedule and it does, running as you, in the channel you asked in. A 15-minute floor and a cap of 20 enabled routines keep a sentence from scheduling more than a person meant, and ten failures in a row switch a routine off rather than burn model spend forever. Needs a worker process, which
scripts/start.shstarts locally; see docs/routines.md.
Bring your own agent
Any AG-UI endpoint can be a Bot.
From /bots, create a Bot with:
- name, title, and role description;
- private or public visibility;
- optional AG-UI endpoint;
- optional write-only authorization header.
MANAGED_AGENT_AG_UI_URL when it is configured, and are refused when it is not.
A private address is refused unless it is listed in AGENT_ENDPOINT_ALLOWED_HOSTS:
AGENT_ENDPOINT_ALLOWED_HOSTS=agents.internal,10.0.0.42:9000
A host on its own covers any port on that host; a host with a port pins that port. Matching is exact: no wildcards, no suffixes. An entry written as a URL, or containing *, stops startup and names that entry.
The list covers agent endpoints only. Browsing is unaffected, the addresses holding a deployment's own cloud credentials are refused whatever is listed, and listing an address permits registering an agent there rather than granting that agent anything.
Tenant package agents are declared in the package's own agents.yaml, in the directory TENANT_PACKAGE_DIR names (examples/fintech by default), or each in a file of its own under that package's agents/ directory, as either:
built-in, with a system prompt; orremote-ag-ui, with an endpoint.
Configuration
.env.example is the source template. The API server refuses to start without:
DATABASE_URLKEY_ENCRYPTION_KEYINTELLIGENCE_API_URLINTELLIGENCE_GATEWAY_WS_URLINTELLIGENCE_API_KEY
COPILOTKIT_LICENSE_TOKEN is optional. A self-hosted Intelligence with its own
licence can still set it and it is forwarded to the runtime; managed Intelligence
does not issue one and startup no longer asks for it. A self-hosted Intelligence
also needs the licence on its own deployment, or it refuses memory; OpenBot logs
intelligence-entitlement-not-ready at boot when that is missing.
Settings worth knowing:
| Variable | Use |
| ------------------------------------ | ------------------------------------------------------------------------- |
| OPENBOT_SINGLE_USER | Admits every request as one administrator. Required when no identity provider is configured; .env.example ships it on. |
| OPENAI_BASE_URL | Answers the OpenAI-shaped calls from somewhere else: a gateway, a proxy. |
| ANTHROPIC_BASE_URL, GOOGLE_GENERATIVE_AI_BASE_URL | The same, for those two APIs. |
| COMPUTER_TOKEN | Secret every Bot computer request must present. start.sh falls back to a fixed dev value. |
| SUPERVISOR_TOKEN | Secret the supervisor requires. start.sh falls back to a fixed dev value. |
| AGENT_TOOL_TOKEN | Secret a Bot presents to call a granted tool back. start.sh sets one. Without it no Bot may call tools. |
| COMPUTER_SUPERVISOR_URL | Gives each Bot a computer of its own instead of one shared computer. |
| COMPUTER_RUNTIME | Set to runsc to run computers under gVisor, where the host has it. |
| COMPUTER_SANDBOX | Set to on for Chromium's own sandbox, where the host permits it. |
| EMBEDDED_POSTGRES | Set to on for a database inside the deployment container. |
| AGENT_COMPUTER_POLICY | JSON action policy. Malformed JSON stops server startup. |
| AGENT_COMPUTER_ALLOW_PRIVATE_HOSTS | Lets a Bot reach this machine's