Mitosis Docs

Building Integrations

Create, test, and publish community integrations.

Building Integrations for Mitosis

Last updated: 2026-04-17

This guide walks you through creating, testing, and publishing a community integration for Mitosis. Integrations connect agents to external services — messaging platforms, APIs, developer tools, VPNs, and more.

How Integrations Work

When a user enables an integration:

  1. Credentials are stored securely on the server side
  2. Credentials are injected into agent pods automatically — agents see them as environment variables
  3. Agents use the credentials directly (API keys, tokens) or connect through a per-office proxy service

Agents don't need custom code to read integration credentials — they're just env vars.

Integration Types

Secret-only

User pastes a credential and it's done. Best for API keys, tokens, and simple auth. Examples: GitHub, Telegram, Slack, ElevenLabs.

Per-office service

User pastes a credential, then a proxy service starts for the colony. Use when the integration needs a running process. Examples: Tailscale (SOCKS5 proxy), Claude Code (OAuth proxy).

OAuth

User clicks "Connect" and authorizes via the provider. Use when the provider supports OAuth flows. Examples: Claude Code, OpenAI Codex, Google Workspace.

Most community integrations are secret-only — the user pastes an API key and agents get it as an env var.

Quick Start: Your First Integration

We'll build a simple integration that gives agents access to a hypothetical "Acme API" using an API key.

Step 1: Define the integration

Add your integration to the registry in src/lib/integrations/registry.ts:

{
  id: 'acme',
  name: 'Acme API',
  description: 'Connect agents to the Acme API for data processing.',
  icon: 'acme',             // Add a matching icon in integration-node.tsx
  category: 'services',     // 'llm' | 'communication' | 'services'
  aliases: ['acme-api'],    // Search terms that resolve to this integration
  verified: false,           // true = shows purple checkmark (Mitosis-verified only)
  capabilities: ['data_processing'],
  channels: [],              // Empty for tool-only integrations
  wizard: 'guide',           // 'guide' | 'interactive' | 'oauth' | 'auto'
  guideFile: 'integrations/acme.md',
  requiredSecrets: [
    {
      key: 'ACME_API_KEY',
      label: 'API Key',
      type: 'password',
      required: true,
      hint: 'Create an API key with read/write access',
      helpUrl: 'https://acme.com/settings/api-keys',
    },
  ],
  agentEnvVars: ['ACME_API_KEY'],
  officeLevel: true,
  k8sSecretName: (colonyId) => `acme-${colonyId}`,
}

Step 2: Write the setup guide

Create public/integrations/acme.md:

# Connect Acme API

Agents can query, transform, and process data using the Acme API.

## Steps

1. Go to your Acme dashboard
2. Create an API key with read/write access
3. Paste it below

## What Agents Can Do

- Query datasets
- Run data pipelines
- Export results

## Notes

- Your API key is stored securely — agents access it as an env var.
- Usage is billed by Acme directly.

Step 3: Add an icon

In src/components/inception/dashboard/integration-node.tsx, import an icon and add it to the BRAND_ICONS map:

import { Database } from 'lucide-react';

const BRAND_ICONS = {
  // ... existing icons ...
  acme: Database,
};

Step 4: Register on the backend

In the office-manager repo, add your integration to the backend registry:

{
    Name:         "Acme API",
    ID:           "acme",
    Status:       "pending",
    SecretName:   fmt.Sprintf("acme-%s", officeID),
    Capabilities: []string{"data_processing"},
    AgentEnvVars: []string{"ACME_API_KEY"},
},

Step 5: Add to reserved keys (optional)

If agents shouldn't be able to override this env var via the Environment Secrets panel, add it to the reserved keys list in the colony-manager backend:

"ACME_API_KEY": true,

That's it. The existing GuideWizard, EnsureSecret, and ToggleAgent handlers do the rest.

Credential Fields

Each field in requiredSecrets becomes an input in the setup wizard.

key (string, required) — The env var name (e.g. ACME_API_KEY).

label (string, required) — Display label shown in the wizard (e.g. "API Key").

type ('text' or 'password', required) — Use password for secrets, text for non-sensitive values.

required (boolean, required) — Must be filled before saving.

hint (string, recommended) — Short help text displayed below the field.

helpUrl (string, strongly recommended) — Direct link to where the user creates or copies this credential. Renders as a clickable link next to the hint. Always include this — it takes users directly to the right page instead of making them search through a provider's settings.

helpLabel (string, optional) — Custom link text. Default: "Find it here".

Multi-Instance Integrations

Some integrations support multiple named instances per office — for example, a user might connect both a personal and a work GitHub account.

To enable this, set multiInstance: true in the registry and add an INSTANCE_LABEL field:

{
  id: 'myservice',
  multiInstance: true,
  requiredSecrets: [
    { key: 'API_KEY', label: 'API Key', type: 'password', required: true },
    { key: 'INSTANCE_LABEL', label: 'Account Label', type: 'text', required: true,
      hint: 'A short name for this account, e.g. "personal" or "work"' },
  ],
  k8sSecretName: (colonyId, instanceLabel) =>
    instanceLabel ? `myservice-${instanceLabel}-${colonyId}` : `myservice-${colonyId}`,
}

Each instance gets its own K8s secret and can be toggled independently per agent.

Per-Office Service Integrations

If your integration needs a running process (proxy, daemon, persistent connection), follow the per-office service pattern.

Create a provisioner in the colony-manager repo that manages these resources:

ResourcePurpose
DeploymentRuns the service container (1 replica, Recreate strategy)
ServiceClusterIP for in-cluster access
PVCPersistent state (optional)
SecretCredentials

Key functions to implement:

func Configure{Name}(image string)                                    // Set image from config
func {Name}URL(namespace string) string                                // Return in-cluster URL
func (c *Client) Ensure{Name}(ctx context.Context, ns string) error   // Create-or-update
func (c *Client) Teardown{Name}(ctx context.Context, ns string) error // Remove (retain PVC)

The service is not provisioned at office creation — it starts lazily when a user first enables the integration (in the ToggleAgent handler).

See the Tailscale integration in the colony-manager repo for a complete example.

Testing

Local testing

# Start the dev stack
make dev

# Set a secret via the colony-manager API
curl -X POST http://localhost:8080/api/v1/offices/{officeID}/integrations/acme/secret \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"secretName":"acme-{officeID}","data":{"ACME_API_KEY":"test-key-123"}}'

# Enable on an agent
curl -X POST http://localhost:8080/api/v1/offices/{officeID}/integrations/acme/agents/{agentName} \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"enabled":true,"secretName":"acme-{officeID}"}'

# Verify the agent has the env var
mi agents exec <colonyId> <agentName> -- env | grep ACME

Dashboard testing

  1. Navigate to the Integrations panel in your office dashboard
  2. Find your integration in the list
  3. Click it → fill in credentials → Save
  4. Toggle it on for an agent
  5. Verify via the agent's terminal: env | grep ACME

Checklist

  • Integration appears in the Integrations panel
  • Guide markdown loads and renders correctly
  • helpUrl links open the correct page
  • Saving credentials shows success
  • Toggling on an agent adds the secret to the pod
  • Agent can read the env var
  • Toggling off removes the env var from the pod
  • Re-saving credentials updates the existing secret (idempotent)
  • For per-office services: proxy pod starts on first enable, stops on teardown

Publishing

Community integrations are submitted as pull requests to the website and office-manager repos.

Your PR should include:

  1. Website repo:

    • Registry entry in src/lib/integrations/registry.ts
    • Icon in src/components/inception/dashboard/integration-node.tsx
    • Guide markdown in public/integrations/{id}.md
  2. Office-manager repo:

    • Backend registration in the integrations handler
    • Reserved keys in the env handler (if applicable)
    • For per-office services: a provisioner module + tests
  3. Description explaining what the integration does, what env vars it injects, and any security considerations.

Verified integrations (purple checkmark) are reviewed and maintained by the Mitosis team. Community integrations are welcome and encouraged — if you build something useful, we'll work with you to get it verified.

Manifest v2 — Composable Layers

Integrations can declare up to 9 composable layers beyond the basic requiredSecrets + agentEnvVars. All layers are optional and backwards-compatible — existing integrations keep working unchanged.

LayerFieldWhat it does
1. ToolstoolsOpenClaw gateway plugins, MCP servers, SDK extensions
2. CLI InstallscliInstallsapt/npm/pip packages and static binaries installed into agent pods
3. Credential FilescredentialFilesConfig files rendered from templates into the agent's persistent volume
4. Shared Drive FoldersharedDrivePermissioned folder at /shared/files/_integrations/<id>/ — only enabled agents can access
5. Colony DatabasedatabasePermissioned tables in the colony postgres — only enabled agents get credentials
6. Task TemplatestaskTemplatesTasks auto-created on enable, or recurring on a cron schedule
7. Member ControlsmembersRequired roles, max agent count, per-agent config overrides
8. Colony ContainercolonyContainerPer-office microservice (Deployment + Service + optional PVC)

Composability

Integrations can declare relationships with other integrations:

FieldTypeDescription
dependsOnstring[]Integrations that must be configured first
providesstring[]Capabilities this integration provides (for dependency resolution)
conflictsstring[]Integrations that cannot coexist
composedWithstring[]Integrations that work better together (soft recommendation)

Example: Full Manifest

{
  id: 'acme',
  name: 'Acme API',
  version: '1.0.0',
  category: 'services',
  // ... basic fields ...

  // Layer 1: MCP server for tool use
  tools: {
    mcpServers: [{
      name: 'acme-mcp',
      command: 'npx',
      args: ['-y', '@acme/mcp-server'],
      env: { ACME_API_KEY: '${ACME_API_KEY}' },
    }],
  },

  // Layer 2: CLI tool
  cliInstalls: {
    npm: ['@acme/cli'],
  },

  // Layer 4: Shared folder for cached data
  sharedDrive: {
    subdirectories: ['cache', 'output'],
  },

  // Layer 5: Database tables for state
  database: {
    migrations: ['001_create_tables.sql'],
  },

  // Composability
  provides: ['data_processing'],
  composedWith: ['github'],
}

For full manifest type definition, see IntegrationDef in src/lib/integrations/registry.ts.