Skip to content

Integrations

There are two separate integration systems in AIOS, and mixing them up is the most common way an integration build-out stalls:

Workspace connectorsTeam Brain integration store
Lives inyour own workspace repo, on your machinethe shared Team Brain deployment
Configured withaios connect, .mcp.json, .claude/integrations.jsonthe Admin UI at /t/<team>/admin/integrations
Who sets it upeach person, for themselvesa Brain admin, once, for the whole team
Secrets storedyour shell env / gitignored .envencrypted in the Brain’s database
What it powerstools your coding agent can callserver-side ingestion, PM sync, and the member invite cascade

Connecting Slack with aios connect slack gives your agent a Slack tool. It does not give the Brain a Slack connector, and vice versa. A team that wants both does both.

The first half of this page covers workspace connectors. The Team Brain integration store covers the second system.


Your AIOS workspace can connect to the tools you already use. Integrations come in two shapes:

  • MCP servers — declared in .mcp.json at the workspace root. Claude Code (and the local GUI, which loads the same project settings) starts them and exposes their tools to the agent.
  • CLI tools — installed on your machine and on PATH; the agent calls them via Bash (e.g. gog-cli for Gmail/Google).

The catalog of what’s connectable lives in .claude/INTEGRATIONS.md (generated from .claude/integrations.json). This page is the how-to-connect companion.


Every workspace generates an integrations catalog (.claude/INTEGRATIONS.md, via npm run gen:catalog) listing each connectable tool with its status and how to connect it. A live .mcp.json stub and a .mcp.example.json starter file of server blocks ship in the scaffold.

To see what’s connectable from the CLI:

Terminal window
aios connect
# → lists connectable integrations with status (✓ wired / ○ available)

aios connect <id> runs a guided, live-validated connect flow for a single integration — it prints the exact key-creation URL and scopes, collects the required secret(s), validates them, and stores the selection.

Terminal window
aios connect slack # interactive: prompts for the required values
aios connect slack --token <value> # non-interactive: pass the primary secret
aios connect github --set GITHUB_TOKEN=… # non-interactive: set a named env value

To wire an MCP server by hand instead:

  1. Copy the server block you want from .mcp.example.json into .mcp.json under mcpServers.
  2. Provide env values. Do not inline real tokens — .mcp.json is committed. Reference shell/managed env with ${VAR}, and keep the actual secrets in your shell profile or a secrets manager (.env / .env.local are gitignored).
  3. Restart Claude Code / the GUI so the server is picked up.
  4. Flip the tool’s status from available to wired in .claude/integrations.json, then run npm run gen:catalog.

These are the integrations shipped in the workspace catalog today.

Create a Slack app, add bot scopes (channels:history, channels:read, chat:write), install it to your workspace, and copy the bot token into SLACK_BOT_TOKEN. Set SLACK_TEAM_ID to your workspace id.

The atlassian server covers both. Create an API token at id.atlassian.com → Security → API tokens. Set ATLASSIAN_URL (e.g. https://your-org.atlassian.net), ATLASSIAN_EMAIL, and ATLASSIAN_API_TOKEN.

Linear (direct API skill + Team Brain PM sync)

Section titled “Linear (direct API skill + Team Brain PM sync)”

The shipped connector uses a personal Linear API key (LINEAR_API_KEY) and the linear-direct skill, because Linear’s official MCP is OAuth-oriented. The Team Brain can also store a Linear integration with non-secret mapping hints (teamId, projectId, doneStateName) and an encrypted token, so merged AIOS work can move linked Linear issues to a completed workflow state.

Plane (REST / API key + Team Brain PM sync)

Section titled “Plane (REST / API key + Team Brain PM sync)”

Use Plane personal access tokens through PLANE_API_KEY. The Team Brain stores the workspace/project mapping (workspaceSlug, projectId, doneStateName, externalSource) and an encrypted token. Merged AIOS work uses task row keys and Plane external_id / external_source to move linked work items to DONE.

Create an internal integration at notion.so/my-integrations, copy its token into NOTION_TOKEN, and share the pages/databases you want reachable with that integration (Notion is deny-by-default per page).

Either add the github MCP server with a fine-grained PAT (GITHUB_TOKEN), or rely on the gh CLI if it’s already authenticated (gh auth status).

Gmail / Google Workspace (CLI — gog-cli)

Section titled “Gmail / Google Workspace (CLI — gog-cli)”

Install gog-cli and run gog auth login once for OAuth. The agent reads/sends mail, calendar, and drive by shelling out to gog. No MCP server.

Export meeting notes/transcripts into 1-inbox/transcripts/, then run the transcript-decisions harness to turn them into decision-log rows. This is a workspace flow — there is no Team Brain Granola connector; meetings reach the brain as transcripts you push with aios push.

A self-hosted Slack alternative. Set MATTERMOST_URL and a personal access token (MATTERMOST_TOKEN).

Set TOGGL_API_KEY (Toggl → Profile → API token). Use it to reconcile timers against 3-log/hours-log.md.


The Team Brain keeps its own connector records, separate from anything in your workspace. This is what powers server-side ingestion, PM sync, and the member invite cascade — none of which can read a connector that only exists on someone’s laptop.

Sign in to the Brain and open Admin → Integrations at:

https://your-brain.example.com/t/<your-team-slug>/admin/integrations

Then add or edit a connector in the UI. Supported types today:

github · slack · notion · linear · plane · openai · anthropic · google · openrouter · typefully

Each record holds a name, a non-secret config object (the allowed keys differ per type — e.g. org for GitHub, inviteLink for Slack, teamId/projectId for Linear), an optional secret, and a status of enabled or disabled.

This surprises people automating a rollout, so it is worth stating plainly:

OperationHow
List enabled integrationsGET /api/v1/integrations — authenticates with a member API key, rate-limited to 60/min, audited
Create / update / delete an integrationBrowser only. A server action behind the admin session guard — there is no POST, PUT, PATCH, or DELETE route

GET /api/v1/integrations returns { id, type, name, config, status } per record. Stored secrets are never included in the response — the query does not select the ciphertext column at all. So you can read the team’s connector inventory from a script, but you cannot provision one from a script. Plan the build-out as an admin sitting in the UI.

Connector secrets are encrypted at rest with AES-256-GCM using the Brain’s SECRETS_KEY environment variable (32 bytes, hex or base64).

If it is unset, the Brain still boots — you get a [boot] warning, not a crash — but:

  • saving a connector secret fails with SECRETS_KEY is required to store/read connector secrets, and the integration row is created without its secret;
  • anything that later reads a stored secret returns a 500.

Set it before the first connector save. Changing it afterwards makes every existing ciphertext undecryptable, so a rotation means re-entering every secret by hand.

Once a slack, linear, plane, or github connector is enabled, the Brain starts pulling from it on its own — you do not trigger a sync.

The scheduler starts with the app, runs its first pass about 20 seconds after boot, and repeats every INGEST_POLL_MINUTES minutes (default 30). To turn it off, set INGEST_POLL_ENABLED=false; there is no opt-in flag, because polling is the default.

Runs are visible under Admin → Integrations → Ingestion runs.


Member onboarding: what the invite cascade needs first

Section titled “Member onboarding: what the invite cascade needs first”

When an admin invites someone — via Admin → Members or aios member invite — the Brain also tries to invite them to Linear, Slack, and GitHub. That cascade is real, but it is inert until it is configured, and an unconfigured tool reports skipped rather than raising an error. Nothing turns red; the invite just quietly does less than you expected.

Configure it at Admin → Integrations → Member onboarding, a panel on the same Integrations page. Each tool has its own prerequisite:

ToolPrerequisiteWithout itWith it
LinearAn enabled Linear integration with an API key storedskipped — “connect Linear first (Admin → Integrations)“sent — Linear emails the invite
SlackA Slack invite link in the Member onboarding panelskipped — “set a Slack invite link…”link_provided — the link is handed back to the admin
GitHubA GitHub org in the Member onboarding panelskipped — “set a GitHub org…”sent — org invitation created

Three things worth knowing before you promise a client a one-click onboarding:

  • Slack never sends anything. Slack Free and Pro have no invite API, so the connector only ever returns a standing workspace join link for a human to pass along. Its status is link_provided, not sent, and acceptance is not verified.
  • GitHub gates on the org, not the token. Set the org and the invite is attempted regardless — the token comes from the integration secret, falling back to the GITHUB_TOKEN environment variable. A missing or under-scoped token therefore reports failed, not skipped. The token needs admin:org.
  • A tool failure never blocks Brain membership. The member record is created either way; the cascade is best-effort by design.

Per-tool results are recorded against the member, and a single tool can be retried on its own from Admin → Members once you have fixed its prerequisite.


Once a team standardizes on a set of integrations, a team lead can publish that set so everyone starts from the same baseline:

Terminal window
aios push blueprint # publish the team's tool set (lead/admin only)
aios pull blueprint # fetch the team's tool set → .aios/blueprint.json