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

# Extend agents with integrations

> Browse the catalog and install MCP servers, skills, and Slack channels for your workspace, then attach them to an agent.

HQ agents gain new capabilities from three kinds of integration: **MCP servers** (tool backends), **skills** (instruction packs), and **Slack channels** (where the HQ bot can post). Each is installed once at the **workspace** level and then attached to individual agents.

All requests use the base URL `https://api.hq.zone` and a personal access token: `Authorization: Bearer hq_pat_...`. Most install and uninstall operations require the `admin` scope; the catalog and status reads require `agents:read`.

<Note>Installing an MCP server or skill makes it available to the *workspace*. To put it in front of a specific agent, attach it with the agent's MCP/skill subset — see [Attach skills and MCP servers](/guides/agents).</Note>

## Check connection status

Before browsing the catalogs, you can fetch a single overview of what the workspace has connected. See [Connection status](/api-reference/integrations/connect-status).

```bash theme={null}
curl https://api.hq.zone/v1/api/connect/status \
  -H "Authorization: Bearer $HQ_TOKEN"
# → {
#   "slack": { "connected": true, "team_name": "Acme" },
#   "teams": { "connected": false, "org_name": null },
#   "extension": { "web_store_url": null, "download_url": null },
#   "recommendations": [ ... ],
#   "detected": [ ... ]
# }
```

The `slack` and `teams` objects report whether each is connected (with the team or org name when available). `extension` carries the browser-extension URLs (null until published). `recommendations` lists suggested or accepted integrations/skills enriched with catalog `display_name`, `description`, `category`, `icon_url`, `confidence`, `priority`, and `rationale`; `detected` lists the technology signals the profiler found about your org's site and DNS. This read requires the `agents:read` scope.

## MCP servers

MCP servers expose tools your agents can call. Some are one-click toggles; others need a credential before they will work.

<Steps>
  <Step title="Browse the catalog">
    List every active MCP server together with your workspace's install state. See [MCP catalog](/api-reference/integrations/mcp-catalog).

    ```bash theme={null}
    curl https://api.hq.zone/v1/mcp/catalog \
      -H "Authorization: Bearer $HQ_TOKEN"
    # → { "servers": [ { "slug": "github", "display_name": "GitHub",
    #       "credential_model": "tenant_api_key", "effective_enabled": false,
    #       "allowed_scopes": ["team","user"], ... } ] }
    ```

    Each server reports `slug`, `display_name`, `description`, `category`, `publisher`, `transport`, `trust_tier`, `version`, `default_enabled`, `credential_model`, `tenant_enabled`, `effective_enabled`, `install_status`, `allowed_scopes`, `featured`, `featured_rank`, and `icon_url`. This read requires the `admin` scope.

    The **`credential_model`** drives how you install:

    * `none` / `platform` — a one-click toggle; no credential needed.
    * `tenant_api_key` — paste an API key (see *Install with an API key* below).
    * `tenant_oauth` — connect through OAuth, then install with the resulting credential reference.

    Fetch a server's brand icon (public, no auth) from [MCP icon](/api-reference/integrations/mcp-icon):

    ```bash theme={null}
    curl https://api.hq.zone/v1/mcp/catalog/<SLUG>/icon
    # → image/svg+xml (404 when the server has no icon)
    ```
  </Step>

  <Step title="Install (no credential)">
    For `none` and `platform` servers, install by slug. See [Install MCP](/api-reference/integrations/install-mcp).

    ```bash theme={null}
    curl -X POST https://api.hq.zone/v1/mcp/installs \
      -H "Authorization: Bearer $HQ_TOKEN" -H "Content-Type: application/json" \
      -d '{"slug": "<SLUG>"}'
    # → { "slug": "<SLUG>", "enabled": true }
    ```

    The body accepts `slug`, an optional `credential_ref` (for `tenant_api_key` / `tenant_oauth` servers), and an optional `config` blob. Re-installing is idempotent and preserves the prior `credential_ref` and `config` when you omit them.

    <Warning>Installing a `tenant_api_key` or `tenant_oauth` server without a `credential_ref` returns `400`. An unknown or inactive slug returns `404`.</Warning>
  </Step>

  <Step title="Install with an API key (tenant_api_key servers)">
    For servers whose `credential_model` is `tenant_api_key`, store the key and install in one call. See [Set MCP key](/api-reference/integrations/set-mcp-key).

    ```bash theme={null}
    curl -X POST https://api.hq.zone/v1/mcp/installs/<SLUG>/api_key \
      -H "Authorization: Bearer $HQ_TOKEN" -H "Content-Type: application/json" \
      -d '{"api_key": "<TOKEN>", "scope": "team"}'
    # → { "slug": "<SLUG>", "enabled": true,
    #     "credential_ref": "<UUID>", "scope": "team" }
    ```

    The body takes `api_key` and an optional `scope`: `team` (shared across the workspace, the default) or `user` (private to you). The chosen scope must be in the server's `allowed_scopes`, and `user` scope requires a resolvable calling user. The key is sealed and, where the backend supports it, validated against the upstream before being saved. Pasting a new key for an existing install rotates the credential in place.

    <Warning>An empty key, a server whose `credential_model` is not `tenant_api_key`, a disallowed scope, or a failed validation probe returns `400`. An unknown or inactive slug returns `404`.</Warning>
  </Step>

  <Step title="Attach it to an agent">
    Installing only makes the server available to the workspace. To equip an agent, replace its MCP subset with the slugs you want — an empty list means "everything installed." See [Attach skills and MCP servers](/guides/agents).

    ```bash theme={null}
    curl -X PUT https://api.hq.zone/v1/agents/<AGENT_ID>/mcp \
      -H "Authorization: Bearer $HQ_TOKEN" -H "Content-Type: application/json" \
      -d '{"enabled": ["<SLUG>"]}'
    ```
  </Step>

  <Step title="Uninstall">
    Disable the server for your workspace. See [Uninstall MCP](/api-reference/integrations/uninstall-mcp).

    ```bash theme={null}
    curl -X DELETE https://api.hq.zone/v1/mcp/installs/<SLUG> \
      -H "Authorization: Bearer $HQ_TOKEN"
    # → { "slug": "<SLUG>", "enabled": false }
    ```

    This works even for servers that are enabled by default with no prior install (it records an explicit opt-out). It also clears any stored tenant credential, so a later re-install of a credentialed server must supply a fresh one.
  </Step>
</Steps>

<Tip>For the OAuth dance that produces a `credential_ref` for `tenant_oauth` servers, see the [OAuth guide](/guides/oauth).</Tip>

## Skills

Skills are instruction packs that shape how agents work. The catalog mixes platform skills with any your workspace has authored.

<Steps>
  <Step title="Browse the catalog">
    List every active skill with your workspace's install state. See [Skills catalog](/api-reference/integrations/skills-catalog).

    ```bash theme={null}
    curl https://api.hq.zone/v1/skills/catalog \
      -H "Authorization: Bearer $HQ_TOKEN"
    # → { "skills": [ { "slug": "research", "display_name": "Research",
    #       "profile": "claude-sdk", "locked": false,
    #       "required_integrations": [ { "slug": "web", "display_name": "Web Search", "met": true } ],
    #       "effective_enabled": true, ... } ] }
    ```

    Each skill reports `slug`, `display_name`, `description`, `category`, `publisher`, `profile`, `version`, `default_enabled`, `trust_tier`, `locked`, `requires`, `required_integrations` (each with `slug`, `display_name`, and whether it is `met`), `tenant_enabled`, `effective_enabled`, `install_status`, `featured`, `featured_rank`, and `icon_url`. A `locked` skill is system-required and always on. This read requires the `agents:read` scope.

    Inspect a skill's full pack — its `SKILL.md` (listed first) and any other files — with [Skill content](/api-reference/integrations/skill-content):

    ```bash theme={null}
    curl https://api.hq.zone/v1/skills/catalog/<SLUG>/content \
      -H "Authorization: Bearer $HQ_TOKEN"
    # → { "slug": "<SLUG>", "display_name": "...", "profile": "claude-sdk",
    #     "trust_tier": "...", "editable": false,
    #     "files": [ { "path": "SKILL.md", "content": "...", "is_external": false } ] }
    ```

    `editable` is `true` only for your own workspace-authored skills. Large external files are listed with empty `content`. Fetch a skill icon (public, no auth) from [Skill icon](/api-reference/integrations/skill-icon).
  </Step>

  <Step title="Install">
    Enable a skill for your workspace by slug. See [Install skill](/api-reference/integrations/install-skill).

    ```bash theme={null}
    curl -X POST https://api.hq.zone/v1/skills/installs \
      -H "Authorization: Bearer $HQ_TOKEN" -H "Content-Type: application/json" \
      -d '{"slug": "<SLUG>"}'
    # → { "slug": "<SLUG>", "enabled": true }
    ```

    The body accepts `slug` and an optional `config` blob. Re-installing is idempotent and preserves the prior `config` when omitted.

    <Warning>System-locked skills cannot be installed this way (they are always on) and return `400`; an unknown or inactive slug returns `404`. Requires the `admin` scope.</Warning>
  </Step>

  <Step title="Author a workspace skill (upload)">
    Create a skill from your own content. See [Upload skill](/api-reference/integrations/upload-skill). The body is either inline markdown or a multi-file pack.

    ```bash theme={null}
    # Inline markdown — wrapped automatically as SKILL.md
    curl -X POST https://api.hq.zone/v1/skills/upload \
      -H "Authorization: Bearer $HQ_TOKEN" -H "Content-Type: application/json" \
      -d '{"kind": "markdown", "name": "Release Notes Style",
           "description": "How we write release notes",
           "body_markdown": "# Release Notes\n..."}'
    # → 201 { "slug": "t:<TENANT>:release-notes-style", "version": "0.1.0" }
    ```

    ```bash theme={null}
    # Multi-file pack — each file is base64-encoded; must include SKILL.md at the root
    curl -X POST https://api.hq.zone/v1/skills/upload \
      -H "Authorization: Bearer $HQ_TOKEN" -H "Content-Type: application/json" \
      -d '{"kind": "files", "name": "Release Notes Style",
           "files": [ { "path": "SKILL.md", "content_base64": "<BASE64>" } ]}'
    # → 201 { "slug": "t:<TENANT>:release-notes-style", "version": "0.1.0" }
    ```

    Fields: `name` (3–60 chars; letters, digits, spaces, hyphens, underscores — used to derive the slug), optional `description`, optional `profile` (`claude-sdk`, `hermes`, or `openai-agents`; defaults to `claude-sdk`), optional `provides` (a capability slot such as `app-design`), and the `body` discriminated by `kind` (`markdown` with `body_markdown`, or `files` with a list of `{ "path", "content_base64" }`). Re-uploading with the same derived slug updates the skill in place.

    <Note>Limits: up to 50 files, 256 KiB total raw content, 64 KiB markdown, and a 1 MB request body. Exceeding them — or a pack with no `SKILL.md` at the root — returns `400`. Requires the `admin` scope.</Note>
  </Step>

  <Step title="Attach it to an agent">
    Replace the agent's skill subset with the slugs you want — an empty list means "everything installed." See [Attach skills and MCP servers](/guides/agents).

    ```bash theme={null}
    curl -X PUT https://api.hq.zone/v1/agents/<AGENT_ID>/skills \
      -H "Authorization: Bearer $HQ_TOKEN" -H "Content-Type: application/json" \
      -d '{"enabled": ["<SLUG>"]}'
    ```
  </Step>

  <Step title="Uninstall or delete">
    Disable a skill for your workspace (opting out even of a default-enabled one). See [Uninstall skill](/api-reference/integrations/uninstall-skill).

    ```bash theme={null}
    curl -X DELETE https://api.hq.zone/v1/skills/installs/<SLUG> \
      -H "Authorization: Bearer $HQ_TOKEN"
    # → { "slug": "<SLUG>", "enabled": false }
    ```

    System-locked skills cannot be disabled (they return `400`). To remove a workspace-authored skill permanently — including its install records — use [Delete skill](/api-reference/integrations/delete-skill):

    ```bash theme={null}
    curl -X DELETE https://api.hq.zone/v1/skills/t:<TENANT>:<NAME> \
      -H "Authorization: Bearer $HQ_TOKEN"
    # → { "slug": "t:<TENANT>:<NAME>", "deleted": true }
    ```

    Only your own workspace-authored (T3) skills may be deleted; deleting a platform skill or another workspace's skill returns `403`, and an unknown slug returns `404`. Both operations require the `admin` scope.
  </Step>
</Steps>

## Slack channels

Once Slack is connected, the HQ bot can post to channels it is a member of (for example, from a scheduled run). These endpoints let you see and grow that membership.

<Steps>
  <Step title="See where HQ can post">
    List the channels the HQ bot already belongs to — the set it can deliver to. See [List Slack channels](/api-reference/integrations/list-channels).

    ```bash theme={null}
    curl https://api.hq.zone/v1/api/slack/channels \
      -H "Authorization: Bearer $HQ_TOKEN"
    # → { "connected": true,
    #     "channels": [ { "id": "C0123ABCD", "name": "general", "is_private": false } ] }
    ```

    Each channel has `id`, `name`, and `is_private`. When `connected` is `false`, the workspace has no active Slack install and `channels` is empty — connect Slack first. This read requires the `agents:read` scope.
  </Step>

  <Step title="Find channels HQ can join">
    List the public channels HQ is *not* yet in but can self-join. See [List joinable channels](/api-reference/integrations/list-joinable-channels).

    ```bash theme={null}
    curl https://api.hq.zone/v1/api/slack/channels/joinable \
      -H "Authorization: Bearer $HQ_TOKEN"
    # → { "connected": true,
    #     "channels": [ { "id": "C09XYZ", "name": "announcements", "is_private": false } ] }
    ```

    Private channels are intentionally excluded — Slack forbids a bot from self-joining them, so a member must run `/invite @HQ` instead. Requires the `admin` scope.
  </Step>

  <Step title="Join a channel">
    Self-join HQ to a public channel by id. See [Join Slack channel](/api-reference/integrations/join-channel).

    ```bash theme={null}
    curl -X POST https://api.hq.zone/v1/api/slack/channels/<CHANNEL_ID>/join \
      -H "Authorization: Bearer $HQ_TOKEN"
    # → { "joined": true,
    #     "channel": { "id": "<CHANNEL_ID>", "name": "announcements", "is_private": false } }
    ```

    Joining is idempotent on Slack's side. If the workspace has no live Slack install, or Slack refuses the join, the call returns `400`. Requires the `admin` scope.
  </Step>
</Steps>

<Tip>To connect Slack in the first place, see the [Connection status](/api-reference/integrations/connect-status) read and the [OAuth guide](/guides/oauth).</Tip>
