Docs navigation
Agent

Integrations

Limited rollout
Hosted integrations are limited to explicitly selected internal agents or agents in an explicitly configured organization, on enabled runtimes: Claude Code, Codex, Qwen, OpenCode, Pi and Kafka Cloud. They remain off for other agents. Kafka Cloud's full compatibility checks are still incomplete; the canary does not establish a customer rollout. The instructions below apply to managed turns with integrations enabled. On enabled Kafka Cloud agents with a compatible runner, synchronous task code and workflow app nodes use the same connection restrictions and permission rules. See Synchronous code and workflow operations for their Ask approval flow. When the managed path is disabled, workflow app nodes keep their existing legacy behavior. Cursor, Factory, Qoder, local CLI harness setup and local isolation are deferred. The legacy Kafka runtime is unchanged.

Integrations give an agent access to apps like Gmail, Slack, Notion and GitHub through Pipedream. You connect the accounts once on the agent's Tools page and set an Allow, Ask or Deny rule for each app or action. Enabled managed turns reach the same apps through one built-in MCP server, brainbase-apps, and Brainbase enforces your rules on its side, not inside the agent.

Connect apps

Connecting accounts is a manager's job. Agent managers (the agent's owner and the team's owners and admins) connect, disconnect and add apps. Other members can see the agent's apps and rules but cannot change them. Connect accounts from your own session. Brainbase keeps account credentials on the server.

How to connect an app
UI
  1. 01Open the agent and go to **Tools**.
  2. 02Under **Integrations**, select **Browse integrations**, pick the app and select **Connect**. Sign in to the app in the window that opens.
  3. 03For an app that needs no account, such as a public data source, select **Add** instead.
  4. 04Set a rule for the app, and for any single action that needs a different rule.

An agent can hold more than one account for the same app. When an action could use several, the agent has to name the account it wants. Brainbase never picks one for it and never switches accounts silently. With exactly one healthy account, that account is used.

Connections belong to the agent, not to a task. You can set them up before the agent has ever run, and every task the agent runs uses the same accounts.

Allow, Ask and Deny

RuleWhat happens when the agent calls the action
AllowThe action runs.
AskThe action waits for a person to approve it. See Approving an Ask.
DenyThe action is refused and nothing is sent to the app. The agent is told which rule refused it.
  • A rule can cover a whole app or one action. A rule on a single action takes precedence over the app's rule, and a rule saved on a task takes precedence over the agent's rule for that task.
  • An action that uses more than one app needs every one of those apps to allow it. Any Deny refuses it, and any Ask makes it wait.
  • When a task was started by another task, the rules of the task that started it also apply. Any Deny in the chain refuses the action, and any Ask in the chain makes it wait.
  • Looking up options for a form field or refreshing an action's fields checks your rules, but it never uses up an approval. Running an action, sending a proxy request or uploading a file uses it up.
  • Brainbase checks rules before app execution. Changing a rule affects later calls, even in a running task; it cannot undo an action already sent to the app.
Rules carry over when you switch runtimes
Accounts and rules are stored on the agent, not on its runtime. If you switch an agent from one runtime to another, for example from Kafka to Claude Code, it keeps its connected accounts and Allow, Ask and Deny rules. Using those apps on the new runtime still requires that runtime to be enabled for the agent.

Which runtimes get integrations

The canary supports Claude Code (claude_code), Codex (codex), Qwen Code (qwen), OpenCode (opencode), Pi (pi) and Kafka Cloud (kafka_cloud). You don't add the server to the agent's MCP list. Brainbase adds it to each enabled turn. Cursor (cursor), Factory (factory) and Qoder (qoder) are deferred. Kafka Cloud is enabled only within the canary while its full compatibility checks continue. Outside the canary, its existing AppFactory path continues; the older kafka runtime is unchanged. See AppFactory for the connection restrictions during enabled managed execution, including synchronous code and workflow app nodes on a compatible runner.

Integrations are turned on one runtime at a time, and at first only for selected agents or organizations. Until then, agents on that runtime do not get the brainbase-apps tools. Once a runtime is enabled for an agent, new tasks get the tools. A task that started before that point does not; start a new task. A task whose sandbox runs an older Brainbase runner gets them once its sandbox is upgraded, and the task view says so in the meantime.

A selected agent, including a new agent in a configured organization, has rule controls on the Tools page for its enabled runtime. Other non-Kafka agents may still see "Integration permission controls are only available for Kafka runtime agents." Kafka agents keep their existing controls. Seeing controls does not by itself mean the new execution path is enabled.

To call your apps from your own code instead of a hosted task, see Integrations from your code.

Organization-scoped rollout

A selected organization covers its current and newly created agents on enabled runtimes, without manual enrollment. These agents get the same integration tools and rule controls as explicitly selected agents. Moving an agent out of the organization or withdrawing organization scope removes org-based eligibility, unless the agent is also explicitly selected. Existing AppFactory grandfather connections remain protected; new agents use the built-in MCP server instead.

What the agent sees

The agent sees one MCP server named brainbase-apps. The name is reserved: on a task that has integrations, an MCP server of your own with that name is replaced by the built-in one. The server's tools are the same on every runtime.

ToolWhat it does
list_appsLists the agent's apps and connected accounts. Shows connected apps by default; pass include: "all" to list every app.
search_actionsSearches one app's actions, including any custom actions you have added.
get_actionReturns an action's fields and which accounts can run it.
configure_propLooks up the choices for one field, such as a list of channels or spreadsheets.
reload_propsRefreshes an action's fields after a field that changes the others has been set.
run_actionRuns an action. Accepts output options to return only some fields or matching items.
proxy_requestSends a direct API request to an app through the connected account, for anything the ready-made actions do not cover.
upload_preflightChecks that an upload is allowed before any file is read.
upload_fileUploads a file from the task's workspace or from a public URL. Files up to 25 MiB.
get_operationLooks up an earlier call by its operation_id, including one that was waiting for approval.

run_action, proxy_request and upload_file take an optional operation_id. If the agent leaves it out, one is generated and returned. Calling again with the same operation_id and the same input never runs the action twice. A call that already succeeded returns success with data.replayed: true (the original data is not returned again), and one that failed returns an error saying the operation ran and failed. Reusing an operation_id with different input is refused with invalid_input. These receipts belong to the task's shared context; a new independent task does not share them.

Results and errors

Every tool returns the same result shape. status tells the agent what happened. The matching field carries the result, approval, denial or error; an error can also include supporting data, and files can contain file information.

json
{
  "contract": "brainbase.integrations/v1",
  "status": "error",
  "operation_id": "6f0c2a4e-2b1d-4c47-9a63-0d1f5c2e8b11",
  "data": null,
  "result_ref": null,
  "files": [],
  "pending": null,
  "denied": null,
  "error": {
    "code": "needs_connection",
    "message": "This agent has no connected gmail account. An agent manager connects one in the agent's Tools page.",
    "retryable": false,
    "dispatched": "no",
    "action_required": { "kind": "connect_account", "app_slug": "gmail" }
  }
}
StatusMeaning
successThe call worked. The result is in data, or in a workspace file named by result_ref when it is large.
pendingThe action needs approval. Nothing has been sent to the app. pending.message says what is waiting.
deniedThe action was denied. Nothing was sent. denied describes the denial and includes the matched rule when available.
errorThe call failed. error.code says why, retryable says whether trying again can help, and dispatched says whether anything reached the app: no, yes or unknown.
Error codeWhat it means
needs_connectionThe app has no connected account, or the account needs reconnecting. An agent manager connects it on the Tools page. The agent cannot do this, and neither can a member who is not a manager.
needs_installThe app needs no account but has not been added to the agent. An agent manager adds it on the Tools page.
account_selection_requiredMore than one account could run the action. Call again and name the account in accounts (actions) or account_id (proxy_request and uploads).
invalid_inputThe input is missing something or has the wrong shape.
invalid_configurationA custom action is set up incorrectly, for example with no component or no app account. An agent manager fixes it on the Tools page.
not_foundThe app, action or operation does not exist for this agent.
upstream_errorThe app answered with an error. When it was an HTTP error, upstream_status carries its status.
outcome_unknownThe request reached the app, but no answer came back, so the action may or may not have happened. It is never retried. See below.
busyAnother action is running in this task, or in a task that started it or that it started. Try again shortly. If the message says an earlier outcome is unknown, retrying will not help: a manager has to acknowledge it.
payload_too_largeA file is over 25 MiB, or a large result could not be saved to the workspace.
rate_limitedToo many calls. Wait and try again.
unsupportedNot available here. For example, integrations are not enabled for this run.
cancelledThis action will never run, and nothing was sent. See below.
internalSomething failed inside Brainbase. Nothing is retried for you. Check dispatched before calling again.

When the outcome is unknown

outcome_unknown means the request left Brainbase but no answer came back from the app, for example after a timeout. The message may have been sent, the record may have been created, or neither. Brainbase never sends it again on its own, because doing so could send it twice.

Until someone resolves it, other app execution in the same context answers busy. This includes tasks that share a parent context. Stopping the task does not clear it. A manager checks the app to see whether the action happened, then acknowledges it in the task view (see Integrations in the task view). Acknowledging only unblocks the task and records what the manager found. It never sends the action again, and calling again with the same operation_id still returns outcome_unknown. If it did not happen, ask the agent to do it again.

When an action is cancelled

cancelled always means nothing was sent. It happens when the task was stopped or redirected while the action was waiting, when the approval the action was waiting on was already used by another action, or when a request from your own code expired before anyone answered it. The same operation_id keeps returning cancelled; call again with a new one, which asks for a new approval if one is needed.

Approving an Ask

When an action has an Ask rule, the call returns pending and nothing is sent to the app. Brainbase stops the task's current run, and the approval request appears in the task view in the console. The task waits there until someone answers. It does not depend on the agent noticing anything.

On Kafka Cloud, a task paused for its current integration approval shows Needs info with the summary Awaiting integration approval. This also applies when the agent called the action through bb-apps. Answer the pending request to continue in a new turn. Choosing Stop cancels that request; a failed action still reports its failure.

  1. The agent calls the action. The call returns pending, and the agent is told to stop and wait.
  2. Brainbase stops the run. The task view shows a card naming the action the agent asked to run, for example slack.slack-send-message.
  3. Someone with access to the task answers it.
  4. Brainbase starts a new turn and tells the agent the answer. The agent calls the action again, and it runs, or it gets denied.
AnswerWhat it doesWho can choose it
Allow onceLets this one action run. The rule stays Ask, so the next call asks again.Managers and members
Allow for this taskSaves an approval for this action on this task. The next run of the action in this task uses it up, so a later call in the same task asks again.Managers and members
Always allowSaves an Allow rule on the agent, so every future task runs this action without asking.Managers
DenyRefuses the action. A manager's Deny saves a Deny rule on the agent. A member sees Deny for this task, which applies to this task only.Managers and members
  • Each request is answered once. A second answer, or an answer from an old or expired card, is refused and changes nothing.
  • If the task's run cannot be stopped cleanly, the card stays in the task view and can still be answered, and the task view says the stop is being retried. The agent continues only after that run has stopped, and the action never runs before someone approves it.
  • If the task was started by another task whose rules also ask for this action, the card says so. Allow once covers both. Allow for this task and Always allow save your rule, but the other task's rule still asks, so the task keeps waiting.
  • Stopping the task, or sending it a new message that redirects it, cancels the waiting request. The action does not run and returns cancelled.

Integrations in the task view

For a task using the new integration path, the task view shows whether it can use your apps. It describes that task only. Connecting accounts, adding apps and setting rules on the Tools page never depend on a task: they work for an agent with no tasks, and one old or blocked task never stops them.

What the task view showsWhat it means
Apps are ready for this task.The task's sandbox runs a runner with integrations.
This task's sandbox needs an upgrade before it can use appsThe sandbox runs an older Brainbase runner without integrations. Apps work in this task once its sandbox is upgraded. Nothing on the agent is affected or needs changing.
Stopping the run that asked for approvalAn action is waiting for approval and Brainbase is stopping the run that asked. The approval card can be answered meanwhile.
Brainbase couldn't stop the run that asked for approvalThe stop failed and is retried. Your answer still counts; the agent continues once that run has stopped.
An app action may or may not have happenedAn action's outcome is unknown, and apps are paused for the task and the tasks it started until a manager acknowledges it.

A task that started before integrations were enabled for its agent shows none of these. Whether the runner is ready is shown once the task's sandbox has started at least once.

How to acknowledge an unknown outcome
UI
  1. 01Open the task. The card lists actions whose outcome is unknown and shows when each became unknown or was sent.
  2. 02Check the app to see whether the action happened.
  3. 03Choose **It happened**, **It did not happen** or **I can't tell**, then select **Acknowledge**.
  4. 04Apps run again in the task. If the action did not happen, ask the agent to do it again.
  • Only managers of the context's agent (its owner or the team's owners and admins) can acknowledge, from their own signed-in session. For delegated tasks, this can be the parent agent's manager. API keys, personal access tokens, task keys and integration grants are refused. Other members see the card without the choices.
  • Each acknowledgement is recorded with who made it, when, and what they found. Acknowledging the same action again changes nothing.

Large results

By default, successful result data bigger than 32 KiB is saved instead of being returned inline. It is written as JSON to a file in the task's workspace under /workspace/.brainbase/integration-results/, named after the operation_id (or a generated name for tools without one). The call returns result_ref instead of data, with the file path, its size, the number of items, where the main list of items sits in the JSON, and up to three sample items. The agent can read the file, or process it with a script, without loading every row into its context.

json
{
  "status": "success",
  "data": null,
  "result_ref": {
    "path": "/workspace/.brainbase/integration-results/6f0c2a4e-2b1d-4c47-9a63-0d1f5c2e8b11.json",
    "format": "json",
    "bytes": 912340,
    "sha256": "9b1c…",
    "items": 500,
    "item_path": "ret.values",
    "summary": "A JSON object whose largest array, ret.values, has 500 items, each an array.",
    "sample": [["2026-10-01", "Acme", 1200], ["2026-10-01", "Globex", 940], ["2026-10-02", "Initech", 310]]
  }
}

To keep results small in the first place, pass output to run_action. Within the action's ret result, fields selects the listed paths and filter keeps matching items when ret is a list. A filter tests whether the value at a path equals or contains a value. These options do not shrink exports or summary. max_inline_bytes sets the inline limit for one call, up to 256 KiB.

Scripting with bb-apps

Enabled hosted tasks on the current runner have a bb-apps command on their path. It runs one brainbase-apps tool and prints the result as JSON, so the agent can loop over rows in a shell script or any language. It goes through the same rules, approvals and accounts as the MCP tools and has no other credentials.

bash
# bb-apps <tool> [--json '<input>' | --input <file> | --input -] [--output <file>] [--wait]
bb-apps list_apps
bb-apps search_actions --json '{"app_slug": "slack", "query": "send message"}'
bb-apps run_action --input message.json

# A loop that stops at the first action that does not succeed,
# and cleanly when one needs approval
while IFS= read -r row || [ -n "$row" ]; do
  bb-apps run_action --json "$row"
  code=$?
  if [ "$code" -eq 10 ]; then
    echo "Waiting for approval; this run is stopping." >&2
    exit 10
  elif [ "$code" -ne 0 ]; then
    exit "$code"
  fi
done < rows.jsonl
Exit codeMeaning
0Success
10Pending: the action needs approval and this run is being stopped. End the script. The task continues in a new turn after someone answers.
11Denied by a rule
12Error. The error field says why.
13Integrations are not enabled for this run, or Brainbase refused the run's access
  • --output <file> saves a successful result to a new file in the workspace (never overwriting one) and prints result_ref in place of data.
  • In a hosted task, an approval stops the run, so bb-apps exits with 10 even with --wait. For standalone approval waiting, use the SDK or a plain MCP client. Local CLI harness setup is deferred.

For loops that write to an app, give each item its own fixed operation_id in the input. If the script is stopped part way and runs again in the next turn, items that already ran return success with data.replayed: true instead of running twice.

Troubleshooting

What you seeWhat to do
The agent has no brainbase-apps toolsCheck the limited rollout above: the agent must be explicitly selected or belong to the configured organization, on an enabled runtime. For an enabled agent, start a new task if this one predates enablement.
The task view says the sandbox needs an upgradeThe task's sandbox runs an older runner. Upgrades are currently limited to the Pi canary; this is not a general self-service rollout. The agent's accounts and rules need no change.
unsupported: Integrations are not enabled for this runSame as above. A bb-apps call exits with 13.
needs_connection or needs_installAn agent manager connects or adds the app on the Tools page. Then ask the agent to try again.
account_selection_requiredThe agent has several accounts for the app. Tell it which one to use, or remove the ones it should not use.
busy that does not clearAn earlier action has an unknown outcome. A manager checks the app and acknowledges it in the task view. Stopping the task does not clear it.
An approval card stays after you answeredAnother task in the chain still has an Ask rule for this action. Use Allow once, or have that agent's manager change its rule.