# Mse Nacos CLI

> Get or publish Nacos / Alibaba Cloud MSE config by DataId using a small Go CLI. RAM auth from a local JSON keyed by host:port; publish only from a file produced by get then edited. CLI reads flags only (no process env). Needs Go 1.21+ and python3 for helpers. Copy skill dir into your agent's skills root per vendor docs.

- Skill: `migoxlab/mse-nacos-cli` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add migoxlab/mse-nacos-cli`
- Raw SKILL.md: https://api.skillmd.com/api/skills/migoxlab/mse-nacos-cli/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: migoxlab (https://skillmd.com/u/migoxlab)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/migoxlab/mse-nacos-cli

---


# Nacos / MSE 配置读写

本技能提供 **命令行方式** 在 Nacos（含 **阿里云 MSE 托管 Nacos**）上按 **DataId** 拉取或发布配置正文。鉴权为 **RAM AccessKey**，与引擎地址一一对应，可维护多组 endpoint。

**分发与安装**：本 skill 与其它 skill 在本仓库**根目录下并列**；安装到目标机的哪个路径由 **你所用 coding agent 的文档** 决定。索引与拷贝示例见 **[`../README.md`](../README.md)**。下文路径一律 **相对本 skill 根**（含本 `SKILL.md` 的 `mse-nacos-cli/` 目录）。

---

## 适用场景

| 适合 | 不适合 |
|------|--------|
| 读/写单个 DataId 的正文（如 YAML、Properties） | STS、SASL、非 RAM 鉴权 |
| 本机或 CI 用脚本化操作 | 在仓库中存放明文 AK/SK |

---

## 前置条件

- **Go 1.21+**（用于 `go run` 编译运行 CLI）
- **python3**（**`prompt-credentials.sh`** 与 **`sanitize-path-segment.sh`** 需要）
- 具备目标 Nacos 的 **RAM AccessKeyId / SecretAccessKey** 及 **host:port**、**Namespace**、**Group**、**DataId**

---

## 目录与路径（skill 根）

**Skill 根目录**：与本 `SKILL.md` 同级的 `mse-nacos-cli/` 目录（安装到磁盘上的绝对位置由你的环境决定；文档只使用**相对 skill 根**的路径）。

- **`scripts/`**：Go 源码、`go run` 工作目录、`sanitize-path-segment.sh`、本地凭据与工作副本（`nacos-endpoint-aksk.json`、`nacos-edit/` 等）

---

## 凭据：`nacos-endpoint-aksk.json`

### 生成与维护

在 **skill 根**执行：

```bash
bash scripts/prompt-credentials.sh
# 或指定输出路径：
# bash scripts/prompt-credentials.sh /path/to/nacos-endpoint-aksk.json
```

按提示多次录入 **`host:port`**、对应的 **AccessKeyId**、**SecretAccessKey**；**endpoint 留空回车**结束。默认写入 **`scripts/nacos-endpoint-aksk.json`**；可选 **第一个参数** 覆盖输出文件路径。

### JSON 格式

键为 **`host:port`**，须与后续 **`go run` 的 `-addr` 完全一致**（含端口、大小写）。值为：

```json
{
  "mse-xxxx.nacos-ans.mse.aliyuncs.com:8848": {
    "access_key": "LTAI...",
    "secret_key": "..."
  }
}
```

---

## 发布流程（必须遵守）

1. **`get`**：把当前线上配置正文保存到本地文件（见下节推荐路径）。
2. **编辑**：在**该文件内容基础上**修改，保留既有结构与语义，仅做必要变更。
3. **`publish`**：仅使用 **`-content-file`** 指向上述文件；**不支持**内联正文参数。

推荐工作副本路径（相对 `scripts/`、已 `.gitignore`）：

**`nacos-edit/<endpoint_safe>/<namespace_safe>/<group_safe>/<dataId_safe>`**

各段由 **`sanitize-path-segment.sh`** 从原始 **`host:port` / namespaceId / group / dataId** 生成：仅保留 **`[A-Za-z0-9._-]`**，**其余字符一律替换为 `_`**。这样 **`:`、`/`、空格、中文等** 都不会破坏路径，且 **Windows / macOS / Linux** 行为一致。

- **`-addr`、`-namespace`、`-group`、`-data-id` 仍传 Nacos 真实值**（与 `go run` 一致）；仅**本地目录名**做上述替换。凭据 JSON 的 key 仍须是真实 **`host:port`**，与 `-addr` 一致。
- **public 命名空间**：与 **`-namespace ""`** 一致；拼路径时令 **`NS=""`**，再 **`NS_SAFE=$(bash ./sanitize-path-segment.sh "${NS:-public}")`**，避免空目录名。
- 极端情况下两段不同原文可能规范成同一路径（碰撞）；若出现，请人为加长区分字段或改目录约定。

---

## 与「环境变量」无关

- **`main.go` 只解析命令行 flag**，不读取任何进程环境变量。
- 下文示例里的 **`ADDR`、`NS`、`GROUP`、`DATA_ID`** 等仅为 **当前 shell 里手写赋值**（少打字、拼 `EDIT_FILE`），请替换为你的真实值，或改由**你方 CI/包装脚本**把参数展开到命令行。**本技能不介绍、不依赖** `*.env`、`source` 注入、`export` 给 CLI 使用。

---

## `go run` 注意事项

- **不要在 `go run .` 与程序参数之间单独写 `--`**，否则 `flag.Parse` 会把后续参数当作非 flag，导致 `-aksk-file` 等失效。
- 示例统一使用 **单横线**：`-addr`、`-data-id`、`-aksk-file` 等。

---

## 命令行参数（CLI）

| Flag | 必填 | 说明 |
|------|------|------|
| `-addr` | 是 | `host:port`，且须在 `nacos-endpoint-aksk.json` 中存在 |
| `-data-id` | 是 | DataId |
| `-aksk-file` | 是 | 凭据 JSON 路径（相对路径通常写 `./nacos-endpoint-aksk.json`） |
| `-namespace` | 否 | 空表示 public |
| `-group` | 否 | 空则使用 `DEFAULT_GROUP` |
| `-op` | 否 | `get`（默认）或 `publish` |
| `-content-file` | publish 时必填 | UTF-8 文件，须为 **get 落盘后经编辑** 的文件 |

---

## 示例：读取（get）

在 **skill 根**：

```bash
cd scripts
# 按你的环境改成字面量，或由外层脚本赋值（勿依赖 .env 给 CLI）
ADDR='mse-xxxx.nacos-ans.mse.aliyuncs.com:8848'
NS=''                       # public 时保持空；与 -namespace 一致
GROUP='DEFAULT_GROUP'
DATA_ID='app.yaml'

EP_SAFE=$(bash ./sanitize-path-segment.sh "$ADDR")
NS_SAFE=$(bash ./sanitize-path-segment.sh "${NS:-public}")
G_SAFE=$(bash ./sanitize-path-segment.sh "$GROUP")
D_SAFE=$(bash ./sanitize-path-segment.sh "$DATA_ID")
EDIT_FILE="nacos-edit/$EP_SAFE/$NS_SAFE/$G_SAFE/$D_SAFE"
mkdir -p "$(dirname "$EDIT_FILE")"
go run . \
  -addr "$ADDR" \
  -namespace "$NS" \
  -group "$GROUP" \
  -data-id "$DATA_ID" \
  -aksk-file ./nacos-endpoint-aksk.json \
  > "$EDIT_FILE"
```

配置正文写入 **`$EDIT_FILE`**。

---

## 示例：发布（publish）

```bash
cd scripts
ADDR='mse-xxxx.nacos-ans.mse.aliyuncs.com:8848'
NS=''
GROUP='DEFAULT_GROUP'
DATA_ID='app.yaml'

EP_SAFE=$(bash ./sanitize-path-segment.sh "$ADDR")
NS_SAFE=$(bash ./sanitize-path-segment.sh "${NS:-public}")
G_SAFE=$(bash ./sanitize-path-segment.sh "$GROUP")
D_SAFE=$(bash ./sanitize-path-segment.sh "$DATA_ID")
EDIT_FILE="nacos-edit/$EP_SAFE/$NS_SAFE/$G_SAFE/$D_SAFE"
go run . \
  -addr "$ADDR" \
  -namespace "$NS" \
  -group "$GROUP" \
  -data-id "$DATA_ID" \
  -aksk-file ./nacos-endpoint-aksk.json \
  -op publish \
  -content-file "$EDIT_FILE"
```

成功时标准输出一行：`publish ok`。生产环境变更请遵守组织内的发布与审批流程。

---

## 给 Agent 的执行要点

1. 首次或新增 endpoint：在 skill 根运行 **`bash scripts/prompt-credentials.sh`**，由用户在终端输入密钥（勿在聊天中持久保存 AK/SK）。
2. 读配置：在 **`scripts/`** 目录下 **`go run`**，`get` 结果写入 **`nacos-edit/<endpoint_safe>/<namespace_safe>/<group_safe>/<dataId_safe>`**（与 **`-addr` / `-namespace` / `-group` / `-data-id`** 对应：public 时 **`NS_SAFE`** 用 **`${NS:-public}`** 与示例一致；**`-namespace` 仍传空字符串**；与 publish 使用同一 **`EDIT_FILE`** 拼法）。
3. 写配置：只引导用户编辑该文件后使用 **`-op publish -content-file`**；不要建议用命令行拼接整段配置覆盖线上。
4. 始终核对 **`-addr`** 与 JSON 中的键一致。

---

## 安全与参考

- 仅 **RAM 长期密钥** 场景；不涉及 STS。
- 阿里云说明：<https://help.aliyun.com/zh/mse/user-guide/access-authentication-by-nacos>

