> ## Documentation Index
> Fetch the complete documentation index at: https://docs.atako.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect a remote MCP server as a custom integration

> Re-probes the server: only tools the server really announces are stored; the body only chooses which are enabled and their read/write scope. `visibility` follows the usual rule ('company' = admins only, 'personal' = any member). Several connections may target the same server (one token each). Agents see enabled tools as `<slug>.<tool>` through the usual grants.



## OpenAPI

````yaml /api-reference/openapi.json post /integrations/mcp/connections
openapi: 3.1.0
info:
  title: Atako API
  version: 0.1.0
  description: >-
    The Atako customer API — manage AI agents, their files, integrations,
    billing, and your company/team, programmatically.


    ## Authentication


    Every non-public endpoint takes a Bearer token that is either:

    - a **programmatic API key** (`aik_…`) — create one at
    [app.atako.ai](https://app.atako.ai) → Settings → API keys (company-admin
    only), or

    - a **Supabase session JWT** — what the web app itself sends; not practical
    to obtain outside a browser session.


    ```bash

    curl https://api.atako.ai/agents -H "Authorization: Bearer aik_..."

    ```


    An API key acts as its owning user, within the limits of the key:


    - **Scope** — a `read` key can only call GET operations (any other verb:
    `403 API_KEY_READ_ONLY`); a `write` key can call everything its user can,
    except the operations below.

    - **Forbidden to every key** — billing changes (every non-GET
    `/subscriptions/*`), minting agent tokens, listing or managing API keys
    (every `/users/api-keys` operation), deleting the account: `403
    API_KEY_FORBIDDEN`. These need a signed-in user in the app.

    - **Expiry** — optional (30, 90 or 365 days); an expired key gets `401
    API_KEY_EXPIRED`.


    Each operation carries `x-atako-api-key: read | write | forbidden` — the
    minimum key scope it needs, or `forbidden`.


    ## Live events


    `GET /notifications/sse` and `GET /agents/{agentId}/events` are Server-Sent
    Events streams (`text/event-stream`), authenticated with the same Bearer
    header — an API key works.


    ## Uploading a file


    Two steps: `POST /client/files/nodes` then `POST
    /client/files/{nodeId}/upload-url` return a signed storage URL; `PUT` the
    raw bytes to it, then call `POST /client/files/{nodeId}/complete-upload`.
    Grant it to an agent with `POST /agents/{agentId}/file-grants`.


    ## Other Atako HTTP surfaces (not covered by this spec)


    - **Atako MCP server** — `POST /mcp` (auth: same Bearer token as above)
    exposes the same capabilities as Model Context Protocol tools for AI clients
    (Claude Code, Claude Desktop, Cursor, ChatGPT), grouped in toolsets
    (`/mcp?toolsets=projects,agents`); a `read` key only gets read-only tools.
    See
    [docs.atako.ai/developers/mcp/overview](https://docs.atako.ai/developers/mcp/overview).

    - **Content API** (`cak_…` key, `/content/*`) — a separate, more restricted
    key type for headless CMS-style access to blog/news/use-case content. Not
    documented here.


    ## Errors


    Errors use a JSON envelope: `{ "error": string, "code"?: string }`. `error`
    is either a short human-readable message or a SCREAMING_SNAKE_CASE code,
    depending on the route — treat it as an opaque string to match against, not
    a stable enum across the whole API.


    ## Rate limits


    Authenticated routes: 6000 requests/min per user (`authRateLimit`). Public
    GET routes: 60/min per IP. A handful of sensitive public POST routes
    (newsletter signup, email-exists, invitation preview) are limited to 10
    requests / 15 min per IP.


    ## Pagination


    List endpoints use either simple `limit`/`offset` query params (marketing
    content — a plain JSON array response, capped at the documented max) or
    `page`/`limit` (credit transactions). Neither returns a total count today;
    fetch until a page comes back shorter than `limit`.
servers:
  - url: https://api.atako.ai
    description: Production
security: []
tags:
  - name: Agents
  - name: Messages
  - name: Activity
  - name: Agent Options
  - name: API Keys
  - name: Files
  - name: Cron Jobs
  - name: Sub-Agents
  - name: Interagent Messages
  - name: Integrations
  - name: Subscriptions
  - name: Users
  - name: Company
  - name: Teams
  - name: Floor
  - name: Search
  - name: Notices
  - name: Organization
  - name: Projects
  - name: Notifications
  - name: Agent Shared Items
  - name: Agent Email
  - name: Agent Webhooks
  - name: Company Dashboard
  - name: LLM Provider Keys
  - name: Public
  - name: Marketing Content
paths:
  /integrations/mcp/connections:
    post:
      tags:
        - Integrations
      summary: Connect a remote MCP server as a custom integration
      description: >-
        Re-probes the server: only tools the server really announces are stored;
        the body only chooses which are enabled and their read/write scope.
        `visibility` follows the usual rule ('company' = admins only, 'personal'
        = any member). Several connections may target the same server (one token
        each). Agents see enabled tools as `<slug>.<tool>` through the usual
        grants.
      operationId: createMcpConnection
      requestBody:
        description: ''
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - url
              properties:
                displayName:
                  type: string
                  maxLength: 80
                visibility:
                  type: string
                  enum:
                    - company
                    - personal
                url:
                  type: string
                  format: uri
                auth:
                  type: object
                  description: >-
                    How the platform authenticates to the MCP server. The token
                    is encrypted at rest and never returned nor shown to agents.
                  properties:
                    mode:
                      type: string
                      enum:
                        - none
                        - bearer
                        - header
                    token:
                      type: string
                      description: bearer/header modes. Write-only.
                    headerName:
                      type: string
                      description: header mode only (e.g. X-API-Key).
                  required:
                    - mode
                tools:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                      enabled:
                        type: boolean
                      scope:
                        type: string
                        enum:
                          - read
                          - write
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationConnection'
        '400':
          description: auth_invalid / too_many_enabled_tools (60 max)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: >-
            Missing, malformed, or invalid bearer token / API key, or revoked
            session (SESSION_REVOKED).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: company_admin_required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >-
            name_taken / mcp_limit_reached (10 per company, 10 personal per
            user) / personal_limit_reached (50 personal connections per user) /
            provider_coming_soon
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: >-
            url_invalid / url_blocked (private, local or non-public address, or
            a redirect) / unreachable / auth_required (with `oauth: true` when
            the server asks for OAuth) / auth_rejected / not_mcp /
            too_many_tools / timeout
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: too_many_requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearerAuth: []
components:
  schemas:
    IntegrationConnection:
      type: object
      description: Never includes credential material.
      properties:
        id:
          type: string
          format: uuid
        companyId:
          type: string
          format: uuid
          nullable: true
        providerKey:
          type: string
        displayName:
          type: string
        authType:
          type: string
          enum:
            - api_key
            - oauth2
            - mcp
            - internal
        visibility:
          type: string
          enum:
            - company
            - personal
          description: >-
            'company' = shared with the whole company, managed by its admins;
            'personal' = visible to, managed and grantable (to their own agents)
            by its creator only. Another member's personal connections are never
            returned.
        isMine:
          type: boolean
          description: Created by the caller.
        actions:
          type: array
          description: >-
            List endpoint, custom MCP connections only (providerKey 'mcp', no
            catalog entry): the active tools, catalog-shaped.
          items:
            type: object
            properties:
              key:
                type: string
              scope:
                type: string
                enum:
                  - read
                  - write
              description:
                type: string
        mcp:
          type: object
          description: List endpoint, custom MCP connections only.
          properties:
            host:
              type: string
              nullable: true
            slug:
              type: string
              nullable: true
            lastSyncedAt:
              type: string
              nullable: true
            toolCount:
              type: integer
            enabledCount:
              type: integer
            pendingReview:
              type: integer
        status:
          type: string
          enum:
            - active
            - error
            - revoked
        externalLabel:
          type: string
          nullable: true
        config:
          type: object
          nullable: true
          additionalProperties:
            type: string
        scopes:
          type: array
          items:
            type: string
        lastUsedAt:
          type: string
          format: date-time
          nullable: true
        createdBy:
          type: string
          format: uuid
        createdAt:
          type: string
          format: date-time
      required:
        - id
        - providerKey
        - displayName
        - authType
        - status
        - createdAt
    Error:
      type: object
      description: >-
        Atako's standard error envelope. `error` is either a short
        human-readable message or a SCREAMING_SNAKE_CASE code (routes are
        inconsistent about which — treat it as an opaque string and match on it
        exactly if you need to branch on error type). Some routes add extra
        fields alongside `error` (see the operation's own error responses).
      properties:
        error:
          type: string
        code:
          type: string
          description: >-
            Present on some routes; a stable machine-readable code duplicating
            or refining `error`.
      required:
        - error
      additionalProperties: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        An `aik_…` programmatic API key (app.atako.ai → Settings → API keys) or
        a Supabase session JWT.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.