Metadata-Version: 2.4
Name: mcp-apollo
Version: 0.1.0
Summary: MCP Server for Apollo configuration management
Project-URL: Homepage, https://github.com/zhouweico/mcp-apollo
Project-URL: Repository, https://github.com/zhouweico/mcp-apollo
Author: zhouweico
License-Expression: MIT
License-File: LICENSE
Keywords: apollo,configuration,mcp,model-context-protocol
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: starlette>=0.37.0
Requires-Dist: uvicorn>=0.27.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: respx>=0.20.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Description-Content-Type: text/markdown

# mcp-apollo

Apollo MCP Server - 让 AI 助手能够查询和管理 [Apollo](https://www.apolloconfig.com/) 配置中心的配置。

基于 Apollo Portal 开放平台 OpenAPI（`/openapi/v1/...`，参见 [OpenAPI 接口文档](https://www.apolloconfig.com/#/zh/portal/apollo-open-api-platform?id=%e4%b8%89%e3%80%81-%e6%8e%a5%e5%8f%a3%e6%96%87%e6%a1%a3)），支持配置的读取与发布。

## 特性

- **多协议传输**：`stdio`（默认）、`sse`、`streamable-http`，一套代码适配本地与远程场景
- **接口认证**：HTTP 传输支持 Bearer Token 保护，未授权请求返回 `401`
- **Apollo 原生概念**：直接以 `env / app / cluster / namespace / item` 组织配置，读写一体
- **灵活部署**：`uvx` 免安装运行、Docker 公开镜像即拉即用、或本地构建

## 前置准备

在 Apollo Portal 的「开放平台」中创建第三方应用并生成 **Token**，并为其授权目标 App / 环境 / 命名空间。你需要准备：

- Apollo Portal 地址（如 `http://localhost:8070`）
- OpenAPI Token
- 目标应用的 `appId`

## 快速开始

### MCP 客户端（stdio，本地）

以 Claude Code 为例，在项目 `.mcp.json` 或全局 `~/.claude.json` 中添加：

```json
{
  "mcpServers": {
    "apollo": {
      "type": "stdio",
      "command": "uvx",
      "args": ["mcp-apollo"],
      "env": {
        "APOLLO_PORTAL_URL": "http://localhost:8070",
        "APOLLO_TOKEN": "your-openapi-token",
        "APOLLO_APP_ID": "your-app-id",
        "APOLLO_ENV": "DEV",
        "APOLLO_CLUSTER": "default",
        "APOLLO_NAMESPACE": "application",
        "APOLLO_READ_ONLY": "false"
      }
    }
  }
}
```

> Cursor、OpenCode、Claude Desktop 等客户端的配置格式相同，核心均为 `command: uvx` + `args: ["mcp-apollo"]`，按各客户端语法填入 `APOLLO_*` 环境变量即可。

### Docker（公开镜像，免构建）

已发布公开镜像 `ghcr.io/zhouweico/mcp-apollo:latest`，无需本地构建。下面以 Claude Code 为例。

**方式一：stdio（由客户端拉起容器，适合本地集成）**

```json
{
  "mcpServers": {
    "apollo": {
      "type": "stdio",
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/zhouweico/mcp-apollo:latest"],
      "env": {
        "APOLLO_PORTAL_URL": "http://your-apollo-portal:8070",
        "APOLLO_TOKEN": "your-openapi-token",
        "APOLLO_APP_ID": "your-app-id",
        "APOLLO_ENV": "DEV"
      }
    }
  }
}
```

> 必须带 `-i`（保持 stdin 管道），否则容器内的 stdio 服务无法与客户端通信。

**方式二：HTTP + 认证（容器独立运行，客户端远程连接，适合多客户端共享）**

先启动容器：

```bash
docker run -d -p 8000:8000 \
  -e MCP_TRANSPORT=streamable-http \
  -e MCP_AUTH_TOKEN=your-strong-token \
  -e APOLLO_PORTAL_URL=http://your-apollo-portal:8070 \
  -e APOLLO_TOKEN=your-openapi-token \
  -e APOLLO_APP_ID=your-app-id \
  ghcr.io/zhouweico/mcp-apollo:latest
```

再在 Claude Code 的 `.mcp.json` 中通过 HTTP 连接：

```json
{
  "mcpServers": {
    "apollo": {
      "type": "streamable-http",
      "url": "http://localhost:8000/mcp",
      "headers": {
        "Authorization": "Bearer your-strong-token"
      }
    }
  }
}
```

## 可用工具

| 工具 | 3.2 接口 | 类型 | 说明 |
|------|---------|------|------|
| `apollo_get_config` | 3.2.6 / 3.2.9 | 只读 | 读取命名空间全部配置项，或指定 key 的单个配置项（支持客户端侧分页） |
| `apollo_get_app_env_clusters` | 3.2.1 | 只读 | 获取 App 的环境与集群信息 |
| `apollo_get_apps` | 3.2.2 | 只读 | 获取 App 信息（可按 appId 过滤） |
| `apollo_get_cluster` | 3.2.3 | 只读 | 获取集群详细信息 |
| `apollo_list_namespaces` | 3.2.5 | 只读 | 获取集群下所有 Namespace |
| `apollo_get_namespace_lock` | 3.2.8 | 只读 | 获取 Namespace 当前编辑锁（PRO 环境才有） |
| `apollo_get_latest_release` | 3.2.14 | 只读 | 获取 Namespace 最近一次已发布配置 |
| `apollo_list_items` | 3.2.16 | 只读 | 分页获取配置项（Apollo 原生服务端分页） |
| `apollo_create_item` | 3.2.10 | 写 | 新建配置项（严格新建，key 已存在则报错） |
| `apollo_update_item` | 3.2.11 | 写 | 更新配置项（默认严格更新，key 不存在则报错；可选 `create_if_not_exists=true` 启用 upsert） |
| `apollo_releases` | 3.2.13 | 写 | 发布命名空间，使改动生效 |
| `apollo_create_cluster` | 3.2.4 | 写 | 创建集群 |
| `apollo_create_namespace` | 3.2.7 | 写 | 创建 Namespace |
| `apollo_delete_item` | 3.2.12 | 写 | 删除配置项（删除后需发布生效） |
| `apollo_rollback_release` | 3.2.15 | 写 | 回滚已发布配置 |
| `apollo_create_app` | 3.2.17 | 写 | 创建 App 并获取管理员权限 |

> 全部 16 个工具完整覆盖 [Apollo OpenAPI 文档「3.2 API接口列表」](https://www.apolloconfig.com/#/zh/portal/apollo-open-api-platform?id=%e4%b8%89%e3%80%81-%e6%8e%a5%e5%8f%a3%e6%96%87%e6%a1%a3) 的 17 个接口（其中 `apollo_get_config` 一个工具同时覆盖 3.2.6 与 3.2.9，故工具数为 16、接口数为 17）。

### `apollo_get_config` 参数

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `namespace_name` | 命名空间（配置文件名） | 环境变量 `APOLLO_NAMESPACE` → `application` |
| `key` | 配置项 key；不填返回整个命名空间 | - |
| `env` / `app_id` / `cluster_name` | Apollo OpenAPI 路径参数（接口层必填）；省略回退 `APOLLO_*` 环境变量，未配置用默认 DEV/default/application；`app_id` 无内置默认值，须由参数或 `APOLLO_APP_ID` 提供，否则报错 | 见各 `APOLLO_*` 环境变量 |
| `page` | 分页页码（从 1 开始），**仅对「整个命名空间」生效** | `1` |
| `page_size` | 分页大小，`0` 表示不分页（返回全部）；**仅对「整个命名空间」生效** | `0` |
| `response_format` | 输出格式：`markdown` / `json` | `markdown` |

> 分页为**客户端侧分页**：Apollo OpenAPI 的 `GET namespace` 一次返回全部配置项，
> 本项目在客户端按 `page`/`page_size` 切片，避免大命名空间一次性输出过多内容。指定 `key` 时分页参数被忽略。

> **只读 / 写的区别**：上表「类型 = 只读」的 8 个工具在 `APOLLO_READ_ONLY=true` 下**仍然可用**；
> 「类型 = 写」的 8 个工具（create/update/delete/releases/cluster/namespace/app/rollback）在该模式下会被
> **完全排除**——不出现在 `tools/list` 中，Agent 既看不到也无法调用（注册期排除，非运行期拦截）。
> 这样生产环境开启只读后，Agent 只能查询、绝无意外改配置的风险。
>
> 写入与发布分两步：先用 `apollo_create_item` / `apollo_update_item` / `apollo_delete_item` 落配置项，
> 再用 `apollo_releases` 发布使其对所有客户端生效。写操作均受 `APOLLO_READ_ONLY` 控制。


## 配置

### 环境变量

**MCP 传输与认证**

| 变量 | 说明 | 默认值 |
|------|------|--------|
| `MCP_TRANSPORT` | 传输协议：`stdio` / `sse` / `streamable-http` | `stdio` |
| `MCP_HOST` | HTTP 传输监听地址（stdio 忽略） | `0.0.0.0` |
| `MCP_PORT` | HTTP 传输监听端口（stdio 忽略） | `8000` |
| `MCP_AUTH_TOKEN` | 设置后启用 Bearer Token 认证，保护 HTTP 接口 | -（不鉴权） |
| `MCP_LOG_LEVEL` | 日志级别：`debug`/`info`/`warning`/`error` | `info` |

**Apollo 连接**

| 变量 | 说明 | 默认值 |
|------|------|--------|
| `APOLLO_PORTAL_URL` | Apollo Portal（OpenAPI）地址 | `http://localhost:8070` |
| `APOLLO_TOKEN` | OpenAPI 第三方应用 Token（必填） | - |
| `APOLLO_APP_ID` | 默认应用 ID（未在工具参数中指定时使用） | - |
| `APOLLO_ENV` | 默认环境：`DEV`/`FAT`/`UAT`/`PRO` | `DEV` |
| `APOLLO_CLUSTER` | 默认集群 | `default` |
| `APOLLO_NAMESPACE` | 默认命名空间（配置文件） | `application` |
| `APOLLO_OPERATOR` | 写入/发布时记录的操作人（域账号） | `apollo` |
| `APOLLO_READ_ONLY` | 只读模式，禁用发布功能（适合生产环境） | `false` |

> env / app_id / cluster_name / namespace_name 为 Apollo OpenAPI 路径参数（接口层必填）；本 MCP 工具允许省略，省略时回退对应 `APOLLO_*` 环境变量，其中 env/cluster/namespace 未配置用内置默认 DEV/default/application；`app_id` 无内置默认值，须由参数或 `APOLLO_APP_ID` 提供，否则报错。

### Apollo 概念说明

Apollo 的配置组织层级为：**环境（env）> 应用（app）> 集群（cluster）> 命名空间（namespace）> 配置项（item，key/value）**。

- `properties` 格式的命名空间：每个 key/value 是一个独立配置项。
- 非 `properties` 格式（`yaml`/`json`/`xml`/`txt`）：整份内容存放在固定 key `content` 下。写入时用 `apollo_create_item` 传 `key=content`、整份内容作为 `value`；再调用 `apollo_releases` 发布（已存在则改用 `apollo_update_item`）。

### 只读模式

设置 `APOLLO_READ_ONLY=true` 可禁用发布功能，仅允许查询配置，适合生产环境使用：

```json
{
  "env": {
    "APOLLO_READ_ONLY": "true"
  }
}
```

## 多协议传输

通过 `MCP_TRANSPORT` 选择传输协议：

- **`stdio`（默认）**：标准输入输出，适合 Claude Code、Cursor 等本地 AI 客户端集成。
- **`sse`**：Server-Sent Events，HTTP 传输，端点 `http://<host>:<port>/sse`。
- **`streamable-http`**：Streamable HTTP，端点 `http://<host>:<port>/mcp`。

以 `streamable-http` 启动示例：

```bash
MCP_TRANSPORT=streamable-http \
MCP_HOST=0.0.0.0 MCP_PORT=8000 \
MCP_AUTH_TOKEN=your-strong-token \
mcp-apollo
```

## 接口认证

设置 `MCP_AUTH_TOKEN` 后，所有 HTTP 请求必须携带正确 Token，否则返回 `401`：

```
Authorization: Bearer <MCP_AUTH_TOKEN>
```

也兼容 `X-Auth-Token` / `X-MCP-Token` 请求头。健康检查端点 `GET /health` 免鉴权，返回 `{"status":"ok"}`，用于容器探活。

> `stdio` 传输为本地进程通信，不涉及网络，无需也不会进行 Token 认证。未设置 `MCP_AUTH_TOKEN` 时 HTTP 接口不鉴权，生产环境请务必配置。
>
> 注意区分两类 Token：`MCP_AUTH_TOKEN` 保护本 MCP Server 的 HTTP 接口；`APOLLO_TOKEN` 用于访问 Apollo OpenAPI，两者互不相关。

## 容器化部署

### 本地构建（Docker）

```bash
# 构建镜像
docker build -t mcp-apollo:latest .

# 以 streamable-http 运行并启用认证
docker run -d --name mcp-apollo -p 8000:8000 \
  -e MCP_TRANSPORT=streamable-http \
  -e MCP_AUTH_TOKEN=your-strong-token \
  -e APOLLO_PORTAL_URL=http://your-apollo-portal:8070 \
  -e APOLLO_TOKEN=your-openapi-token \
  -e APOLLO_APP_ID=your-app-id \
  -e APOLLO_ENV=DEV \
  -e APOLLO_CLUSTER=default \
  -e APOLLO_NAMESPACE=application \
  mcp-apollo:latest
```

> 直接拉取已发布的公开镜像、免本地构建的用法见 [快速开始 → Docker](#docker公开镜像免构建)。

### Docker Compose

复制 `.env.example` 为 `.env` 并按需修改，然后：

```bash
cp .env.example .env
docker compose up -d
```

`docker-compose.yml` 已内置 `build`（基于本地 `Dockerfile` 构建并标记为 `mcp-apollo:latest`）和健康检查（探测 `/health`），以非 root 用户运行，适合本地开发部署。

> 若想直接运行已发布的公开镜像、跳过本地构建，可将 `docker-compose.yml` 中的 `build:` 段删除，仅保留 `image: ghcr.io/zhouweico/mcp-apollo:latest`。

## 使用场景示例

配置好后，你可以这样和 AI 对话：

**查询配置：**

```
帮我获取 Apollo 中 application 命名空间的所有配置项
```

```
查看 redis 命名空间里 key 为 timeout 的配置，环境是 PRO
```

```
获取 app-id 为 order-service 的 gateway 命名空间配置，集群是 default
```

```
列出 order-service 在 DEV 环境下的所有 Namespace
```

```
查看 application 命名空间最近一次发布的内容
```

```
分页查看 application 命名空间第 2 页的配置项（每页 50 条）
```

**发布配置：**

```
把 application 命名空间的 timeout 改成 3000 并发布
```

```
在 redis 命名空间新增配置项 max-connections=100，环境 DEV
```

```
把下面这段 yaml 作为 content 发布到 order-service 的 application.yaml 命名空间：
server:
  port: 6379
```

## License

MIT
