# cc-connect Management API Specification

> **Version:** 1.1-draft  
> **Status:** Draft — subject to change before implementation  
> **Last Updated:** 2026-03-24

---

## 1. Overview

The cc-connect Management API is an HTTP-based REST API that enables external applications (web dashboards, TUI clients, GUI desktop apps, Mac tray apps) to manage and monitor cc-connect instances. It complements the existing internal Unix socket API by providing a network-accessible, token-authenticated interface suitable for remote and local management tools.

### 1.1 Architecture

```
┌─────────────────────────────────────────────────────────────────────────┐
│                         cc-connect Process                               │
│                                                                          │
│  ┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐  │
│  │  Unix Socket API │    │  Management API   │    │  Bridge Server   │  │
│  │  (internal)      │    │  (HTTP :9820)     │    │  (WebSocket)     │  │
│  └────────┬─────────┘    └────────┬─────────┘    └────────┬─────────┘  │
│           │                       │                       │             │
│           └───────────────────────┼───────────────────────┘             │
│                                   │                                      │
│                          ┌────────┴────────┐                            │
│                          │  Core Engine(s)  │                            │
│                          │  Projects       │                            │
│                          │  Sessions      │                            │
│                          │  Cron/Heartbeat │                            │
│                          └─────────────────┘                            │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
              ┌─────────────────────┼─────────────────────┐
              │                     │                     │
     ┌────────┴────────┐   ┌───────┴───────┐   ┌─────────┴─────────┐
     │  Web Dashboard  │   │  TUI Client   │   │  Mac Tray App      │
     └─────────────────┘   └───────────────┘   └────────────────────┘
```

### 1.2 Design Principles

- **RESTful:** Resource-oriented URLs, standard HTTP methods
- **JSON:** All request/response bodies use `application/json`
- **Consistent envelope:** Every response uses `{"ok": true|false, "data"|"error": ...}`
- **Token auth:** Bearer token or query parameter for all endpoints

---

## 2. Configuration

### 2.1 Management Block

Add the following to `config.toml`:

```toml
[management]
enabled = true
port = 9820
token = "mgmt-secret"
```

| Field    | Type    | Default   | Description                                      |
|----------|---------|-----------|--------------------------------------------------|
| `enabled`| boolean | `false`   | Enable the Management API server                 |
| `port`   | integer | `9820`    | TCP port to listen on                            |
| `token`  | string  | (required)| Shared secret for authentication                 |

When `enabled` is `false`, the Management API is not started. The token should be a strong, random string (e.g. 32+ characters).

### 2.2 Base URL

All endpoints are relative to:

```
http://<host>:<port>/api/v1
```

Example: `http://localhost:9820/api/v1/status`

---

## 3. Authentication

Every request must include a valid token. Two methods are supported:

### 3.1 Bearer Token (Recommended)

```
Authorization: Bearer <token>
```

Example:

```bash
curl -H "Authorization: Bearer mgmt-secret" http://localhost:9820/api/v1/status
```

### 3.2 Query Parameter

```
GET /api/v1/status?token=mgmt-secret
```

> **Note:** Query parameter auth is provided for environments where setting headers is difficult. Prefer Bearer token for security (tokens in URLs may be logged).

### 3.3 Unauthorized Response

If the token is missing or invalid:

- **HTTP Status:** `401 Unauthorized`
- **Body:**

```json
{
  "ok": false,
  "error": "unauthorized: missing or invalid token"
}
```

---

## 4. Response Format

### 4.1 Success

```json
{
  "ok": true,
  "data": { ... }
}
```

### 4.2 Error

```json
{
  "ok": false,
  "error": "human-readable error message"
}
```

### 4.3 HTTP Status Codes

| Code | Meaning                                      |
|------|----------------------------------------------|
| 200  | Success                                      |
| 400  | Bad request (invalid body, missing params)   |
| 401  | Unauthorized (missing/invalid token)        |
| 404  | Resource not found (project, session, etc.) |
| 405  | Method not allowed                          |
| 500  | Internal server error                        |

---

## 5. Endpoint Reference

### 5.1 System

#### GET /api/v1/status

Returns system status and summary.

**Response:**

```json
{
  "ok": true,
  "data": {
    "version": "v1.2.0",
    "uptime_seconds": 3600,
    "connected_platforms": ["feishu", "telegram"],
    "projects_count": 2,
    "bridge_adapters": [
      {
        "platform": "custom",
        "project": "my-backend",
        "capabilities": ["text", "images"]
      }
    ]
  }
}
```

| Field                 | Type     | Description                                      |
|-----------------------|----------|--------------------------------------------------|
| `version`             | string   | cc-connect version (e.g. `v1.2.0`)              |
| `uptime_seconds`      | number   | Process uptime in seconds                        |
| `connected_platforms` | string[] | Platform types currently connected               |
| `projects_count`      | number   | Number of configured projects                    |
| `bridge_adapters`     | array   | External adapters connected via Bridge WebSocket |

---

#### POST /api/v1/restart

Triggers a graceful restart. The process will shut down cleanly and exec itself. A "restart successful" message may be sent to the session that initiated the restart (if applicable).

**Request body (optional):**

```json
{
  "session_key": "telegram:123:456",
  "platform": "telegram"
}
```

If provided, the restart notification will be sent to the specified session after the new process starts.

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "restart initiated"
  }
}
```

---

#### POST /api/v1/reload

Reloads configuration from disk without restarting the process. New projects may be added; removed projects are stopped. Changed project settings take effect.

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "config reloaded",
    "projects_added": ["new-project"],
    "projects_removed": [],
    "projects_updated": ["my-backend"]
  }
}
```

---

#### GET /api/v1/config

Returns the current configuration with secrets redacted. Useful for debugging and UI display.

**Query parameters:** None

**Response:**

```json
{
  "ok": true,
  "data": {
    "data_dir": "/home/user/.cc-connect",
    "language": "en",
    "projects": [
      {
        "name": "my-backend",
        "agent": {
          "type": "claudecode",
          "providers": [
            {
              "name": "anthropic",
              "api_key": "***",
              "base_url": "",
              "model": "claude-sonnet-4-20250514"
            }
          ]
        },
        "platforms": [
          {
            "type": "feishu",
            "options": {
              "app_id": "***",
              "app_secret": "***"
            }
          }
        ]
      }
    ]
  }
}
```

Secrets (e.g. `api_key`, `token`, `app_secret`, `client_secret`) are replaced with `"***"`.

---

#### GET /api/v1/logs

Returns recent log entries.

**Query parameters:**

| Param   | Type   | Default | Description                          |
|---------|--------|---------|--------------------------------------|
| `level` | string | `info`  | Minimum level: `debug`, `info`, `warn`, `error` |
| `limit` | int    | `100`   | Max entries to return (1–1000)       |

**Response:**

```json
{
  "ok": true,
  "data": {
    "entries": [
      {
        "time": "2026-03-10T10:30:00Z",
        "level": "info",
        "message": "api server started",
        "attrs": {"socket": "/home/user/.cc-connect/run/api.sock"}
      }
    ]
  }
}
```

---

### 5.2 Projects

#### GET /api/v1/projects

Lists all projects with a summary.

**Response:**

```json
{
  "ok": true,
  "data": {
    "projects": [
      {
        "name": "my-backend",
        "agent_type": "claudecode",
        "platforms": ["feishu", "telegram"],
        "sessions_count": 3,
        "heartbeat_enabled": true
      }
    ]
  }
}
```

---

#### GET /api/v1/projects/{name}

Returns detailed information for a single project.

**Path parameters:**

| Param  | Type   | Description        |
|--------|--------|--------------------|
| `name` | string | Project name       |

**Response:**

```json
{
  "ok": true,
  "data": {
    "name": "my-backend",
    "agent_type": "claudecode",
    "platforms": [
      {
        "type": "feishu",
        "connected": true
      },
      {
        "type": "telegram",
        "connected": true
      }
    ],
    "sessions_count": 3,
    "active_session_keys": ["telegram:123:456", "feishu:ou_xxx:chat_xxx"],
    "heartbeat": {
      "enabled": true,
      "paused": false,
      "interval_mins": 30,
      "session_key": "telegram:123:456"
    },
    "settings": {
      "quiet": false,
      "admin_from": "user1,user2",
      "language": "en",
      "disabled_commands": ["restart", "upgrade"]
    }
  }
}
```

**Error (404):**

```json
{
  "ok": false,
  "error": "project not found: my-backend"
}
```

---

#### PATCH /api/v1/projects/{name}

Updates project settings. Only provided fields are updated.

**Request body:**

```json
{
  "quiet": true,
  "admin_from": "user1,user2,user3",
  "language": "zh",
  "disabled_commands": ["restart", "upgrade", "cron"]
}
```

| Field               | Type     | Description                                              |
|---------------------|----------|----------------------------------------------------------|
| `quiet`             | boolean  | Suppress thinking/tool progress messages                 |
| `admin_from`        | string   | Comma-separated user IDs for privileged commands; `"*"` = all |
| `language`          | string   | UI language: `en`, `zh`, `zh-TW`, `ja`, `es`             |
| `disabled_commands` | string[] | Commands to disable (e.g. `restart`, `upgrade`, `cron`)  |

**Response:**

```json
{
  "ok": true,
  "data": {
    "name": "my-backend",
    "settings": {
      "quiet": true,
      "admin_from": "user1,user2,user3",
      "language": "zh",
      "disabled_commands": ["restart", "upgrade", "cron"]
    }
  }
}
```

---

### 5.3 Sessions

Sessions are conversation contexts within a project. A session is identified by a `session_key` (format: `platform:chatId:userId`) and optionally by an internal `id` for named sessions (e.g. `/new work` creates a named session).

#### GET /api/v1/projects/{name}/sessions

Lists sessions for a project with summary info including the last message preview.

**Response:**

```json
{
  "ok": true,
  "data": {
    "sessions": [
      {
        "id": "sess_abc123",
        "session_key": "telegram:123:456",
        "name": "work",
        "platform": "telegram",
        "agent_type": "claudecode",
        "active": true,
        "live": true,
        "history_count": 12,
        "created_at": "2026-03-10T09:00:00Z",
        "updated_at": "2026-03-10T10:30:00Z",
        "last_message": {
          "role": "assistant",
          "content": "Done! The tests are passing now...",
          "timestamp": "2026-03-10T10:30:00Z"
        },
        "user_name": "Alice",
        "chat_name": "dev-channel"
      }
    ],
    "active_keys": {
      "telegram:123:456": "telegram"
    }
  }
}
```

| Field          | Type    | Description                                                       |
|----------------|---------|-------------------------------------------------------------------|
| `active`       | boolean | Whether this is the selected session for its user key             |
| `live`         | boolean | Whether there is a running agent process for this session         |
| `last_message` | object  | Preview of the last message (role, content truncated to 200 chars, timestamp). `null` if no history. |
| `user_name`    | string  | Display name of the user (from platform metadata)                 |
| `chat_name`    | string  | Name of the chat/channel (from platform metadata)                 |
| `active_keys`  | object  | Map of session keys with active agent connections → platform name |

---

#### POST /api/v1/projects/{name}/sessions

Creates a new session.

**Request body:**

```json
{
  "session_key": "telegram:123:456",
  "name": "work"
}
```

| Field        | Type   | Required | Description                          |
|--------------|--------|----------|--------------------------------------|
| `session_key`| string | yes      | Platform routing key (e.g. `telegram:123:456`) |
| `name`       | string | no       | Human-readable session name           |

**Response:**

```json
{
  "ok": true,
  "data": {
    "id": "sess_xyz789",
    "session_key": "telegram:123:456",
    "name": "work",
    "created_at": "2026-03-10T10:35:00Z"
  }
}
```

---

#### GET /api/v1/projects/{name}/sessions/{id}

Returns session detail including message history.

**Path parameters:**

| Param  | Type   | Description                          |
|--------|--------|--------------------------------------|
| `name` | string | Project name                         |
| `id`   | string | Session ID                           |

**Query parameters:**

| Param   | Type | Default | Description                    |
|---------|------|---------|--------------------------------|
| `history_limit` | int | 50 | Max history entries to return |

**Response:**

```json
{
  "ok": true,
  "data": {
    "id": "sess_abc123",
    "session_key": "telegram:123:456",
    "name": "work",
    "platform": "telegram",
    "agent_type": "claudecode",
    "agent_session_id": "as_xxx",
    "active": true,
    "live": true,
    "history_count": 12,
    "created_at": "2026-03-10T09:00:00Z",
    "updated_at": "2026-03-10T10:30:00Z",
    "history": [
      {
        "role": "user",
        "content": "Hello",
        "timestamp": "2026-03-10T09:00:05Z"
      },
      {
        "role": "assistant",
        "content": "Hi! How can I help?",
        "timestamp": "2026-03-10T09:00:10Z"
      }
    ]
  }
}
```

| Field   | Type    | Description                                                   |
|---------|---------|---------------------------------------------------------------|
| `live`  | boolean | Whether the session has an active agent process (can receive messages via `/send`) |

---

#### DELETE /api/v1/projects/{name}/sessions/{id}

Deletes a session and its history.

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "session deleted"
  }
}
```

---

#### POST /api/v1/projects/{name}/sessions/switch

Switches the active session for a given session_key (e.g. when a user has multiple named sessions).

**Request body:**

```json
{
  "session_key": "telegram:123:456",
  "session_id": "sess_xyz789"
}
```

| Field         | Type   | Required | Description                    |
|---------------|--------|----------|--------------------------------|
| `session_key` | string | yes      | Platform routing key           |
| `session_id`  | string | yes      | Session ID to make active      |

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "active session switched",
    "active_session_id": "sess_xyz789"
  }
}
```

---

#### POST /api/v1/projects/{name}/send

Sends a message to a session. The message is delivered to the agent as if the user had sent it via the platform. **Requires the session to be live** (i.e., have an active agent process). Check the `live` field from session detail to verify before sending.

**Request body:**

```json
{
  "session_key": "telegram:123:456",
  "message": "Review the latest commit"
}
```

| Field         | Type   | Required | Description                    |
|---------------|--------|----------|--------------------------------|
| `session_key`| string | yes      | Platform routing key           |
| `message`    | string | yes      | Text to send to the agent      |

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "message sent"
  }
}
```

---

### 5.4 Providers

Providers are API backends (e.g. Anthropic, OpenAI, custom endpoints) that supply the AI model for a project's agent.

#### GET /api/v1/projects/{name}/providers

Lists providers with active indicator.

**Response:**

```json
{
  "ok": true,
  "data": {
    "providers": [
      {
        "name": "anthropic",
        "active": true,
        "model": "claude-sonnet-4-20250514",
        "base_url": ""
      },
      {
        "name": "relay",
        "active": false,
        "model": "claude-sonnet-4-20250514",
        "base_url": "https://api.relay.example.com"
      }
    ],
    "active_provider": "anthropic"
  }
}
```

---

#### POST /api/v1/projects/{name}/providers

Adds a new provider.

**Request body:**

```json
{
  "name": "relay",
  "api_key": "sk-xxx",
  "base_url": "https://api.relay.example.com",
  "model": "claude-sonnet-4-20250514",
  "thinking": "disabled",
  "env": {
    "CLAUDE_CODE_USE_BEDROCK": "1",
    "AWS_PROFILE": "bedrock"
  }
}
```

| Field     | Type            | Required | Description                              |
|-----------|-----------------|----------|------------------------------------------|
| `name`    | string          | yes      | Provider identifier                      |
| `api_key` | string          | no*      | API key (*required if no `env`)          |
| `base_url`| string          | no       | Custom API endpoint                      |
| `model`   | string          | no       | Model override                           |
| `thinking`| string          | no       | `"disabled"` for providers without adaptive thinking |
| `env`     | object (k/v)    | no       | Extra environment variables              |

**Response:**

```json
{
  "ok": true,
  "data": {
    "name": "relay",
    "message": "provider added"
  }
}
```

---

#### DELETE /api/v1/projects/{name}/providers/{provider}

Removes a provider. The active provider cannot be removed; switch first.

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "provider removed"
  }
}
```

**Error (400):**

```json
{
  "ok": false,
  "error": "cannot remove active provider; switch to another first"
}
```

---

#### POST /api/v1/projects/{name}/providers/{provider}/activate

Switches the active provider.

**Response:**

```json
{
  "ok": true,
  "data": {
    "active_provider": "relay",
    "message": "provider activated"
  }
}
```

---

#### GET /api/v1/projects/{name}/models

Lists available models for the project's agent type.

**Response:**

```json
{
  "ok": true,
  "data": {
    "models": [
      "claude-sonnet-4-20250514",
      "claude-3-5-sonnet-20241022",
      "claude-3-opus-20240229"
    ],
    "current": "claude-sonnet-4-20250514"
  }
}
```

---

#### POST /api/v1/projects/{name}/model

Sets the model for the project.

**Request body:**

```json
{
  "model": "claude-3-5-sonnet-20241022"
}
```

**Response:**

```json
{
  "ok": true,
  "data": {
    "model": "claude-3-5-sonnet-20241022",
    "message": "model updated"
  }
}
```

---

### 5.5 Cron Jobs

#### GET /api/v1/cron

Lists all cron jobs, optionally filtered by project.

**Query parameters:**

| Param     | Type   | Description        |
|-----------|--------|--------------------|
| `project` | string | Filter by project  |

**Response:**

```json
{
  "ok": true,
  "data": {
    "jobs": [
      {
        "id": "cron_abc123",
        "project": "my-backend",
        "session_key": "telegram:123:456",
        "cron_expr": "0 6 * * *",
        "prompt": "Summarize GitHub trending",
        "exec": "",
        "work_dir": "",
        "description": "Daily GitHub Trending",
        "enabled": true,
        "silent": true,
        "created_at": "2026-03-10T08:00:00Z",
        "last_run": "2026-03-10T06:00:00Z",
        "last_error": ""
      }
    ]
  }
}
```

---

#### POST /api/v1/cron

Adds a cron job. Either `prompt` or `exec` must be provided, not both.

**Request body (prompt job):**

```json
{
  "project": "my-backend",
  "session_key": "telegram:123:456",
  "cron_expr": "0 6 * * *",
  "prompt": "Summarize GitHub trending",
  "description": "Daily GitHub Trending",
  "silent": true
}
```

**Request body (exec job):**

```json
{
  "project": "my-backend",
  "session_key": "telegram:123:456",
  "cron_expr": "0 9 * * 1",
  "exec": "npm run weekly-report",
  "work_dir": "/path/to/project",
  "description": "Weekly Report",
  "silent": false
}
```

| Field        | Type    | Required | Description                                    |
|--------------|---------|----------|------------------------------------------------|
| `project`    | string  | no*      | Project name (*required if multiple projects) |
| `session_key`| string  | yes      | Target session for prompt jobs                 |
| `cron_expr`  | string  | yes      | Cron expression (5 or 6 fields)                |
| `prompt`     | string  | no*      | Prompt to send (*required if no `exec`)        |
| `exec`       | string  | no*      | Shell command (*required if no `prompt`)       |
| `work_dir`   | string  | no       | Working directory for exec                    |
| `description`| string  | no       | Human-readable label                           |
| `silent`     | boolean | no       | Suppress start notification                   |
| `session_mode` | string | no       | `reuse` (default) or `new_per_run` — new agent session each run |
| `timeout_mins` | int    | no       | Scheduler wait per run: omit = 30 min, `0` = no time limit |

**Response:**

```json
{
  "ok": true,
  "data": {
    "id": "cron_xyz789",
    "project": "my-backend",
    "session_key": "telegram:123:456",
    "cron_expr": "0 6 * * *",
    "prompt": "Summarize GitHub trending",
    "description": "Daily GitHub Trending",
    "enabled": true,
    "created_at": "2026-03-10T10:40:00Z"
  }
}
```

---

#### DELETE /api/v1/cron/{id}

Deletes a cron job.

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "cron job deleted"
  }
}
```

#### POST /api/v1/cron/{id}/exec

Triggers an existing cron job immediately. Disabled jobs can still be triggered manually.
`/api/v1/cron/{id}/run` is accepted as a compatibility alias.

**Response:**

```json
{
  "ok": true,
  "data": {
    "id": "cron_xyz789",
    "status": "triggered"
  }
}
```

---

### 5.6 Heartbeat

Heartbeat runs periodic prompts in a session (e.g. "check inbox") to keep the agent aware of the environment.

#### GET /api/v1/projects/{name}/heartbeat

Returns heartbeat status.

**Response:**

```json
{
  "ok": true,
  "data": {
    "enabled": true,
    "paused": false,
    "interval_mins": 30,
    "only_when_idle": true,
    "session_key": "telegram:123:456",
    "silent": true,
    "run_count": 42,
    "error_count": 0,
    "skipped_busy": 5,
    "last_run": "2026-03-10T10:00:00Z",
    "last_error": ""
  }
}
```

---

#### POST /api/v1/projects/{name}/heartbeat/pause

Pauses heartbeat.

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "heartbeat paused"
  }
}
```

---

#### POST /api/v1/projects/{name}/heartbeat/resume

Resumes heartbeat.

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "heartbeat resumed"
  }
}
```

---

#### POST /api/v1/projects/{name}/heartbeat/run

Triggers heartbeat immediately (one-shot).

**Response:**

```json
{
  "ok": true,
  "data": {
    "message": "heartbeat triggered"
  }
}
```

---

#### POST /api/v1/projects/{name}/heartbeat/interval

Sets the heartbeat interval.

**Request body:**

```json
{
  "minutes": 15
}
```

**Response:**

```json
{
  "ok": true,
  "data": {
    "interval_mins": 15,
    "message": "interval updated"
  }
}
```

---

### 5.7 Bridge

#### GET /api/v1/bridge/adapters

Lists connected bridge adapters (external platforms via WebSocket).

**Response:**

```json
{
  "ok": true,
  "data": {
    "adapters": [
      {
        "platform": "custom",
        "project": "my-backend",
        "capabilities": ["text", "images", "files"],
        "connected_at": "2026-03-10T09:00:00Z"
      }
    ]
  }
}
```

---

## 6. Error Handling Conventions

### 6.1 Standard Error Response

All errors use the same envelope:

```json
{
  "ok": false,
  "error": "human-readable message"
}
```

### 6.2 Common Errors

| HTTP | Error message example                          | Cause                          |
|------|-------------------------------------------------|--------------------------------|
| 400  | `"project is required (multiple projects)"`     | Missing required parameter     |
| 400  | `"either prompt or exec is required"`           | Invalid cron job body          |
| 401  | `"unauthorized: missing or invalid token"`      | Auth failure                   |
| 404  | `"project not found: xyz"`                      | Unknown project/session/cron   |
| 404  | `"session not found"`                           | Unknown session ID             |
| 405  | `"method not allowed"`                          | Wrong HTTP method              |
| 500  | `"internal error"`                              | Unexpected server error        |

### 6.3 Validation Errors

When request body validation fails:

```json
{
  "ok": false,
  "error": "invalid request: session_key is required"
}
```

---

## 7. Session Key Format

The `session_key` is a composite identifier used to route messages to the correct platform and chat:

```
<platform>:<chat_id>:<user_id>
```

Examples:

- `telegram:123456789:123456789` — Telegram user 123456789 in chat 123456789
- `feishu:ou_xxx:chat_yyy` — Feishu user in chat
- `slack:C01234:U05678` — Slack channel and user
- `discord:123456789:987654321` — Discord guild and user

For multi-workspace mode, the format may include a workspace prefix:

```
<workspace>:<platform>:<chat_id>:<user_id>
```

---

## 8. CORS

When the Management API is used by web dashboards, CORS headers should be configurable. A suggested config extension:

```toml
[management]
enabled = true
port = 9820
token = "mgmt-secret"
cors_origins = ["http://localhost:3000", "https://dashboard.example.com"]
```

If not configured, CORS may be disabled or use a default (e.g. `*` for same-origin only).

---

## 9. Changelog

| Version   | Date       | Changes                    |
|-----------|------------|----------------------------|
| 1.1-draft | 2026-03-24 | Enrich session list/detail with `live`, `last_message`, `agent_type`, `user_name`, `chat_name`, `active_keys` fields |
| 1.0-draft | 2026-03-10 | Initial specification      |

---

## 10. References

- [Bridge Protocol](bridge-protocol.md) — WebSocket protocol for external platform adapters
- [Usage Guide](usage.md) — End-user features and slash commands
- [config.example.toml](../config.example.toml) — Configuration template
