nacos-config-mcp
# nacos-config-mcp
一个**只读**的 [Model Context Protocol (MCP)](https://modelcontextprotocol.io) 服务器,用于读取 Nacos 配置中心里的配置,**同时兼容 Nacos 1.x / 2.x / 3.x**。
它把 Nacos 的命名空间、配置检索、配置详情与历史版本能力,通过 6 个只读工具暴露给支持 MCP 的 AI 客户端(Claude Desktop、Cursor、Trae 等),让模型能够安全地查阅你的配置,而**永远无法修改**它们。
## 特性
- **只读**:仅使用 `GET` 请求(`POST` 仅用于登录换取 token),不提供任何发布、更新、删除配置的能力。
- **多版本兼容**:自动探测 Nacos 大版本,并为每个操作准备有序的端点回退链;探测失败时也能通过回退链自愈。
- **双传输**:默认 `stdio`,也可切换为 Streamable HTTP(无状态、可选 Bearer Token 鉴权)。
- **多种鉴权**:匿名、Nacos 用户名/密码(1.x/2.x 的 `/v1/auth/login`、3.x 的 `/v3/auth/user/login`)、预置 access token、以及 server identity 头。
- **TypeScript + Node**:基于官方 `@modelcontextprotocol/sdk`,Node.js ≥ 18.17,零运行时框架依赖。
- **日志走 stderr**:stdout 完全留给 stdio 的 JSON-RPC 通信。
## 版本兼容性
| 能力 | Nacos 1.x | Nacos 2.x | Nacos 3.x |
| --- | --- | --- | --- |
| 登录 | `POST /nacos/v1/auth/login` | 同 1.x | `POST /v3/auth/user/login` |
| 命名空间列表 | `/v1/console/namespaces` | `/v2/console/namespace/list` | `/v3/console/core/namespace/list` |
| 获取配置 | `/v1/cs/configs`(纯文本) | `/v2/cs/config`(JSON) | `/v3/client/cs/config` |
| 搜索/列出配置 | `/v1/cs/configs?search=...` | `/v2/cs/config/list` | `/v3/console/cs/config/list` |
| 历史列表 | `/v1/cs/history` | `/v2/cs/history/list` | `/v3/console/cs/history/list` |
| 版本探测 | `/v1/console/server/state` | 同 1.x | `/v3/console/server/state` |
| 默认命名空间 | `""` | `""` | `"public"` |
> 说明:v3 的 Console API 默认监听独立端口(通常 `8080`)且不带 `/nacos` 前缀,可通过 `NACOS_CONSOLE_URL` / `NACOS_CONSOLE_CONTEXT_PATH` 单独指定。默认命名空间在内部统一归一化为空字符串,`""` 与 `"public"` 均会被接受。
## 安装
```bash
npm install
npm run build
```
构建产物位于 `dist/`,可通过 `npx nacos-config-mcp` 或 `node dist/index.js` 启动。
## 配置项
所有配置均可通过命令行参数或环境变量提供(命令行优先)。
| 命令行 | 环境变量 | 说明 | 默认值 |
| --- | --- | --- | --- |
| `--base-url` | `NACOS_BASE_URL` | Nacos 服务地址,如 `http://127.0.0.1:8848` | 必填 |
| `--context-path` | `NACOS_CONTEXT_PATH` | Server 端上下文路径 | `/nacos` |
| `--console-url` | `NACOS_CONSOLE_URL` | Nacos 3.x Console 地址,如 `http://127.0.0.1:8080` | 与 `NACOS_BASE_URL` 相同 |
| `--console-context-path` | `NACOS_CONSOLE_CONTEXT_PATH` | Console 上下文路径 | 空 |
| `--version` | `NACOS_VERSION` | 强制指定大版本:`auto` \| `1` \| `2` \| `3` | `auto` |
| `--namespace` | `NACOS_NAMESPACE` | 工具未指定命名空间时使用的默认命名空间 | 空(public) |
| `--timeout` | `NACOS_TIMEOUT_MS` | HTTP 超时(毫秒) | `10000` |
| `--tls-insecure` | `NACOS_TLS_INSECURE` | 跳过 TLS 证书校验 | `false` |
| `--auth-type` | `NACOS_AUTH_TYPE` | `none` \| `nacos` \| `bearer` | 有凭据时 `nacos` |
| `--username` | `NACOS_USERNAME` | Nacos 用户名 | — |
| `--password` | `NACOS_PASSWORD` | Nacos 密码 | — |
| `--access-token` | `NACOS_ACCESS_TOKEN` | 预置 access token | — |
| — | `NACOS_SERVER_IDENTITY_KEY` | Server identity 头名称 | — |
| — | `NACOS_SERVER_IDENTITY_VALUE` | Server identity 头取值 | — |
| `--transport` / `--http` | `MCP_TRANSPORT` | `stdio` \| `http` | `stdio` |
| `--host` | `MCP_HTTP_HOST` | HTTP 监听地址 | `127.0.0.1` |
| `--port` | `MCP_HTTP_PORT` | HTTP 监听端口 | `3000` |
| `--http-path` | `MCP_HTTP_PATH` | HTTP 端点路径 | `/mcp` |
| `--http-token` | `MCP_HTTP_TOKEN` | HTTP 请求所需的 Bearer Token | 不校验 |
| `--log-level` | `NACOS_LOG_LEVEL` | `debug` \| `info` \| `warn` \| `error` \| `silent` | `warn` |
## 客户端接入
### stdio(默认)
Claude Desktop / Cursor / Trae 等客户端配置示例:
```json
{
"mcpServers": {
"nacos-config": {
"command": "npx",
"args": ["-y", "nacos-config-mcp"],
"env": {
"NACOS_BASE_URL": "http://127.0.0.1:8848",
"NACOS_USERNAME": "nacos",
"NACOS_PASSWORD": "nacos"
}
}
}
}
```
使用本地构建产物时:
```json
{
"mcpServers": {
"nacos-config": {
"command": "node",
"args": ["/absolute/path/to/nacos-config-mcp/dist/index.js"],
"env": {
"NACOS_BASE_URL": "http://127.0.0.1:8848"
}
}
}
}
```
### Streamable HTTP
```bash
NACOS_BASE_URL=http://127.0.0.1:8848 \
MCP_TRANSPORT=http MCP_HTTP_PORT=3000 MCP_HTTP_TOKEN=secret \
node dist/index.js
```
端点:`http://127.0.0.1:3000/mcp`(无状态模式,仅接受 `POST`)。设置 `MCP_HTTP_TOKEN` 后,请求需携带 `Authorization: Bearer secret`。
## 提供的工具
| 工具 | 说明 | 主要参数 |
| --- | --- | --- |
| `nacos_server_info` | 报告连接信息:探测到的版本、大版本、实际使用的端点、上下文路径与鉴权方式。排查连通性/版本问题时优先调用。 | 无 |
| `nacos_list_namespaces` | 列出命名空间(租户),可按命名空间 ID 过滤。 | `namespaceId?` |
| `nacos_search_configs` | 搜索/分页浏览配置项,支持精确/模糊匹配与分组、应用名、标签、类型过滤。返回分页摘要(不含内容)。 | `dataId?` `group?` `namespaceId?` `search?` `appName?` `configTags?` `type?` `pageNo?` `pageSize?` |
| `nacos_get_config` | 读取单个配置的完整内容与元数据。 | `dataId` `group?` `namespaceId?` |
| `nacos_list_config_history` | 列出配置的历史修订,返回可传给详情工具的修订 ID(`nid`)。 | `dataId` `group?` `namespaceId?` `pageNo?` `pageSize?` |
| `nacos_get_config_history_detail` | 读取某个历史修订的内容与元数据。 | `nid` `dataId` `group?` `namespaceId?` |
所有工具均带有 `readOnlyHint: true`、`destructiveHint: false` 注解,单页最多返回 500 条(`pageSize` 上限)。
## 只读保证
- HTTP 客户端只允许 `GET` 与 `POST` 两种方法([client.ts](src/nacos/client.ts)),`POST` 仅用于登录换取 token。
- 代码中不存在任何发布、更新、删除配置的端点。
- 所有工具均标注为只读。
## 开发
```bash
npm run dev # 以 tsx 直接运行源码
npm run build # 编译到 dist/
npm run typecheck # 类型检查(不产出文件)
npm test # 运行 vitest 单测
```
### 目录结构
```
src/
├── index.ts # CLI 入口:分发 stdio / http
├── server.ts # 组装 HttpClient/Auth/Version/Api 与 McpServer
├── config.ts # 参数与环境变量解析
├── nacos/
│ ├── client.ts # 只读 HTTP 客户端(超时、重试)
│ ├── auth.ts # 登录与 token 缓存
│ ├── version.ts # 大版本探测
│ ├── api.ts # 多版本兼容 API 层 + 解析器
│ └── types.ts # 领域类型
├── tools/ # 6 个 MCP 工具
└── util/ # 错误、日志、文本工具
```
## License
[MIT](LICENSE)
TDQS
Scored across 6 tools
Each tool targets a distinct action: server info, namespace listing, config search, config content retrieval, and history list/detail. The search tool explicitly returns summaries without content and points to get_config, so there is no functional overlap.
All tool names share a consistent nacos_ prefix and mostly follow the verb_noun pattern (list_namespaces, search_configs, get_config, list_config_history). The only deviation is nacos_server_info, which lacks a verb, but this is a minor inconsistency.
Six tools is a well-scoped set for reading Nacos configurations and their history. Each tool has a clear purpose and none feel redundant.
The read-side coverage is solid: namespaces, search, content retrieval, and full history review are all present. However, there are no create, update, delete, publish, or remove operations, leaving the configuration lifecycle incomplete.