# How are integrations (email, calendar, chat, docs) implemented?

> Open-source personal assistants — a good answer covers: Which services; API clients vs MCP; OAuth flow; token storage; sync vs on-demand fetch.

Canonical page: https://llms-technical-reviews.com/personal-assistants/q/integrations/

## Verdict

Both projects lean on managed catalogues plus MCP instead of hand-written Gmail or Calendar clients.

[OpenBot](/p/openbot/) routes every catalogue entry through one transport seam with MCP's own `listTools`/`callTool` shape. Behind it sit MCP servers, Composio (one deployment key, per-person connections), a Google Drive REST adapter (because Drive's MCP server is gated), and built-in routines. OAuth uses PKCE with an encrypted state token, and credentials are AES-GCM encrypted at rest and write-only. Tools are listed at grant time; calls go through the same policy and approvals path as computer actions.

[Rakazo](/p/rakazo/) builds a connector stack in the worker: user-installed connectors (remote MCP, Treg, OpenAPI documents), Composio, Pipedream Connect, and MCP (stdio only with `MCP_STDIO_ENABLED` and an allowlist). Connector secrets go into an encrypted store. Tools are discovered when a run starts, with no background sync. Rakazo also connects chat platforms (Slack, Telegram, WhatsApp, Sendblue) as places to talk to bots.

OpenBot suits an admin-curated catalogue with uniform governance. Rakazo suits users who want to bring their own APIs, including any OpenAPI spec, without operator work.

More projects in this category are being researched.

## Per-project answers

### CopilotKit/OpenBot (answered)

**Supported services.** Integrations are accessed through three mechanisms: (1) **Composio** (`server/src/plugins/composio.ts`) — a broker for 200+ SaaS apps (Gmail, Slack, GitHub, Notion, etc.). Each action is exposed as a tool the agent can call; the deployment holds one Composio API key and connections are per-person. (2) **MCP** (`server/src/plugins/mcp.ts:1-7`) — the Model Context Protocol for connecting arbitrary external servers. Each MCP server is a catalogue entry with a URL, optional token, and tool list. (3) **Built-in routines** (`server/src/plugins/builtin-routines.ts`) — server-side scheduled tasks like daily summaries. A dedicated **Google Drive REST** adapter (`server/src/plugins/google-drive-rest.ts`) exists because Google's Drive MCP server is gated behind a developer preview — it implements the same `listTools`/`callTool` interface as MCP, making transports swappable per catalogue entry.

**OAuth flow.** The OAuth module (`server/src/plugins/oauth.ts`) implements the PKCE authorization code flow. A sealed, encrypted state token carries the connect origin (`"settings"` or `"admin"`), PKCE verifier, and target user; the callback is the single path `/api/plugins/oauth/callback`. The state is encrypted (not just signed) so proxy logs holding the callback URL cannot redeem the code. Dynamic MCP client registration is handled; the state expires after 10 minutes.

**Token storage.** Credentials are encrypted at rest using AES-GCM (`server/src/credentials.ts:7-13`) with a `keyEncryptionKey` from deployment config. Stored in the `credentials` table with `kind`, `provider`, `keyId`, `metadata`, and `encryptedValue`. Keys are write-only — there is no way to read a stored credential back.

**Sync vs on-demand.** Tool listing is on-demand: the system calls the vendor to list available tools at grant time via `refreshTools`. Composio actions are paginated with a limit of 1000 per page and followed to the end via cursor. MCP servers get a 15-second listing timeout. When a Bot calls a tool, it goes through the approval gate, the transport (MCP/Composio/Drive/built-in), and the result (capped at 20,000 characters) is returned to the model.


Citations: [server/src/plugins/composio.ts:1-30](https://github.com/CopilotKit/OpenBot/blob/f4bc60bf9b12c65eb3d7640173f1b3432f6b2a60/server/src/plugins/composio.ts#L1-L30) · [server/src/plugins/mcp.ts:1-18](https://github.com/CopilotKit/OpenBot/blob/f4bc60bf9b12c65eb3d7640173f1b3432f6b2a60/server/src/plugins/mcp.ts#L1-L18) · [server/src/plugins/oauth.ts:1-55](https://github.com/CopilotKit/OpenBot/blob/f4bc60bf9b12c65eb3d7640173f1b3432f6b2a60/server/src/plugins/oauth.ts#L1-L55) · [server/src/plugins/google-drive-rest.ts:1-30](https://github.com/CopilotKit/OpenBot/blob/f4bc60bf9b12c65eb3d7640173f1b3432f6b2a60/server/src/plugins/google-drive-rest.ts#L1-L30) · [server/src/credentials.ts:1-13](https://github.com/CopilotKit/OpenBot/blob/f4bc60bf9b12c65eb3d7640173f1b3432f6b2a60/server/src/credentials.ts#L1-L13) · [server/src/plugins/transport.ts:1-44](https://github.com/CopilotKit/OpenBot/blob/f4bc60bf9b12c65eb3d7640173f1b3432f6b2a60/server/src/plugins/transport.ts#L1-L44)

### elie222/rakazo (answered)

**Integration services and API clients.** Rakazo supports four integration tool sources, all accessed through a unified `ConnectorProvider` interface (`packages/adapter-kit/src/interfaces.ts`). The connector stack is built in `apps/worker/src/index.ts` line 145: `InstalledConnectorProvider` (user-installed connectors), Composio, Pipedream Connect, and MCP servers. Each resolves to a `ConnectorTool` with a name, description, and inputSchema.

**Composio** (`packages/adapters/src/composio-connector.ts`): wraps the Composio SDK to provide 200+ SaaS integrations (Google Calendar, Gmail, Slack, GitHub, etc.). It maps Composio tool definitions to the connector interface. Enabled via `COMPOSIO_API_KEY` env var. Tools are fetched from Composio's catalog and cached.

**Pipedream Connect** (`packages/adapters/src`): triggered via `PIPEDREAM_CLIENT_ID`/`CLIENT_SECRET`/`PROJECT_ID` env vars. Runs user-configured Pipedream workflows as tool invocations. Connector credentials are encrypted server-side using `EncryptedSecretStore` (`packages/adapters/src/secrets.ts`).

**MCP** (`packages/core/src/mcp.ts` and `packages/adapters/src`): supports both stdio-based and remote HTTPS MCP servers. Users add MCP servers through the Integrations settings UI. Stdio MCP is opt-in via `MCP_STDIO_ENABLED=true` with an allowlist of commands (`MCP_STDIO_ALLOWED_COMMANDS`). Remote MCP can target private endpoints when `MCP_ALLOW_PRIVATE_ENDPOINT=true`. OAuth for MCP goes through `McpOAuthBroker`.

**OpenAPI** integration: users can point at any OpenAPI JSON document to expose those endpoints as tools.

**OAuth flow.** Model providers use OAuth tokens stored in `ModelCredential` rows via encrypted `ciphertext` fields. `packages/adapters/src/pi-oauth.ts` handles OAuth device-code flows for ChatGPT Plus/Pro (`openai-codex`), GitHub Copilot, and xAI SuperGrok, plus auth-url flow for Claude Pro/Max (`anthropic`). Refresh tokens are cycled automatically; failed refreshes retire the credential.

**Sync vs on-demand.** Connector tools are discovered at run start via `connector.discoverTools()`. Composio connections are synced lazily on first use; Pipedream and MCP tools are fetched per run. There is no background sync — tools are resolved when a run begins.


Citations: [apps/worker/src/index.ts:134-155](https://github.com/elie222/rakazo/blob/4cdf3e23315c2633b6b3fde8977f197b986f06fa/apps/worker/src/index.ts#L134-L155) · [packages/adapters/src/composio-connector.ts:1-80](https://github.com/elie222/rakazo/blob/4cdf3e23315c2633b6b3fde8977f197b986f06fa/packages/adapters/src/composio-connector.ts#L1-L80) · [packages/adapters/src/pi-oauth.ts:1-60](https://github.com/elie222/rakazo/blob/4cdf3e23315c2633b6b3fde8977f197b986f06fa/packages/adapters/src/pi-oauth.ts#L1-L60) · [packages/core/src/mcp.ts:1-10](https://github.com/elie222/rakazo/blob/4cdf3e23315c2633b6b3fde8977f197b986f06fa/packages/core/src/mcp.ts#L1-L10)
