Connect External Agents
Connect Claude Code, Codex, ChatGPT, OpenClaw, or custom MCP/HTTP agents to your BuildOS project context.
Your messy thinking lives in BuildOS. Your AI tools — Claude Code, OpenClaw, Codex, ChatGPT Actions, custom HTTP clients, and browser-based remote connectors — can read off the same sheet of paper instead of starting from zero each session.
Generate a key, or approve an OAuth grant from a remote MCP client. Choose where you are installing it. BuildOS gives you the right storage instructions for that client. Local tools usually use an MCP config, env var, or local stdio bridge. Private ChatGPT Actions use the Action authentication secret. Browser/cloud clients should use remote MCP with OAuth.
Per-project scope. Per-op write whitelist. Audit log. Rotate or revoke any time. No retraining your agents on your context every session.
What agents should do first
BuildOS is usually a workspace with many projects. After an agent connects, it should:
- If using MCP, initialize the MCP connection and call
tools/list. If using the JSON-RPC gateway, callcall.dialfirst, thentools/list. - Use the direct tool names returned by
tools/list. - If it is about to work inside an existing project, call
get_onto_project_statuswith theproject_idfirst. - If the project it needs is missing, or a call fails with
project_not_granted_to_connector, give you thegrant_urlfrom the response and retry after you approve. See When an agent can’t see a project.
get_onto_project_status is the BuildOS equivalent of git status for a project. It returns the compact snapshot an agent needs before deeper reads or writes: START HERE orientation context, project description, task/document/plan/goal/collaborator counts, active collaborators, recent changes, overdue and due-soon tasks, and upcoming events.
Client profiles
Same BuildOS auth core. Different save location.
| Client profile | Best storage path | Status |
|---|---|---|
| OpenClaw | OpenClaw env, SecretRef, or plugin config | BuildOS side ready; OpenClaw connector in progress |
| Claude Code | claude mcp add with a bearer header or OAuth | Remote HTTP MCP ready at /mcp/buildos |
| Claude Desktop / local MCP hosts | Local stdio bridge env vars, or direct remote MCP if supported | Bridge exists in repo; package is not published to npm |
| ChatGPT Actions | GPT Action API key secret | Ready for private GPTs; use OAuth before sharing broadly |
| ChatGPT MCP / Apps | Remote MCP OAuth connector | OAuth remote MCP ready at /mcp/buildos |
| Codex CLI / IDE | ~/.codex/config.toml with bearer_token_env_var | Remote MCP config ready; local bridge available |
| Custom HTTP / scripts | Your env file or secret manager | Ready |
BuildOS speaks the Model Context Protocol at /mcp/buildos. Local clients can authenticate with the agent key in an Authorization: Bearer header or an env-backed MCP config; browser/cloud clients (Claude.ai, ChatGPT) authenticate with OAuth — no pasted token. The older JSON-RPC gateway at POST /api/agent-call/buildos (the call.dial → tools/list → tools/call → call.hangup flow) still works for any HTTP-capable tool and is the fallback when a client can’t speak MCP.
The MCP endpoint supports three profiles:
| Profile | URL | Tool surface |
|---|---|---|
general | /mcp/buildos | Scoped BuildOS read/write tools; discovery tools are hidden. |
chatgpt_data_app | /mcp/buildos?profile=chatgpt_data_app | Read-only search and fetch only, even if the underlying grant allows writes. |
local_admin | /mcp/buildos?profile=local_admin | Full scoped surface including skill_load, tool_search, and tool_schema. Use only for local/admin clients you control. |
Generate an agent key
- Go to Profile → People & agents and choose Connect an agent.
- Click Generate.
- Choose the Client Profile for the place this key will be installed.
- Pick a scope:
read_only— reads only, no writes.read_write— reads plus the writes you whitelist.
- Choose which projects the key can see:
- All standard projects (default) — every project you own, including ones you create later.
- Only selected projects — a fixed list. Picking every project here freezes today’s list, so BuildOS warns you and offers to switch to All standard projects.
- If you picked
read_write, whitelist the specific write ops. - Copy the profile-specific setup block. The one-time secret shows only once; BuildOS stores a prefix for identification and never the full key.
- Save it in the profile’s config, secret store, Action auth field, or connector backend.
/integrations has the same flow plus the public landing page.
Install as a plugin (Claude Code and Codex)
The BuildOS repository is also a plugin marketplace. The same plugins/buildos directory carries a Claude Code manifest, a Codex manifest, and a skill that teaches the agent how to work inside a BuildOS workspace (find the project, call get_onto_project_status, then read or write).
# Claude Code
claude plugin marketplace add Wolverine971/buildos-platform
claude plugin install buildos@buildos
# then /mcp → buildos → approve the BuildOS consent screen
# Codex
codex plugin marketplace add /absolute/path/to/buildos-platform
codex plugin add buildos@buildos The plugin connects over remote MCP with OAuth, so no key is pasted anywhere. Consent grants a refresh token, so the connection survives past the one-hour access-token lifetime without re-approval.
Setting it up in Claude Code
Choose the Claude Code client profile when generating the key, then add BuildOS as an MCP server. The Agents section shows this exact command (with your key filled in):
claude mcp add --transport http buildos https://build-os.com/mcp/buildos --header "Authorization: Bearer boca_your_one_time_secret" Restart Claude Code and BuildOS tools appear. Then prompt:
“Connect to BuildOS and list my projects.”
When you pick a project, ask it to call get_onto_project_status before deeper reads or writes — it’s a compact, git-status-style snapshot of the project.
Prefer not to paste a key? Run the same command without --header:
claude mcp add --transport http buildos https://build-os.com/mcp/buildos Then run /mcp inside Claude Code and follow the browser login flow. Claude Code discovers BuildOS’s OAuth metadata, and you approve scope and projects — no token stored locally.
Working from a checkout of this repository? Keep the key in the macOS Keychain and let the stdio bridge launcher read it, so nothing secret lands in ~/.claude.json:
security add-generic-password -a "$USER" -s buildos-agent-token -w 'boca_your_one_time_secret'
pnpm --filter @buildos/mcp-server build
claude mcp add --scope user --transport stdio buildos --
/absolute/path/to/buildos-platform/packages/buildos-mcp-server/bin/buildos-mcp-bridge.sh The JSON-RPC gateway at POST /api/agent-call/buildos remains available as a fallback if you’d rather drive the call.dial flow directly with the env block:
BUILDOS_BASE_URL=https://build-os.com
BUILDOS_AGENT_TOKEN=boca_your_one_time_secret
BUILDOS_CALLEE_HANDLE=buildos:user:YOUR_USER_ID
BUILDOS_CALLER_KEY=claude-code:local:your-handle Setting it up in Cursor
Use the direct remote MCP URL if your Cursor build supports remote HTTP MCP:
URL: https://build-os.com/mcp/buildos
Header: Authorization: Bearer boca_your_one_time_secret If your Cursor setup only launches local stdio MCP servers, use the local bridge in packages/buildos-mcp-server:
pnpm --filter @buildos/mcp-server build Then point Cursor’s MCP config at the built entrypoint:
{
"mcpServers": {
"buildos": {
"command": "node",
"args": [
"/absolute/path/to/buildos-platform/packages/buildos-mcp-server/dist/index.js"
],
"env": {
"BUILDOS_BASE_URL": "https://build-os.com",
"BUILDOS_AGENT_TOKEN": "boca_your_agent_key"
}
}
}
} Then prompt:
“Connect to BuildOS, list my projects.”
For project work, ask it to call get_onto_project_status first so it has the current project snapshot.
Setting it up in Claude Desktop and Claude browser
There are two different paths:
- Claude Desktop / local MCP hosts can use direct remote HTTP MCP if supported, or the local stdio bridge in
packages/buildos-mcp-serverwhen the client expects a local process. - Claude browser or cloud-brokered remote connectors authenticate with OAuth, not a pasted token. Browser chat is not a secret store, and Claude’s cloud cannot read your local env.
For browser/cloud clients, add https://build-os.com/mcp/buildos as a custom/remote MCP connector. BuildOS publishes OAuth metadata, so the client takes you through a consent screen where you pick scope and projects, then issues its own token behind the scenes. Nothing to copy or paste.
Setting it up in Codex
Choose Codex CLI / IDE when generating the key. Add BuildOS to ~/.codex/config.toml and keep the secret in your environment:
[mcp_servers.buildos]
url = "https://build-os.com/mcp/buildos"
bearer_token_env_var = "BUILDOS_AGENT_TOKEN" export BUILDOS_AGENT_TOKEN=boca_your_one_time_secret If a Codex surface only supports local stdio MCP servers, use the bridge launcher (codex mcp add buildos -- /absolute/path/to/buildos-platform/packages/buildos-mcp-server/bin/buildos-mcp-bridge.sh); it reads the key from the macOS Keychain and works from the Codex desktop app as well as the CLI. For direct remote MCP, append ?profile=chatgpt_data_app to the URL only when you intentionally want a read-only search/fetch surface; for the local bridge, set BUILDOS_MCP_PROFILE=chatgpt_data_app.
Setting it up in ChatGPT (Custom GPT)
Choose ChatGPT Actions for a private Custom GPT:
- In your Custom GPT, add a new Action.
- Use API key auth with Bearer placement, and paste the one-time BuildOS token into the Action authentication secret.
- Import the OpenAPI artifact from the BuildOS bootstrap document.
- Point it at
POST https://build-os.com/api/agent-call/buildoswith a JSON-RPC body.
The Custom GPT can then run call.dial → tools/list → tools/call → call.hangup like any other client.
For shared GPTs or workspace-wide installs, use OAuth instead of a single bearer token.
Setting it up in ChatGPT Developer Mode
Choose ChatGPT Developer Mode only when you are building a remote MCP connector. Developer Mode is the right path for MCP tools in ChatGPT, but it should be backed by remote MCP and OAuth, not a pasted BuildOS bearer token.
Use https://build-os.com/mcp/buildos?profile=chatgpt_data_app when ChatGPT should only search and fetch BuildOS context. Use https://build-os.com/mcp/buildos only for trusted full-tool connectors where the OAuth grant and BuildOS scope allow the requested writes.
Setting it up in OpenClaw
Choose OpenClaw when generating the key. Store the values in OpenClaw env, SecretRef, or plugin config. The OpenClaw-specific connector is still mid-build. Once it ships, it should read those values and call the BuildOS gateway.
What you can scope
| Control | What it does |
|---|---|
| Mode | read_only blocks every write op. read_write allows the ones you whitelist. |
| Project scope | All standard projects (includes future ones) or a fixed list. Shared and restricted projects always need an explicit grant. |
| Write op whitelist | Per-op toggle for every mutation the gateway exposes. |
| Audit trail | Every call is logged with the key prefix, the op, and the entity touched. |
When an agent can’t see a project
If a key is limited to selected projects and your agent reaches for one outside that list, BuildOS doesn’t just refuse. The response includes a grant_url, and project lists include a count of projects the agent can’t see. Neither ever shows the hidden projects’ names. Open the link and choose:
- Share just this project — adds that one project, at the key’s existing read or read/write level.
- Share all my projects — switches the key to All standard projects, so this won’t come up again.
The agent retries and keeps working. The key isn’t rotated and nothing reconnects. Every grant is logged. You can also open /profile/agent-keys/<key id>/grant directly to see and share everything a key can’t reach yet.
Saving a key from the Agents editor re-issues a static key’s secret, so update the client’s config afterward. The grant page never rotates the key. OAuth connectors are always edited in place.
Projects where you turned on Only agents you pick can reach this project (in the project’s Share window) are never included automatically. Projects someone else shared with you are left out too, unless you turn on Projects shared with me for that key or connector (open it under Profile → People & agents → Agents, or on its grant page). It’s off by default, and each owner’s setting for your agents still applies.
Other people’s projects
Your agent works for you, so it sees what you can see and nothing more. Other people’s projects reach it only through you:
- Find someone.
find_buildos_personlooks up an exact@handle. It finds only people who turned on “People with my handle can find me”, and it returns their name, handle, and bio, never an email. If they published a page at build-os.com/@handle, the result includes itsprofile_url, andget_builder_profilereads that page as data: what they’re building, what they’re looking for, and how to ask. Your agent sees the page as you would. - Ask.
request_buildos_accesssends that person an access request in your name, with an optional note. Agents can ask; only people approve, in BuildOS. There is no tool that approves or shares. - Check.
list_buildos_peopleshows the requests you sent and received, and the projects shared with you that this connection can read.
Once someone shares a project with you, your agent still needs two more yeses: the owner’s setting for your agents (Off, Read, or Write; Read by default), and your own grant of that project to this key or connector. Shared projects carry shared_with_you and owner_name in project results.
When an owner allows your agents to write, they stay in a lane: they can add tasks and documents, and edit only what you created or are assigned to. Goals, plans, milestones, risks, tables, and the project itself stay with the owner. They can’t archive, delete, invite, or change the project’s START HERE. Each agent can make 50 changes per project per day before it pauses and the owner hears about it once.
Owners can also turn on Editors’ agents can make changes for a project (in the project’s Share window, under Agents in this project). While it’s on, every editor’s agents can write there without asking, except people whose agents the owner turned off.
When an agent hits a wall
Every refusal in a project you can see says what is in the way, who can clear it, and the one step that does. It’s in error.details.access_needed:
wall | Who fixes it | What the agent does |
|---|---|---|
project_not_granted | You | Shows next.open_url; one tap gives this connection the project |
connection_read_only | You | Shows next.open_url; one tap allows changes (OAuth connections reconnect) |
owner_turned_agents_off | The owner | Asks you, then sends request_project_access |
owner_allows_read_only | The owner | Asks you, then sends request_project_access for changes |
viewer_only | The owner | Asks you, then asks the owner to make you an editor |
outside_guest_lane | Nobody (a rule) | Explains; offers to add it as a task, or you make the change in BuildOS |
daily_limit | Nobody (a rule) | Says it paused until tomorrow; the owner was told once |
Each one carries say_to_user, a sentence the agent can show you as is. Projects the connection can’t read are never named in it.
- Your walls come with a link to your own page for that connection. Clients on the 2026-07-28 MCP protocol that support URL elicitation open it inline, then retry the call; others show the link.
- Owner walls never ping the owner on the agent’s own say. The agent asks you first; on your yes,
request_project_accesssends one request in your name, labeled as sent by your agent. The owner gets a notification and an email and answers with one tap in Profile → People & agents. Asking again while a request waits adds to it, so the owner answers once. Limits: 5 agent requests per connection per day, 10 waiting per person, and “Not now” holds for a week per project. - Picking back up.
check_project_accesstells the agent where it stands without trying a change:ready,needs_you,needs_owner,waiting_on_owner,owner_said_no, ornot_found. When the owner says yes, the request’s projects are added to the connection that asked, so the agent can retry right away.
Permission bundles
The Agents setup leads with preset bundles. Pick one and you’re done — the per-op matrix sits behind an Advanced permissions disclosure if you need finer control.
| Bundle | What it grants |
|---|---|
| Read only | Every read op. No writes. |
| Author docs + tasks (recommended default) | Reads plus onto.document.create/update and onto.task.create/update. |
| Full read/write | Reads plus every write op the gateway currently exposes. |
| Custom | Any per-op combination you pick in Advanced. |
Existing OpenClaw keys that still carry the old narrow default (task writes only) auto-upgrade to Author docs + tasks on the next call — no action needed.
Project creation is its own write op: onto.project.create requires read_write and the op whitelisted. It is not tied to all-project access — a key scoped to selected projects can still create new ones, and each project it creates is automatically added to that key’s scope so it can immediately read and write the project it just made. To prevent a key from creating projects, leave onto.project.create out of its write whitelist.
What’s exposed
Reads (available on every key)
- Projects:
onto.project.list,onto.project.search,onto.project.get,onto.project.status.get,onto.project.graph.get - Tasks:
onto.task.list,onto.task.search,onto.task.get,onto.task.docs.list - Documents:
onto.document.list,onto.document.search,onto.document.get,onto.document.tree.get,onto.document.path.get - Goals, plans, milestones, risks: list/search/get for each entity
- Assets:
onto.asset.search,onto.asset.get - Links:
onto.entity.relationships.get,onto.entity.links.get - Search:
onto.search - Calendar:
cal.event.list,cal.event.get,cal.project.get
Writes (require read_write)
onto.task.create,onto.task.updateonto.task.docs.create_or_attachonto.document.create,onto.document.updateonto.document.tree.moveonto.project.create,onto.project.updateonto.goal.create,onto.goal.updateonto.plan.create,onto.plan.updateonto.milestone.create,onto.milestone.updateonto.risk.create,onto.risk.updateonto.edge.link,onto.edge.unlinkcal.event.create,cal.event.update,cal.event.deletecal.project.set
Discovery
skill_load,tool_search,tool_schemaare available through the JSON-RPC gateway and through MCP only when using?profile=local_admin.
JSON-RPC gateway session methods
call.dial,tools/list,tools/call,call.hangup
MCP resources
resources/listexposes in-scope projects as START HERE orientation resources.resources/readacceptsbuildos://project/<id>andbuildos://document/<id>.
Getting Project Status
The project status op is onto.project.status.get, exposed by tools/list as get_onto_project_status. It is read-only and available on normal read grants.
Use it when an agent first attaches to a known project, before it starts searching individual tasks or documents. It returns:
overview: short description, task/document/plan/goal/collaborator counts, count summary, and next step when availablecollaborators: active project members with actor ID, display name (never an email address), role/access, role profile, and whether the member is the connected userrecent_changes: most recent project log entries with entity type, action, title, timestamp, and sourceupcoming: overdue tasks, due-soon tasks, upcoming project events, and the time windows used
If the agent does not know the project ID yet, it can list/search projects first, or pass a query if the status tool is available and the project name is clear.
For MCP clients, call get_onto_project_status through the client’s normal tool-call UI with the same arguments object. The call_id wrapper below is only for the JSON-RPC gateway.
{
"method": "tools/call",
"params": {
"call_id": "<your call id>",
"name": "get_onto_project_status",
"arguments": {
"project_id": "<project uuid>"
}
}
} Saving a markdown document from an external agent
The headline v1 write op is onto.document.create, exposed by tools/list as create_onto_document. Any connected tool can save a markdown artifact into a specific project in a single call.
For MCP clients, call create_onto_document directly with the same arguments object. The method and call_id wrapper below is only for the JSON-RPC gateway.
{
"method": "tools/call",
"params": {
"call_id": "<your call id>",
"name": "create_onto_document",
"arguments": {
"project_id": "<project uuid>",
"title": "Research: creator distribution loops",
"content": "# Research\n\nFull markdown body here...",
"description": "Initial pass on distribution tactics",
"state_key": "draft",
"idempotency_key": "claude-code:<project>:research-creator-distribution-loops:2026-05-11"
}
}
} Notes:
- Content is stored as-is. No H1/H2 tree parsing; the markdown you send is the markdown we save.
- Content cap is 200 KB per document. Larger bodies return
VALIDATION_ERROR. - Use
contentfor document bodies. External direct tools reject legacy compatibility parameters such asbody_markdownandparent_idwithVALIDATION_ERRORso agents learn the canonical schema. onto.document.updatedefaults to replace. It also acceptsupdate_strategy: "append"andupdate_strategy: "merge_llm"; on the external gateway,merge_llmgracefully falls back to append when no merge worker is available.parent_document_idis optional; omit it to land at the project root.- Use
parent_document_idfor tree placement;parent_idis not accepted on the external direct tool. positionis optional on create for sibling ordering within the project document tree.- Documents created through the gateway are tagged with
props.origin = "external_agent"for auditability.
Creating a project from an external agent
The project creation op is onto.project.create, exposed by tools/list as create_onto_project. It uses the same ProjectSpec contract as internal BuildOS project creation: include project, entities, and relationships; use empty arrays when the new project should start minimal.
For MCP clients, call create_onto_project directly with the same arguments object. The method and call_id wrapper below is only for the JSON-RPC gateway.
{
"method": "tools/call",
"params": {
"call_id": "<your call id>",
"name": "create_onto_project",
"arguments": {
"idempotency_key": "claude-code:project:creator-launch-plan:2026-05-21",
"project": {
"name": "Creator Launch Plan",
"type_key": "project.business.product_launch",
"description": "Plan and assets for launching the creator product."
},
"entities": [],
"relationships": []
}
}
} Notes:
project.type_keymust use theproject.{realm}.{domain}format, for exampleproject.business.product_launch.entitiescan include initialtask,document,goal,plan,milestone,risk,requirement,metric, andsourcerecords usingtemp_idreferences.relationshipsconnectstemp_identities to each other. The project itself is implicit and should not be a relationship endpoint.- Optional
context_documentcreates adocument.context.projectdocument linked to the project. - Project-scoped keys can create projects when
onto.project.createis whitelisted. The created project is added to that key’s project scope automatically.
One-click bootstrap
When you generate a key in the UI, BuildOS also produces a bootstrap URL:
GET /api/agent-call/bootstrap/<setupToken> That endpoint returns an agent_profile_bootstrap_v1 document with:
- the BuildOS env block
- client-specific storage targets
- setup steps
- artifacts such as a ChatGPT Action OpenAPI schema or MCP config target notes
- guidance to call
get_onto_project_statusfirst for existing project work - OAuth guidance for browser/cloud clients
It is short-lived and returns Cache-Control: no-store.
Custom agents
If you’re building your own client, point it at:
POST https://build-os.com/api/agent-call/buildos
Authorization: Bearer <your agent key>
Content-Type: application/json Payload is JSON-RPC. Start with call.dial, list your tools with tools/list, call them via tools/call, and close with call.hangup. Types live in packages/shared-types/src/agent-call.types.ts.
Roadmap
- Project, document, task, goal, plan, milestone, risk, link, and calendar writes — shipped. External agents can create and update the same core ontology primitives used by internal BuildOS chat, subject to scope, write audit, and idempotency.
- Content idea wrappers — still planned. They should compose the shipped primitives rather than inventing a separate top-level entity.
Design doc: apps/web/docs/features/agent-call/MULTI_SURFACE_CONTENT_IDEA_WORKFLOW.md.
Next
- Reference & Help
- Integrations — per-agent setup walk-throughs.