{"id":"420d1aa7-b8b6-4ae5-86d7-18aa3298414b","entityType":"agent","slug":"clawhub-areyoubugcoder-mp2rss","name":"mp2rss","canonicalUrl":"https://www.xpersona.co/agent/clawhub-areyoubugcoder-mp2rss","canonicalPath":"/agent/clawhub-areyoubugcoder-mp2rss","generatedAt":"2026-10-11T05:28:29.290Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T03:05:37.224Z","emptyReason":null},"description":"Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。 **当以下情况使用此 Skill**： (1) 用户要订阅 / 取消订阅 / 列出 / 搜索**微信公众号**：「订阅这个公众号 https://mp.weixin.qq.com/s/...」「我订阅了哪些公众号」「列一下我的公众号 RSS」「搜一下我订阅的财经类公众号」「取消订阅那个号」「把 <公众号名> 从订阅里删了」 (2) 用户要查**公众号历史文章**：「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」「<公众号名> 的历史文章」 (3) 用户要操作 **X（Twitter）账号**：「我订阅了哪些 X 账号」「@elonmusk 最近发了啥」「拉一下某个 X 号的推文 / 长文」（注：X 的订阅 / 取消订阅仅在 Web 控制台，CLI 只能列出已订阅与拉内容） (4) 用户要管理**登录态**：「登录公众号 RSS 服务」「登出 mp2rss」「我的 Feed Key 是什么」「我在 mp2rss 里登录了吗」 (5) 用户要**安装 / 配置 Mp2rss CLI**：「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪里」","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.2K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s174daqafqh94pzabz5dsfx16986yz79:mp2rss","sourceUrl":"https://clawhub.ai/areyoubugcoder/mp2rss","homepage":"https://clawhub.ai/areyoubugcoder/skills/mp2rss","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/areyoubugcoder/mp2rss","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/areyoubugcoder/skills/mp2rss","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":61,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"mp2rss technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T03:05:37.224Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T03:05:37.224Z","emptyReason":null},"stars":null,"forks":null,"downloads":1178,"packageName":null,"latestVersion":"0.2.3","tractionLabel":"1.2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T03:05:37.151Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T03:05:37.224Z","lastCrawledAt":"2026-10-11T03:05:37.151Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T03:05:37.151Z","lastVerifiedAt":null,"highlights":[{"version":"0.2.3","createdAt":"2026-10-08T08:02:00.486Z","changelog":"同步 CLI v1.3.0：429 按 Retry-After 退避重试一次（--max-retry-wait / MP2RSS_MAX_RETRY_WAIT，默认 90s），锁定期内不再盲重试；新增跨进程最小请求间隔（MP2RSS_MIN_INTERVAL_MS，默认 1200ms）；错误 envelope 新增 error.kind=rate_limited，references/errors.md 补「被限流」样例","fileCount":11,"zipByteSize":23858},{"version":"0.2.2","createdAt":"2026-08-28T03:56:04.304Z","changelog":"配套 CLI v1.2.0：新增 mp2rss skills sync / status / list（本地 Agent Skills 同步与漂移检测），update 增加 --skip-skills 并在升级后顺带同步；install.md 新增「Agent Skills 同步」一节，SKILL.md 命令总表同步补充（标注 CLI ≥ 1.2.0）。","fileCount":11,"zipByteSize":23126},{"version":"0.2.1","createdAt":"2026-08-28T02:45:58.853Z","changelog":"仓库迁移：skill 源码并入 mp2rss-cli 主仓库（openclaw/mp2rss/ 子目录），mp2rss-openclaw 独立仓库废弃；修正 errors.md 中 HTTP 403/429 的 exit code 映射（实测均为 1，非 3/5）；auth status 文档补充 name/email 字段。","fileCount":11,"zipByteSize":22682},{"version":"0.2.0","createdAt":"2026-05-26T02:57:15.680Z","changelog":"新增 X（Twitter）账号支持：x list / x posts / x articles 三个读类命令与对应 references/x.md；SKILL.md 路由表加入 X 子命令组并明确 X 写类操作仅 Web 控制台；README 重排为 MP / X / 通用三块；消除文档中作占位符的裸 'X' 与 X 平台简称的歧义","fileCount":11,"zipByteSize":22017},{"version":"0.1.1","createdAt":"2026-05-18T08:50:01.319Z","changelog":"Set display name to Mp2rss（0.1.0 首发时未传 --name，被自动派生为 Mp2rss Openclaw）。无功能/内容变更。","fileCount":9,"zipByteSize":15555},{"version":"0.1.0","createdAt":"2026-05-18T08:21:56.636Z","changelog":"Initial release: Mp2rss CLI Skill — 微信公众号转 RSS 订阅与文章管理。单一入口 SKILL.md + references/ 子文档（install / auth / mp / errors）。","fileCount":9,"zipByteSize":15554}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s174daqafqh94pzabz5dsfx16986yz79:mp2rss","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s174daqafqh94pzabz5dsfx16986yz79:mp2rss` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/areyoubugcoder/mp2rss before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T05:28:29.285Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-areyoubugcoder-mp2rss/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T03:05:37.224Z","emptyReason":null},"readme":"Skill: mp2rss\n\nOwner: areyoubugcoder\n\nSummary: Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。 **当以下情况使用此 Skill**： (1) 用户要订阅 / 取消订阅 / 列出 / 搜索**微信公众号**：「订阅这个公众号 https://mp.weixin.qq.com/s/...」「我订阅了哪些公众号」「列一下我的公众号 RSS」「搜一下我订阅的财经类公众号」「取消订阅那个号」「把 <公众号名> 从订阅里删了」 (2) 用户要查**公众号历史文章**：「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」「<公众号名> 的历史文章」 (3) 用户要操作 **X（Twitter）账号**：「我订阅了哪些 X 账号」「@elonmusk 最近发了啥」「拉一下某个 X 号的推文 / 长文」（注：X 的订阅 / 取消订阅仅在 Web 控制台，CLI 只能列出已订阅与拉内容） (4) 用户要管理**登录态**：「登录公众号 RSS 服务」「登出 mp2rss」「我的 Feed Key 是什么」「我在 mp2rss 里登录了吗」 (5) 用户要**安装 / 配置 Mp2rss CLI**：「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪里」\n\nTags: latest:0.2.3\n\nVersion history:\n\nv0.2.3 | 2026-10-08T08:02:00.486Z | user\n\n同步 CLI v1.3.0：429 按 Retry-After 退避重试一次（--max-retry-wait / MP2RSS_MAX_RETRY_WAIT，默认 90s），锁定期内不再盲重试；新增跨进程最小请求间隔（MP2RSS_MIN_INTERVAL_MS，默认 1200ms）；错误 envelope 新增 error.kind=rate_limited，references/errors.md 补「被限流」样例\n\nv0.2.2 | 2026-08-28T03:56:04.304Z | user\n\n配套 CLI v1.2.0：新增 mp2rss skills sync / status / list（本地 Agent Skills 同步与漂移检测），update 增加 --skip-skills 并在升级后顺带同步；install.md 新增「Agent Skills 同步」一节，SKILL.md 命令总表同步补充（标注 CLI ≥ 1.2.0）。\n\nv0.2.1 | 2026-08-28T02:45:58.853Z | user\n\n仓库迁移：skill 源码并入 mp2rss-cli 主仓库（openclaw/mp2rss/ 子目录），mp2rss-openclaw 独立仓库废弃；修正 errors.md 中 HTTP 403/429 的 exit code 映射（实测均为 1，非 3/5）；auth status 文档补充 name/email 字段。\n\nv0.2.0 | 2026-05-26T02:57:15.680Z | user\n\n新增 X（Twitter）账号支持：x list / x posts / x articles 三个读类命令与对应 references/x.md；SKILL.md 路由表加入 X 子命令组并明确 X 写类操作仅 Web 控制台；README 重排为 MP / X / 通用三块；消除文档中作占位符的裸 'X' 与 X 平台简称的歧义\n\nv0.1.1 | 2026-05-18T08:50:01.319Z | user\n\nSet display name to Mp2rss（0.1.0 首发时未传 --name，被自动派生为 Mp2rss Openclaw）。无功能/内容变更。\n\nv0.1.0 | 2026-05-18T08:21:56.636Z | user\n\nInitial release: Mp2rss CLI Skill — 微信公众号转 RSS 订阅与文章管理。单一入口 SKILL.md + references/ 子文档（install / auth / mp / errors）。\n\nArchive index:\n\nArchive v0.2.3: 11 files, 23858 bytes\n\nFiles: LICENSE (909b), package.json (949b), README.md (7450b), references/auth.md (3850b), references/errors.md (6432b), references/install.md (3278b), references/mp.md (5716b), references/x.md (7174b), skill-card.md (2305b), SKILL.md (11856b), _meta.json (125b)\n\nFile v0.2.3:SKILL.md\n\n---\nname: mp2rss\ndescription: |\n  Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。\n\n  **当以下情况使用此 Skill**：\n  (1) 用户要订阅 / 取消订阅 / 列出 / 搜索**微信公众号**：「订阅这个公众号 https://mp.weixin.qq.com/s/...」「我订阅了哪些公众号」「列一下我的公众号 RSS」「搜一下我订阅的财经类公众号」「取消订阅那个号」「把 <公众号名> 从订阅里删了」\n  (2) 用户要查**公众号历史文章**：「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」「<公众号名> 的历史文章」\n  (3) 用户要操作 **X（Twitter）账号**：「我订阅了哪些 X 账号」「@elonmusk 最近发了啥」「拉一下某个 X 号的推文 / 长文」（注：X 的订阅 / 取消订阅仅在 Web 控制台，CLI 只能列出已订阅与拉内容）\n  (4) 用户要管理**登录态**：「登录公众号 RSS 服务」「登出 mp2rss」「我的 Feed Key 是什么」「我在 mp2rss 里登录了吗」\n  (5) 用户要**安装 / 配置 Mp2rss CLI**：「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪里」\nversion: 0.2.3\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - mp2rss\n    envVars:\n      - name: MP2RSS_FEED_KEY\n        required: false\n        description: Mp2rss Feed Key；也可由 `mp2rss auth login` 写入配置文件，二者任一即可。\n      - name: MP2RSS_API_URL\n        required: false\n        description: Mp2rss API URL，默认 https://mp2rss.bugcode.dev。\n    homepage: https://mp2rss.bugcode.dev\n    emoji: \"📡\"\n---\n\n# Mp2rss Skill\n\n通过 Mp2rss CLI（Go 二进制 `mp2rss`）把**微信公众号**与 **X（Twitter）账号**转成 RSS / JSON Feed 并管理订阅。本 skill 是路由入口，按用户意图分发到 `references/` 子文档读取详细命令规格。\n\n> **术语提示**：本文档中 **\"X\"** 一律指 X（原 Twitter）平台；用作\"某个公众号\"占位时统一写作 `<公众号名>` 或具名描述，避免与 X 平台混淆。\n\n## ⚠️ Agent 必读约束\n\n### 🔧 运行时前置\n\n所有命令通过本地 `mp2rss` 二进制调用，**不直接打 HTTP**。Agent 不应自己拼 API 请求，统一走 CLI 子命令 + `-o json` 解析。\n\n**Base URL 由 CLI 自动决定**（命令行 flag > 环境变量 > 配置文件 > 默认 `https://mp2rss.bugcode.dev`）。\n\n### 🔑 凭证与登录态\n\n调用任何 `mp2rss mp` / `mp2rss x` 子命令前，**必须先确认登录态**：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `{\"loggedIn\": false}` 时停止后续调用，引导用户跑 `mp2rss auth login`，详见 [references/auth.md](references/auth.md)。\n\n凭证优先级（高 → 低）：命令行 `--api-key` flag > `MP2RSS_FEED_KEY` 环境变量 > `~/.mp2rss/config.json` 配置文件。\n\n### 🔢 mpId 是 int64 / xUserId 是字符串\n\n两种业务键形态不同，**不要混用**：\n\n- **`mpId`**（公众号）：int64 整数。超出 JavaScript `Number.MAX_SAFE_INTEGER`，Agent 在 JS 环境下解析 `mp list / mp articles -o json` 输出时**始终把 mpId 当字符串处理**：\n\n  ```javascript\n  const safe = text.replace(/\"(mpId)\"\\s*:\\s*(\\d+)/g, '\"$1\":\"$2\"');\n  const data = JSON.parse(safe);\n  ```\n\n- **`xUserId`**（X 账号）：API 契约即为字符串（虽然内容是数字串），原样消费即可，不必转换。\n\nPython / Go / jq 原生支持大整数，无 mpId 精度问题。\n\n### 🚫 反幻觉边界\n\n- **禁止编造 mpId / xUserId**：所有业务键必须来自 `mp list` / `mp search` / `x list` 的响应，不得凭空构造\n- **禁止跳过订阅参数校验**：`mp subscribe <url>` 的 `<url>` **必须**是 `https://mp.weixin.qq.com/s/...` 文章链接；不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时**反问用户索要任意一篇文章链接**，不要直接尝试\n- **禁止伪造执行结果**：不调用 CLI 不得告诉用户「已订阅」「已删除」\n- **禁止忽略 exit code**：CLI 返回非 0 必须解析 stderr / JSON envelope 并报告用户\n- **X 订阅 / 取消订阅必须走 Web 控制台**：CLI 与 API 都不暴露 X 写类端点；用户要订阅 X 账号时**只能引导到 <https://mp2rss.bugcode.dev/>「订阅管理 → X」**，不要尝试构造 CLI 写命令\n\n### 🔄 错误处理\n\nCLI 错误统一 JSON envelope（见 [references/errors.md](references/errors.md)）：\n\n```json\n{\"error\": {\"message\": \"...\", \"code\": <int>}}\n```\n\nExit code 速查：\n\n| Code | 含义 | Agent 处理 |\n|------|------|-----------|\n| 0 | 成功 | 解析 stdout |\n| 1 | 通用错误（网络 / cobra 解析层：缺参、flag 值非法，此类输出裸文本非 JSON / 限流 429 且 envelope `kind: \"rate_limited\"`） | 网络类报告 + 建议稍后重试；解析类修正参数；限流不要立刻重试，转告 message 里的解锁时间 |\n| 2 | 参数错误（业务校验层） | 检查参数；若是 `mp subscribe` 检查 URL 格式 |\n| 3 | 鉴权失败 | 引导跑 `mp2rss auth login`（见 [auth.md](references/auth.md)） |\n| 4 | 资源不存在 | mpId 错 / 文章 URL 失效 / **X 账号未订阅**（典型 message `X account is not subscribed`） |\n| 5 | 上游不可用 | 报告 + 建议稍后重试 |\n\n---\n\n## 执行流程概览\n\n```\n用户意图 → 路由匹配 → 读对应 references/xxx.md → 构造 mp2rss 子命令 → 执行 → 解析 JSON / 验证 exit code → 返回结果\n                                                                                      ↓\n                                                                                  exit ≠ 0 → 按错误码分支处理\n```\n\n**关键原则**\n\n- **CLI 输出是真理**：所有状态以 `mp2rss xxx -o json` 返回为准，不依赖上下文记忆\n- **`-o json` 优先**：批量 / 结构化场景统一加 `-o json`（除 `auth login` 不支持外）\n- **mpId 字符串化**（JS 环境）；xUserId 本身就是字符串\n\n---\n\n## 指令路由表\n\n| 用户意图 / 自然语言 | 角色 | 详细文档 |\n|------|------|---------|\n| 「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪」 | ⚙️ 安装/配置 | [references/install.md](references/install.md) |\n| 「登录」「登出」「我的 Feed Key 是什么」「我登录了吗」 | 🔐 认证 | [references/auth.md](references/auth.md) |\n| 「订阅这个公众号 https://mp.weixin.qq.com/s/...」 | 📡 公众号订阅 | [references/mp.md](references/mp.md#subscribe) |\n| 「我订阅了哪些公众号」「列一下我的公众号 RSS」 | 📋 公众号列表 | [references/mp.md](references/mp.md#list) |\n| 「搜一下我订阅的财经类公众号」 | 🔍 公众号搜索 | [references/mp.md](references/mp.md#search) |\n| 「取消订阅 <公众号名>」「把 <公众号名> 从订阅里删了」 | 🗑️ 公众号取消订阅 | [references/mp.md](references/mp.md#remove) |\n| 「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」 | 📰 公众号文章 | [references/mp.md](references/mp.md#articles) |\n| 「我订阅了哪些 X 账号」「列一下我的 X 订阅」 | 🐦 X 列表 | [references/x.md](references/x.md#list) |\n| 「<X 账号> 最近发了啥」「@xxx 的推文」 | 🐦 X 推文 | [references/x.md](references/x.md#posts) |\n| 「<X 账号> 的长文 / Articles」 | 🐦 X 长文 | [references/x.md](references/x.md#articles) |\n| 「订阅一个 X 账号 / 取消订阅 X」 | 🐦 ⚠️ Web 控制台 | [references/x.md](references/x.md#关键边界x-订阅必须在-web-控制台完成) |\n| 错误码 / JSON envelope / exit code 处理 | 🚨 错误 | [references/errors.md](references/errors.md) |\n\n---\n\n## 自然语言路由（细分 trigger）\n\n```\n包含 mp.weixin.qq.com/s/ URL              → mp subscribe（参数 = 该 URL）\n「订阅」+ 任何 URL 形态                    → 先校验是不是 mp.weixin.qq.com/s/...，否则反问\n「订阅了哪些 公众号」「我的公众号」          → mp list\n「订阅了哪些 X / Twitter 账号」「我的 X 订阅」 → x list\n「搜公众号」「找一下带 关键词 的公众号」      → mp list -q <kw> 或 mp search <kw>\n「取消订阅 <公众号名>」「删了 <公众号名>」    → 先 mp list -q <名> 确认 mpId，再 mp remove <mpId>\n「<公众号名> 最近发的文章 / 历史文章」        → mp articles <mpId>（先列表确认 mpId）\n「@elonmusk 最近的推文」「<X 账号名> 发了啥」  → 先 x list 拿到 xUserId，再 x posts <xUserId>\n「<X 账号名> 的长文 / Articles」              → 先 x list，再 x articles <xUserId>\n「订阅 / 取消订阅一个 X 账号」               → 引导用户去 Web 控制台「订阅管理 → X」，不要走 CLI\n「登录」「授权」                            → auth login（参考 auth.md 选三种登录模式之一）\n「我的 Key」「登录了吗」「状态」              → auth status -o json\n「登出」「退出登录」                         → auth logout\n```\n\n**决策原则**：\n\n- 有 `mp.weixin.qq.com/s/` URL → 直接 `mp subscribe`\n- 用户给的是**公众号名而非 URL** → **反问索要文章 URL**，不要先 `mp search`（搜索是用于在已订阅源里找，不会订阅新号）\n- 取消订阅公众号前**先用 `mp list -q` / `mp search` 拿到准确 mpId**，避免误删\n- 用户给 X 账号是 `@handle` 或显示名 → **先 `x list -o json` 找 xUserId**，不要把 handle 直接传给 `x posts / x articles`\n- 用户想**添加** X 订阅 → **不要尝试 CLI**，直接引导 <https://mp2rss.bugcode.dev/>「订阅管理 → X」\n\n---\n\n## API 路由（CLI 子命令总表）\n\n| 子命令 | 用途 | 详细文档 |\n|--------|------|---------|\n| `mp2rss auth login [-k <key>] [--no-browser]` | 登录（三种模式） | [auth.md](references/auth.md#log-in) |\n| `mp2rss auth status [-o json]` | 查询登录态 | [auth.md](references/auth.md#check-status) |\n| `mp2rss auth logout` | 登出 | [auth.md](references/auth.md#log-out) |\n| `mp2rss mp subscribe <article-url> [-o json]` | 订阅公众号 | [mp.md](references/mp.md#subscribe) |\n| `mp2rss mp list [-q <kw>] [-p <page>] [--page-size <n>] [-o json]` | 列出公众号订阅 | [mp.md](references/mp.md#list) |\n| `mp2rss mp search <keyword> [-o json]` | 搜索已订阅公众号 | [mp.md](references/mp.md#search) |\n| `mp2rss mp remove <mpId> [-y] [-o json]` | 取消订阅公众号 | [mp.md](references/mp.md#remove) |\n| `mp2rss mp articles <mpId> [-p <page>] [--page-size <n>] [-o json]` | 查公众号文章 | [mp.md](references/mp.md#articles) |\n| `mp2rss x list [-q <kw>] [-p <page>] [--page-size <n>] [-o json]` | 列出已订阅 X 账号 | [x.md](references/x.md#list) |\n| `mp2rss x posts <xUserId> [-p <page>] [--page-size <n>] [-o json]` | 拉 X 推文流 | [x.md](references/x.md#posts) |\n| `mp2rss x articles <xUserId> [-p <page>] [--page-size <n>] [-o json]` | 拉 X 长文流 | [x.md](references/x.md#articles) |\n| `mp2rss update [--check] [--skip-skills]` | 升级 CLI | [install.md](references/install.md#升级) |\n| `mp2rss skills sync [--global] / status / list` | 同步 / 查看 Agent Skills（CLI ≥ 1.2.0） | [install.md](references/install.md#agent-skills-同步cli--120) |\n\n> X 写类（搜索 / 订阅 / 取消订阅）**不存在对应 CLI 命令**，仅 Web 控制台提供，详见 [x.md](references/x.md#关键边界x-订阅必须在-web-控制台完成)。\n\n---\n\n## 全局 flag\n\n所有子命令都支持：\n\n| Flag | 等价环境变量 | 说明 |\n|------|-------------|------|\n| `-o, --output <table\\|json>` | — | 输出格式，默认 `table` |\n| `--api-key <feed-key>` | `MP2RSS_FEED_KEY` | 覆盖 Feed Key |\n| `--api-url <url>` | `MP2RSS_API_URL` | 覆盖 API 地址 |\n\n优先级（高 → 低）：CLI flag > env > 配置文件 > 默认。\n\nFile v0.2.3:README.md\n\n# Mp2rss Skill\n\n[![License: MIT-0](https://img.shields.io/badge/License-MIT--0-blue.svg)](https://opensource.org/licenses/MIT-0)\n\n让 AI Agent 帮你管理 **微信公众号** 与 **X（Twitter）账号** 的 RSS 订阅 —— 一句话订阅、自然语言查找、按需读历史文章 / 推文 / 长文。\n\n本目录是 [Mp2rss](https://mp2rss.bugcode.dev) 服务的 OpenClaw Agent Skill 包，随 [`mp2rss` CLI](https://github.com/areyoubugcoder/mp2rss-cli) 同仓库维护（`openclaw/mp2rss/` 子目录），发布到 ClawHub（slug：`mp2rss`）。Claude Code 用户请改用仓库根的 `skills/`（插件市场 / `npx skills add` 安装），见主仓库 README。\n\n---\n\n## ✨ 核心能力\n\n### 微信公众号（MP）\n\n| 能力 | 说明 |\n|------|------|\n| 📡 **一键订阅** | 发一个公众号文章链接（`mp.weixin.qq.com/s/...`），Agent 自动把整个公众号订阅到你的 Feed |\n| 📋 **列表与搜索** | 「我订阅了哪些公众号」「搜一下我订阅的财经类公众号」 |\n| 🗑️ **取消订阅** | 「把 某号 从订阅里删了」，Agent 先核对 mpId 再删 |\n| 📰 **历史文章** | 「某号 最近发了什么」/「拉一下 某号 的文章」 |\n\n### X（Twitter）账号\n\n| 能力 | 说明 |\n|------|------|\n| 🐦 **列出 X 订阅** | 「我订阅了哪些 X 账号」 |\n| 📨 **推文流** | 「@elonmusk 最近发了啥」（Agent 先 `x list` 找到 `xUserId` 再拉推文） |\n| 📝 **长文流** | 「拉一下 某 X 账号的 Articles」 |\n| ⚠️ **订阅 / 取消订阅 X 账号** | **仅在 Web 控制台**（<https://mp2rss.bugcode.dev/>）—— CLI 与 API 都不暴露 X 写类端点，Agent 会引导你去控制台 |\n\n### 通用\n\n| 能力 | 说明 |\n|------|------|\n| 🔐 **登录态管理** | 「我的 Feed Key 是什么」「登录 mp2rss」 |\n| 📤 **结构化输出** | 所有命令支持 `-o json`，Agent 可直接解析做后续处理 |\n\n---\n\n## 💡 使用场景\n\n### 通勤路上看到好公众号\n\n> 👤 订阅这个公众号 https://mp.weixin.qq.com/s/abc123xyz\n>\n> 🤖 已订阅「某公众号」到你的 Feed。\n\n### 不记得订过哪些号\n\n> 👤 我订阅了哪些公众号？\n>\n> 🤖 当前共 42 个订阅。前 20 个：某公众号（最近发文 2 小时前）、另一个号（昨天）……\n\n### 找特定主题\n\n> 👤 我订阅的财经类公众号有哪些\n>\n> 🤖 找到 5 个匹配：财经早知道、第一财经……\n\n### 翻看历史\n\n> 👤 财经早知道 最近发了什么\n>\n> 🤖 最近 10 篇文章：1. xxx 标题（昨天）2. xxx 标题（前天）……\n\n### 不想看了\n\n> 👤 把 财经早知道 从订阅里删了\n>\n> 🤖 确认删除「财经早知道」（mpId 123456）？已删除 ✓\n\n### 看大 V 推文\n\n> 👤 @elonmusk 最近发了啥？\n>\n> 🤖 （先 `x list` 拿到 xUserId 44196397）最近 5 条推文：1. ……\n\n### 想订阅一个 X 账号\n\n> 👤 帮我订阅 @paulg 这个号\n>\n> 🤖 X 账号的订阅 / 取消订阅只能在 Web 控制台操作。打开 https://mp2rss.bugcode.dev/「订阅管理 → X」搜索 paulg 完成订阅；订阅好我就能用 `mp2rss x posts/articles` 帮你拉内容。\n\n---\n\n## 📦 安装\n\n### 前置：装 Mp2rss CLI 二进制\n\nskill 本身只描述如何调用 CLI，所以必须先装 `mp2rss` 二进制（任选其一）：\n\n```bash\n# 方式 A：npm（推荐，跨平台一致）\npnpm add -g @mp2rss/cli\n\n# 方式 B：macOS / Linux 一键脚本\ncurl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh\n```\n\n也可在 [Releases](https://github.com/areyoubugcoder/mp2rss-cli/releases/latest) 下载对应平台二进制。\n\n### 装 Skill\n\n```bash\n# 方式 A：通过 ClawHub（推荐）\nopenclaw skills install mp2rss\n\n# 方式 B：手动\nmkdir -p ~/.openclaw/workspace/skills/mp2rss\ncd ~/.openclaw/workspace/skills/mp2rss\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/openclaw/mp2rss/SKILL.md -o SKILL.md\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/openclaw/mp2rss/package.json -o package.json\n# 视需要再拉 references/ 子文档\n```\n\n---\n\n## 🔑 授权登录\n\n安装完成后说「登录 mp2rss」，Agent 自动跑 `mp2rss auth login` 走浏览器 loopback 授权。CI / 无头环境用：\n\n```bash\nmp2rss auth login -k <feed-key>            # 直传\nmp2rss auth login --no-browser             # 远程模式，仅打印授权 URL\n```\n\nFeed Key 可在 <https://mp2rss.bugcode.dev/> 登录后查看或重置。配置文件位置 `~/.mp2rss/config.json`。\n\n### 用环境变量配置（可选）\n\n```bash\nexport MP2RSS_FEED_KEY=gk_live_xxxxxxxx\nexport MP2RSS_API_URL=https://mp2rss.bugcode.dev    # 自托管时需要\n```\n\n优先级（高 → 低）：CLI flag `--api-key` > `MP2RSS_FEED_KEY` env > `~/.mp2rss/config.json`。\n\n---\n\n## 🛠 子命令速查\n\n### 通用\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss auth login [-k <key>] [--no-browser]` | 登录（三种模式：浏览器 / Feed Key 直传 / 远程） |\n| `mp2rss auth status [-o json]` | 查登录态、Feed Key 来源、最近登录时间 |\n| `mp2rss auth logout` | 清空 Feed Key |\n\n### 微信公众号\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss mp subscribe <article-url> [-o json]` | 订阅；参数必须是 `mp.weixin.qq.com/s/...` 文章 URL |\n| `mp2rss mp list [-q <kw>] [-p <page>] [--page-size <n>]` | 列出公众号订阅 |\n| `mp2rss mp search <keyword>` | `mp list -q` 语法糖 |\n| `mp2rss mp remove <mpId> [-y]` | 取消订阅公众号 |\n| `mp2rss mp articles <mpId> [-p <page>] [--page-size <n>]` | 查公众号历史文章 |\n\n### X（Twitter）\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss x list [-q <kw>] [-p <page>] [--page-size <n>]` | 列出已订阅的 X 账号 |\n| `mp2rss x posts <xUserId> [-p <page>] [--page-size <n>]` | 拉 X 账号推文流 |\n| `mp2rss x articles <xUserId> [-p <page>] [--page-size <n>]` | 拉 X 账号长文流 |\n\n> X 账号**搜索 / 订阅 / 取消订阅**仅 Web 控制台支持，CLI 与 Open API 都不暴露这些写类端点。\n\n完整字段、JSON shape 与 Agent 行为规范见 [SKILL.md](SKILL.md) 和 [references/](references/) 子文档。\n\n---\n\n## ⚠️ 重要约束\n\n- **订阅公众号传的是文章 URL** —— 不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时 Agent 应反问用户索要任意一篇文章链接\n- **`mpId` 是 int64** —— JS 环境解析 JSON 时需先把 `mpId` 替换为字符串再 `JSON.parse`，否则精度丢失\n- **`xUserId` 是字符串** —— 虽然内容是数字串，API 契约即字符串形态，无需转换；注意不要传 `@handle`\n- **取消订阅公众号前先核对 mpId** —— 用 `mp list -q` / `mp search` 拿到准确 mpId 再删，避免误删\n- **X 写类操作不可达** —— 用户要订阅 / 取消订阅 X 账号时，Agent 必须引导到 Web 控制台「订阅管理 → X」，不要尝试构造 CLI 命令\n- **`auth login` 不支持 `-o json`** —— 仅输出文本反馈，其它子命令均支持\n\n---\n\n## 🔗 相关\n\n- [Mp2rss 服务](https://mp2rss.bugcode.dev) —— 微信公众号 / X 账号 RSS 订阅服务\n- [`mp2rss` CLI](https://github.com/areyoubugcoder/mp2rss-cli) —— Go 命令行客户端（Skill 调用的底层）\n- [Mp2rss 文档站](https://areyoubugcoder.github.io/Mp2RSS/) —— 服务介绍、Open API 与 CLI 完整文档\n\n---\n\n## License\n\n[MIT-0](LICENSE)\n\nFile v0.2.3:_meta.json\n\n{\n  \"ownerId\": \"kn7acxx408jk3phdk3326sx5fs86zndf\",\n  \"slug\": \"mp2rss\",\n  \"version\": \"0.2.3\",\n  \"publishedAt\": 1791446520486\n}\n\nFile v0.2.3:references/auth.md\n\n# 认证管理\n\n本文档供 Agent 在用户询问「登录」「登出」「我的 Feed Key 是什么」「我登录了吗」「在 mp2rss 里登录」时按需读取。\n\n## 触发条件\n\n调用任何 `mp2rss mp` 子命令前，**必须先**确认登录态：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `loggedIn: false` 时停止后续 mp 调用，引导用户登录后再继续原始请求。\n\n## Log in\n\n```\nmp2rss auth login [-k <feed-key>] [--no-browser]\n```\n\n三种模式：\n\n| 模式 | 命令 | 适用场景 |\n|------|------|---------|\n| 浏览器（默认） | `mp2rss auth login` | 桌面环境；CLI 启动本地 loopback HTTP 服务，打开浏览器登录后回调写入 `~/.mp2rss/config.json` |\n| Feed Key 直传 | `mp2rss auth login -k <feed-key>` | CI / 无头环境；Feed Key 在 https://mp2rss.bugcode.dev/ 登录后获取或重置 |\n| 远程模式 | `mp2rss auth login --no-browser` | 远程 SSH / 无浏览器；CLI 仅打印授权 URL，用户在本地浏览器打开后复制 Feed Key 回填 |\n\n```bash\nmp2rss auth login                          # 默认浏览器\nmp2rss auth login -k gk_live_xxxxxxxx      # 直传\nmp2rss auth login --no-browser             # 远程\n```\n\n### Agent 处理远程模式\n\n`mp2rss auth login --no-browser` 输出形如：\n\n```\n请在浏览器打开下面的链接完成授权：\n\n  https://mp2rss.bugcode.dev/auth/cli?code=...\n\n授权后将页面上显示的 Feed Key 粘贴到此终端：\n```\n\nAgent 应：\n\n1. **完整提取授权 URL** 转发给用户\n2. 提示「请在浏览器打开此链接，登录后把页面上的 Feed Key 粘贴回这里」\n3. 不要替用户决定使用哪个浏览器；不要把 URL 截断或缩短\n\n⚠️ `auth login` **不支持 `-o json`**，输出为纯文本反馈。\n\n## Check status\n\n```\nmp2rss auth status [-o json]\n```\n\n```bash\nmp2rss auth status            # 人类可读\nmp2rss auth status -o json    # Agent 解析\n```\n\n### JSON shape（已登录）\n\n```json\n{\n  \"loggedIn\": true,\n  \"source\": \"config\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\",\n  \"feedKeyMasked\": \"abcdef***\",\n  \"name\": \"张三\",\n  \"email\": \"user@example.com\",\n  \"lastLoginAt\": 1705000000000,\n  \"lastVerifyAt\": 1705000001000\n}\n```\n\n### JSON shape（未登录）\n\n```json\n{\n  \"loggedIn\": false,\n  \"source\": \"none\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\"\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `loggedIn` | bool | 是否已配置可用凭证 |\n| `source` | string | `\"env\"` / `\"config\"` / `\"none\"` |\n| `apiUrl` | string | 当前生效的 API URL |\n| `feedKeyMasked` | string | 已脱敏 Feed Key（仅前几位 + `***`） |\n| `name` | string? | 账号昵称；仅浏览器登录回调成功时落盘，`-k` / `--no-browser` 流程没有，`omitempty` 省略 |\n| `email` | string? | 账号邮箱；同 `name`，仅浏览器登录流程有 |\n| `lastLoginAt` | int64 | 最近登录时间，unix 毫秒 |\n| `lastVerifyAt` | int64 | 最近一次验证时间，unix 毫秒 |\n\n## Log out\n\n```\nmp2rss auth logout\n```\n\n清空 `~/.mp2rss/config.json` 里的 `feed_key`，保留 `api_url` 等其它配置。\n\n```bash\nmp2rss auth logout\n```\n\n## 凭证优先级\n\n高 → 低：\n\n1. CLI flag：`--api-key <feed-key>`\n2. 环境变量：`MP2RSS_FEED_KEY`\n3. 配置文件：`~/.mp2rss/config.json` 的 `feed_key`\n\nAPI URL 同理：`--api-url` > `MP2RSS_API_URL` > 配置文件 > 默认 `https://mp2rss.bugcode.dev`。\n\n## Agent 注意事项\n\n- 调用 `mp2rss mp` 任何子命令前先 `mp2rss auth status -o json`\n- 时间字段是 unix 毫秒（int64），不是格式化字符串\n- 不要直接读写 `~/.mp2rss/config.json`，统一用 `mp2rss auth ...` 子命令\n- 鉴权错误（exit code 3 / HTTP 401）时引导用户跑 `mp2rss auth login`，不要反复重试\n- `feedKeyMasked` 仅供展示用户身份，**不要试图从掩码还原完整 Key**\n\nFile v0.2.3:references/errors.md\n\n# 错误处理\n\n本文档供 Agent 在 mp2rss 命令返回非零 exit code 或 JSON envelope 含 `error` 字段时按需读取。\n\n## JSON 错误 envelope\n\n任何子命令在 `-o json` 模式下出错时统一返回：\n\n```json\n{\n  \"error\": {\n    \"message\": \"human-readable 错误信息\",\n    \"code\": <int>,\n    \"kind\": \"rate_limited\"\n  }\n}\n```\n\n- `code` 字段是 HTTP 状态码（来自上游 API）或 CLI 自身 exit code\n- `message` 是人类可读描述（中文），可直接转发给用户\n- `kind` 可选，仅在需要特殊处理时出现；目前只有 `rate_limited`（被限流且 CLI 已放弃等待）。没有该字段 = 普通错误\n\n> ⚠️ 例外（实测 CLI 1.1.0）：**cobra 参数解析层**的错误（必填位置参数缺失、flag 值类型非法如 `--page-size abc`）以 exit 1 退出，且**即使带 `-o json` 也输出裸文本到 stderr**，不是 JSON envelope。Agent 解析 JSON 失败时应回退读 stderr 文本。\n\n## Exit codes\n\n| Code | 含义 | 典型场景 | Agent 处理 |\n|------|------|---------|-----------|\n| `0` | 成功 | 命令正常执行 | 解析 stdout |\n| `1` | 通用错误（网络）/ 解析层错误 / **限流** | DNS 失败 / TCP 连不上 / 超时；**必填参数缺失、flag 值非法**（cobra 解析层，裸文本 stderr）；HTTP 429 且 `kind: \"rate_limited\"` | 网络类：报告 + 建议稍后重试；解析类：修正命令参数后重试一次；限流：**不要立刻重试**，把 message 里的解锁时间告诉用户 |\n| `2` | 参数错误（业务校验层） | `mp subscribe` URL 不是 `mp.weixin.qq.com/s/...` / 位置参数格式非法（如 mpId 非数字） | 解析 envelope 给用户具体提示；URL 错就反问用户索要正确文章链接 |\n| `3` | 鉴权失败 | Feed Key 错 / 过期 / 未配置 / HTTP 401 | 引导用户跑 `mp2rss auth login`（见 [auth.md](auth.md)）；**不要反复重试** |\n| `4` | 资源不存在 | mpId 错 / 文章 URL 失效 / **xUserId 未订阅**（X 读类端点要求已订阅）/ HTTP 404 | MP：用 `mp list` 重新核对 mpId 或更换文章链接；X：先 `x list` 确认是否已订阅，未订阅的话引导用户去 Web 控制台「订阅管理 → X」 |\n| `5` | 上游不可用 | API 服务挂 / HTTP 5xx | 报告 + 建议稍后重试 |\n\n## HTTP code 对应\n\nCLI 把上游 HTTP 状态码映射到上面的 exit codes：\n\n| HTTP | Exit | 说明 |\n|------|------|------|\n| 200 | 0 | OK |\n| 400 | 2 | 请求参数错 |\n| 401 | 3 | Feed Key 无效 |\n| 403 | 1 | 权限不足（CLI 未特判 403，落到通用错误；message 会带上游原文） |\n| 404 | 4 | 资源不存在 |\n| 429 | 1 | 限流（每个 Feed Key 60 次/分钟，超限锁 10 分钟）。CLI 按响应 `Retry-After` 等待后**重试一次**；等待时长超过 `--max-retry-wait`（默认 90s）或重试仍 429 → 立即返回，envelope 带 `\"kind\":\"rate_limited\"`，message 含预计解锁时间（本地时间）。另外 CLI 在同一台机器上自动把相邻请求间隔拉到 ≥ 1.2s（`MP2RSS_MIN_INTERVAL_MS`） |\n| 5xx | 5 | 上游错误（CLI 自动退避重试 1 次，即最多发 2 次请求） |\n\n## Agent 处理策略\n\n### 失败重试\n\n| 错误类型 | 重试策略 |\n|---------|---------|\n| Exit 1（网络） | 等待 5 秒后**最多重试一次**；二次失败明确报告网络问题 |\n| Exit 1（解析层：缺参 / flag 值非法） | **不要原样重试**；按 stderr 提示修正命令参数后再执行 |\n| Exit 1 + `kind: \"rate_limited\"`（限流） | **不要立刻重试**；message 里有预计解锁时间，告诉用户并等到那之后再跑；批量任务改为串行 + 每次间隔 ≥ 1.2s |\n| Exit 3（鉴权） | **不要重试**；直接引导 `mp2rss auth login` |\n| Exit 4（不存在） | **不要重试**；引导用户核对 mpId / URL |\n| Exit 5（上游 5xx） | 等待 5 秒后**最多重试一次**；二次失败建议稍后再试 |\n| Exit 2（参数） | **不要重试**；告诉用户具体是哪个参数错了 |\n\n### 错误信息提取\n\n人类可读模式（无 `-o json`）下，错误写到 stderr，Agent 应捕获 stderr 转发给用户。\n\nJSON 模式下，错误 envelope 写到 stdout（保持单一输出流），Agent 解析 `error.message` 和 `error.code` 字段。\n\n### 反幻觉\n\n- **禁止编造错误信息**：所有报告给用户的错误必须来自 CLI 真实输出（stderr 或 JSON envelope）\n- **禁止隐瞒错误**：CLI 返回非零退出码时必须告诉用户，不能装作执行成功\n- **禁止过度解读 message**：`error.message` 直接转发，不要\"翻译\"成自己的描述（容易扭曲原意）\n\n## 常见错误样例\n\n### Feed Key 失效\n\n```bash\n$ mp2rss mp list -o json\n{\"error\":{\"message\":\"鉴权失败：Feed Key 无效或已重置，请重新登录\",\"code\":401}}\n$ echo $?\n3\n```\n\nAgent → 引导 `mp2rss auth login` 而非重试。\n\n### URL 格式错\n\n```bash\n$ mp2rss mp subscribe https://example.com/article -o json\n{\"error\":{\"message\":\"参数错误：subscribe 需要 mp.weixin.qq.com/s/... 文章链接\",\"code\":400}}\n$ echo $?\n2\n```\n\nAgent → 告诉用户必须用微信公众号文章 URL，并反问索要正确链接。\n\n### mpId 不存在\n\n```bash\n$ mp2rss mp articles 999999999 -o json\n{\"error\":{\"message\":\"未找到（HTTP 404）：MP account is not subscribed\",\"code\":404}}\n$ echo $?\n4\n```\n\nAgent → 用 `mp list` 核对正确 mpId。\n\n### 被限流\n\n```bash\n$ mp2rss mp articles 2392014380 -o json\n{\"error\":{\"message\":\"请求被限流（HTTP 429）：Rate limit exceeded; retry after the Retry-After header。预计 22:10:52（本地时间，约 9m50s 后）解除，超过 --max-retry-wait（1m30s）未自动等待。服务端限制每分钟 60 次请求；请减少并发、串行调用并加大请求间隔后再试\",\"code\":429,\"kind\":\"rate_limited\"}}\n$ echo $?\n1\n```\n\nAgent → 不要重试；把解锁时间转告用户。若用户在跑批量脚本，提示改为串行、每次间隔 ≥ 1.2s（CLI 默认已自动间隔，并发多开才会撞）。\n\n### X 账号未订阅\n\n```bash\n$ mp2rss x posts 999999999 -o json\n{\"error\":{\"message\":\"X account is not subscribed\",\"code\":404}}\n$ echo $?\n4\n```\n\nAgent → 提示用户：`mp2rss x posts / x articles` **只能查已订阅 X 账号**；订阅 X 账号必须去 Web 控制台「订阅管理 → X」操作（CLI 与 API 都不暴露 X 写类端点）。先 `mp2rss x list` 看一下是否已订阅 / `xUserId` 是否抄错。\n\nFile v0.2.3:references/install.md\n\n# 安装与升级\n\n本文档供 Agent 在用户询问「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪」时按需读取。\n\n## 环境要求\n\n- macOS / Linux / Windows 任一\n- Node.js ≥ 18（仅 npm 安装方式需要）\n- Go ≥ 1.21（仅从源码构建需要）\n\n## 安装方式\n\n任选其一：\n\n### A. npm（推荐，跨平台一致）\n\n```bash\npnpm add -g @mp2rss/cli\n# 或 npm install -g @mp2rss/cli\n```\n\n`postinstall` 脚本会按平台自动下载对应的 Go 二进制，绑定为全局 `mp2rss` 命令。\n\n### B. 一键脚本（macOS / Linux）\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh\n```\n\n自动选 macOS / Linux 对应平台二进制，安装到 `/usr/local/bin` 或 `~/.local/bin`。\n\n### C. 直接下载 Release 二进制\n\n打开 <https://github.com/areyoubugcoder/mp2rss-cli/releases/latest> 选对应平台的归档下载，解压后把 `mp2rss` 加入 `PATH`。\n\n可用平台：\n\n| OS | amd64 | arm64 |\n|----|:---:|:---:|\n| macOS | ✅ | ✅ |\n| Linux | ✅ | ✅ |\n| Windows | ✅ | ✅ |\n\n## 验证安装\n\n```bash\nmp2rss --version\n```\n\n预期输出版本号字符串（如 `mp2rss v0.x.x`），exit 0。\n\n## 升级\n\n```bash\nmp2rss update                   # 检查并升级到最新\nmp2rss update --check           # 只检查不升级\nmp2rss update --skip-skills     # 升级但本次不同步本地 Agent Skills\n```\n\n`update` 会从 GitHub Releases 拉最新版二进制就地替换。注意：通过 npm 安装的二进制由 npm 管理，建议改用 `pnpm up -g @mp2rss/cli`。\n\n## Agent Skills 同步（CLI ≥ 1.2.0）\n\nCLI 自更新只替换二进制，本地已安装的 Agent Skills 不会自动跟着升级。CLI ≥ 1.2.0 内置同步命令（旧版本无此命令，继续用 `npx -y skills add areyoubugcoder/mp2rss-cli -y`）：\n\n```bash\nmp2rss skills sync              # 同步到当前项目 ./.agents/skills\nmp2rss skills sync --global     # 同步到全局 ~/.claude/skills\nmp2rss skills status [-o json]  # 本地 skills 版本 vs CLI 版本，是否漂移\nmp2rss skills list [-o json]    # 列出仓库提供的 skills\n```\n\n- 通过 `skills sync` 装过之后，`mp2rss update` 升级二进制时会**顺带同步** skills 到新版本（`--skip-skills` 跳过）；从未 sync 过则只提示不执行。\n- 同步状态记录在 `~/.mp2rss/skills-state.json`（0600）。\n- 底层执行 `npx -y skills add areyoubugcoder/mp2rss-cli -y`，需要 Node.js（npx）。\n\n## 配置文件位置\n\n`~/.mp2rss/config.json`（目录权限 `0700` / 文件权限 `0600`），结构：\n\n```json\n{\n  \"feed_key\": \"9f3a2c...（64 位 hex）\",\n  \"api_url\": \"https://mp2rss.bugcode.dev\",\n  \"last_login_at\": 1747194198000,\n  \"last_verify_at\": 1747194198000\n}\n```\n\n- 由 `mp2rss auth login` 自动写入\n- `mp2rss auth logout` 只清 `feed_key`，保留 `api_url` 等其它字段\n- Agent **不应该**直接读写此文件，统一用 `mp2rss auth ...` 子命令\n\n## Agent 注意事项\n\n- 用户问\"装好了吗\"→ `mp2rss --version`，exit 0 即装好\n- 用户问\"配置在哪\"→ 答 `~/.mp2rss/config.json` + 强调不要手改，用 `mp2rss auth login` 管理\n- 用户问\"怎么升级\"→ 给 `mp2rss update`；若用户是 npm 装的优先建议 `pnpm up -g @mp2rss/cli`\n\nFile v0.2.3:references/mp.md\n\n# 微信公众号（MP）订阅与文章管理\n\n本文档供 Agent 在用户询问**公众号**订阅、列出、搜索、取消订阅、查文章等需求时按需读取。\n\n**调用前提**：先确认登录态（见 [auth.md](auth.md)）；未登录时不要直接调本节命令。\n\n> 本文档中所有用作\"某个公众号\"占位的地方一律写作 `<公众号名>` 或具名形式（如「财经早知道」），避免歧义。\n\n---\n\n## Subscribe\n\n```\nmp2rss mp subscribe <article-url> [-o json]\n```\n\n订阅一个公众号。⚠️ **传入的是文章 URL**（`https://mp.weixin.qq.com/s/...`），不是公众号名、不是二维码、不是公众号主页链接。从公众号任意一篇文章里复制链接即可，Mp2rss 会从该文章解析出所属公众号并把整个公众号订阅到你的 Feed。\n\n```bash\nmp2rss mp subscribe https://mp.weixin.qq.com/s/abcDEFghIJKlmnop\nmp2rss mp subscribe https://mp.weixin.qq.com/s/abc -o json\n```\n\n### JSON shape\n\n```json\n{\n  \"ok\": true,\n  \"articleUrl\": \"https://mp.weixin.qq.com/s/...\"\n}\n```\n\n### Agent 处理\n\n- 用户给的不是 `mp.weixin.qq.com/s/...` URL → **反问**索要任意一篇文章链接，不要直接试\n- 用户给的是公众号名 → 不能搜索 + 订阅，必须用户提供文章 URL\n- 订阅成功后建议跟一句 `mp list -q <推断的公众号名>` 让用户看到刚订阅的条目（可选）\n\n---\n\n## List\n\n```\nmp2rss mp list [-q <keyword>] [-p <page>] [--page-size <n>] [-o json]\n```\n\n列出当前 Feed Key 名下的所有订阅。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-q, --query` | — | 按公众号名模糊搜索（与 `mp search` 等价） |\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（最大 50） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss mp list\nmp2rss mp list -q 财经\nmp2rss mp list -p 2 --page-size 50\nmp2rss mp list -o json | jq '.items[].mpName'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"mpId\": 123456,\n      \"mpName\": \"某公众号\",\n      \"mpAvatarUrl\": \"https://...\",\n      \"createdAt\": 1705000000000,\n      \"mpLastArticleAt\": 1705000050000\n    }\n  ],\n  \"total\": 42,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n⚠️ **`mpId` 是 int64**，JS 环境解析前先正则替换为字符串（见 [SKILL.md - mpId 是 int64](../SKILL.md#-mpid-是-int64) 段）。\n\n---\n\n## Search\n\n```\nmp2rss mp search <keyword> [-p <page>] [--page-size <n>] [-o json]\n```\n\n`mp2rss mp list -q <keyword>` 的语法糖，flag 集与输出与 `list` 完全一致。\n\n```bash\nmp2rss mp search 财经\nmp2rss mp search 财经 -o json\n```\n\n### Agent 注意\n\n`mp search` **只在已订阅源中模糊查找**，不会发现公众号、不会订阅新号。用户要\"搜公众号订阅\"指的就是这个；要订阅新公众号必须走 `mp subscribe + 文章 URL` 路径。\n\n---\n\n## Remove\n\n```\nmp2rss mp remove <mpId> [-y] [-o json]\n```\n\n按 mpId 取消订阅。`-y` 跳过交互式确认（适合脚本调用）。\n\n```bash\nmp2rss mp remove 123456            # 会交互式确认\nmp2rss mp remove 123456 -y         # 直接执行\nmp2rss mp remove 123456 -y -o json\n```\n\n### JSON shape\n\n```json\n{\n  \"ok\": true,\n  \"mpId\": 123456\n}\n```\n\n### Agent 处理\n\n- **取消订阅前必须先确认 mpId**：用 `mp list -q <name> -o json` 或 `mp search <name> -o json` 拿到准确 mpId 再调 remove\n- 用户只给公众号名时，不要凭名字猜 mpId\n- 若 `items` 多条匹配 → 列给用户让其挑选哪个，不要默认删第一个\n- 自动化脚本场景统一加 `-y`，否则 Agent 会卡在交互式 prompt\n\n---\n\n## Articles\n\n```\nmp2rss mp articles <mpId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 mpId 查询公众号历史文章。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 100 | 每页条数（最大 100） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss mp articles 123456\nmp2rss mp articles 123456 -p 2 --page-size 100\nmp2rss mp articles 123456 -o json | jq '.items[].title'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"mpId\": 123456,\n      \"articleId\": \"article-id-string\",\n      \"title\": \"文章标题\",\n      \"summary\": \"文章摘要\",\n      \"coverImageUrl\": \"https://...\",\n      \"originalUrl\": \"https://mp.weixin.qq.com/s/...\",\n      \"contentMarkdown\": \"# Markdown 正文\",\n      \"publishedAt\": 1705000000000,\n      \"updatedAt\": 1705000010000\n    }\n  ]\n}\n```\n\n⚠️ **没有分页字段**（无 `total` / `page` / `pageSize`）；`items` 为空数组即视为本页结束。Agent 翻页直接 `-p N` 试到空为止。\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `mpId` | int64 | 公众号 ID（同样字符串化处理） |\n| `articleId` | string | 文章唯一 ID |\n| `title` | string | 文章标题 |\n| `summary` | string | 文章摘要（可能为空） |\n| `coverImageUrl` | string | 封面图 URL（可能为空） |\n| `originalUrl` | string | 原文链接（`mp.weixin.qq.com/s/...`） |\n| `contentMarkdown` | string | Markdown 格式正文 |\n| `publishedAt` | int64 | 发布时间，unix 毫秒 |\n| `updatedAt` | int64 | 更新时间，unix 毫秒 |\n\n---\n\n## Agent 综合注意事项\n\n- **结构化解析统一 `-o json`**\n- **字段命名 camelCase**：`mpId` / `mpName` / `mpAvatarUrl` / `mpLastArticleAt` / `articleId` / `originalUrl` / `contentMarkdown` / `publishedAt`\n- **mpId 是 int64**：JS 解析前先字符串化（见 [SKILL.md](../SKILL.md#-mpid-是-int64)）\n- **时间字段统一 unix 毫秒**（int64 number）\n- **取消订阅前先 list/search 确认 mpId**\n- **文章列表无分页字段**，靠 `--page-size`（最大 100）+ `-p` 翻页\n- 错误码处理见 [errors.md](errors.md)\n\nFile v0.2.3:references/x.md\n\n# X（Twitter）订阅与内容拉取\n\n本文档供 Agent 在用户询问 X / Twitter 账号订阅、推文、长文相关需求时按需读取。\n\n**调用前提**：先确认登录态（见 [auth.md](auth.md)）；未登录时不要直接调本节命令。\n\n---\n\n## ⚠️ 关键边界：X 订阅必须在 Web 控制台完成\n\nX 账号的**搜索**与**订阅 / 取消订阅**仅由 Web 控制台 <https://mp2rss.bugcode.dev/> 提供，**CLI 与 Open API 都不暴露这些写类端点**。\n\nCLI 在 `x` 子命令组下**只覆盖读类**三件事：\n\n| 子命令 | 作用 |\n|--------|------|\n| `mp2rss x list`     | 列出当前 Feed Key 已订阅的 X 账号 |\n| `mp2rss x posts`    | 拉取已订阅 X 账号的推文流 |\n| `mp2rss x articles` | 拉取已订阅 X 账号的长文流 |\n\n### Agent 路由策略\n\n- 用户说「订阅 X 上的 @xxx」「订阅这个推特账号」「在 mp2rss 里加个 X 号」\n  → **不要尝试 CLI**，告诉用户去 Web 控制台「订阅管理 → X」搜索并订阅，之后回到这里可用 CLI 列出/拉内容。\n- 用户说「取消订阅 X 账号 xxx」\n  → 同上，引导去 Web 控制台。\n- 用户说「我订阅了哪些 X 号」「拉一下 @elonmusk 的推文」\n  → 走本文档的 `x list` / `x posts` 流程。\n\n---\n\n## xUserId vs @handle\n\nX 的业务键是 `xUserId`（X 平台的数字 user_id，字符串形态），**不是** `@handle`：\n\n- `@handle` 用户可随时改，订阅指向会失效；\n- `xUserId` 是 X 平台稳定的唯一 ID。\n\nCLI 与 Open API 的所有 X 读类端点（`x posts` / `x articles`）**只接受 `xUserId`**。用户给的是 `@handle` 或显示名时，Agent 必须先 `mp2rss x list -o json` 查出对应 `xUserId` 再调用。\n\n```bash\nmp2rss x list -o json | jq -r '.items[] | \"\\(.xUserId)\\t@\\(.xUsername)\\t\\(.xDisplayName)\"'\n```\n\n---\n\n## List\n\n```\nmp2rss x list [-q <keyword>] [-p <page>] [--page-size <n>] [-o json]\n```\n\n列出当前 Feed Key 名下已订阅的全部 X 账号。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-q, --query` | — | 按 `xDisplayName` / `xUsername` 模糊匹配 |\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（最大 50） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x list\nmp2rss x list -q elon\nmp2rss x list -p 2 --page-size 20\nmp2rss x list -o json | jq '.items[].xUserId'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"sourceType\": \"x\",\n      \"xUserId\": \"44196397\",\n      \"xUsername\": \"elonmusk\",\n      \"xDisplayName\": \"Elon Musk\",\n      \"xVerified\": true,\n      \"createdAt\": 1776640000000,\n      \"xLastItemAt\": 1776854096000\n    }\n  ],\n  \"total\": 1,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `sourceType` | string | 固定 `\"x\"` |\n| `xUserId` | string | X 数字 user_id（字符串形态） |\n| `xUsername` | string | X handle，不含 `@` |\n| `xDisplayName` | string | X 显示名 |\n| `xVerified` | bool | 是否已认证 |\n| `createdAt` | int64 | 订阅创建时间，unix 毫秒 |\n| `xLastItemAt` | int64? | 最近一条推文/长文收录时间，unix 毫秒，可能为 null |\n\n---\n\n## Posts\n\n```\nmp2rss x posts <xUserId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 `postedAt DESC` 拉取已订阅 X 账号的推文流。**仅允许查询已订阅的 xUserId**，未订阅返回 exit code 4（`X account is not subscribed`）。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（**最大 50**） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x posts 44196397\nmp2rss x posts 44196397 -p 2 --page-size 20\nmp2rss x posts 44196397 -o json | jq '.items[].content'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"postId\": \"1234567890\",\n      \"content\": \"hello world\",\n      \"media\": [{ \"url\": \"https://x.com/img.jpg\", \"type\": \"photo\" }],\n      \"retweetedPost\": null,\n      \"quotedPost\": { \"id\": \"99\", \"content\": \"...\" },\n      \"threadPosts\": [{ \"content\": \"reply 1\" }],\n      \"postedAt\": 1746864000000\n    }\n  ],\n  \"total\": 42,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `postId` | string | 推文业务 ID |\n| `content` | string | 推文正文（明文，未渲染 HTML） |\n| `media` | array | 媒体附件数组；无媒体或解析失败为 `[]` |\n| `media[].url` | string | 媒体资源 URL |\n| `media[].type` | string | `photo` / `video` / `animated_gif` 等 |\n| `retweetedPost` | object? | 转推原推文对象；无则 null |\n| `quotedPost` | object? | 引用的推文对象；无则 null |\n| `threadPosts` | array | Thread 系列推文数组；无则 `[]` |\n| `postedAt` | int64 | 发布时间，unix 毫秒 |\n\n::: tip 结构化 vs 渲染\n本端点返回的是**结构化原始数据**（含 media / quotedPost / threadPosts 嵌套），供 Agent 自定义渲染。\n如果用户只想在阅读器里订阅来看，请引导走 Web 控制台「账户设置」复制的 Feed 链接（公开 RSS / Atom / JSON Feed 层），不要让 Agent 重新拼装。\n:::\n\n---\n\n## Articles\n\n```\nmp2rss x articles <xUserId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 `publishedAt DESC` 拉取已订阅 X 账号的长文（X Articles）流。订阅闭环校验同 `x posts`，未订阅返回 exit code 4。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（**最大 50**） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x articles 44196397\nmp2rss x articles 44196397 -o json | jq '.items[].url'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"url\": \"https://x.com/elonmusk/article/...\",\n      \"title\": \"My take on...\",\n      \"description\": \"summary\",\n      \"contentMarkdown\": \"# Heading\\n\\nfull body markdown source\",\n      \"coverUrl\": \"https://...\",\n      \"publishedAt\": 1747353600000\n    }\n  ],\n  \"total\": 8,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `url` | string | 长文原始 URL |\n| `title` | string | 标题 |\n| `description` | string | 摘要 |\n| `contentMarkdown` | string? | 长文 markdown 原文，可能为 null |\n| `coverUrl` | string? | 封面图 URL |\n| `publishedAt` | int64 | 发布时间，unix 毫秒 |\n\n---\n\n## Agent 综合注意事项\n\n- **xUserId 是字符串**，不要按整数处理（与 `mpId` 不同；handle 起源是数字，但 API 契约统一为字符串）\n- **不接受 `@handle`**：从 `x list` 输出里取 `xUserId` 再调 posts / articles\n- **写类操作不可达**：用户要订阅/取消订阅 X，**统一引导到 Web 控制台**，不要尝试构造 CLI 写命令\n- **结构化解析统一 `-o json`**\n- **字段命名 camelCase**：`xUserId` / `xUsername` / `xDisplayName` / `xLastItemAt` / `postId` / `postedAt` / `publishedAt`\n- **时间字段统一 unix 毫秒**（int64 number）\n- **页大小上限 50**（`x posts` / `x articles` 最大都是 50，注意与 `mp articles` 的 100 不同）\n- 错误码处理见 [errors.md](errors.md)；典型场景：未订阅返回 exit 4，message `X account is not subscribed`\n\nFile v0.2.3:skill-card.md\n\n## Description:\n\nHelps agents manage WeChat public-account RSS subscriptions and read subscribed WeChat and X content through the mp2rss CLI.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[areyoubugcoder](https://clawhub.ai/user/areyoubugcoder)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPeople and agents use this skill to subscribe to and manage WeChat public accounts, retrieve their articles, read posts and articles from subscribed X accounts, and manage mp2rss login. X account subscriptions must be changed in the web console.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Installation and updates can run code from mutable remote sources.\n\nMitigation: Review install and update paths; prefer pinned packages or release downloads with verified checksums instead of piping a mutable-branch script to a shell.\n\nRisk: Skill synchronization during updates can change installed agent skills across sessions.\n\nMitigation: Review skill-sync changes before applying updates; use the documented option to skip automatic skill synchronization when appropriate.\n\nRisk: Authentication stores a Feed Key locally.\n\nMitigation: Protect the local credential and manage login through the CLI rather than exposing or editing the stored key.\n\n## Reference(s):\n\n- [Mp2rss service](https://mp2rss.bugcode.dev)\n- [Mp2rss documentation](https://areyoubugcoder.github.io/Mp2RSS/)\n- [Authentication guide](references/auth.md)\n- [Installation and updates](references/install.md)\n- [WeChat account commands](references/mp.md)\n- [X account commands](references/x.md)\n- [Error handling](references/errors.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Guidance]\n\n**Output Format:** [Markdown with CLI commands and content summaries]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires the mp2rss CLI and an authorized Feed Key for account operations.]\n\n## Skill Version(s):\n\n0.2.3 (source: frontmatter, package.json, ClawHub release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v0.2.3:package.json\n\n{\n  \"name\": \"mp2rss\",\n  \"version\": \"0.2.3\",\n  \"description\": \"Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。订阅 / 列出 / 搜索 / 取消订阅公众号，查询公众号历史文章；列出已订阅 X 账号，拉取 X 推文 / 长文流（X 写类操作仅 Web 控制台）；管理 Feed Key 登录态。\",\n  \"license\": \"MIT-0\",\n  \"author\": \"areyoubugcoder\",\n  \"homepage\": \"https://mp2rss.bugcode.dev\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/areyoubugcoder/mp2rss-cli.git\",\n    \"directory\": \"openclaw/mp2rss\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/areyoubugcoder/mp2rss-cli/issues\"\n  },\n  \"keywords\": [\n    \"mp2rss\",\n    \"wechat\",\n    \"weixin\",\n    \"微信\",\n    \"公众号\",\n    \"x\",\n    \"twitter\",\n    \"推特\",\n    \"rss\",\n    \"feed\",\n    \"subscription\",\n    \"订阅\",\n    \"openclaw\",\n    \"skill\"\n  ],\n  \"clawhub\": {\n    \"acceptLicenseTerms\": true\n  }\n}\n\nFile v0.2.3:LICENSE\n\nMIT No Attribution\n\nCopyright 2026 areyoubugcoder\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v0.2.2: 11 files, 23126 bytes\n\nFiles: LICENSE (909b), package.json (949b), README.md (7450b), references/auth.md (3850b), references/errors.md (4967b), references/install.md (3278b), references/mp.md (5716b), references/x.md (7174b), skill-card.md (2369b), SKILL.md (11744b), _meta.json (125b)\n\nFile v0.2.2:SKILL.md\n\n---\nname: mp2rss\ndescription: |\n  Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。\n\n  **当以下情况使用此 Skill**：\n  (1) 用户要订阅 / 取消订阅 / 列出 / 搜索**微信公众号**：「订阅这个公众号 https://mp.weixin.qq.com/s/...」「我订阅了哪些公众号」「列一下我的公众号 RSS」「搜一下我订阅的财经类公众号」「取消订阅那个号」「把 <公众号名> 从订阅里删了」\n  (2) 用户要查**公众号历史文章**：「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」「<公众号名> 的历史文章」\n  (3) 用户要操作 **X（Twitter）账号**：「我订阅了哪些 X 账号」「@elonmusk 最近发了啥」「拉一下某个 X 号的推文 / 长文」（注：X 的订阅 / 取消订阅仅在 Web 控制台，CLI 只能列出已订阅与拉内容）\n  (4) 用户要管理**登录态**：「登录公众号 RSS 服务」「登出 mp2rss」「我的 Feed Key 是什么」「我在 mp2rss 里登录了吗」\n  (5) 用户要**安装 / 配置 Mp2rss CLI**：「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪里」\nversion: 0.2.2\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - mp2rss\n    envVars:\n      - name: MP2RSS_FEED_KEY\n        required: false\n        description: Mp2rss Feed Key；也可由 `mp2rss auth login` 写入配置文件，二者任一即可。\n      - name: MP2RSS_API_URL\n        required: false\n        description: Mp2rss API URL，默认 https://mp2rss.bugcode.dev。\n    homepage: https://mp2rss.bugcode.dev\n    emoji: \"📡\"\n---\n\n# Mp2rss Skill\n\n通过 Mp2rss CLI（Go 二进制 `mp2rss`）把**微信公众号**与 **X（Twitter）账号**转成 RSS / JSON Feed 并管理订阅。本 skill 是路由入口，按用户意图分发到 `references/` 子文档读取详细命令规格。\n\n> **术语提示**：本文档中 **\"X\"** 一律指 X（原 Twitter）平台；用作\"某个公众号\"占位时统一写作 `<公众号名>` 或具名描述，避免与 X 平台混淆。\n\n## ⚠️ Agent 必读约束\n\n### 🔧 运行时前置\n\n所有命令通过本地 `mp2rss` 二进制调用，**不直接打 HTTP**。Agent 不应自己拼 API 请求，统一走 CLI 子命令 + `-o json` 解析。\n\n**Base URL 由 CLI 自动决定**（命令行 flag > 环境变量 > 配置文件 > 默认 `https://mp2rss.bugcode.dev`）。\n\n### 🔑 凭证与登录态\n\n调用任何 `mp2rss mp` / `mp2rss x` 子命令前，**必须先确认登录态**：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `{\"loggedIn\": false}` 时停止后续调用，引导用户跑 `mp2rss auth login`，详见 [references/auth.md](references/auth.md)。\n\n凭证优先级（高 → 低）：命令行 `--api-key` flag > `MP2RSS_FEED_KEY` 环境变量 > `~/.mp2rss/config.json` 配置文件。\n\n### 🔢 mpId 是 int64 / xUserId 是字符串\n\n两种业务键形态不同，**不要混用**：\n\n- **`mpId`**（公众号）：int64 整数。超出 JavaScript `Number.MAX_SAFE_INTEGER`，Agent 在 JS 环境下解析 `mp list / mp articles -o json` 输出时**始终把 mpId 当字符串处理**：\n\n  ```javascript\n  const safe = text.replace(/\"(mpId)\"\\s*:\\s*(\\d+)/g, '\"$1\":\"$2\"');\n  const data = JSON.parse(safe);\n  ```\n\n- **`xUserId`**（X 账号）：API 契约即为字符串（虽然内容是数字串），原样消费即可，不必转换。\n\nPython / Go / jq 原生支持大整数，无 mpId 精度问题。\n\n### 🚫 反幻觉边界\n\n- **禁止编造 mpId / xUserId**：所有业务键必须来自 `mp list` / `mp search` / `x list` 的响应，不得凭空构造\n- **禁止跳过订阅参数校验**：`mp subscribe <url>` 的 `<url>` **必须**是 `https://mp.weixin.qq.com/s/...` 文章链接；不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时**反问用户索要任意一篇文章链接**，不要直接尝试\n- **禁止伪造执行结果**：不调用 CLI 不得告诉用户「已订阅」「已删除」\n- **禁止忽略 exit code**：CLI 返回非 0 必须解析 stderr / JSON envelope 并报告用户\n- **X 订阅 / 取消订阅必须走 Web 控制台**：CLI 与 API 都不暴露 X 写类端点；用户要订阅 X 账号时**只能引导到 <https://mp2rss.bugcode.dev/>「订阅管理 → X」**，不要尝试构造 CLI 写命令\n\n### 🔄 错误处理\n\nCLI 错误统一 JSON envelope（见 [references/errors.md](references/errors.md)）：\n\n```json\n{\"error\": {\"message\": \"...\", \"code\": <int>}}\n```\n\nExit code 速查：\n\n| Code | 含义 | Agent 处理 |\n|------|------|-----------|\n| 0 | 成功 | 解析 stdout |\n| 1 | 通用错误（网络 / cobra 解析层：缺参、flag 值非法，此类输出裸文本非 JSON） | 网络类报告 + 建议稍后重试；解析类修正参数 |\n| 2 | 参数错误（业务校验层） | 检查参数；若是 `mp subscribe` 检查 URL 格式 |\n| 3 | 鉴权失败 | 引导跑 `mp2rss auth login`（见 [auth.md](references/auth.md)） |\n| 4 | 资源不存在 | mpId 错 / 文章 URL 失效 / **X 账号未订阅**（典型 message `X account is not subscribed`） |\n| 5 | 上游不可用 | 报告 + 建议稍后重试 |\n\n---\n\n## 执行流程概览\n\n```\n用户意图 → 路由匹配 → 读对应 references/xxx.md → 构造 mp2rss 子命令 → 执行 → 解析 JSON / 验证 exit code → 返回结果\n                                                                                      ↓\n                                                                                  exit ≠ 0 → 按错误码分支处理\n```\n\n**关键原则**\n\n- **CLI 输出是真理**：所有状态以 `mp2rss xxx -o json` 返回为准，不依赖上下文记忆\n- **`-o json` 优先**：批量 / 结构化场景统一加 `-o json`（除 `auth login` 不支持外）\n- **mpId 字符串化**（JS 环境）；xUserId 本身就是字符串\n\n---\n\n## 指令路由表\n\n| 用户意图 / 自然语言 | 角色 | 详细文档 |\n|------|------|---------|\n| 「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪」 | ⚙️ 安装/配置 | [references/install.md](references/install.md) |\n| 「登录」「登出」「我的 Feed Key 是什么」「我登录了吗」 | 🔐 认证 | [references/auth.md](references/auth.md) |\n| 「订阅这个公众号 https://mp.weixin.qq.com/s/...」 | 📡 公众号订阅 | [references/mp.md](references/mp.md#subscribe) |\n| 「我订阅了哪些公众号」「列一下我的公众号 RSS」 | 📋 公众号列表 | [references/mp.md](references/mp.md#list) |\n| 「搜一下我订阅的财经类公众号」 | 🔍 公众号搜索 | [references/mp.md](references/mp.md#search) |\n| 「取消订阅 <公众号名>」「把 <公众号名> 从订阅里删了」 | 🗑️ 公众号取消订阅 | [references/mp.md](references/mp.md#remove) |\n| 「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」 | 📰 公众号文章 | [references/mp.md](references/mp.md#articles) |\n| 「我订阅了哪些 X 账号」「列一下我的 X 订阅」 | 🐦 X 列表 | [references/x.md](references/x.md#list) |\n| 「<X 账号> 最近发了啥」「@xxx 的推文」 | 🐦 X 推文 | [references/x.md](references/x.md#posts) |\n| 「<X 账号> 的长文 / Articles」 | 🐦 X 长文 | [references/x.md](references/x.md#articles) |\n| 「订阅一个 X 账号 / 取消订阅 X」 | 🐦 ⚠️ Web 控制台 | [references/x.md](references/x.md#关键边界x-订阅必须在-web-控制台完成) |\n| 错误码 / JSON envelope / exit code 处理 | 🚨 错误 | [references/errors.md](references/errors.md) |\n\n---\n\n## 自然语言路由（细分 trigger）\n\n```\n包含 mp.weixin.qq.com/s/ URL              → mp subscribe（参数 = 该 URL）\n「订阅」+ 任何 URL 形态                    → 先校验是不是 mp.weixin.qq.com/s/...，否则反问\n「订阅了哪些 公众号」「我的公众号」          → mp list\n「订阅了哪些 X / Twitter 账号」「我的 X 订阅」 → x list\n「搜公众号」「找一下带 关键词 的公众号」      → mp list -q <kw> 或 mp search <kw>\n「取消订阅 <公众号名>」「删了 <公众号名>」    → 先 mp list -q <名> 确认 mpId，再 mp remove <mpId>\n「<公众号名> 最近发的文章 / 历史文章」        → mp articles <mpId>（先列表确认 mpId）\n「@elonmusk 最近的推文」「<X 账号名> 发了啥」  → 先 x list 拿到 xUserId，再 x posts <xUserId>\n「<X 账号名> 的长文 / Articles」              → 先 x list，再 x articles <xUserId>\n「订阅 / 取消订阅一个 X 账号」               → 引导用户去 Web 控制台「订阅管理 → X」，不要走 CLI\n「登录」「授权」                            → auth login（参考 auth.md 选三种登录模式之一）\n「我的 Key」「登录了吗」「状态」              → auth status -o json\n「登出」「退出登录」                         → auth logout\n```\n\n**决策原则**：\n\n- 有 `mp.weixin.qq.com/s/` URL → 直接 `mp subscribe`\n- 用户给的是**公众号名而非 URL** → **反问索要文章 URL**，不要先 `mp search`（搜索是用于在已订阅源里找，不会订阅新号）\n- 取消订阅公众号前**先用 `mp list -q` / `mp search` 拿到准确 mpId**，避免误删\n- 用户给 X 账号是 `@handle` 或显示名 → **先 `x list -o json` 找 xUserId**，不要把 handle 直接传给 `x posts / x articles`\n- 用户想**添加** X 订阅 → **不要尝试 CLI**，直接引导 <https://mp2rss.bugcode.dev/>「订阅管理 → X」\n\n---\n\n## API 路由（CLI 子命令总表）\n\n| 子命令 | 用途 | 详细文档 |\n|--------|------|---------|\n| `mp2rss auth login [-k <key>] [--no-browser]` | 登录（三种模式） | [auth.md](references/auth.md#log-in) |\n| `mp2rss auth status [-o json]` | 查询登录态 | [auth.md](references/auth.md#check-status) |\n| `mp2rss auth logout` | 登出 | [auth.md](references/auth.md#log-out) |\n| `mp2rss mp subscribe <article-url> [-o json]` | 订阅公众号 | [mp.md](references/mp.md#subscribe) |\n| `mp2rss mp list [-q <kw>] [-p <page>] [--page-size <n>] [-o json]` | 列出公众号订阅 | [mp.md](references/mp.md#list) |\n| `mp2rss mp search <keyword> [-o json]` | 搜索已订阅公众号 | [mp.md](references/mp.md#search) |\n| `mp2rss mp remove <mpId> [-y] [-o json]` | 取消订阅公众号 | [mp.md](references/mp.md#remove) |\n| `mp2rss mp articles <mpId> [-p <page>] [--page-size <n>] [-o json]` | 查公众号文章 | [mp.md](references/mp.md#articles) |\n| `mp2rss x list [-q <kw>] [-p <page>] [--page-size <n>] [-o json]` | 列出已订阅 X 账号 | [x.md](references/x.md#list) |\n| `mp2rss x posts <xUserId> [-p <page>] [--page-size <n>] [-o json]` | 拉 X 推文流 | [x.md](references/x.md#posts) |\n| `mp2rss x articles <xUserId> [-p <page>] [--page-size <n>] [-o json]` | 拉 X 长文流 | [x.md](references/x.md#articles) |\n| `mp2rss update [--check] [--skip-skills]` | 升级 CLI | [install.md](references/install.md#升级) |\n| `mp2rss skills sync [--global] / status / list` | 同步 / 查看 Agent Skills（CLI ≥ 1.2.0） | [install.md](references/install.md#agent-skills-同步cli--120) |\n\n> X 写类（搜索 / 订阅 / 取消订阅）**不存在对应 CLI 命令**，仅 Web 控制台提供，详见 [x.md](references/x.md#关键边界x-订阅必须在-web-控制台完成)。\n\n---\n\n## 全局 flag\n\n所有子命令都支持：\n\n| Flag | 等价环境变量 | 说明 |\n|------|-------------|------|\n| `-o, --output <table\\|json>` | — | 输出格式，默认 `table` |\n| `--api-key <feed-key>` | `MP2RSS_FEED_KEY` | 覆盖 Feed Key |\n| `--api-url <url>` | `MP2RSS_API_URL` | 覆盖 API 地址 |\n\n优先级（高 → 低）：CLI flag > env > 配置文件 > 默认。\n\nFile v0.2.2:README.md\n\n# Mp2rss Skill\n\n[![License: MIT-0](https://img.shields.io/badge/License-MIT--0-blue.svg)](https://opensource.org/licenses/MIT-0)\n\n让 AI Agent 帮你管理 **微信公众号** 与 **X（Twitter）账号** 的 RSS 订阅 —— 一句话订阅、自然语言查找、按需读历史文章 / 推文 / 长文。\n\n本目录是 [Mp2rss](https://mp2rss.bugcode.dev) 服务的 OpenClaw Agent Skill 包，随 [`mp2rss` CLI](https://github.com/areyoubugcoder/mp2rss-cli) 同仓库维护（`openclaw/mp2rss/` 子目录），发布到 ClawHub（slug：`mp2rss`）。Claude Code 用户请改用仓库根的 `skills/`（插件市场 / `npx skills add` 安装），见主仓库 README。\n\n---\n\n## ✨ 核心能力\n\n### 微信公众号（MP）\n\n| 能力 | 说明 |\n|------|------|\n| 📡 **一键订阅** | 发一个公众号文章链接（`mp.weixin.qq.com/s/...`），Agent 自动把整个公众号订阅到你的 Feed |\n| 📋 **列表与搜索** | 「我订阅了哪些公众号」「搜一下我订阅的财经类公众号」 |\n| 🗑️ **取消订阅** | 「把 某号 从订阅里删了」，Agent 先核对 mpId 再删 |\n| 📰 **历史文章** | 「某号 最近发了什么」/「拉一下 某号 的文章」 |\n\n### X（Twitter）账号\n\n| 能力 | 说明 |\n|------|------|\n| 🐦 **列出 X 订阅** | 「我订阅了哪些 X 账号」 |\n| 📨 **推文流** | 「@elonmusk 最近发了啥」（Agent 先 `x list` 找到 `xUserId` 再拉推文） |\n| 📝 **长文流** | 「拉一下 某 X 账号的 Articles」 |\n| ⚠️ **订阅 / 取消订阅 X 账号** | **仅在 Web 控制台**（<https://mp2rss.bugcode.dev/>）—— CLI 与 API 都不暴露 X 写类端点，Agent 会引导你去控制台 |\n\n### 通用\n\n| 能力 | 说明 |\n|------|------|\n| 🔐 **登录态管理** | 「我的 Feed Key 是什么」「登录 mp2rss」 |\n| 📤 **结构化输出** | 所有命令支持 `-o json`，Agent 可直接解析做后续处理 |\n\n---\n\n## 💡 使用场景\n\n### 通勤路上看到好公众号\n\n> 👤 订阅这个公众号 https://mp.weixin.qq.com/s/abc123xyz\n>\n> 🤖 已订阅「某公众号」到你的 Feed。\n\n### 不记得订过哪些号\n\n> 👤 我订阅了哪些公众号？\n>\n> 🤖 当前共 42 个订阅。前 20 个：某公众号（最近发文 2 小时前）、另一个号（昨天）……\n\n### 找特定主题\n\n> 👤 我订阅的财经类公众号有哪些\n>\n> 🤖 找到 5 个匹配：财经早知道、第一财经……\n\n### 翻看历史\n\n> 👤 财经早知道 最近发了什么\n>\n> 🤖 最近 10 篇文章：1. xxx 标题（昨天）2. xxx 标题（前天）……\n\n### 不想看了\n\n> 👤 把 财经早知道 从订阅里删了\n>\n> 🤖 确认删除「财经早知道」（mpId 123456）？已删除 ✓\n\n### 看大 V 推文\n\n> 👤 @elonmusk 最近发了啥？\n>\n> 🤖 （先 `x list` 拿到 xUserId 44196397）最近 5 条推文：1. ……\n\n### 想订阅一个 X 账号\n\n> 👤 帮我订阅 @paulg 这个号\n>\n> 🤖 X 账号的订阅 / 取消订阅只能在 Web 控制台操作。打开 https://mp2rss.bugcode.dev/「订阅管理 → X」搜索 paulg 完成订阅；订阅好我就能用 `mp2rss x posts/articles` 帮你拉内容。\n\n---\n\n## 📦 安装\n\n### 前置：装 Mp2rss CLI 二进制\n\nskill 本身只描述如何调用 CLI，所以必须先装 `mp2rss` 二进制（任选其一）：\n\n```bash\n# 方式 A：npm（推荐，跨平台一致）\npnpm add -g @mp2rss/cli\n\n# 方式 B：macOS / Linux 一键脚本\ncurl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh\n```\n\n也可在 [Releases](https://github.com/areyoubugcoder/mp2rss-cli/releases/latest) 下载对应平台二进制。\n\n### 装 Skill\n\n```bash\n# 方式 A：通过 ClawHub（推荐）\nopenclaw skills install mp2rss\n\n# 方式 B：手动\nmkdir -p ~/.openclaw/workspace/skills/mp2rss\ncd ~/.openclaw/workspace/skills/mp2rss\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/openclaw/mp2rss/SKILL.md -o SKILL.md\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/openclaw/mp2rss/package.json -o package.json\n# 视需要再拉 references/ 子文档\n```\n\n---\n\n## 🔑 授权登录\n\n安装完成后说「登录 mp2rss」，Agent 自动跑 `mp2rss auth login` 走浏览器 loopback 授权。CI / 无头环境用：\n\n```bash\nmp2rss auth login -k <feed-key>            # 直传\nmp2rss auth login --no-browser             # 远程模式，仅打印授权 URL\n```\n\nFeed Key 可在 <https://mp2rss.bugcode.dev/> 登录后查看或重置。配置文件位置 `~/.mp2rss/config.json`。\n\n### 用环境变量配置（可选）\n\n```bash\nexport MP2RSS_FEED_KEY=gk_live_xxxxxxxx\nexport MP2RSS_API_URL=https://mp2rss.bugcode.dev    # 自托管时需要\n```\n\n优先级（高 → 低）：CLI flag `--api-key` > `MP2RSS_FEED_KEY` env > `~/.mp2rss/config.json`。\n\n---\n\n## 🛠 子命令速查\n\n### 通用\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss auth login [-k <key>] [--no-browser]` | 登录（三种模式：浏览器 / Feed Key 直传 / 远程） |\n| `mp2rss auth status [-o json]` | 查登录态、Feed Key 来源、最近登录时间 |\n| `mp2rss auth logout` | 清空 Feed Key |\n\n### 微信公众号\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss mp subscribe <article-url> [-o json]` | 订阅；参数必须是 `mp.weixin.qq.com/s/...` 文章 URL |\n| `mp2rss mp list [-q <kw>] [-p <page>] [--page-size <n>]` | 列出公众号订阅 |\n| `mp2rss mp search <keyword>` | `mp list -q` 语法糖 |\n| `mp2rss mp remove <mpId> [-y]` | 取消订阅公众号 |\n| `mp2rss mp articles <mpId> [-p <page>] [--page-size <n>]` | 查公众号历史文章 |\n\n### X（Twitter）\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss x list [-q <kw>] [-p <page>] [--page-size <n>]` | 列出已订阅的 X 账号 |\n| `mp2rss x posts <xUserId> [-p <page>] [--page-size <n>]` | 拉 X 账号推文流 |\n| `mp2rss x articles <xUserId> [-p <page>] [--page-size <n>]` | 拉 X 账号长文流 |\n\n> X 账号**搜索 / 订阅 / 取消订阅**仅 Web 控制台支持，CLI 与 Open API 都不暴露这些写类端点。\n\n完整字段、JSON shape 与 Agent 行为规范见 [SKILL.md](SKILL.md) 和 [references/](references/) 子文档。\n\n---\n\n## ⚠️ 重要约束\n\n- **订阅公众号传的是文章 URL** —— 不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时 Agent 应反问用户索要任意一篇文章链接\n- **`mpId` 是 int64** —— JS 环境解析 JSON 时需先把 `mpId` 替换为字符串再 `JSON.parse`，否则精度丢失\n- **`xUserId` 是字符串** —— 虽然内容是数字串，API 契约即字符串形态，无需转换；注意不要传 `@handle`\n- **取消订阅公众号前先核对 mpId** —— 用 `mp list -q` / `mp search` 拿到准确 mpId 再删，避免误删\n- **X 写类操作不可达** —— 用户要订阅 / 取消订阅 X 账号时，Agent 必须引导到 Web 控制台「订阅管理 → X」，不要尝试构造 CLI 命令\n- **`auth login` 不支持 `-o json`** —— 仅输出文本反馈，其它子命令均支持\n\n---\n\n## 🔗 相关\n\n- [Mp2rss 服务](https://mp2rss.bugcode.dev) —— 微信公众号 / X 账号 RSS 订阅服务\n- [`mp2rss` CLI](https://github.com/areyoubugcoder/mp2rss-cli) —— Go 命令行客户端（Skill 调用的底层）\n- [Mp2rss 文档站](https://areyoubugcoder.github.io/Mp2RSS/) —— 服务介绍、Open API 与 CLI 完整文档\n\n---\n\n## License\n\n[MIT-0](LICENSE)\n\nFile v0.2.2:_meta.json\n\n{\n  \"ownerId\": \"kn7acxx408jk3phdk3326sx5fs86zndf\",\n  \"slug\": \"mp2rss\",\n  \"version\": \"0.2.2\",\n  \"publishedAt\": 1787889364304\n}\n\nFile v0.2.2:references/auth.md\n\n# 认证管理\n\n本文档供 Agent 在用户询问「登录」「登出」「我的 Feed Key 是什么」「我登录了吗」「在 mp2rss 里登录」时按需读取。\n\n## 触发条件\n\n调用任何 `mp2rss mp` 子命令前，**必须先**确认登录态：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `loggedIn: false` 时停止后续 mp 调用，引导用户登录后再继续原始请求。\n\n## Log in\n\n```\nmp2rss auth login [-k <feed-key>] [--no-browser]\n```\n\n三种模式：\n\n| 模式 | 命令 | 适用场景 |\n|------|------|---------|\n| 浏览器（默认） | `mp2rss auth login` | 桌面环境；CLI 启动本地 loopback HTTP 服务，打开浏览器登录后回调写入 `~/.mp2rss/config.json` |\n| Feed Key 直传 | `mp2rss auth login -k <feed-key>` | CI / 无头环境；Feed Key 在 https://mp2rss.bugcode.dev/ 登录后获取或重置 |\n| 远程模式 | `mp2rss auth login --no-browser` | 远程 SSH / 无浏览器；CLI 仅打印授权 URL，用户在本地浏览器打开后复制 Feed Key 回填 |\n\n```bash\nmp2rss auth login                          # 默认浏览器\nmp2rss auth login -k gk_live_xxxxxxxx      # 直传\nmp2rss auth login --no-browser             # 远程\n```\n\n### Agent 处理远程模式\n\n`mp2rss auth login --no-browser` 输出形如：\n\n```\n请在浏览器打开下面的链接完成授权：\n\n  https://mp2rss.bugcode.dev/auth/cli?code=...\n\n授权后将页面上显示的 Feed Key 粘贴到此终端：\n```\n\nAgent 应：\n\n1. **完整提取授权 URL** 转发给用户\n2. 提示「请在浏览器打开此链接，登录后把页面上的 Feed Key 粘贴回这里」\n3. 不要替用户决定使用哪个浏览器；不要把 URL 截断或缩短\n\n⚠️ `auth login` **不支持 `-o json`**，输出为纯文本反馈。\n\n## Check status\n\n```\nmp2rss auth status [-o json]\n```\n\n```bash\nmp2rss auth status            # 人类可读\nmp2rss auth status -o json    # Agent 解析\n```\n\n### JSON shape（已登录）\n\n```json\n{\n  \"loggedIn\": true,\n  \"source\": \"config\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\",\n  \"feedKeyMasked\": \"abcdef***\",\n  \"name\": \"张三\",\n  \"email\": \"user@example.com\",\n  \"lastLoginAt\": 1705000000000,\n  \"lastVerifyAt\": 1705000001000\n}\n```\n\n### JSON shape（未登录）\n\n```json\n{\n  \"loggedIn\": false,\n  \"source\": \"none\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\"\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `loggedIn` | bool | 是否已配置可用凭证 |\n| `source` | string | `\"env\"` / `\"config\"` / `\"none\"` |\n| `apiUrl` | string | 当前生效的 API URL |\n| `feedKeyMasked` | string | 已脱敏 Feed Key（仅前几位 + `***`） |\n| `name` | string? | 账号昵称；仅浏览器登录回调成功时落盘，`-k` / `--no-browser` 流程没有，`omitempty` 省略 |\n| `email` | string? | 账号邮箱；同 `name`，仅浏览器登录流程有 |\n| `lastLoginAt` | int64 | 最近登录时间，unix 毫秒 |\n| `lastVerifyAt` | int64 | 最近一次验证时间，unix 毫秒 |\n\n## Log out\n\n```\nmp2rss auth logout\n```\n\n清空 `~/.mp2rss/config.json` 里的 `feed_key`，保留 `api_url` 等其它配置。\n\n```bash\nmp2rss auth logout\n```\n\n## 凭证优先级\n\n高 → 低：\n\n1. CLI flag：`--api-key <feed-key>`\n2. 环境变量：`MP2RSS_FEED_KEY`\n3. 配置文件：`~/.mp2rss/config.json` 的 `feed_key`\n\nAPI URL 同理：`--api-url` > `MP2RSS_API_URL` > 配置文件 > 默认 `https://mp2rss.bugcode.dev`。\n\n## Agent 注意事项\n\n- 调用 `mp2rss mp` 任何子命令前先 `mp2rss auth status -o json`\n- 时间字段是 unix 毫秒（int64），不是格式化字符串\n- 不要直接读写 `~/.mp2rss/config.json`，统一用 `mp2rss auth ...` 子命令\n- 鉴权错误（exit code 3 / HTTP 401）时引导用户跑 `mp2rss auth login`，不要反复重试\n- `feedKeyMasked` 仅供展示用户身份，**不要试图从掩码还原完整 Key**\n\nFile v0.2.2:references/errors.md\n\n# 错误处理\n\n本文档供 Agent 在 mp2rss 命令返回非零 exit code 或 JSON envelope 含 `error` 字段时按需读取。\n\n## JSON 错误 envelope\n\n任何子命令在 `-o json` 模式下出错时统一返回：\n\n```json\n{\n  \"error\": {\n    \"message\": \"human-readable 错误信息\",\n    \"code\": <int>\n  }\n}\n```\n\n- `code` 字段是 HTTP 状态码（来自上游 API）或 CLI 自身 exit code\n- `message` 是人类可读描述（中文），可直接转发给用户\n\n> ⚠️ 例外（实测 CLI 1.1.0）：**cobra 参数解析层**的错误（必填位置参数缺失、flag 值类型非法如 `--page-size abc`）以 exit 1 退出，且**即使带 `-o json` 也输出裸文本到 stderr**，不是 JSON envelope。Agent 解析 JSON 失败时应回退读 stderr 文本。\n\n## Exit codes\n\n| Code | 含义 | 典型场景 | Agent 处理 |\n|------|------|---------|-----------|\n| `0` | 成功 | 命令正常执行 | 解析 stdout |\n| `1` | 通用错误（网络）/ 解析层错误 | DNS 失败 / TCP 连不上 / 超时；**必填参数缺失、flag 值非法**（cobra 解析层，裸文本 stderr） | 网络类：报告 + 建议稍后重试；解析类：修正命令参数后重试一次 |\n| `2` | 参数错误（业务校验层） | `mp subscribe` URL 不是 `mp.weixin.qq.com/s/...` / 位置参数格式非法（如 mpId 非数字） | 解析 envelope 给用户具体提示；URL 错就反问用户索要正确文章链接 |\n| `3` | 鉴权失败 | Feed Key 错 / 过期 / 未配置 / HTTP 401 | 引导用户跑 `mp2rss auth login`（见 [auth.md](auth.md)）；**不要反复重试** |\n| `4` | 资源不存在 | mpId 错 / 文章 URL 失效 / **xUserId 未订阅**（X 读类端点要求已订阅）/ HTTP 404 | MP：用 `mp list` 重新核对 mpId 或更换文章链接；X：先 `x list` 确认是否已订阅，未订阅的话引导用户去 Web 控制台「订阅管理 → X」 |\n| `5` | 上游不可用 | API 服务挂 / HTTP 5xx | 报告 + 建议稍后重试 |\n\n## HTTP code 对应\n\nCLI 把上游 HTTP 状态码映射到上面的 exit codes：\n\n| HTTP | Exit | 说明 |\n|------|------|------|\n| 200 | 0 | OK |\n| 400 | 2 | 请求参数错 |\n| 401 | 3 | Feed Key 无效 |\n| 403 | 1 | 权限不足（CLI 未特判 403，落到通用错误；message 会带上游原文） |\n| 404 | 4 | 资源不存在 |\n| 429 | 1 | 限流；CLI 会自动退避重试 2 次，仍失败后按通用错误退出（未特判） |\n| 5xx | 5 | 上游错误（CLI 同样先自动退避重试 2 次） |\n\n## Agent 处理策略\n\n### 失败重试\n\n| 错误类型 | 重试策略 |\n|---------|---------|\n| Exit 1（网络） | 等待 5 秒后**最多重试一次**；二次失败明确报告网络问题 |\n| Exit 1（解析层：缺参 / flag 值非法） | **不要原样重试**；按 stderr 提示修正命令参数后再执行 |\n| Exit 3（鉴权） | **不要重试**；直接引导 `mp2rss auth login` |\n| Exit 4（不存在） | **不要重试**；引导用户核对 mpId / URL |\n| Exit 5（上游 5xx） | 等待 5 秒后**最多重试一次**；二次失败建议稍后再试 |\n| Exit 2（参数） | **不要重试**；告诉用户具体是哪个参数错了 |\n\n### 错误信息提取\n\n人类可读模式（无 `-o json`）下，错误写到 stderr，Agent 应捕获 stderr 转发给用户。\n\nJSON 模式下，错误 envelope 写到 stdout（保持单一输出流），Agent 解析 `error.message` 和 `error.code` 字段。\n\n### 反幻觉\n\n- **禁止编造错误信息**：所有报告给用户的错误必须来自 CLI 真实输出（stderr 或 JSON envelope）\n- **禁止隐瞒错误**：CLI 返回非零退出码时必须告诉用户，不能装作执行成功\n- **禁止过度解读 message**：`error.message` 直接转发，不要\"翻译\"成自己的描述（容易扭曲原意）\n\n## 常见错误样例\n\n### Feed Key 失效\n\n```bash\n$ mp2rss mp list -o json\n{\"error\":{\"message\":\"鉴权失败：Feed Key 无效或已重置，请重新登录\",\"code\":401}}\n$ echo $?\n3\n```\n\nAgent → 引导 `mp2rss auth login` 而非重试。\n\n### URL 格式错\n\n```bash\n$ mp2rss mp subscribe https://example.com/article -o json\n{\"error\":{\"message\":\"参数错误：subscribe 需要 mp.weixin.qq.com/s/... 文章链接\",\"code\":400}}\n$ echo $?\n2\n```\n\nAgent → 告诉用户必须用微信公众号文章 URL，并反问索要正确链接。\n\n### mpId 不存在\n\n```bash\n$ mp2rss mp articles 999999999 -o json\n{\"error\":{\"message\":\"未找到（HTTP 404）：MP account is not subscribed\",\"code\":404}}\n$ echo $?\n4\n```\n\nAgent → 用 `mp list` 核对正确 mpId。\n\n### X 账号未订阅\n\n```bash\n$ mp2rss x posts 999999999 -o json\n{\"error\":{\"message\":\"X account is not subscribed\",\"code\":404}}\n$ echo $?\n4\n```\n\nAgent → 提示用户：`mp2rss x posts / x articles` **只能查已订阅 X 账号**；订阅 X 账号必须去 Web 控制台「订阅管理 → X」操作（CLI 与 API 都不暴露 X 写类端点）。先 `mp2rss x list` 看一下是否已订阅 / `xUserId` 是否抄错。\n\nFile v0.2.2:references/install.md\n\n# 安装与升级\n\n本文档供 Agent 在用户询问「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪」时按需读取。\n\n## 环境要求\n\n- macOS / Linux / Windows 任一\n- Node.js ≥ 18（仅 npm 安装方式需要）\n- Go ≥ 1.21（仅从源码构建需要）\n\n## 安装方式\n\n任选其一：\n\n### A. npm（推荐，跨平台一致）\n\n```bash\npnpm add -g @mp2rss/cli\n# 或 npm install -g @mp2rss/cli\n```\n\n`postinstall` 脚本会按平台自动下载对应的 Go 二进制，绑定为全局 `mp2rss` 命令。\n\n### B. 一键脚本（macOS / Linux）\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh\n```\n\n自动选 macOS / Linux 对应平台二进制，安装到 `/usr/local/bin` 或 `~/.local/bin`。\n\n### C. 直接下载 Release 二进制\n\n打开 <https://github.com/areyoubugcoder/mp2rss-cli/releases/latest> 选对应平台的归档下载，解压后把 `mp2rss` 加入 `PATH`。\n\n可用平台：\n\n| OS | amd64 | arm64 |\n|----|:---:|:---:|\n| macOS | ✅ | ✅ |\n| Linux | ✅ | ✅ |\n| Windows | ✅ | ✅ |\n\n## 验证安装\n\n```bash\nmp2rss --version\n```\n\n预期输出版本号字符串（如 `mp2rss v0.x.x`），exit 0。\n\n## 升级\n\n```bash\nmp2rss update                   # 检查并升级到最新\nmp2rss update --check           # 只检查不升级\nmp2rss update --skip-skills     # 升级但本次不同步本地 Agent Skills\n```\n\n`update` 会从 GitHub Releases 拉最新版二进制就地替换。注意：通过 npm 安装的二进制由 npm 管理，建议改用 `pnpm up -g @mp2rss/cli`。\n\n## Agent Skills 同步（CLI ≥ 1.2.0）\n\nCLI 自更新只替换二进制，本地已安装的 Agent Skills 不会自动跟着升级。CLI ≥ 1.2.0 内置同步命令（旧版本无此命令，继续用 `npx -y skills add areyoubugcoder/mp2rss-cli -y`）：\n\n```bash\nmp2rss skills sync              # 同步到当前项目 ./.agents/skills\nmp2rss skills sync --global     # 同步到全局 ~/.claude/skills\nmp2rss skills status [-o json]  # 本地 skills 版本 vs CLI 版本，是否漂移\nmp2rss skills list [-o json]    # 列出仓库提供的 skills\n```\n\n- 通过 `skills sync` 装过之后，`mp2rss update` 升级二进制时会**顺带同步** skills 到新版本（`--skip-skills` 跳过）；从未 sync 过则只提示不执行。\n- 同步状态记录在 `~/.mp2rss/skills-state.json`（0600）。\n- 底层执行 `npx -y skills add areyoubugcoder/mp2rss-cli -y`，需要 Node.js（npx）。\n\n## 配置文件位置\n\n`~/.mp2rss/config.json`（目录权限 `0700` / 文件权限 `0600`），结构：\n\n```json\n{\n  \"feed_key\": \"9f3a2c...（64 位 hex）\",\n  \"api_url\": \"https://mp2rss.bugcode.dev\",\n  \"last_login_at\": 1747194198000,\n  \"last_verify_at\": 1747194198000\n}\n```\n\n- 由 `mp2rss auth login` 自动写入\n- `mp2rss auth logout` 只清 `feed_key`，保留 `api_url` 等其它字段\n- Agent **不应该**直接读写此文件，统一用 `mp2rss auth ...` 子命令\n\n## Agent 注意事项\n\n- 用户问\"装好了吗\"→ `mp2rss --version`，exit 0 即装好\n- 用户问\"配置在哪\"→ 答 `~/.mp2rss/config.json` + 强调不要手改，用 `mp2rss auth login` 管理\n- 用户问\"怎么升级\"→ 给 `mp2rss update`；若用户是 npm 装的优先建议 `pnpm up -g @mp2rss/cli`\n\nFile v0.2.2:references/mp.md\n\n# 微信公众号（MP）订阅与文章管理\n\n本文档供 Agent 在用户询问**公众号**订阅、列出、搜索、取消订阅、查文章等需求时按需读取。\n\n**调用前提**：先确认登录态（见 [auth.md](auth.md)）；未登录时不要直接调本节命令。\n\n> 本文档中所有用作\"某个公众号\"占位的地方一律写作 `<公众号名>` 或具名形式（如「财经早知道」），避免歧义。\n\n---\n\n## Subscribe\n\n```\nmp2rss mp subscribe <article-url> [-o json]\n```\n\n订阅一个公众号。⚠️ **传入的是文章 URL**（`https://mp.weixin.qq.com/s/...`），不是公众号名、不是二维码、不是公众号主页链接。从公众号任意一篇文章里复制链接即可，Mp2rss 会从该文章解析出所属公众号并把整个公众号订阅到你的 Feed。\n\n```bash\nmp2rss mp subscribe https://mp.weixin.qq.com/s/abcDEFghIJKlmnop\nmp2rss mp subscribe https://mp.weixin.qq.com/s/abc -o json\n```\n\n### JSON shape\n\n```json\n{\n  \"ok\": true,\n  \"articleUrl\": \"https://mp.weixin.qq.com/s/...\"\n}\n```\n\n### Agent 处理\n\n- 用户给的不是 `mp.weixin.qq.com/s/...` URL → **反问**索要任意一篇文章链接，不要直接试\n- 用户给的是公众号名 → 不能搜索 + 订阅，必须用户提供文章 URL\n- 订阅成功后建议跟一句 `mp list -q <推断的公众号名>` 让用户看到刚订阅的条目（可选）\n\n---\n\n## List\n\n```\nmp2rss mp list [-q <keyword>] [-p <page>] [--page-size <n>] [-o json]\n```\n\n列出当前 Feed Key 名下的所有订阅。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-q, --query` | — | 按公众号名模糊搜索（与 `mp search` 等价） |\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（最大 50） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss mp list\nmp2rss mp list -q 财经\nmp2rss mp list -p 2 --page-size 50\nmp2rss mp list -o json | jq '.items[].mpName'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"mpId\": 123456,\n      \"mpName\": \"某公众号\",\n      \"mpAvatarUrl\": \"https://...\",\n      \"createdAt\": 1705000000000,\n      \"mpLastArticleAt\": 1705000050000\n    }\n  ],\n  \"total\": 42,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n⚠️ **`mpId` 是 int64**，JS 环境解析前先正则替换为字符串（见 [SKILL.md - mpId 是 int64](../SKILL.md#-mpid-是-int64) 段）。\n\n---\n\n## Search\n\n```\nmp2rss mp search <keyword> [-p <page>] [--page-size <n>] [-o json]\n```\n\n`mp2rss mp list -q <keyword>` 的语法糖，flag 集与输出与 `list` 完全一致。\n\n```bash\nmp2rss mp search 财经\nmp2rss mp search 财经 -o json\n```\n\n### Agent 注意\n\n`mp search` **只在已订阅源中模糊查找**，不会发现公众号、不会订阅新号。用户要\"搜公众号订阅\"指的就是这个；要订阅新公众号必须走 `mp subscribe + 文章 URL` 路径。\n\n---\n\n## Remove\n\n```\nmp2rss mp remove <mpId> [-y] [-o json]\n```\n\n按 mpId 取消订阅。`-y` 跳过交互式确认（适合脚本调用）。\n\n```bash\nmp2rss mp remove 123456            # 会交互式确认\nmp2rss mp remove 123456 -y         # 直接执行\nmp2rss mp remove 123456 -y -o json\n```\n\n### JSON shape\n\n```json\n{\n  \"ok\": true,\n  \"mpId\": 123456\n}\n```\n\n### Agent 处理\n\n- **取消订阅前必须先确认 mpId**：用 `mp list -q <name> -o json` 或 `mp search <name> -o json` 拿到准确 mpId 再调 remove\n- 用户只给公众号名时，不要凭名字猜 mpId\n- 若 `items` 多条匹配 → 列给用户让其挑选哪个，不要默认删第一个\n- 自动化脚本场景统一加 `-y`，否则 Agent 会卡在交互式 prompt\n\n---\n\n## Articles\n\n```\nmp2rss mp articles <mpId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 mpId 查询公众号历史文章。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 100 | 每页条数（最大 100） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss mp articles 123456\nmp2rss mp articles 123456 -p 2 --page-size 100\nmp2rss mp articles 123456 -o json | jq '.items[].title'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"mpId\": 123456,\n      \"articleId\": \"article-id-string\",\n      \"title\": \"文章标题\",\n      \"summary\": \"文章摘要\",\n      \"coverImageUrl\": \"https://...\",\n      \"originalUrl\": \"https://mp.weixin.qq.com/s/...\",\n      \"contentMarkdown\": \"# Markdown 正文\",\n      \"publishedAt\": 1705000000000,\n      \"updatedAt\": 1705000010000\n    }\n  ]\n}\n```\n\n⚠️ **没有分页字段**（无 `total` / `page` / `pageSize`）；`items` 为空数组即视为本页结束。Agent 翻页直接 `-p N` 试到空为止。\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `mpId` | int64 | 公众号 ID（同样字符串化处理） |\n| `articleId` | string | 文章唯一 ID |\n| `title` | string | 文章标题 |\n| `summary` | string | 文章摘要（可能为空） |\n| `coverImageUrl` | string | 封面图 URL（可能为空） |\n| `originalUrl` | string | 原文链接（`mp.weixin.qq.com/s/...`） |\n| `contentMarkdown` | string | Markdown 格式正文 |\n| `publishedAt` | int64 | 发布时间，unix 毫秒 |\n| `updatedAt` | int64 | 更新时间，unix 毫秒 |\n\n---\n\n## Agent 综合注意事项\n\n- **结构化解析统一 `-o json`**\n- **字段命名 camelCase**：`mpId` / `mpName` / `mpAvatarUrl` / `mpLastArticleAt` / `articleId` / `originalUrl` / `contentMarkdown` / `publishedAt`\n- **mpId 是 int64**：JS 解析前先字符串化（见 [SKILL.md](../SKILL.md#-mpid-是-int64)）\n- **时间字段统一 unix 毫秒**（int64 number）\n- **取消订阅前先 list/search 确认 mpId**\n- **文章列表无分页字段**，靠 `--page-size`（最大 100）+ `-p` 翻页\n- 错误码处理见 [errors.md](errors.md)\n\nFile v0.2.2:references/x.md\n\n# X（Twitter）订阅与内容拉取\n\n本文档供 Agent 在用户询问 X / Twitter 账号订阅、推文、长文相关需求时按需读取。\n\n**调用前提**：先确认登录态（见 [auth.md](auth.md)）；未登录时不要直接调本节命令。\n\n---\n\n## ⚠️ 关键边界：X 订阅必须在 Web 控制台完成\n\nX 账号的**搜索**与**订阅 / 取消订阅**仅由 Web 控制台 <https://mp2rss.bugcode.dev/> 提供，**CLI 与 Open API 都不暴露这些写类端点**。\n\nCLI 在 `x` 子命令组下**只覆盖读类**三件事：\n\n| 子命令 | 作用 |\n|--------|------|\n| `mp2rss x list`     | 列出当前 Feed Key 已订阅的 X 账号 |\n| `mp2rss x posts`    | 拉取已订阅 X 账号的推文流 |\n| `mp2rss x articles` | 拉取已订阅 X 账号的长文流 |\n\n### Agent 路由策略\n\n- 用户说「订阅 X 上的 @xxx」「订阅这个推特账号」「在 mp2rss 里加个 X 号」\n  → **不要尝试 CLI**，告诉用户去 Web 控制台「订阅管理 → X」搜索并订阅，之后回到这里可用 CLI 列出/拉内容。\n- 用户说「取消订阅 X 账号 xxx」\n  → 同上，引导去 Web 控制台。\n- 用户说「我订阅了哪些 X 号」「拉一下 @elonmusk 的推文」\n  → 走本文档的 `x list` / `x posts` 流程。\n\n---\n\n## xUserId vs @handle\n\nX 的业务键是 `xUserId`（X 平台的数字 user_id，字符串形态），**不是** `@handle`：\n\n- `@handle` 用户可随时改，订阅指向会失效；\n- `xUserId` 是 X 平台稳定的唯一 ID。\n\nCLI 与 Open API 的所有 X 读类端点（`x posts` / `x articles`）**只接受 `xUserId`**。用户给的是 `@handle` 或显示名时，Agent 必须先 `mp2rss x list -o json` 查出对应 `xUserId` 再调用。\n\n```bash\nmp2rss x list -o json | jq -r '.items[] | \"\\(.xUserId)\\t@\\(.xUsername)\\t\\(.xDisplayName)\"'\n```\n\n---\n\n## List\n\n```\nmp2rss x list [-q <keyword>] [-p <page>] [--page-size <n>] [-o json]\n```\n\n列出当前 Feed Key 名下已订阅的全部 X 账号。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-q, --query` | — | 按 `xDisplayName` / `xUsername` 模糊匹配 |\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（最大 50） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x list\nmp2rss x list -q elon\nmp2rss x list -p 2 --page-size 20\nmp2rss x list -o json | jq '.items[].xUserId'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"sourceType\": \"x\",\n      \"xUserId\": \"44196397\",\n      \"xUsername\": \"elonmusk\",\n      \"xDisplayName\": \"Elon Musk\",\n      \"xVerified\": true,\n      \"createdAt\": 1776640000000,\n      \"xLastItemAt\": 1776854096000\n    }\n  ],\n  \"total\": 1,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `sourceType` | string | 固定 `\"x\"` |\n| `xUserId` | string | X 数字 user_id（字符串形态） |\n| `xUsername` | string | X handle，不含 `@` |\n| `xDisplayName` | string | X 显示名 |\n| `xVerified` | bool | 是否已认证 |\n| `createdAt` | int64 | 订阅创建时间，unix 毫秒 |\n| `xLastItemAt` | int64? | 最近一条推文/长文收录时间，unix 毫秒，可能为 null |\n\n---\n\n## Posts\n\n```\nmp2rss x posts <xUserId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 `postedAt DESC` 拉取已订阅 X 账号的推文流。**仅允许查询已订阅的 xUserId**，未订阅返回 exit code 4（`X account is not subscribed`）。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（**最大 50**） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x posts 44196397\nmp2rss x posts 44196397 -p 2 --page-size 20\nmp2rss x posts 44196397 -o json | jq '.items[].content'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"postId\": \"1234567890\",\n      \"content\": \"hello world\",\n      \"media\": [{ \"url\": \"https://x.com/img.jpg\", \"type\": \"photo\" }],\n      \"retweetedPost\": null,\n      \"quotedPost\": { \"id\": \"99\", \"content\": \"...\" },\n      \"threadPosts\": [{ \"content\": \"reply 1\" }],\n      \"postedAt\": 1746864000000\n    }\n  ],\n  \"total\": 42,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `postId` | string | 推文业务 ID |\n| `content` | string | 推文正文（明文，未渲染 HTML） |\n| `media` | array | 媒体附件数组；无媒体或解析失败为 `[]` |\n| `media[].url` | string | 媒体资源 URL |\n| `media[].type` | string | `photo` / `video` / `animated_gif` 等 |\n| `retweetedPost` | object? | 转推原推文对象；无则 null |\n| `quotedPost` | object? | 引用的推文对象；无则 null |\n| `threadPosts` | array | Thread 系列推文数组；无则 `[]` |\n| `postedAt` | int64 | 发布时间，unix 毫秒 |\n\n::: tip 结构化 vs 渲染\n本端点返回的是**结构化原始数据**（含 media / quotedPost / threadPosts 嵌套），供 Agent 自定义渲染。\n如果用户只想在阅读器里订阅来看，请引导走 Web 控制台「账户设置」复制的 Feed 链接（公开 RSS / Atom / JSON Feed 层），不要让 Agent 重新拼装。\n:::\n\n---\n\n## Articles\n\n```\nmp2rss x articles <xUserId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 `publishedAt DESC` 拉取已订阅 X 账号的长文（X Articles）流。订阅闭环校验同 `x posts`，未订阅返回 exit code 4。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（**最大 50**） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x articles 44196397\nmp2rss x articles 44196397 -o json | jq '.items[].url'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"url\": \"https://x.com/elonmusk/article/...\",\n      \"title\": \"My take on...\",\n      \"description\": \"summary\",\n      \"contentMarkdown\": \"# Heading\\n\\nfull body markdown source\",\n      \"coverUrl\": \"https://...\",\n      \"publishedAt\": 1747353600000\n    }\n  ],\n  \"total\": 8,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `url` | string | 长文原始 URL |\n| `title` | string | 标题 |\n| `description` | string | 摘要 |\n| `contentMarkdown` | string? | 长文 markdown 原文，可能为 null |\n| `coverUrl` | string? | 封面图 URL |\n| `publishedAt` | int64 | 发布时间，unix 毫秒 |\n\n---\n\n## Agent 综合注意事项\n\n- **xUserId 是字符串**，不要按整数处理（与 `mpId` 不同；handle 起源是数字，但 API 契约统一为字符串）\n- **不接受 `@handle`**：从 `x list` 输出里取 `xUserId` 再调 posts / articles\n- **写类操作不可达**：用户要订阅/取消订阅 X，**统一引导到 Web 控制台**，不要尝试构造 CLI 写命令\n- **结构化解析统一 `-o json`**\n- **字段命名 camelCase**：`xUserId` / `xUsername` / `xDisplayName` / `xLastItemAt` / `postId` / `postedAt` / `publishedAt`\n- **时间字段统一 unix 毫秒**（int64 number）\n- **页大小上限 50**（`x posts` / `x articles` 最大都是 50，注意与 `mp articles` 的 100 不同）\n- 错误码处理见 [errors.md](errors.md)；典型场景：未订阅返回 exit 4，message `X account is not subscribed`\n\nFile v0.2.2:skill-card.md\n\n## Description:\n\nmp2rss helps agents use the mp2rss CLI to manage WeChat Official Account and X (Twitter) RSS subscriptions, authentication, and content retrieval.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[areyoubugcoder](https://clawhub.ai/user/areyoubugcoder)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and developers use this skill to let an agent manage mp2rss subscriptions, check login state, and retrieve WeChat Official Account articles or subscribed X posts/articles through the local CLI.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Install and update paths can execute mutable remote code or alter local agent skills across sessions.\n\nMitigation: Prefer version-pinned releases with published checksums or signatures, avoid curl-to-shell installation, and run self-update or global skill sync only after trusting the publisher.\n\nRisk: The skill depends on a local Feed Key credential for account operations.\n\nMitigation: Use mp2rss auth commands or MP2RSS_FEED_KEY for credential handling, and do not expose full Feed Keys in prompts or logs.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/areyoubugcoder/skills/mp2rss)\n- [Mp2rss service homepage](https://mp2rss.bugcode.dev)\n- [README](artifact/README.md)\n- [Authentication reference](artifact/references/auth.md)\n- [Installation and upgrade reference](artifact/references/install.md)\n- [WeChat Official Account reference](artifact/references/mp.md)\n- [X account reference](artifact/references/x.md)\n- [Error handling reference](artifact/references/errors.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with CLI command examples and JSON output schemas]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires the local mp2rss CLI and Feed Key authentication; structured operations prefer CLI JSON output via -o json.]\n\n## Skill Version(s):\n\n0.2.2 (source: server release metadata, SKILL.md frontmatter, package.json)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v0.2.2:package.json\n\n{\n  \"name\": \"mp2rss\",\n  \"version\": \"0.2.2\",\n  \"description\": \"Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。订阅 / 列出 / 搜索 / 取消订阅公众号，查询公众号历史文章；列出已订阅 X 账号，拉取 X 推文 / 长文流（X 写类操作仅 Web 控制台）；管理 Feed Key 登录态。\",\n  \"license\": \"MIT-0\",\n  \"author\": \"areyoubugcoder\",\n  \"homepage\": \"https://mp2rss.bugcode.dev\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/areyoubugcoder/mp2rss-cli.git\",\n    \"directory\": \"openclaw/mp2rss\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/areyoubugcoder/mp2rss-cli/issues\"\n  },\n  \"keywords\": [\n    \"mp2rss\",\n    \"wechat\",\n    \"weixin\",\n    \"微信\",\n    \"公众号\",\n    \"x\",\n    \"twitter\",\n    \"推特\",\n    \"rss\",\n    \"feed\",\n    \"subscription\",\n    \"订阅\",\n    \"openclaw\",\n    \"skill\"\n  ],\n  \"clawhub\": {\n    \"acceptLicenseTerms\": true\n  }\n}\n\nFile v0.2.2:LICENSE\n\nMIT No Attribution\n\nCopyright 2026 areyoubugcoder\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v0.2.1: 11 files, 22682 bytes\n\nFiles: LICENSE (909b), package.json (949b), README.md (7450b), references/auth.md (3850b), references/errors.md (4967b), references/install.md (2286b), references/mp.md (5716b), references/x.md (7174b), skill-card.md (2541b), SKILL.md (11560b), _meta.json (125b)\n\nFile v0.2.1:SKILL.md\n\n---\nname: mp2rss\ndescription: |\n  Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。\n\n  **当以下情况使用此 Skill**：\n  (1) 用户要订阅 / 取消订阅 / 列出 / 搜索**微信公众号**：「订阅这个公众号 https://mp.weixin.qq.com/s/...」「我订阅了哪些公众号」「列一下我的公众号 RSS」「搜一下我订阅的财经类公众号」「取消订阅那个号」「把 <公众号名> 从订阅里删了」\n  (2) 用户要查**公众号历史文章**：「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」「<公众号名> 的历史文章」\n  (3) 用户要操作 **X（Twitter）账号**：「我订阅了哪些 X 账号」「@elonmusk 最近发了啥」「拉一下某个 X 号的推文 / 长文」（注：X 的订阅 / 取消订阅仅在 Web 控制台，CLI 只能列出已订阅与拉内容）\n  (4) 用户要管理**登录态**：「登录公众号 RSS 服务」「登出 mp2rss」「我的 Feed Key 是什么」「我在 mp2rss 里登录了吗」\n  (5) 用户要**安装 / 配置 Mp2rss CLI**：「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪里」\nversion: 0.2.1\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - mp2rss\n    envVars:\n      - name: MP2RSS_FEED_KEY\n        required: false\n        description: Mp2rss Feed Key；也可由 `mp2rss auth login` 写入配置文件，二者任一即可。\n      - name: MP2RSS_API_URL\n        required: false\n        description: Mp2rss API URL，默认 https://mp2rss.bugcode.dev。\n    homepage: https://mp2rss.bugcode.dev\n    emoji: \"📡\"\n---\n\n# Mp2rss Skill\n\n通过 Mp2rss CLI（Go 二进制 `mp2rss`）把**微信公众号**与 **X（Twitter）账号**转成 RSS / JSON Feed 并管理订阅。本 skill 是路由入口，按用户意图分发到 `references/` 子文档读取详细命令规格。\n\n> **术语提示**：本文档中 **\"X\"** 一律指 X（原 Twitter）平台；用作\"某个公众号\"占位时统一写作 `<公众号名>` 或具名描述，避免与 X 平台混淆。\n\n## ⚠️ Agent 必读约束\n\n### 🔧 运行时前置\n\n所有命令通过本地 `mp2rss` 二进制调用，**不直接打 HTTP**。Agent 不应自己拼 API 请求，统一走 CLI 子命令 + `-o json` 解析。\n\n**Base URL 由 CLI 自动决定**（命令行 flag > 环境变量 > 配置文件 > 默认 `https://mp2rss.bugcode.dev`）。\n\n### 🔑 凭证与登录态\n\n调用任何 `mp2rss mp` / `mp2rss x` 子命令前，**必须先确认登录态**：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `{\"loggedIn\": false}` 时停止后续调用，引导用户跑 `mp2rss auth login`，详见 [references/auth.md](references/auth.md)。\n\n凭证优先级（高 → 低）：命令行 `--api-key` flag > `MP2RSS_FEED_KEY` 环境变量 > `~/.mp2rss/config.json` 配置文件。\n\n### 🔢 mpId 是 int64 / xUserId 是字符串\n\n两种业务键形态不同，**不要混用**：\n\n- **`mpId`**（公众号）：int64 整数。超出 JavaScript `Number.MAX_SAFE_INTEGER`，Agent 在 JS 环境下解析 `mp list / mp articles -o json` 输出时**始终把 mpId 当字符串处理**：\n\n  ```javascript\n  const safe = text.replace(/\"(mpId)\"\\s*:\\s*(\\d+)/g, '\"$1\":\"$2\"');\n  const data = JSON.parse(safe);\n  ```\n\n- **`xUserId`**（X 账号）：API 契约即为字符串（虽然内容是数字串），原样消费即可，不必转换。\n\nPython / Go / jq 原生支持大整数，无 mpId 精度问题。\n\n### 🚫 反幻觉边界\n\n- **禁止编造 mpId / xUserId**：所有业务键必须来自 `mp list` / `mp search` / `x list` 的响应，不得凭空构造\n- **禁止跳过订阅参数校验**：`mp subscribe <url>` 的 `<url>` **必须**是 `https://mp.weixin.qq.com/s/...` 文章链接；不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时**反问用户索要任意一篇文章链接**，不要直接尝试\n- **禁止伪造执行结果**：不调用 CLI 不得告诉用户「已订阅」「已删除」\n- **禁止忽略 exit code**：CLI 返回非 0 必须解析 stderr / JSON envelope 并报告用户\n- **X 订阅 / 取消订阅必须走 Web 控制台**：CLI 与 API 都不暴露 X 写类端点；用户要订阅 X 账号时**只能引导到 <https://mp2rss.bugcode.dev/>「订阅管理 → X」**，不要尝试构造 CLI 写命令\n\n### 🔄 错误处理\n\nCLI 错误统一 JSON envelope（见 [references/errors.md](references/errors.md)）：\n\n```json\n{\"error\": {\"message\": \"...\", \"code\": <int>}}\n```\n\nExit code 速查：\n\n| Code | 含义 | Agent 处理 |\n|------|------|-----------|\n| 0 | 成功 | 解析 stdout |\n| 1 | 通用错误（网络 / cobra 解析层：缺参、flag 值非法，此类输出裸文本非 JSON） | 网络类报告 + 建议稍后重试；解析类修正参数 |\n| 2 | 参数错误（业务校验层） | 检查参数；若是 `mp subscribe` 检查 URL 格式 |\n| 3 | 鉴权失败 | 引导跑 `mp2rss auth login`（见 [auth.md](references/auth.md)） |\n| 4 | 资源不存在 | mpId 错 / 文章 URL 失效 / **X 账号未订阅**（典型 message `X account is not subscribed`） |\n| 5 | 上游不可用 | 报告 + 建议稍后重试 |\n\n---\n\n## 执行流程概览\n\n```\n用户意图 → 路由匹配 → 读对应 references/xxx.md → 构造 mp2rss 子命令 → 执行 → 解析 JSON / 验证 exit code → 返回结果\n                                                                                      ↓\n                                                                                  exit ≠ 0 → 按错误码分支处理\n```\n\n**关键原则**\n\n- **CLI 输出是真理**：所有状态以 `mp2rss xxx -o json` 返回为准，不依赖上下文记忆\n- **`-o json` 优先**：批量 / 结构化场景统一加 `-o json`（除 `auth login` 不支持外）\n- **mpId 字符串化**（JS 环境）；xUserId 本身就是字符串\n\n---\n\n## 指令路由表\n\n| 用户意图 / 自然语言 | 角色 | 详细文档 |\n|------|------|---------|\n| 「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪」 | ⚙️ 安装/配置 | [references/install.md](references/install.md) |\n| 「登录」「登出」「我的 Feed Key 是什么」「我登录了吗」 | 🔐 认证 | [references/auth.md](references/auth.md) |\n| 「订阅这个公众号 https://mp.weixin.qq.com/s/...」 | 📡 公众号订阅 | [references/mp.md](references/mp.md#subscribe) |\n| 「我订阅了哪些公众号」「列一下我的公众号 RSS」 | 📋 公众号列表 | [references/mp.md](references/mp.md#list) |\n| 「搜一下我订阅的财经类公众号」 | 🔍 公众号搜索 | [references/mp.md](references/mp.md#search) |\n| 「取消订阅 <公众号名>」「把 <公众号名> 从订阅里删了」 | 🗑️ 公众号取消订阅 | [references/mp.md](references/mp.md#remove) |\n| 「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」 | 📰 公众号文章 | [references/mp.md](references/mp.md#articles) |\n| 「我订阅了哪些 X 账号」「列一下我的 X 订阅」 | 🐦 X 列表 | [references/x.md](references/x.md#list) |\n| 「<X 账号> 最近发了啥」「@xxx 的推文」 | 🐦 X 推文 | [references/x.md](references/x.md#posts) |\n| 「<X 账号> 的长文 / Articles」 | 🐦 X 长文 | [references/x.md](references/x.md#articles) |\n| 「订阅一个 X 账号 / 取消订阅 X」 | 🐦 ⚠️ Web 控制台 | [references/x.md](references/x.md#关键边界x-订阅必须在-web-控制台完成) |\n| 错误码 / JSON envelope / exit code 处理 | 🚨 错误 | [references/errors.md](references/errors.md) |\n\n---\n\n## 自然语言路由（细分 trigger）\n\n```\n包含 mp.weixin.qq.com/s/ URL              → mp subscribe（参数 = 该 URL）\n「订阅」+ 任何 URL 形态                    → 先校验是不是 mp.weixin.qq.com/s/...，否则反问\n「订阅了哪些 公众号」「我的公众号」          → mp list\n「订阅了哪些 X / Twitter 账号」「我的 X 订阅」 → x list\n「搜公众号」「找一下带 关键词 的公众号」      → mp list -q <kw> 或 mp search <kw>\n「取消订阅 <公众号名>」「删了 <公众号名>」    → 先 mp list -q <名> 确认 mpId，再 mp remove <mpId>\n「<公众号名> 最近发的文章 / 历史文章」        → mp articles <mpId>（先列表确认 mpId）\n「@elonmusk 最近的推文」「<X 账号名> 发了啥」  → 先 x list 拿到 xUserId，再 x posts <xUserId>\n「<X 账号名> 的长文 / Articles」              → 先 x list，再 x articles <xUserId>\n「订阅 / 取消订阅一个 X 账号」               → 引导用户去 Web 控制台「订阅管理 → X」，不要走 CLI\n「登录」「授权」                            → auth login（参考 auth.md 选三种登录模式之一）\n「我的 Key」「登录了吗」「状态」              → auth status -o json\n「登出」「退出登录」                         → auth logout\n```\n\n**决策原则**：\n\n- 有 `mp.weixin.qq.com/s/` URL → 直接 `mp subscribe`\n- 用户给的是**公众号名而非 URL** → **反问索要文章 URL**，不要先 `mp search`（搜索是用于在已订阅源里找，不会订阅新号）\n- 取消订阅公众号前**先用 `mp list -q` / `mp search` 拿到准确 mpId**，避免误删\n- 用户给 X 账号是 `@handle` 或显示名 → **先 `x list -o json` 找 xUserId**，不要把 handle 直接传给 `x posts / x articles`\n- 用户想**添加** X 订阅 → **不要尝试 CLI**，直接引导 <https://mp2rss.bugcode.dev/>「订阅管理 → X」\n\n---\n\n## API 路由（CLI 子命令总表）\n\n| 子命令 | 用途 | 详细文档 |\n|--------|------|---------|\n| `mp2rss auth login [-k <key>] [--no-browser]` | 登录（三种模式） | [auth.md](references/auth.md#log-in) |\n| `mp2rss auth status [-o json]` | 查询登录态 | [auth.md](references/auth.md#check-status) |\n| `mp2rss auth logout` | 登出 | [auth.md](references/auth.md#log-out) |\n| `mp2rss mp subscribe <article-url> [-o json]` | 订阅公众号 | [mp.md](references/mp.md#subscribe) |\n| `mp2rss mp list [-q <kw>] [-p <page>] [--page-size <n>] [-o json]` | 列出公众号订阅 | [mp.md](references/mp.md#list) |\n| `mp2rss mp search <keyword> [-o json]` | 搜索已订阅公众号 | [mp.md](references/mp.md#search) |\n| `mp2rss mp remove <mpId> [-y] [-o json]` | 取消订阅公众号 | [mp.md](references/mp.md#remove) |\n| `mp2rss mp articles <mpId> [-p <page>] [--page-size <n>] [-o json]` | 查公众号文章 | [mp.md](references/mp.md#articles) |\n| `mp2rss x list [-q <kw>] [-p <page>] [--page-size <n>] [-o json]` | 列出已订阅 X 账号 | [x.md](references/x.md#list) |\n| `mp2rss x posts <xUserId> [-p <page>] [--page-size <n>] [-o json]` | 拉 X 推文流 | [x.md](references/x.md#posts) |\n| `mp2rss x articles <xUserId> [-p <page>] [--page-size <n>] [-o json]` | 拉 X 长文流 | [x.md](references/x.md#articles) |\n| `mp2rss update [--check]` | 升级 CLI | [install.md](references/install.md#升级) |\n\n> X 写类（搜索 / 订阅 / 取消订阅）**不存在对应 CLI 命令**，仅 Web 控制台提供，详见 [x.md](references/x.md#关键边界x-订阅必须在-web-控制台完成)。\n\n---\n\n## 全局 flag\n\n所有子命令都支持：\n\n| Flag | 等价环境变量 | 说明 |\n|------|-------------|------|\n| `-o, --output <table\\|json>` | — | 输出格式，默认 `table` |\n| `--api-key <feed-key>` | `MP2RSS_FEED_KEY` | 覆盖 Feed Key |\n| `--api-url <url>` | `MP2RSS_API_URL` | 覆盖 API 地址 |\n\n优先级（高 → 低）：CLI flag > env > 配置文件 > 默认。\n\nFile v0.2.1:README.md\n\n# Mp2rss Skill\n\n[![License: MIT-0](https://img.shields.io/badge/License-MIT--0-blue.svg)](https://opensource.org/licenses/MIT-0)\n\n让 AI Agent 帮你管理 **微信公众号** 与 **X（Twitter）账号** 的 RSS 订阅 —— 一句话订阅、自然语言查找、按需读历史文章 / 推文 / 长文。\n\n本目录是 [Mp2rss](https://mp2rss.bugcode.dev) 服务的 OpenClaw Agent Skill 包，随 [`mp2rss` CLI](https://github.com/areyoubugcoder/mp2rss-cli) 同仓库维护（`openclaw/mp2rss/` 子目录），发布到 ClawHub（slug：`mp2rss`）。Claude Code 用户请改用仓库根的 `skills/`（插件市场 / `npx skills add` 安装），见主仓库 README。\n\n---\n\n## ✨ 核心能力\n\n### 微信公众号（MP）\n\n| 能力 | 说明 |\n|------|------|\n| 📡 **一键订阅** | 发一个公众号文章链接（`mp.weixin.qq.com/s/...`），Agent 自动把整个公众号订阅到你的 Feed |\n| 📋 **列表与搜索** | 「我订阅了哪些公众号」「搜一下我订阅的财经类公众号」 |\n| 🗑️ **取消订阅** | 「把 某号 从订阅里删了」，Agent 先核对 mpId 再删 |\n| 📰 **历史文章** | 「某号 最近发了什么」/「拉一下 某号 的文章」 |\n\n### X（Twitter）账号\n\n| 能力 | 说明 |\n|------|------|\n| 🐦 **列出 X 订阅** | 「我订阅了哪些 X 账号」 |\n| 📨 **推文流** | 「@elonmusk 最近发了啥」（Agent 先 `x list` 找到 `xUserId` 再拉推文） |\n| 📝 **长文流** | 「拉一下 某 X 账号的 Articles」 |\n| ⚠️ **订阅 / 取消订阅 X 账号** | **仅在 Web 控制台**（<https://mp2rss.bugcode.dev/>）—— CLI 与 API 都不暴露 X 写类端点，Agent 会引导你去控制台 |\n\n### 通用\n\n| 能力 | 说明 |\n|------|------|\n| 🔐 **登录态管理** | 「我的 Feed Key 是什么」「登录 mp2rss」 |\n| 📤 **结构化输出** | 所有命令支持 `-o json`，Agent 可直接解析做后续处理 |\n\n---\n\n## 💡 使用场景\n\n### 通勤路上看到好公众号\n\n> 👤 订阅这个公众号 https://mp.weixin.qq.com/s/abc123xyz\n>\n> 🤖 已订阅「某公众号」到你的 Feed。\n\n### 不记得订过哪些号\n\n> 👤 我订阅了哪些公众号？\n>\n> 🤖 当前共 42 个订阅。前 20 个：某公众号（最近发文 2 小时前）、另一个号（昨天）……\n\n### 找特定主题\n\n> 👤 我订阅的财经类公众号有哪些\n>\n> 🤖 找到 5 个匹配：财经早知道、第一财经……\n\n### 翻看历史\n\n> 👤 财经早知道 最近发了什么\n>\n> 🤖 最近 10 篇文章：1. xxx 标题（昨天）2. xxx 标题（前天）……\n\n### 不想看了\n\n> 👤 把 财经早知道 从订阅里删了\n>\n> 🤖 确认删除「财经早知道」（mpId 123456）？已删除 ✓\n\n### 看大 V 推文\n\n> 👤 @elonmusk 最近发了啥？\n>\n> 🤖 （先 `x list` 拿到 xUserId 44196397）最近 5 条推文：1. ……\n\n### 想订阅一个 X 账号\n\n> 👤 帮我订阅 @paulg 这个号\n>\n> 🤖 X 账号的订阅 / 取消订阅只能在 Web 控制台操作。打开 https://mp2rss.bugcode.dev/「订阅管理 → X」搜索 paulg 完成订阅；订阅好我就能用 `mp2rss x posts/articles` 帮你拉内容。\n\n---\n\n## 📦 安装\n\n### 前置：装 Mp2rss CLI 二进制\n\nskill 本身只描述如何调用 CLI，所以必须先装 `mp2rss` 二进制（任选其一）：\n\n```bash\n# 方式 A：npm（推荐，跨平台一致）\npnpm add -g @mp2rss/cli\n\n# 方式 B：macOS / Linux 一键脚本\ncurl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh\n```\n\n也可在 [Releases](https://github.com/areyoubugcoder/mp2rss-cli/releases/latest) 下载对应平台二进制。\n\n### 装 Skill\n\n```bash\n# 方式 A：通过 ClawHub（推荐）\nopenclaw skills install mp2rss\n\n# 方式 B：手动\nmkdir -p ~/.openclaw/workspace/skills/mp2rss\ncd ~/.openclaw/workspace/skills/mp2rss\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/openclaw/mp2rss/SKILL.md -o SKILL.md\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/openclaw/mp2rss/package.json -o package.json\n# 视需要再拉 references/ 子文档\n```\n\n---\n\n## 🔑 授权登录\n\n安装完成后说「登录 mp2rss」，Agent 自动跑 `mp2rss auth login` 走浏览器 loopback 授权。CI / 无头环境用：\n\n```bash\nmp2rss auth login -k <feed-key>            # 直传\nmp2rss auth login --no-browser             # 远程模式，仅打印授权 URL\n```\n\nFeed Key 可在 <https://mp2rss.bugcode.dev/> 登录后查看或重置。配置文件位置 `~/.mp2rss/config.json`。\n\n### 用环境变量配置（可选）\n\n```bash\nexport MP2RSS_FEED_KEY=gk_live_xxxxxxxx\nexport MP2RSS_API_URL=https://mp2rss.bugcode.dev    # 自托管时需要\n```\n\n优先级（高 → 低）：CLI flag `--api-key` > `MP2RSS_FEED_KEY` env > `~/.mp2rss/config.json`。\n\n---\n\n## 🛠 子命令速查\n\n### 通用\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss auth login [-k <key>] [--no-browser]` | 登录（三种模式：浏览器 / Feed Key 直传 / 远程） |\n| `mp2rss auth status [-o json]` | 查登录态、Feed Key 来源、最近登录时间 |\n| `mp2rss auth logout` | 清空 Feed Key |\n\n### 微信公众号\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss mp subscribe <article-url> [-o json]` | 订阅；参数必须是 `mp.weixin.qq.com/s/...` 文章 URL |\n| `mp2rss mp list [-q <kw>] [-p <page>] [--page-size <n>]` | 列出公众号订阅 |\n| `mp2rss mp search <keyword>` | `mp list -q` 语法糖 |\n| `mp2rss mp remove <mpId> [-y]` | 取消订阅公众号 |\n| `mp2rss mp articles <mpId> [-p <page>] [--page-size <n>]` | 查公众号历史文章 |\n\n### X（Twitter）\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss x list [-q <kw>] [-p <page>] [--page-size <n>]` | 列出已订阅的 X 账号 |\n| `mp2rss x posts <xUserId> [-p <page>] [--page-size <n>]` | 拉 X 账号推文流 |\n| `mp2rss x articles <xUserId> [-p <page>] [--page-size <n>]` | 拉 X 账号长文流 |\n\n> X 账号**搜索 / 订阅 / 取消订阅**仅 Web 控制台支持，CLI 与 Open API 都不暴露这些写类端点。\n\n完整字段、JSON shape 与 Agent 行为规范见 [SKILL.md](SKILL.md) 和 [references/](references/) 子文档。\n\n---\n\n## ⚠️ 重要约束\n\n- **订阅公众号传的是文章 URL** —— 不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时 Agent 应反问用户索要任意一篇文章链接\n- **`mpId` 是 int64** —— JS 环境解析 JSON 时需先把 `mpId` 替换为字符串再 `JSON.parse`，否则精度丢失\n- **`xUserId` 是字符串** —— 虽然内容是数字串，API 契约即字符串形态，无需转换；注意不要传 `@handle`\n- **取消订阅公众号前先核对 mpId** —— 用 `mp list -q` / `mp search` 拿到准确 mpId 再删，避免误删\n- **X 写类操作不可达** —— 用户要订阅 / 取消订阅 X 账号时，Agent 必须引导到 Web 控制台「订阅管理 → X」，不要尝试构造 CLI 命令\n- **`auth login` 不支持 `-o json`** —— 仅输出文本反馈，其它子命令均支持\n\n---\n\n## 🔗 相关\n\n- [Mp2rss 服务](https://mp2rss.bugcode.dev) —— 微信公众号 / X 账号 RSS 订阅服务\n- [`mp2rss` CLI](https://github.com/areyoubugcoder/mp2rss-cli) —— Go 命令行客户端（Skill 调用的底层）\n- [Mp2rss 文档站](https://areyoubugcoder.github.io/Mp2RSS/) —— 服务介绍、Open API 与 CLI 完整文档\n\n---\n\n## License\n\n[MIT-0](LICENSE)\n\nFile v0.2.1:_meta.json\n\n{\n  \"ownerId\": \"kn7acxx408jk3phdk3326sx5fs86zndf\",\n  \"slug\": \"mp2rss\",\n  \"version\": \"0.2.1\",\n  \"publishedAt\": 1787885158853\n}\n\nFile v0.2.1:references/auth.md\n\n# 认证管理\n\n本文档供 Agent 在用户询问「登录」「登出」「我的 Feed Key 是什么」「我登录了吗」「在 mp2rss 里登录」时按需读取。\n\n## 触发条件\n\n调用任何 `mp2rss mp` 子命令前，**必须先**确认登录态：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `loggedIn: false` 时停止后续 mp 调用，引导用户登录后再继续原始请求。\n\n## Log in\n\n```\nmp2rss auth login [-k <feed-key>] [--no-browser]\n```\n\n三种模式：\n\n| 模式 | 命令 | 适用场景 |\n|------|------|---------|\n| 浏览器（默认） | `mp2rss auth login` | 桌面环境；CLI 启动本地 loopback HTTP 服务，打开浏览器登录后回调写入 `~/.mp2rss/config.json` |\n| Feed Key 直传 | `mp2rss auth login -k <feed-key>` | CI / 无头环境；Feed Key 在 https://mp2rss.bugcode.dev/ 登录后获取或重置 |\n| 远程模式 | `mp2rss auth login --no-browser` | 远程 SSH / 无浏览器；CLI 仅打印授权 URL，用户在本地浏览器打开后复制 Feed Key 回填 |\n\n```bash\nmp2rss auth login                          # 默认浏览器\nmp2rss auth login -k gk_live_xxxxxxxx      # 直传\nmp2rss auth login --no-browser             # 远程\n```\n\n### Agent 处理远程模式\n\n`mp2rss auth login --no-browser` 输出形如：\n\n```\n请在浏览器打开下面的链接完成授权：\n\n  https://mp2rss.bugcode.dev/auth/cli?code=...\n\n授权后将页面上显示的 Feed Key 粘贴到此终端：\n```\n\nAgent 应：\n\n1. **完整提取授权 URL** 转发给用户\n2. 提示「请在浏览器打开此链接，登录后把页面上的 Feed Key 粘贴回这里」\n3. 不要替用户决定使用哪个浏览器；不要把 URL 截断或缩短\n\n⚠️ `auth login` **不支持 `-o json`**，输出为纯文本反馈。\n\n## Check status\n\n```\nmp2rss auth status [-o json]\n```\n\n```bash\nmp2rss auth status            # 人类可读\nmp2rss auth status -o json    # Agent 解析\n```\n\n### JSON shape（已登录）\n\n```json\n{\n  \"loggedIn\": true,\n  \"source\": \"config\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\",\n  \"feedKeyMasked\": \"abcdef***\",\n  \"name\": \"张三\",\n  \"email\": \"user@example.com\",\n  \"lastLoginAt\": 1705000000000,\n  \"lastVerifyAt\": 1705000001000\n}\n```\n\n### JSON shape（未登录）\n\n```json\n{\n  \"loggedIn\": false,\n  \"source\": \"none\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\"\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `loggedIn` | bool | 是否已配置可用凭证 |\n| `source` | string | `\"env\"` / `\"config\"` / `\"none\"` |\n| `apiUrl` | string | 当前生效的 API URL |\n| `feedKeyMasked` | string | 已脱敏 Feed Key（仅前几位 + `***`） |\n| `name` | string? | 账号昵称；仅浏览器登录回调成功时落盘，`-k` / `--no-browser` 流程没有，`omitempty` 省略 |\n| `email` | string? | 账号邮箱；同 `name`，仅浏览器登录流程有 |\n| `lastLoginAt` | int64 | 最近登录时间，unix 毫秒 |\n| `lastVerifyAt` | int64 | 最近一次验证时间，unix 毫秒 |\n\n## Log out\n\n```\nmp2rss auth logout\n```\n\n清空 `~/.mp2rss/config.json` 里的 `feed_key`，保留 `api_url` 等其它配置。\n\n```bash\nmp2rss auth logout\n```\n\n## 凭证优先级\n\n高 → 低：\n\n1. CLI flag：`--api-key <feed-key>`\n2. 环境变量：`MP2RSS_FEED_KEY`\n3. 配置文件：`~/.mp2rss/config.json` 的 `feed_key`\n\nAPI URL 同理：`--api-url` > `MP2RSS_API_URL` > 配置文件 > 默认 `https://mp2rss.bugcode.dev`。\n\n## Agent 注意事项\n\n- 调用 `mp2rss mp` 任何子命令前先 `mp2rss auth status -o json`\n- 时间字段是 unix 毫秒（int64），不是格式化字符串\n- 不要直接读写 `~/.mp2rss/config.json`，统一用 `mp2rss auth ...` 子命令\n- 鉴权错误（exit code 3 / HTTP 401）时引导用户跑 `mp2rss auth login`，不要反复重试\n- `feedKeyMasked` 仅供展示用户身份，**不要试图从掩码还原完整 Key**\n\nFile v0.2.1:references/errors.md\n\n# 错误处理\n\n本文档供 Agent 在 mp2rss 命令返回非零 exit code 或 JSON envelope 含 `error` 字段时按需读取。\n\n## JSON 错误 envelope\n\n任何子命令在 `-o json` 模式下出错时统一返回：\n\n```json\n{\n  \"error\": {\n    \"message\": \"human-readable 错误信息\",\n    \"code\": <int>\n  }\n}\n```\n\n- `code` 字段是 HTTP 状态码（来自上游 API）或 CLI 自身 exit code\n- `message` 是人类可读描述（中文），可直接转发给用户\n\n> ⚠️ 例外（实测 CLI 1.1.0）：**cobra 参数解析层**的错误（必填位置参数缺失、flag 值类型非法如 `--page-size abc`）以 exit 1 退出，且**即使带 `-o json` 也输出裸文本到 stderr**，不是 JSON envelope。Agent 解析 JSON 失败时应回退读 stderr 文本。\n\n## Exit codes\n\n| Code | 含义 | 典型场景 | Agent 处理 |\n|------|------|---------|-----------|\n| `0` | 成功 | 命令正常执行 | 解析 stdout |\n| `1` | 通用错误（网络）/ 解析层错误 | DNS 失败 / TCP 连不上 / 超时；**必填参数缺失、flag 值非法**（cobra 解析层，裸文本 stderr） | 网络类：报告 + 建议稍后重试；解析类：修正命令参数后重试一次 |\n| `2` | 参数错误（业务校验层） | `mp subscribe` URL 不是 `mp.weixin.qq.com/s/...` / 位置参数格式非法（如 mpId 非数字） | 解析 envelope 给用户具体提示；URL 错就反问用户索要正确文章链接 |\n| `3` | 鉴权失败 | Feed Key 错 / 过期 / 未配置 / HTTP 401 | 引导用户跑 `mp2rss auth login`（见 [auth.md](auth.md)）；**不要反复重试** |\n| `4` | 资源不存在 | mpId 错 / 文章 URL 失效 / **xUserId 未订阅**（X 读类端点要求已订阅）/ HTTP 404 | MP：用 `mp list` 重新核对 mpId 或更换文章链接；X：先 `x list` 确认是否已订阅，未订阅的话引导用户去 Web 控制台「订阅管理 → X」 |\n| `5` | 上游不可用 | API 服务挂 / HTTP 5xx | 报告 + 建议稍后重试 |\n\n## HTTP code 对应\n\nCLI 把上游 HTTP 状态码映射到上面的 exit codes：\n\n| HTTP | Exit | 说明 |\n|------|------|------|\n| 200 | 0 | OK |\n| 400 | 2 | 请求参数错 |\n| 401 | 3 | Feed Key 无效 |\n| 403 | 1 | 权限不足（CLI 未特判 403，落到通用错误；message 会带上游原文） |\n| 404 | 4 | 资源不存在 |\n| 429 | 1 | 限流；CLI 会自动退避重试 2 次，仍失败后按通用错误退出（未特判） |\n| 5xx | 5 | 上游错误（CLI 同样先自动退避重试 2 次） |\n\n## Agent 处理策略\n\n### 失败重试\n\n| 错误类型 | 重试策略 |\n|---------|---------|\n| Exit 1（网络） | 等待 5 秒后**最多重试一次**；二次失败明确报告网络问题 |\n| Exit 1（解析层：缺参 / flag 值非法） | **不要原样重试**；按 stderr 提示修正命令参数后再执行 |\n| Exit 3（鉴权） | **不要重试**；直接引导 `mp2rss auth login` |\n| Exit 4（不存在） | **不要重试**；引导用户核对 mpId / URL |\n| Exit 5（上游 5xx） | 等待 5 秒后**最多重试一次**；二次失败建议稍后再试 |\n| Exit 2（参数） | **不要重试**；告诉用户具体是哪个参数错了 |\n\n### 错误信息提取\n\n人类可读模式（无 `-o json`）下，错误写到 stderr，Agent 应捕获 stderr 转发给用户。\n\nJSON 模式下，错误 envelope 写到 stdout（保持单一输出流），Agent 解析 `error.message` 和 `error.code` 字段。\n\n### 反幻觉\n\n- **禁止编造错误信息**：所有报告给用户的错误必须来自 CLI 真实输出（stderr 或 JSON envelope）\n- **禁止隐瞒错误**：CLI 返回非零退出码时必须告诉用户，不能装作执行成功\n- **禁止过度解读 message**：`error.message` 直接转发，不要\"翻译\"成自己的描述（容易扭曲原意）\n\n## 常见错误样例\n\n### Feed Key 失效\n\n```bash\n$ mp2rss mp list -o json\n{\"error\":{\"message\":\"鉴权失败：Feed Key 无效或已重置，请重新登录\",\"code\":401}}\n$ echo $?\n3\n```\n\nAgent → 引导 `mp2rss auth login` 而非重试。\n\n### URL 格式错\n\n```bash\n$ mp2rss mp subscribe https://example.com/article -o json\n{\"error\":{\"message\":\"参数错误：subscribe 需要 mp.weixin.qq.com/s/... 文章链接\",\"code\":400}}\n$ echo $?\n2\n```\n\nAgent → 告诉用户必须用微信公众号文章 URL，并反问索要正确链接。\n\n### mpId 不存在\n\n```bash\n$ mp2rss mp articles 999999999 -o json\n{\"error\":{\"message\":\"未找到（HTTP 404）：MP account is not subscribed\",\"code\":404}}\n$ echo $?\n4\n```\n\nAgent → 用 `mp list` 核对正确 mpId。\n\n### X 账号未订阅\n\n```bash\n$ mp2rss x posts 999999999 -o json\n{\"error\":{\"message\":\"X account is not subscribed\",\"code\":404}}\n$ echo $?\n4\n```\n\nAgent → 提示用户：`mp2rss x posts / x articles` **只能查已订阅 X 账号**；订阅 X 账号必须去 Web 控制台「订阅管理 → X」操作（CLI 与 API 都不暴露 X 写类端点）。先 `mp2rss x list` 看一下是否已订阅 / `xUserId` 是否抄错。\n\nFile v0.2.1:references/install.md\n\n# 安装与升级\n\n本文档供 Agent 在用户询问「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪」时按需读取。\n\n## 环境要求\n\n- macOS / Linux / Windows 任一\n- Node.js ≥ 18（仅 npm 安装方式需要）\n- Go ≥ 1.21（仅从源码构建需要）\n\n## 安装方式\n\n任选其一：\n\n### A. npm（推荐，跨平台一致）\n\n```bash\npnpm add -g @mp2rss/cli\n# 或 npm install -g @mp2rss/cli\n```\n\n`postinstall` 脚本会按平台自动下载对应的 Go 二进制，绑定为全局 `mp2rss` 命令。\n\n### B. 一键脚本（macOS / Linux）\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh\n```\n\n自动选 macOS / Linux 对应平台二进制，安装到 `/usr/local/bin` 或 `~/.local/bin`。\n\n### C. 直接下载 Release 二进制\n\n打开 <https://github.com/areyoubugcoder/mp2rss-cli/releases/latest> 选对应平台的归档下载，解压后把 `mp2rss` 加入 `PATH`。\n\n可用平台：\n\n| OS | amd64 | arm64 |\n|----|:---:|:---:|\n| macOS | ✅ | ✅ |\n| Linux | ✅ | ✅ |\n| Windows | ✅ | ✅ |\n\n## 验证安装\n\n```bash\nmp2rss --version\n```\n\n预期输出版本号字符串（如 `mp2rss v0.x.x`），exit 0。\n\n## 升级\n\n```bash\nmp2rss update              # 检查并升级到最新\nmp2rss update --check      # 只检查不升级\n```\n\n`update` 会从 GitHub Releases 拉最新版二进制就地替换。注意：通过 npm 安装的二进制由 npm 管理，建议改用 `pnpm up -g @mp2rss/cli`。\n\n## 配置文件位置\n\n`~/.mp2rss/config.json`（目录权限 `0700` / 文件权限 `0600`），结构：\n\n```json\n{\n  \"feed_key\": \"9f3a2c...（64 位 hex）\",\n  \"api_url\": \"https://mp2rss.bugcode.dev\",\n  \"last_login_at\": 1747194198000,\n  \"last_verify_at\": 1747194198000\n}\n```\n\n- 由 `mp2rss auth login` 自动写入\n- `mp2rss auth logout` 只清 `feed_key`，保留 `api_url` 等其它字段\n- Agent **不应该**直接读写此文件，统一用 `mp2rss auth ...` 子命令\n\n## Agent 注意事项\n\n- 用户问\"装好了吗\"→ `mp2rss --version`，exit 0 即装好\n- 用户问\"配置在哪\"→ 答 `~/.mp2rss/config.json` + 强调不要手改，用 `mp2rss auth login` 管理\n- 用户问\"怎么升级\"→ 给 `mp2rss update`；若用户是 npm 装的优先建议 `pnpm up -g @mp2rss/cli`\n\nFile v0.2.1:references/mp.md\n\n# 微信公众号（MP）订阅与文章管理\n\n本文档供 Agent 在用户询问**公众号**订阅、列出、搜索、取消订阅、查文章等需求时按需读取。\n\n**调用前提**：先确认登录态（见 [auth.md](auth.md)）；未登录时不要直接调本节命令。\n\n> 本文档中所有用作\"某个公众号\"占位的地方一律写作 `<公众号名>` 或具名形式（如「财经早知道」），避免歧义。\n\n---\n\n## Subscribe\n\n```\nmp2rss mp subscribe <article-url> [-o json]\n```\n\n订阅一个公众号。⚠️ **传入的是文章 URL**（`https://mp.weixin.qq.com/s/...`），不是公众号名、不是二维码、不是公众号主页链接。从公众号任意一篇文章里复制链接即可，Mp2rss 会从该文章解析出所属公众号并把整个公众号订阅到你的 Feed。\n\n```bash\nmp2rss mp subscribe https://mp.weixin.qq.com/s/abcDEFghIJKlmnop\nmp2rss mp subscribe https://mp.weixin.qq.com/s/abc -o json\n```\n\n### JSON shape\n\n```json\n{\n  \"ok\": true,\n  \"articleUrl\": \"https://mp.weixin.qq.com/s/...\"\n}\n```\n\n### Agent 处理\n\n- 用户给的不是 `mp.weixin.qq.com/s/...` URL → **反问**索要任意一篇文章链接，不要直接试\n- 用户给的是公众号名 → 不能搜索 + 订阅，必须用户提供文章 URL\n- 订阅成功后建议跟一句 `mp list -q <推断的公众号名>` 让用户看到刚订阅的条目（可选）\n\n---\n\n## List\n\n```\nmp2rss mp list [-q <keyword>] [-p <page>] [--page-size <n>] [-o json]\n```\n\n列出当前 Feed Key 名下的所有订阅。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-q, --query` | — | 按公众号名模糊搜索（与 `mp search` 等价） |\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（最大 50） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss mp list\nmp2rss mp list -q 财经\nmp2rss mp list -p 2 --page-size 50\nmp2rss mp list -o json | jq '.items[].mpName'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"mpId\": 123456,\n      \"mpName\": \"某公众号\",\n      \"mpAvatarUrl\": \"https://...\",\n      \"createdAt\": 1705000000000,\n      \"mpLastArticleAt\": 1705000050000\n    }\n  ],\n  \"total\": 42,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n⚠️ **`mpId` 是 int64**，JS 环境解析前先正则替换为字符串（见 [SKILL.md - mpId 是 int64](../SKILL.md#-mpid-是-int64) 段）。\n\n---\n\n## Search\n\n```\nmp2rss mp search <keyword> [-p <page>] [--page-size <n>] [-o json]\n```\n\n`mp2rss mp list -q <keyword>` 的语法糖，flag 集与输出与 `list` 完全一致。\n\n```bash\nmp2rss mp search 财经\nmp2rss mp search 财经 -o json\n```\n\n### Agent 注意\n\n`mp search` **只在已订阅源中模糊查找**，不会发现公众号、不会订阅新号。用户要\"搜公众号订阅\"指的就是这个；要订阅新公众号必须走 `mp subscribe + 文章 URL` 路径。\n\n---\n\n## Remove\n\n```\nmp2rss mp remove <mpId> [-y] [-o json]\n```\n\n按 mpId 取消订阅。`-y` 跳过交互式确认（适合脚本调用）。\n\n```bash\nmp2rss mp remove 123456            # 会交互式确认\nmp2rss mp remove 123456 -y         # 直接执行\nmp2rss mp remove 123456 -y -o json\n```\n\n### JSON shape\n\n```json\n{\n  \"ok\": true,\n  \"mpId\": 123456\n}\n```\n\n### Agent 处理\n\n- **取消订阅前必须先确认 mpId**：用 `mp list -q <name> -o json` 或 `mp search <name> -o json` 拿到准确 mpId 再调 remove\n- 用户只给公众号名时，不要凭名字猜 mpId\n- 若 `items` 多条匹配 → 列给用户让其挑选哪个，不要默认删第一个\n- 自动化脚本场景统一加 `-y`，否则 Agent 会卡在交互式 prompt\n\n---\n\n## Articles\n\n```\nmp2rss mp articles <mpId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 mpId 查询公众号历史文章。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 100 | 每页条数（最大 100） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss mp articles 123456\nmp2rss mp articles 123456 -p 2 --page-size 100\nmp2rss mp articles 123456 -o json | jq '.items[].title'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"mpId\": 123456,\n      \"articleId\": \"article-id-string\",\n      \"title\": \"文章标题\",\n      \"summary\": \"文章摘要\",\n      \"coverImageUrl\": \"https://...\",\n      \"originalUrl\": \"https://mp.weixin.qq.com/s/...\",\n      \"contentMarkdown\": \"# Markdown 正文\",\n      \"publishedAt\": 1705000000000,\n      \"updatedAt\": 1705000010000\n    }\n  ]\n}\n```\n\n⚠️ **没有分页字段**（无 `total` / `page` / `pageSize`）；`items` 为空数组即视为本页结束。Agent 翻页直接 `-p N` 试到空为止。\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `mpId` | int64 | 公众号 ID（同样字符串化处理） |\n| `articleId` | string | 文章唯一 ID |\n| `title` | string | 文章标题 |\n| `summary` | string | 文章摘要（可能为空） |\n| `coverImageUrl` | string | 封面图 URL（可能为空） |\n| `originalUrl` | string | 原文链接（`mp.weixin.qq.com/s/...`） |\n| `contentMarkdown` | string | Markdown 格式正文 |\n| `publishedAt` | int64 | 发布时间，unix 毫秒 |\n| `updatedAt` | int64 | 更新时间，unix 毫秒 |\n\n---\n\n## Agent 综合注意事项\n\n- **结构化解析统一 `-o json`**\n- **字段命名 camelCase**：`mpId` / `mpName` / `mpAvatarUrl` / `mpLastArticleAt` / `articleId` / `originalUrl` / `contentMarkdown` / `publishedAt`\n- **mpId 是 int64**：JS 解析前先字符串化（见 [SKILL.md](../SKILL.md#-mpid-是-int64)）\n- **时间字段统一 unix 毫秒**（int64 number）\n- **取消订阅前先 list/search 确认 mpId**\n- **文章列表无分页字段**，靠 `--page-size`（最大 100）+ `-p` 翻页\n- 错误码处理见 [errors.md](errors.md)\n\nFile v0.2.1:references/x.md\n\n# X（Twitter）订阅与内容拉取\n\n本文档供 Agent 在用户询问 X / Twitter 账号订阅、推文、长文相关需求时按需读取。\n\n**调用前提**：先确认登录态（见 [auth.md](auth.md)）；未登录时不要直接调本节命令。\n\n---\n\n## ⚠️ 关键边界：X 订阅必须在 Web 控制台完成\n\nX 账号的**搜索**与**订阅 / 取消订阅**仅由 Web 控制台 <https://mp2rss.bugcode.dev/> 提供，**CLI 与 Open API 都不暴露这些写类端点**。\n\nCLI 在 `x` 子命令组下**只覆盖读类**三件事：\n\n| 子命令 | 作用 |\n|--------|------|\n| `mp2rss x list`     | 列出当前 Feed Key 已订阅的 X 账号 |\n| `mp2rss x posts`    | 拉取已订阅 X 账号的推文流 |\n| `mp2rss x articles` | 拉取已订阅 X 账号的长文流 |\n\n### Agent 路由策略\n\n- 用户说「订阅 X 上的 @xxx」「订阅这个推特账号」「在 mp2rss 里加个 X 号」\n  → **不要尝试 CLI**，告诉用户去 Web 控制台「订阅管理 → X」搜索并订阅，之后回到这里可用 CLI 列出/拉内容。\n- 用户说「取消订阅 X 账号 xxx」\n  → 同上，引导去 Web 控制台。\n- 用户说「我订阅了哪些 X 号」「拉一下 @elonmusk 的推文」\n  → 走本文档的 `x list` / `x posts` 流程。\n\n---\n\n## xUserId vs @handle\n\nX 的业务键是 `xUserId`（X 平台的数字 user_id，字符串形态），**不是** `@handle`：\n\n- `@handle` 用户可随时改，订阅指向会失效；\n- `xUserId` 是 X 平台稳定的唯一 ID。\n\nCLI 与 Open API 的所有 X 读类端点（`x posts` / `x articles`）**只接受 `xUserId`**。用户给的是 `@handle` 或显示名时，Agent 必须先 `mp2rss x list -o json` 查出对应 `xUserId` 再调用。\n\n```bash\nmp2rss x list -o json | jq -r '.items[] | \"\\(.xUserId)\\t@\\(.xUsername)\\t\\(.xDisplayName)\"'\n```\n\n---\n\n## List\n\n```\nmp2rss x list [-q <keyword>] [-p <page>] [--page-size <n>] [-o json]\n```\n\n列出当前 Feed Key 名下已订阅的全部 X 账号。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-q, --query` | — | 按 `xDisplayName` / `xUsername` 模糊匹配 |\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（最大 50） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x list\nmp2rss x list -q elon\nmp2rss x list -p 2 --page-size 20\nmp2rss x list -o json | jq '.items[].xUserId'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"sourceType\": \"x\",\n      \"xUserId\": \"44196397\",\n      \"xUsername\": \"elonmusk\",\n      \"xDisplayName\": \"Elon Musk\",\n      \"xVerified\": true,\n      \"createdAt\": 1776640000000,\n      \"xLastItemAt\": 1776854096000\n    }\n  ],\n  \"total\": 1,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `sourceType` | string | 固定 `\"x\"` |\n| `xUserId` | string | X 数字 user_id（字符串形态） |\n| `xUsername` | string | X handle，不含 `@` |\n| `xDisplayName` | string | X 显示名 |\n| `xVerified` | bool | 是否已认证 |\n| `createdAt` | int64 | 订阅创建时间，unix 毫秒 |\n| `xLastItemAt` | int64? | 最近一条推文/长文收录时间，unix 毫秒，可能为 null |\n\n---\n\n## Posts\n\n```\nmp2rss x posts <xUserId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 `postedAt DESC` 拉取已订阅 X 账号的推文流。**仅允许查询已订阅的 xUserId**，未订阅返回 exit code 4（`X account is not subscribed`）。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（**最大 50**） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x posts 44196397\nmp2rss x posts 44196397 -p 2 --page-size 20\nmp2rss x posts 44196397 -o json | jq '.items[].content'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"postId\": \"1234567890\",\n      \"content\": \"hello world\",\n      \"media\": [{ \"url\": \"https://x.com/img.jpg\", \"type\": \"photo\" }],\n      \"retweetedPost\": null,\n      \"quotedPost\": { \"id\": \"99\", \"content\": \"...\" },\n      \"threadPosts\": [{ \"content\": \"reply 1\" }],\n      \"postedAt\": 1746864000000\n    }\n  ],\n  \"total\": 42,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `postId` | string | 推文业务 ID |\n| `content` | string | 推文正文（明文，未渲染 HTML） |\n| `media` | array | 媒体附件数组；无媒体或解析失败为 `[]` |\n| `media[].url` | string | 媒体资源 URL |\n| `media[].type` | string | `photo` / `video` / `animated_gif` 等 |\n| `retweetedPost` | object? | 转推原推文对象；无则 null |\n| `quotedPost` | object? | 引用的推文对象；无则 null |\n| `threadPosts` | array | Thread 系列推文数组；无则 `[]` |\n| `postedAt` | int64 | 发布时间，unix 毫秒 |\n\n::: tip 结构化 vs 渲染\n本端点返回的是**结构化原始数据**（含 media / quotedPost / threadPosts 嵌套），供 Agent 自定义渲染。\n如果用户只想在阅读器里订阅来看，请引导走 Web 控制台「账户设置」复制的 Feed 链接（公开 RSS / Atom / JSON Feed 层），不要让 Agent 重新拼装。\n:::\n\n---\n\n## Articles\n\n```\nmp2rss x articles <xUserId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 `publishedAt DESC` 拉取已订阅 X 账号的长文（X Articles）流。订阅闭环校验同 `x posts`，未订阅返回 exit code 4。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（**最大 50**） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x articles 44196397\nmp2rss x articles 44196397 -o json | jq '.items[].url'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"url\": \"https://x.com/elonmusk/article/...\",\n      \"title\": \"My take on...\",\n      \"description\": \"summary\",\n      \"contentMarkdown\": \"# Heading\\n\\nfull body markdown source\",\n      \"coverUrl\": \"https://...\",\n      \"publishedAt\": 1747353600000\n    }\n  ],\n  \"total\": 8,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `url` | string | 长文原始 URL |\n| `title` | string | 标题 |\n| `description` | string | 摘要 |\n| `contentMarkdown` | string? | 长文 markdown 原文，可能为 null |\n| `coverUrl` | string? | 封面图 URL |\n| `publishedAt` | int64 | 发布时间，unix 毫秒 |\n\n---\n\n## Agent 综合注意事项\n\n- **xUserId 是字符串**，不要按整数处理（与 `mpId` 不同；handle 起源是数字，但 API 契约统一为字符串）\n- **不接受 `@handle`**：从 `x list` 输出里取 `xUserId` 再调 posts / articles\n- **写类操作不可达**：用户要订阅/取消订阅 X，**统一引导到 Web 控制台**，不要尝试构造 CLI 写命令\n- **结构化解析统一 `-o json`**\n- **字段命名 camelCase**：`xUserId` / `xUsername` / `xDisplayName` / `xLastItemAt` / `postId` / `postedAt` / `publishedAt`\n- **时间字段统一 unix 毫秒**（int64 number）\n- **页大小上限 50**（`x posts` / `x articles` 最大都是 50，注意与 `mp articles` 的 100 不同）\n- 错误码处理见 [errors.md](errors.md)；典型场景：未订阅返回 exit 4，message `X account is not subscribed`\n\nFile v0.2.1:skill-card.md\n\n## Description:\n\nmp2rss helps agents use the mp2rss CLI to manage WeChat Official Account and X/Twitter RSS subscriptions, retrieve historical content, and manage authentication state.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[areyoubugcoder](https://clawhub.ai/user/areyoubugcoder)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and external users use this skill to let an agent operate the local mp2rss CLI for subscribing to WeChat Official Account feeds, listing and searching subscriptions, reading WeChat and X/Twitter content, and managing Feed Key login state.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Logging in can store the Feed Key persistently under ~/.mp2rss/config.json.\n\nMitigation: Use MP2RSS_FEED_KEY or --api-key for less persistent sessions, and run mp2rss auth logout when the stored key should be cleared.\n\nRisk: The skill depends on a local mp2rss CLI and the mp2rss upstream service.\n\nMitigation: Install it only when you intend to use that service and trust the CLI and upstream downloads.\n\nRisk: Subscription management commands can change the user's feed state.\n\nMitigation: Verify login state, article URLs, mpId values, and X/Twitter user identifiers from CLI output before acting.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/areyoubugcoder/skills/mp2rss)\n- [Mp2rss service homepage](https://mp2rss.bugcode.dev)\n- [Skill README](README.md)\n- [Authentication guide](references/auth.md)\n- [Installation and upgrade guide](references/install.md)\n- [WeChat subscription and article guide](references/mp.md)\n- [X/Twitter subscription and content guide](references/x.md)\n- [Error handling guide](references/errors.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown with inline shell commands and structured CLI-output guidance]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [The skill expects mp2rss CLI output, preferably JSON for structured operations, and turns it into user-facing subscription, content, authentication, and error-handling guidance.]\n\n## Skill Version(s):\n\n0.2.1 (source: frontmatter, package.json, server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v0.2.1:package.json\n\n{\n  \"name\": \"mp2rss\",\n  \"version\": \"0.2.1\",\n  \"description\": \"Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。订阅 / 列出 / 搜索 / 取消订阅公众号，查询公众号历史文章；列出已订阅 X 账号，拉取 X 推文 / 长文流（X 写类操作仅 Web 控制台）；管理 Feed Key 登录态。\",\n  \"license\": \"MIT-0\",\n  \"author\": \"areyoubugcoder\",\n  \"homepage\": \"https://mp2rss.bugcode.dev\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/areyoubugcoder/mp2rss-cli.git\",\n    \"directory\": \"openclaw/mp2rss\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/areyoubugcoder/mp2rss-cli/issues\"\n  },\n  \"keywords\": [\n    \"mp2rss\",\n    \"wechat\",\n    \"weixin\",\n    \"微信\",\n    \"公众号\",\n    \"x\",\n    \"twitter\",\n    \"推特\",\n    \"rss\",\n    \"feed\",\n    \"subscription\",\n    \"订阅\",\n    \"openclaw\",\n    \"skill\"\n  ],\n  \"clawhub\": {\n    \"acceptLicenseTerms\": true\n  }\n}\n\nFile v0.2.1:LICENSE\n\nMIT No Attribution\n\nCopyright 2026 areyoubugcoder\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v0.2.0: 11 files, 22017 bytes\n\nFiles: LICENSE (909b), package.json (923b), README.md (7229b), references/auth.md (3583b), references/errors.md (4181b), references/install.md (2286b), references/mp.md (5716b), references/x.md (7174b), skill-card.md (2642b), SKILL.md (11430b), _meta.json (125b)\n\nFile v0.2.0:SKILL.md\n\n---\nname: mp2rss\ndescription: |\n  Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。\n\n  **当以下情况使用此 Skill**：\n  (1) 用户要订阅 / 取消订阅 / 列出 / 搜索**微信公众号**：「订阅这个公众号 https://mp.weixin.qq.com/s/...」「我订阅了哪些公众号」「列一下我的公众号 RSS」「搜一下我订阅的财经类公众号」「取消订阅那个号」「把 <公众号名> 从订阅里删了」\n  (2) 用户要查**公众号历史文章**：「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」「<公众号名> 的历史文章」\n  (3) 用户要操作 **X（Twitter）账号**：「我订阅了哪些 X 账号」「@elonmusk 最近发了啥」「拉一下某个 X 号的推文 / 长文」（注：X 的订阅 / 取消订阅仅在 Web 控制台，CLI 只能列出已订阅与拉内容）\n  (4) 用户要管理**登录态**：「登录公众号 RSS 服务」「登出 mp2rss」「我的 Feed Key 是什么」「我在 mp2rss 里登录了吗」\n  (5) 用户要**安装 / 配置 Mp2rss CLI**：「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪里」\nversion: 0.2.0\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - mp2rss\n    envVars:\n      - name: MP2RSS_FEED_KEY\n        required: false\n        description: Mp2rss Feed Key；也可由 `mp2rss auth login` 写入配置文件，二者任一即可。\n      - name: MP2RSS_API_URL\n        required: false\n        description: Mp2rss API URL，默认 https://mp2rss.bugcode.dev。\n    homepage: https://mp2rss.bugcode.dev\n    emoji: \"📡\"\n---\n\n# Mp2rss Skill\n\n通过 Mp2rss CLI（Go 二进制 `mp2rss`）把**微信公众号**与 **X（Twitter）账号**转成 RSS / JSON Feed 并管理订阅。本 skill 是路由入口，按用户意图分发到 `references/` 子文档读取详细命令规格。\n\n> **术语提示**：本文档中 **\"X\"** 一律指 X（原 Twitter）平台；用作\"某个公众号\"占位时统一写作 `<公众号名>` 或具名描述，避免与 X 平台混淆。\n\n## ⚠️ Agent 必读约束\n\n### 🔧 运行时前置\n\n所有命令通过本地 `mp2rss` 二进制调用，**不直接打 HTTP**。Agent 不应自己拼 API 请求，统一走 CLI 子命令 + `-o json` 解析。\n\n**Base URL 由 CLI 自动决定**（命令行 flag > 环境变量 > 配置文件 > 默认 `https://mp2rss.bugcode.dev`）。\n\n### 🔑 凭证与登录态\n\n调用任何 `mp2rss mp` / `mp2rss x` 子命令前，**必须先确认登录态**：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `{\"loggedIn\": false}` 时停止后续调用，引导用户跑 `mp2rss auth login`，详见 [references/auth.md](references/auth.md)。\n\n凭证优先级（高 → 低）：命令行 `--api-key` flag > `MP2RSS_FEED_KEY` 环境变量 > `~/.mp2rss/config.json` 配置文件。\n\n### 🔢 mpId 是 int64 / xUserId 是字符串\n\n两种业务键形态不同，**不要混用**：\n\n- **`mpId`**（公众号）：int64 整数。超出 JavaScript `Number.MAX_SAFE_INTEGER`，Agent 在 JS 环境下解析 `mp list / mp articles -o json` 输出时**始终把 mpId 当字符串处理**：\n\n  ```javascript\n  const safe = text.replace(/\"(mpId)\"\\s*:\\s*(\\d+)/g, '\"$1\":\"$2\"');\n  const data = JSON.parse(safe);\n  ```\n\n- **`xUserId`**（X 账号）：API 契约即为字符串（虽然内容是数字串），原样消费即可，不必转换。\n\nPython / Go / jq 原生支持大整数，无 mpId 精度问题。\n\n### 🚫 反幻觉边界\n\n- **禁止编造 mpId / xUserId**：所有业务键必须来自 `mp list` / `mp search` / `x list` 的响应，不得凭空构造\n- **禁止跳过订阅参数校验**：`mp subscribe <url>` 的 `<url>` **必须**是 `https://mp.weixin.qq.com/s/...` 文章链接；不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时**反问用户索要任意一篇文章链接**，不要直接尝试\n- **禁止伪造执行结果**：不调用 CLI 不得告诉用户「已订阅」「已删除」\n- **禁止忽略 exit code**：CLI 返回非 0 必须解析 stderr / JSON envelope 并报告用户\n- **X 订阅 / 取消订阅必须走 Web 控制台**：CLI 与 API 都不暴露 X 写类端点；用户要订阅 X 账号时**只能引导到 <https://mp2rss.bugcode.dev/>「订阅管理 → X」**，不要尝试构造 CLI 写命令\n\n### 🔄 错误处理\n\nCLI 错误统一 JSON envelope（见 [references/errors.md](references/errors.md)）：\n\n```json\n{\"error\": {\"message\": \"...\", \"code\": <int>}}\n```\n\nExit code 速查：\n\n| Code | 含义 | Agent 处理 |\n|------|------|-----------|\n| 0 | 成功 | 解析 stdout |\n| 1 | 通用错误（网络） | 报告 + 建议稍后重试 |\n| 2 | 参数错误 | 检查参数；若是 `mp subscribe` 检查 URL 格式 |\n| 3 | 鉴权失败 | 引导跑 `mp2rss auth login`（见 [auth.md](references/auth.md)） |\n| 4 | 资源不存在 | mpId 错 / 文章 URL 失效 / **X 账号未订阅**（典型 message `X account is not subscribed`） |\n| 5 | 上游不可用 | 报告 + 建议稍后重试 |\n\n---\n\n## 执行流程概览\n\n```\n用户意图 → 路由匹配 → 读对应 references/xxx.md → 构造 mp2rss 子命令 → 执行 → 解析 JSON / 验证 exit code → 返回结果\n                                                                                      ↓\n                                                                                  exit ≠ 0 → 按错误码分支处理\n```\n\n**关键原则**\n\n- **CLI 输出是真理**：所有状态以 `mp2rss xxx -o json` 返回为准，不依赖上下文记忆\n- **`-o json` 优先**：批量 / 结构化场景统一加 `-o json`（除 `auth login` 不支持外）\n- **mpId 字符串化**（JS 环境）；xUserId 本身就是字符串\n\n---\n\n## 指令路由表\n\n| 用户意图 / 自然语言 | 角色 | 详细文档 |\n|------|------|---------|\n| 「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪」 | ⚙️ 安装/配置 | [references/install.md](references/install.md) |\n| 「登录」「登出」「我的 Feed Key 是什么」「我登录了吗」 | 🔐 认证 | [references/auth.md](references/auth.md) |\n| 「订阅这个公众号 https://mp.weixin.qq.com/s/...」 | 📡 公众号订阅 | [references/mp.md](references/mp.md#subscribe) |\n| 「我订阅了哪些公众号」「列一下我的公众号 RSS」 | 📋 公众号列表 | [references/mp.md](references/mp.md#list) |\n| 「搜一下我订阅的财经类公众号」 | 🔍 公众号搜索 | [references/mp.md](references/mp.md#search) |\n| 「取消订阅 <公众号名>」「把 <公众号名> 从订阅里删了」 | 🗑️ 公众号取消订阅 | [references/mp.md](references/mp.md#remove) |\n| 「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」 | 📰 公众号文章 | [references/mp.md](references/mp.md#articles) |\n| 「我订阅了哪些 X 账号」「列一下我的 X 订阅」 | 🐦 X 列表 | [references/x.md](references/x.md#list) |\n| 「<X 账号> 最近发了啥」「@xxx 的推文」 | 🐦 X 推文 | [references/x.md](references/x.md#posts) |\n| 「<X 账号> 的长文 / Articles」 | 🐦 X 长文 | [references/x.md](references/x.md#articles) |\n| 「订阅一个 X 账号 / 取消订阅 X」 | 🐦 ⚠️ Web 控制台 | [references/x.md](references/x.md#关键边界x-订阅必须在-web-控制台完成) |\n| 错误码 / JSON envelope / exit code 处理 | 🚨 错误 | [references/errors.md](references/errors.md) |\n\n---\n\n## 自然语言路由（细分 trigger）\n\n```\n包含 mp.weixin.qq.com/s/ URL              → mp subscribe（参数 = 该 URL）\n「订阅」+ 任何 URL 形态                    → 先校验是不是 mp.weixin.qq.com/s/...，否则反问\n「订阅了哪些 公众号」「我的公众号」          → mp list\n「订阅了哪些 X / Twitter 账号」「我的 X 订阅」 → x list\n「搜公众号」「找一下带 关键词 的公众号」      → mp list -q <kw> 或 mp search <kw>\n「取消订阅 <公众号名>」「删了 <公众号名>」    → 先 mp list -q <名> 确认 mpId，再 mp remove <mpId>\n「<公众号名> 最近发的文章 / 历史文章」        → mp articles <mpId>（先列表确认 mpId）\n「@elonmusk 最近的推文」「<X 账号名> 发了啥」  → 先 x list 拿到 xUserId，再 x posts <xUserId>\n「<X 账号名> 的长文 / Articles」              → 先 x list，再 x articles <xUserId>\n「订阅 / 取消订阅一个 X 账号」               → 引导用户去 Web 控制台「订阅管理 → X」，不要走 CLI\n「登录」「授权」                            → auth login（参考 auth.md 选三种登录模式之一）\n「我的 Key」「登录了吗」「状态」              → auth status -o json\n「登出」「退出登录」                         → auth logout\n```\n\n**决策原则**：\n\n- 有 `mp.weixin.qq.com/s/` URL → 直接 `mp subscribe`\n- 用户给的是**公众号名而非 URL** → **反问索要文章 URL**，不要先 `mp search`（搜索是用于在已订阅源里找，不会订阅新号）\n- 取消订阅公众号前**先用 `mp list -q` / `mp search` 拿到准确 mpId**，避免误删\n- 用户给 X 账号是 `@handle` 或显示名 → **先 `x list -o json` 找 xUserId**，不要把 handle 直接传给 `x posts / x articles`\n- 用户想**添加** X 订阅 → **不要尝试 CLI**，直接引导 <https://mp2rss.bugcode.dev/>「订阅管理 → X」\n\n---\n\n## API 路由（CLI 子命令总表）\n\n| 子命令 | 用途 | 详细文档 |\n|--------|------|---------|\n| `mp2rss auth login [-k <key>] [--no-browser]` | 登录（三种模式） | [auth.md](references/auth.md#log-in) |\n| `mp2rss auth status [-o json]` | 查询登录态 | [auth.md](references/auth.md#check-status) |\n| `mp2rss auth logout` | 登出 | [auth.md](references/auth.md#log-out) |\n| `mp2rss mp subscribe <article-url> [-o json]` | 订阅公众号 | [mp.md](references/mp.md#subscribe) |\n| `mp2rss mp list [-q <kw>] [-p <page>] [--page-size <n>] [-o json]` | 列出公众号订阅 | [mp.md](references/mp.md#list) |\n| `mp2rss mp search <keyword> [-o json]` | 搜索已订阅公众号 | [mp.md](references/mp.md#search) |\n| `mp2rss mp remove <mpId> [-y] [-o json]` | 取消订阅公众号 | [mp.md](references/mp.md#remove) |\n| `mp2rss mp articles <mpId> [-p <page>] [--page-size <n>] [-o json]` | 查公众号文章 | [mp.md](references/mp.md#articles) |\n| `mp2rss x list [-q <kw>] [-p <page>] [--page-size <n>] [-o json]` | 列出已订阅 X 账号 | [x.md](references/x.md#list) |\n| `mp2rss x posts <xUserId> [-p <page>] [--page-size <n>] [-o json]` | 拉 X 推文流 | [x.md](references/x.md#posts) |\n| `mp2rss x articles <xUserId> [-p <page>] [--page-size <n>] [-o json]` | 拉 X 长文流 | [x.md](references/x.md#articles) |\n| `mp2rss update [--check]` | 升级 CLI | [install.md](references/install.md#升级) |\n\n> X 写类（搜索 / 订阅 / 取消订阅）**不存在对应 CLI 命令**，仅 Web 控制台提供，详见 [x.md](references/x.md#关键边界x-订阅必须在-web-控制台完成)。\n\n---\n\n## 全局 flag\n\n所有子命令都支持：\n\n| Flag | 等价环境变量 | 说明 |\n|------|-------------|------|\n| `-o, --output <table\\|json>` | — | 输出格式，默认 `table` |\n| `--api-key <feed-key>` | `MP2RSS_FEED_KEY` | 覆盖 Feed Key |\n| `--api-url <url>` | `MP2RSS_API_URL` | 覆盖 API 地址 |\n\n优先级（高 → 低）：CLI flag > env > 配置文件 > 默认。\n\nFile v0.2.0:README.md\n\n# Mp2rss Skill\n\n[![License: MIT-0](https://img.shields.io/badge/License-MIT--0-blue.svg)](https://opensource.org/licenses/MIT-0)\n\n让 AI Agent 帮你管理 **微信公众号** 与 **X（Twitter）账号** 的 RSS 订阅 —— 一句话订阅、自然语言查找、按需读历史文章 / 推文 / 长文。\n\n本仓库是 [Mp2rss](https://mp2rss.bugcode.dev) 服务的 OpenClaw Agent Skill 包，基于 [`mp2rss` CLI](https://github.com/areyoubugcoder/mp2rss-cli) 实现。\n\n---\n\n## ✨ 核心能力\n\n### 微信公众号（MP）\n\n| 能力 | 说明 |\n|------|------|\n| 📡 **一键订阅** | 发一个公众号文章链接（`mp.weixin.qq.com/s/...`），Agent 自动把整个公众号订阅到你的 Feed |\n| 📋 **列表与搜索** | 「我订阅了哪些公众号」「搜一下我订阅的财经类公众号」 |\n| 🗑️ **取消订阅** | 「把 某号 从订阅里删了」，Agent 先核对 mpId 再删 |\n| 📰 **历史文章** | 「某号 最近发了什么」/「拉一下 某号 的文章」 |\n\n### X（Twitter）账号\n\n| 能力 | 说明 |\n|------|------|\n| 🐦 **列出 X 订阅** | 「我订阅了哪些 X 账号」 |\n| 📨 **推文流** | 「@elonmusk 最近发了啥」（Agent 先 `x list` 找到 `xUserId` 再拉推文） |\n| 📝 **长文流** | 「拉一下 某 X 账号的 Articles」 |\n| ⚠️ **订阅 / 取消订阅 X 账号** | **仅在 Web 控制台**（<https://mp2rss.bugcode.dev/>）—— CLI 与 API 都不暴露 X 写类端点，Agent 会引导你去控制台 |\n\n### 通用\n\n| 能力 | 说明 |\n|------|------|\n| 🔐 **登录态管理** | 「我的 Feed Key 是什么」「登录 mp2rss」 |\n| 📤 **结构化输出** | 所有命令支持 `-o json`，Agent 可直接解析做后续处理 |\n\n---\n\n## 💡 使用场景\n\n### 通勤路上看到好公众号\n\n> 👤 订阅这个公众号 https://mp.weixin.qq.com/s/abc123xyz\n>\n> 🤖 已订阅「某公众号」到你的 Feed。\n\n### 不记得订过哪些号\n\n> 👤 我订阅了哪些公众号？\n>\n> 🤖 当前共 42 个订阅。前 20 个：某公众号（最近发文 2 小时前）、另一个号（昨天）……\n\n### 找特定主题\n\n> 👤 我订阅的财经类公众号有哪些\n>\n> 🤖 找到 5 个匹配：财经早知道、第一财经……\n\n### 翻看历史\n\n> 👤 财经早知道 最近发了什么\n>\n> 🤖 最近 10 篇文章：1. xxx 标题（昨天）2. xxx 标题（前天）……\n\n### 不想看了\n\n> 👤 把 财经早知道 从订阅里删了\n>\n> 🤖 确认删除「财经早知道」（mpId 123456）？已删除 ✓\n\n### 看大 V 推文\n\n> 👤 @elonmusk 最近发了啥？\n>\n> 🤖 （先 `x list` 拿到 xUserId 44196397）最近 5 条推文：1. ……\n\n### 想订阅一个 X 账号\n\n> 👤 帮我订阅 @paulg 这个号\n>\n> 🤖 X 账号的订阅 / 取消订阅只能在 Web 控制台操作。打开 https://mp2rss.bugcode.dev/「订阅管理 → X」搜索 paulg 完成订阅；订阅好我就能用 `mp2rss x posts/articles` 帮你拉内容。\n\n---\n\n## 📦 安装\n\n### 前置：装 Mp2rss CLI 二进制\n\nskill 本身只描述如何调用 CLI，所以必须先装 `mp2rss` 二进制（任选其一）：\n\n```bash\n# 方式 A：npm（推荐，跨平台一致）\npnpm add -g @mp2rss/cli\n\n# 方式 B：macOS / Linux 一键脚本\ncurl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh\n```\n\n也可在 [Releases](https://github.com/areyoubugcoder/mp2rss-cli/releases/latest) 下载对应平台二进制。\n\n### 装 Skill\n\n```bash\n# 方式 A：通过 ClawHub（推荐）\nopenclaw skills install mp2rss\n\n# 方式 B：手动\nmkdir -p ~/.openclaw/workspace/skills/mp2rss\ncd ~/.openclaw/workspace/skills/mp2rss\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-openclaw/main/SKILL.md -o SKILL.md\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-openclaw/main/package.json -o package.json\n# 视需要再拉 references/ 子文档\n```\n\n---\n\n## 🔑 授权登录\n\n安装完成后说「登录 mp2rss」，Agent 自动跑 `mp2rss auth login` 走浏览器 loopback 授权。CI / 无头环境用：\n\n```bash\nmp2rss auth login -k <feed-key>            # 直传\nmp2rss auth login --no-browser             # 远程模式，仅打印授权 URL\n```\n\nFeed Key 可在 <https://mp2rss.bugcode.dev/> 登录后查看或重置。配置文件位置 `~/.mp2rss/config.json`。\n\n### 用环境变量配置（可选）\n\n```bash\nexport MP2RSS_FEED_KEY=gk_live_xxxxxxxx\nexport MP2RSS_API_URL=https://mp2rss.bugcode.dev    # 自托管时需要\n```\n\n优先级（高 → 低）：CLI flag `--api-key` > `MP2RSS_FEED_KEY` env > `~/.mp2rss/config.json`。\n\n---\n\n## 🛠 子命令速查\n\n### 通用\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss auth login [-k <key>] [--no-browser]` | 登录（三种模式：浏览器 / Feed Key 直传 / 远程） |\n| `mp2rss auth status [-o json]` | 查登录态、Feed Key 来源、最近登录时间 |\n| `mp2rss auth logout` | 清空 Feed Key |\n\n### 微信公众号\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss mp subscribe <article-url> [-o json]` | 订阅；参数必须是 `mp.weixin.qq.com/s/...` 文章 URL |\n| `mp2rss mp list [-q <kw>] [-p <page>] [--page-size <n>]` | 列出公众号订阅 |\n| `mp2rss mp search <keyword>` | `mp list -q` 语法糖 |\n| `mp2rss mp remove <mpId> [-y]` | 取消订阅公众号 |\n| `mp2rss mp articles <mpId> [-p <page>] [--page-size <n>]` | 查公众号历史文章 |\n\n### X（Twitter）\n\n| 命令 | 说明 |\n|------|------|\n| `mp2rss x list [-q <kw>] [-p <page>] [--page-size <n>]` | 列出已订阅的 X 账号 |\n| `mp2rss x posts <xUserId> [-p <page>] [--page-size <n>]` | 拉 X 账号推文流 |\n| `mp2rss x articles <xUserId> [-p <page>] [--page-size <n>]` | 拉 X 账号长文流 |\n\n> X 账号**搜索 / 订阅 / 取消订阅**仅 Web 控制台支持，CLI 与 Open API 都不暴露这些写类端点。\n\n完整字段、JSON shape 与 Agent 行为规范见 [SKILL.md](SKILL.md) 和 [references/](references/) 子文档。\n\n---\n\n## ⚠️ 重要约束\n\n- **订阅公众号传的是文章 URL** —— 不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时 Agent 应反问用户索要任意一篇文章链接\n- **`mpId` 是 int64** —— JS 环境解析 JSON 时需先把 `mpId` 替换为字符串再 `JSON.parse`，否则精度丢失\n- **`xUserId` 是字符串** —— 虽然内容是数字串，API 契约即字符串形态，无需转换；注意不要传 `@handle`\n- **取消订阅公众号前先核对 mpId** —— 用 `mp list -q` / `mp search` 拿到准确 mpId 再删，避免误删\n- **X 写类操作不可达** —— 用户要订阅 / 取消订阅 X 账号时，Agent 必须引导到 Web 控制台「订阅管理 → X」，不要尝试构造 CLI 命令\n- **`auth login` 不支持 `-o json`** —— 仅输出文本反馈，其它子命令均支持\n\n---\n\n## 🔗 相关\n\n- [Mp2rss 服务](https://mp2rss.bugcode.dev) —— 微信公众号 / X 账号 RSS 订阅服务\n- [`mp2rss` CLI](https://github.com/areyoubugcoder/mp2rss-cli) —— Go 命令行客户端（Skill 调用的底层）\n- [Mp2rss 文档站](https://areyoubugcoder.github.io/Mp2RSS/) —— 服务介绍、Open API 与 CLI 完整文档\n\n---\n\n## License\n\n[MIT-0](LICENSE)\n\nFile v0.2.0:_meta.json\n\n{\n  \"ownerId\": \"kn7acxx408jk3phdk3326sx5fs86zndf\",\n  \"slug\": \"mp2rss\",\n  \"version\": \"0.2.0\",\n  \"publishedAt\": 1779764235680\n}\n\nFile v0.2.0:references/auth.md\n\n# 认证管理\n\n本文档供 Agent 在用户询问「登录」「登出」「我的 Feed Key 是什么」「我登录了吗」「在 mp2rss 里登录」时按需读取。\n\n## 触发条件\n\n调用任何 `mp2rss mp` 子命令前，**必须先**确认登录态：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `loggedIn: false` 时停止后续 mp 调用，引导用户登录后再继续原始请求。\n\n## Log in\n\n```\nmp2rss auth login [-k <feed-key>] [--no-browser]\n```\n\n三种模式：\n\n| 模式 | 命令 | 适用场景 |\n|------|------|---------|\n| 浏览器（默认） | `mp2rss auth login` | 桌面环境；CLI 启动本地 loopback HTTP 服务，打开浏览器登录后回调写入 `~/.mp2rss/config.json` |\n| Feed Key 直传 | `mp2rss auth login -k <feed-key>` | CI / 无头环境；Feed Key 在 https://mp2rss.bugcode.dev/ 登录后获取或重置 |\n| 远程模式 | `mp2rss auth login --no-browser` | 远程 SSH / 无浏览器；CLI 仅打印授权 URL，用户在本地浏览器打开后复制 Feed Key 回填 |\n\n```bash\nmp2rss auth login                          # 默认浏览器\nmp2rss auth login -k gk_live_xxxxxxxx      # 直传\nmp2rss auth login --no-browser             # 远程\n```\n\n### Agent 处理远程模式\n\n`mp2rss auth login --no-browser` 输出形如：\n\n```\n请在浏览器打开下面的链接完成授权：\n\n  https://mp2rss.bugcode.dev/auth/cli?code=...\n\n授权后将页面上显示的 Feed Key 粘贴到此终端：\n```\n\nAgent 应：\n\n1. **完整提取授权 URL** 转发给用户\n2. 提示「请在浏览器打开此链接，登录后把页面上的 Feed Key 粘贴回这里」\n3. 不要替用户决定使用哪个浏览器；不要把 URL 截断或缩短\n\n⚠️ `auth login` **不支持 `-o json`**，输出为纯文本反馈。\n\n## Check status\n\n```\nmp2rss auth status [-o json]\n```\n\n```bash\nmp2rss auth status            # 人类可读\nmp2rss auth status -o json    # Agent 解析\n```\n\n### JSON shape（已登录）\n\n```json\n{\n  \"loggedIn\": true,\n  \"source\": \"config\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\",\n  \"feedKeyMasked\": \"abcdef***\",\n  \"lastLoginAt\": 1705000000000,\n  \"lastVerifyAt\": 1705000001000\n}\n```\n\n### JSON shape（未登录）\n\n```json\n{\n  \"loggedIn\": false,\n  \"source\": \"none\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\"\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `loggedIn` | bool | 是否已配置可用凭证 |\n| `source` | string | `\"env\"` / `\"config\"` / `\"none\"` |\n| `apiUrl` | string | 当前生效的 API URL |\n| `feedKeyMasked` | string | 已脱敏 Feed Key（仅前几位 + `***`） |\n| `lastLoginAt` | int64 | 最近登录时间，unix 毫秒 |\n| `lastVerifyAt` | int64 | 最近一次验证时间，unix 毫秒 |\n\n## Log out\n\n```\nmp2rss auth logout\n```\n\n清空 `~/.mp2rss/config.json` 里的 `feed_key`，保留 `api_url` 等其它配置。\n\n```bash\nmp2rss auth logout\n```\n\n## 凭证优先级\n\n高 → 低：\n\n1. CLI flag：`--api-key <feed-key>`\n2. 环境变量：`MP2RSS_FEED_KEY`\n3. 配置文件：`~/.mp2rss/config.json` 的 `feed_key`\n\nAPI URL 同理：`--api-url` > `MP2RSS_API_URL` > 配置文件 > 默认 `https://mp2rss.bugcode.dev`。\n\n## Agent 注意事项\n\n- 调用 `mp2rss mp` 任何子命令前先 `mp2rss auth status -o json`\n- 时间字段是 unix 毫秒（int64），不是格式化字符串\n- 不要直接读写 `~/.mp2rss/config.json`，统一用 `mp2rss auth ...` 子命令\n- 鉴权错误（exit code 3 / HTTP 401）时引导用户跑 `mp2rss auth login`，不要反复重试\n- `feedKeyMasked` 仅供展示用户身份，**不要试图从掩码还原完整 Key**\n\nFile v0.2.0:references/errors.md\n\n# 错误处理\n\n本文档供 Agent 在 mp2rss 命令返回非零 exit code 或 JSON envelope 含 `error` 字段时按需读取。\n\n## JSON 错误 envelope\n\n任何子命令在 `-o json` 模式下出错时统一返回：\n\n```json\n{\n  \"error\": {\n    \"message\": \"human-readable 错误信息\",\n    \"code\": <int>\n  }\n}\n```\n\n- `code` 字段是 HTTP 状态码（来自上游 API）或 CLI 自身 exit code\n- `message` 是人类可读描述（中文），可直接转发给用户\n\n## Exit codes\n\n| Code | 含义 | 典型场景 | Agent 处理 |\n|------|------|---------|-----------|\n| `0` | 成功 | 命令正常执行 | 解析 stdout |\n| `1` | 通用错误（网络） | DNS 失败 / TCP 连不上 / 超时 | 报告 + 建议稍后重试；检查网络 |\n| `2` | 参数错误 | flag 拼错 / 必填参数缺失 / `mp subscribe` URL 不是 `mp.weixin.qq.com/s/...` | 解析 stderr 给用户具体提示；URL 错就反问用户索要正确文章链接 |\n| `3` | 鉴权失败 | Feed Key 错 / 过期 / 未配置 / HTTP 401 | 引导用户跑 `mp2rss auth login`（见 [auth.md](auth.md)）；**不要反复重试** |\n| `4` | 资源不存在 | mpId 错 / 文章 URL 失效 / **xUserId 未订阅**（X 读类端点要求已订阅）/ HTTP 404 | MP：用 `mp list` 重新核对 mpId 或更换文章链接；X：先 `x list` 确认是否已订阅，未订阅的话引导用户去 Web 控制台「订阅管理 → X」 |\n| `5` | 上游不可用 | API 服务挂 / HTTP 5xx | 报告 + 建议稍后重试 |\n\n## HTTP code 对应\n\nCLI 把上游 HTTP 状态码映射到上面的 exit codes：\n\n| HTTP | Exit | 说明 |\n|------|------|------|\n| 200 | 0 | OK |\n| 400 | 2 | 请求参数错 |\n| 401 | 3 | Feed Key 无效 |\n| 403 | 3 | 权限不足（实际同 401 处理） |\n| 404 | 4 | 资源不存在 |\n| 429 | 5 | 限流（视为上游不可用） |\n| 5xx | 5 | 上游错误 |\n\n## Agent 处理策略\n\n### 失败重试\n\n| 错误类型 | 重试策略 |\n|---------|---------|\n| Exit 1（网络） | 等待 5 秒后**最多重试一次**；二次失败明确报告网络问题 |\n| Exit 3（鉴权） | **不要重试**；直接引导 `mp2rss auth login` |\n| Exit 4（不存在） | **不要重试**；引导用户核对 mpId / URL |\n| Exit 5（上游 5xx） | 等待 5 秒后**最多重试一次**；二次失败建议稍后再试 |\n| Exit 2（参数） | **不要重试**；告诉用户具体是哪个参数错了 |\n\n### 错误信息提取\n\n人类可读模式（无 `-o json`）下，错误写到 stderr，Agent 应捕获 stderr 转发给用户。\n\nJSON 模式下，错误 envelope 写到 stdout（保持单一输出流），Agent 解析 `error.message` 和 `error.code` 字段。\n\n### 反幻觉\n\n- **禁止编造错误信息**：所有报告给用户的错误必须来自 CLI 真实输出（stderr 或 JSON envelope）\n- **禁止隐瞒错误**：CLI 返回非零退出码时必须告诉用户，不能装作执行成功\n- **禁止过度解读 message**：`error.message` 直接转发，不要\"翻译\"成自己的描述（容易扭曲原意）\n\n## 常见错误样例\n\n### Feed Key 失效\n\n```bash\n$ mp2rss mp list -o json\n{\"error\":{\"message\":\"鉴权失败：Feed Key 无效或已重置，请重新登录\",\"code\":401}}\n$ echo $?\n3\n```\n\nAgent → 引导 `mp2rss auth login` 而非重试。\n\n### URL 格式错\n\n```bash\n$ mp2rss mp subscribe https://example.com/article -o json\n{\"error\":{\"message\":\"参数错误：subscribe 需要 mp.weixin.qq.com/s/... 文章链接\",\"code\":400}}\n$ echo $?\n2\n```\n\nAgent → 告诉用户必须用微信公众号文章 URL，并反问索要正确链接。\n\n### mpId 不存在\n\n```bash\n$ mp2rss mp articles 999999999 -o json\n{\"error\":{\"message\":\"该公众号不在你的订阅中\",\"code\":404}}\n$ echo $?\n4\n```\n\nAgent → 用 `mp list` 核对正确 mpId。\n\n### X 账号未订阅\n\n```bash\n$ mp2rss x posts 999999999 -o json\n{\"error\":{\"message\":\"X account is not subscribed\",\"code\":404}}\n$ echo $?\n4\n```\n\nAgent → 提示用户：`mp2rss x posts / x articles` **只能查已订阅 X 账号**；订阅 X 账号必须去 Web 控制台「订阅管理 → X」操作（CLI 与 API 都不暴露 X 写类端点）。先 `mp2rss x list` 看一下是否已订阅 / `xUserId` 是否抄错。\n\nFile v0.2.0:references/install.md\n\n# 安装与升级\n\n本文档供 Agent 在用户询问「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪」时按需读取。\n\n## 环境要求\n\n- macOS / Linux / Windows 任一\n- Node.js ≥ 18（仅 npm 安装方式需要）\n- Go ≥ 1.21（仅从源码构建需要）\n\n## 安装方式\n\n任选其一：\n\n### A. npm（推荐，跨平台一致）\n\n```bash\npnpm add -g @mp2rss/cli\n# 或 npm install -g @mp2rss/cli\n```\n\n`postinstall` 脚本会按平台自动下载对应的 Go 二进制，绑定为全局 `mp2rss` 命令。\n\n### B. 一键脚本（macOS / Linux）\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh\n```\n\n自动选 macOS / Linux 对应平台二进制，安装到 `/usr/local/bin` 或 `~/.local/bin`。\n\n### C. 直接下载 Release 二进制\n\n打开 <https://github.com/areyoubugcoder/mp2rss-cli/releases/latest> 选对应平台的归档下载，解压后把 `mp2rss` 加入 `PATH`。\n\n可用平台：\n\n| OS | amd64 | arm64 |\n|----|:---:|:---:|\n| macOS | ✅ | ✅ |\n| Linux | ✅ | ✅ |\n| Windows | ✅ | ✅ |\n\n## 验证安装\n\n```bash\nmp2rss --version\n```\n\n预期输出版本号字符串（如 `mp2rss v0.x.x`），exit 0。\n\n## 升级\n\n```bash\nmp2rss update              # 检查并升级到最新\nmp2rss update --check      # 只检查不升级\n```\n\n`update` 会从 GitHub Releases 拉最新版二进制就地替换。注意：通过 npm 安装的二进制由 npm 管理，建议改用 `pnpm up -g @mp2rss/cli`。\n\n## 配置文件位置\n\n`~/.mp2rss/config.json`（目录权限 `0700` / 文件权限 `0600`），结构：\n\n```json\n{\n  \"feed_key\": \"9f3a2c...（64 位 hex）\",\n  \"api_url\": \"https://mp2rss.bugcode.dev\",\n  \"last_login_at\": 1747194198000,\n  \"last_verify_at\": 1747194198000\n}\n```\n\n- 由 `mp2rss auth login` 自动写入\n- `mp2rss auth logout` 只清 `feed_key`，保留 `api_url` 等其它字段\n- Agent **不应该**直接读写此文件，统一用 `mp2rss auth ...` 子命令\n\n## Agent 注意事项\n\n- 用户问\"装好了吗\"→ `mp2rss --version`，exit 0 即装好\n- 用户问\"配置在哪\"→ 答 `~/.mp2rss/config.json` + 强调不要手改，用 `mp2rss auth login` 管理\n- 用户问\"怎么升级\"→ 给 `mp2rss update`；若用户是 npm 装的优先建议 `pnpm up -g @mp2rss/cli`\n\nFile v0.2.0:references/mp.md\n\n# 微信公众号（MP）订阅与文章管理\n\n本文档供 Agent 在用户询问**公众号**订阅、列出、搜索、取消订阅、查文章等需求时按需读取。\n\n**调用前提**：先确认登录态（见 [auth.md](auth.md)）；未登录时不要直接调本节命令。\n\n> 本文档中所有用作\"某个公众号\"占位的地方一律写作 `<公众号名>` 或具名形式（如「财经早知道」），避免歧义。\n\n---\n\n## Subscribe\n\n```\nmp2rss mp subscribe <article-url> [-o json]\n```\n\n订阅一个公众号。⚠️ **传入的是文章 URL**（`https://mp.weixin.qq.com/s/...`），不是公众号名、不是二维码、不是公众号主页链接。从公众号任意一篇文章里复制链接即可，Mp2rss 会从该文章解析出所属公众号并把整个公众号订阅到你的 Feed。\n\n```bash\nmp2rss mp subscribe https://mp.weixin.qq.com/s/abcDEFghIJKlmnop\nmp2rss mp subscribe https://mp.weixin.qq.com/s/abc -o json\n```\n\n### JSON shape\n\n```json\n{\n  \"ok\": true,\n  \"articleUrl\": \"https://mp.weixin.qq.com/s/...\"\n}\n```\n\n### Agent 处理\n\n- 用户给的不是 `mp.weixin.qq.com/s/...` URL → **反问**索要任意一篇文章链接，不要直接试\n- 用户给的是公众号名 → 不能搜索 + 订阅，必须用户提供文章 URL\n- 订阅成功后建议跟一句 `mp list -q <推断的公众号名>` 让用户看到刚订阅的条目（可选）\n\n---\n\n## List\n\n```\nmp2rss mp list [-q <keyword>] [-p <page>] [--page-size <n>] [-o json]\n```\n\n列出当前 Feed Key 名下的所有订阅。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-q, --query` | — | 按公众号名模糊搜索（与 `mp search` 等价） |\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（最大 50） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss mp list\nmp2rss mp list -q 财经\nmp2rss mp list -p 2 --page-size 50\nmp2rss mp list -o json | jq '.items[].mpName'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"mpId\": 123456,\n      \"mpName\": \"某公众号\",\n      \"mpAvatarUrl\": \"https://...\",\n      \"createdAt\": 1705000000000,\n      \"mpLastArticleAt\": 1705000050000\n    }\n  ],\n  \"total\": 42,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n⚠️ **`mpId` 是 int64**，JS 环境解析前先正则替换为字符串（见 [SKILL.md - mpId 是 int64](../SKILL.md#-mpid-是-int64) 段）。\n\n---\n\n## Search\n\n```\nmp2rss mp search <keyword> [-p <page>] [--page-size <n>] [-o json]\n```\n\n`mp2rss mp list -q <keyword>` 的语法糖，flag 集与输出与 `list` 完全一致。\n\n```bash\nmp2rss mp search 财经\nmp2rss mp search 财经 -o json\n```\n\n### Agent 注意\n\n`mp search` **只在已订阅源中模糊查找**，不会发现公众号、不会订阅新号。用户要\"搜公众号订阅\"指的就是这个；要订阅新公众号必须走 `mp subscribe + 文章 URL` 路径。\n\n---\n\n## Remove\n\n```\nmp2rss mp remove <mpId> [-y] [-o json]\n```\n\n按 mpId 取消订阅。`-y` 跳过交互式确认（适合脚本调用）。\n\n```bash\nmp2rss mp remove 123456            # 会交互式确认\nmp2rss mp remove 123456 -y         # 直接执行\nmp2rss mp remove 123456 -y -o json\n```\n\n### JSON shape\n\n```json\n{\n  \"ok\": true,\n  \"mpId\": 123456\n}\n```\n\n### Agent 处理\n\n- **取消订阅前必须先确认 mpId**：用 `mp list -q <name> -o json` 或 `mp search <name> -o json` 拿到准确 mpId 再调 remove\n- 用户只给公众号名时，不要凭名字猜 mpId\n- 若 `items` 多条匹配 → 列给用户让其挑选哪个，不要默认删第一个\n- 自动化脚本场景统一加 `-y`，否则 Agent 会卡在交互式 prompt\n\n---\n\n## Articles\n\n```\nmp2rss mp articles <mpId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 mpId 查询公众号历史文章。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 100 | 每页条数（最大 100） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss mp articles 123456\nmp2rss mp articles 123456 -p 2 --page-size 100\nmp2rss mp articles 123456 -o json | jq '.items[].title'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"mpId\": 123456,\n      \"articleId\": \"article-id-string\",\n      \"title\": \"文章标题\",\n      \"summary\": \"文章摘要\",\n      \"coverImageUrl\": \"https://...\",\n      \"originalUrl\": \"https://mp.weixin.qq.com/s/...\",\n      \"contentMarkdown\": \"# Markdown 正文\",\n      \"publishedAt\": 1705000000000,\n      \"updatedAt\": 1705000010000\n    }\n  ]\n}\n```\n\n⚠️ **没有分页字段**（无 `total` / `page` / `pageSize`）；`items` 为空数组即视为本页结束。Agent 翻页直接 `-p N` 试到空为止。\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `mpId` | int64 | 公众号 ID（同样字符串化处理） |\n| `articleId` | string | 文章唯一 ID |\n| `title` | string | 文章标题 |\n| `summary` | string | 文章摘要（可能为空） |\n| `coverImageUrl` | string | 封面图 URL（可能为空） |\n| `originalUrl` | string | 原文链接（`mp.weixin.qq.com/s/...`） |\n| `contentMarkdown` | string | Markdown 格式正文 |\n| `publishedAt` | int64 | 发布时间，unix 毫秒 |\n| `updatedAt` | int64 | 更新时间，unix 毫秒 |\n\n---\n\n## Agent 综合注意事项\n\n- **结构化解析统一 `-o json`**\n- **字段命名 camelCase**：`mpId` / `mpName` / `mpAvatarUrl` / `mpLastArticleAt` / `articleId` / `originalUrl` / `contentMarkdown` / `publishedAt`\n- **mpId 是 int64**：JS 解析前先字符串化（见 [SKILL.md](../SKILL.md#-mpid-是-int64)）\n- **时间字段统一 unix 毫秒**（int64 number）\n- **取消订阅前先 list/search 确认 mpId**\n- **文章列表无分页字段**，靠 `--page-size`（最大 100）+ `-p` 翻页\n- 错误码处理见 [errors.md](errors.md)\n\nFile v0.2.0:references/x.md\n\n# X（Twitter）订阅与内容拉取\n\n本文档供 Agent 在用户询问 X / Twitter 账号订阅、推文、长文相关需求时按需读取。\n\n**调用前提**：先确认登录态（见 [auth.md](auth.md)）；未登录时不要直接调本节命令。\n\n---\n\n## ⚠️ 关键边界：X 订阅必须在 Web 控制台完成\n\nX 账号的**搜索**与**订阅 / 取消订阅**仅由 Web 控制台 <https://mp2rss.bugcode.dev/> 提供，**CLI 与 Open API 都不暴露这些写类端点**。\n\nCLI 在 `x` 子命令组下**只覆盖读类**三件事：\n\n| 子命令 | 作用 |\n|--------|------|\n| `mp2rss x list`     | 列出当前 Feed Key 已订阅的 X 账号 |\n| `mp2rss x posts`    | 拉取已订阅 X 账号的推文流 |\n| `mp2rss x articles` | 拉取已订阅 X 账号的长文流 |\n\n### Agent 路由策略\n\n- 用户说「订阅 X 上的 @xxx」「订阅这个推特账号」「在 mp2rss 里加个 X 号」\n  → **不要尝试 CLI**，告诉用户去 Web 控制台「订阅管理 → X」搜索并订阅，之后回到这里可用 CLI 列出/拉内容。\n- 用户说「取消订阅 X 账号 xxx」\n  → 同上，引导去 Web 控制台。\n- 用户说「我订阅了哪些 X 号」「拉一下 @elonmusk 的推文」\n  → 走本文档的 `x list` / `x posts` 流程。\n\n---\n\n## xUserId vs @handle\n\nX 的业务键是 `xUserId`（X 平台的数字 user_id，字符串形态），**不是** `@handle`：\n\n- `@handle` 用户可随时改，订阅指向会失效；\n- `xUserId` 是 X 平台稳定的唯一 ID。\n\nCLI 与 Open API 的所有 X 读类端点（`x posts` / `x articles`）**只接受 `xUserId`**。用户给的是 `@handle` 或显示名时，Agent 必须先 `mp2rss x list -o json` 查出对应 `xUserId` 再调用。\n\n```bash\nmp2rss x list -o json | jq -r '.items[] | \"\\(.xUserId)\\t@\\(.xUsername)\\t\\(.xDisplayName)\"'\n```\n\n---\n\n## List\n\n```\nmp2rss x list [-q <keyword>] [-p <page>] [--page-size <n>] [-o json]\n```\n\n列出当前 Feed Key 名下已订阅的全部 X 账号。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-q, --query` | — | 按 `xDisplayName` / `xUsername` 模糊匹配 |\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（最大 50） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x list\nmp2rss x list -q elon\nmp2rss x list -p 2 --page-size 20\nmp2rss x list -o json | jq '.items[].xUserId'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"sourceType\": \"x\",\n      \"xUserId\": \"44196397\",\n      \"xUsername\": \"elonmusk\",\n      \"xDisplayName\": \"Elon Musk\",\n      \"xVerified\": true,\n      \"createdAt\": 1776640000000,\n      \"xLastItemAt\": 1776854096000\n    }\n  ],\n  \"total\": 1,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `sourceType` | string | 固定 `\"x\"` |\n| `xUserId` | string | X 数字 user_id（字符串形态） |\n| `xUsername` | string | X handle，不含 `@` |\n| `xDisplayName` | string | X 显示名 |\n| `xVerified` | bool | 是否已认证 |\n| `createdAt` | int64 | 订阅创建时间，unix 毫秒 |\n| `xLastItemAt` | int64? | 最近一条推文/长文收录时间，unix 毫秒，可能为 null |\n\n---\n\n## Posts\n\n```\nmp2rss x posts <xUserId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 `postedAt DESC` 拉取已订阅 X 账号的推文流。**仅允许查询已订阅的 xUserId**，未订阅返回 exit code 4（`X account is not subscribed`）。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（**最大 50**） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x posts 44196397\nmp2rss x posts 44196397 -p 2 --page-size 20\nmp2rss x posts 44196397 -o json | jq '.items[].content'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"postId\": \"1234567890\",\n      \"content\": \"hello world\",\n      \"media\": [{ \"url\": \"https://x.com/img.jpg\", \"type\": \"photo\" }],\n      \"retweetedPost\": null,\n      \"quotedPost\": { \"id\": \"99\", \"content\": \"...\" },\n      \"threadPosts\": [{ \"content\": \"reply 1\" }],\n      \"postedAt\": 1746864000000\n    }\n  ],\n  \"total\": 42,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `postId` | string | 推文业务 ID |\n| `content` | string | 推文正文（明文，未渲染 HTML） |\n| `media` | array | 媒体附件数组；无媒体或解析失败为 `[]` |\n| `media[].url` | string | 媒体资源 URL |\n| `media[].type` | string | `photo` / `video` / `animated_gif` 等 |\n| `retweetedPost` | object? | 转推原推文对象；无则 null |\n| `quotedPost` | object? | 引用的推文对象；无则 null |\n| `threadPosts` | array | Thread 系列推文数组；无则 `[]` |\n| `postedAt` | int64 | 发布时间，unix 毫秒 |\n\n::: tip 结构化 vs 渲染\n本端点返回的是**结构化原始数据**（含 media / quotedPost / threadPosts 嵌套），供 Agent 自定义渲染。\n如果用户只想在阅读器里订阅来看，请引导走 Web 控制台「账户设置」复制的 Feed 链接（公开 RSS / Atom / JSON Feed 层），不要让 Agent 重新拼装。\n:::\n\n---\n\n## Articles\n\n```\nmp2rss x articles <xUserId> [-p <page>] [--page-size <n>] [-o json]\n```\n\n按 `publishedAt DESC` 拉取已订阅 X 账号的长文（X Articles）流。订阅闭环校验同 `x posts`，未订阅返回 exit code 4。\n\n| Flag | 默认 | 说明 |\n|------|------|------|\n| `-p, --page` | 1 | 页码 |\n| `--page-size` | 20 | 每页条数（**最大 50**） |\n| `-o, --output` | table | `table` / `json` |\n\n```bash\nmp2rss x articles 44196397\nmp2rss x articles 44196397 -o json | jq '.items[].url'\n```\n\n### JSON shape\n\n```json\n{\n  \"items\": [\n    {\n      \"url\": \"https://x.com/elonmusk/article/...\",\n      \"title\": \"My take on...\",\n      \"description\": \"summary\",\n      \"contentMarkdown\": \"# Heading\\n\\nfull body markdown source\",\n      \"coverUrl\": \"https://...\",\n      \"publishedAt\": 1747353600000\n    }\n  ],\n  \"total\": 8,\n  \"page\": 1,\n  \"pageSize\": 20\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `url` | string | 长文原始 URL |\n| `title` | string | 标题 |\n| `description` | string | 摘要 |\n| `contentMarkdown` | string? | 长文 markdown 原文，可能为 null |\n| `coverUrl` | string? | 封面图 URL |\n| `publishedAt` | int64 | 发布时间，unix 毫秒 |\n\n---\n\n## Agent 综合注意事项\n\n- **xUserId 是字符串**，不要按整数处理（与 `mpId` 不同；handle 起源是数字，但 API 契约统一为字符串）\n- **不接受 `@handle`**：从 `x list` 输出里取 `xUserId` 再调 posts / articles\n- **写类操作不可达**：用户要订阅/取消订阅 X，**统一引导到 Web 控制台**，不要尝试构造 CLI 写命令\n- **结构化解析统一 `-o json`**\n- **字段命名 camelCase**：`xUserId` / `xUsername` / `xDisplayName` / `xLastItemAt` / `postId` / `postedAt` / `publishedAt`\n- **时间字段统一 unix 毫秒**（int64 number）\n- **页大小上限 50**（`x posts` / `x articles` 最大都是 50，注意与 `mp articles` 的 100 不同）\n- 错误码处理见 [errors.md](errors.md)；典型场景：未订阅返回 exit 4，message `X account is not subscribed`\n\nFile v0.2.0:skill-card.md\n\n## Description: <br>\nMp2rss helps agents manage WeChat Official Account and X (Twitter) RSS subscriptions, authentication, and content retrieval through the mp2rss CLI. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[areyoubugcoder](https://clawhub.ai/user/areyoubugcoder) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to configure the mp2rss CLI, manage Feed Key authentication, manage WeChat Official Account RSS subscriptions, and retrieve WeChat articles or subscribed X posts and articles. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: MP2RSS_FEED_KEY is a bearer credential and can expose the user's mp2rss account if logged or shared. <br>\nMitigation: Use a trusted local terminal or secret store, avoid putting the key in shared shells or CI logs, and rely on mp2rss auth login when possible. <br>\nRisk: The documented curl pipe shell installer executes remote shell content. <br>\nMitigation: Prefer the npm package or downloaded release binary; inspect installer content before using a piped shell install. <br>\nRisk: Authenticated mp2rss commands can change WeChat Official Account subscriptions. <br>\nMitigation: Check login status, validate user-provided URLs, and confirm subscription identifiers from CLI output before changing subscriptions. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/areyoubugcoder/mp2rss) <br>\n- [Mp2rss service homepage](https://mp2rss.bugcode.dev) <br>\n- [Installation reference](references/install.md) <br>\n- [Authentication reference](references/auth.md) <br>\n- [WeChat Official Account reference](references/mp.md) <br>\n- [X account reference](references/x.md) <br>\n- [Error handling reference](references/errors.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with inline shell commands and JSON parsing notes] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May propose mp2rss CLI commands and summarize JSON command results; authenticated actions require a local mp2rss binary and a Feed Key.] <br>\n\n## Skill Version(s): <br>\n0.2.0 (source: frontmatter, package.json, server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.2.0:package.json\n\n{\n  \"name\": \"mp2rss\",\n  \"version\": \"0.2.0\",\n  \"description\": \"Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。订阅 / 列出 / 搜索 / 取消订阅公众号，查询公众号历史文章；列出已订阅 X 账号，拉取 X 推文 / 长文流（X 写类操作仅 Web 控制台）；管理 Feed Key 登录态。\",\n  \"license\": \"MIT-0\",\n  \"author\": \"areyoubugcoder\",\n  \"homepage\": \"https://mp2rss.bugcode.dev\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/areyoubugcoder/mp2rss-openclaw.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/areyoubugcoder/mp2rss-openclaw/issues\"\n  },\n  \"keywords\": [\n    \"mp2rss\",\n    \"wechat\",\n    \"weixin\",\n    \"微信\",\n    \"公众号\",\n    \"x\",\n    \"twitter\",\n    \"推特\",\n    \"rss\",\n    \"feed\",\n    \"subscription\",\n    \"订阅\",\n    \"openclaw\",\n    \"skill\"\n  ],\n  \"clawhub\": {\n    \"acceptLicenseTerms\": true\n  }\n}\n\nFile v0.2.0:LICENSE\n\nMIT No Attribution\n\nCopyright 2026 areyoubugcoder\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v0.1.1: 9 files, 15555 bytes\n\nFiles: LICENSE (909b), package.json (774b), README.md (5336b), references/auth.md (3583b), references/errors.md (3595b), references/install.md (2286b), references/mp.md (5536b), SKILL.md (8389b), _meta.json (125b)\n\nFile v0.1.1:SKILL.md\n\n---\nname: mp2rss\ndescription: |\n  Mp2rss CLI Skill —— 微信公众号转 RSS 订阅与文章管理。\n\n  **当以下情况使用此 Skill**：\n  (1) 用户要订阅 / 取消订阅 / 列出 / 搜索公众号：「订阅这个公众号 https://mp.weixin.qq.com/s/...」「我订阅了哪些公众号」「列一下我的公众号 RSS」「搜一下我订阅的财经类公众号」「取消订阅 X」「把 X 从订阅里删了」\n  (2) 用户要查公众号历史文章：「X 这个号最近发了什么」「拉一下 X 的文章」「<X 号> 的历史文章」\n  (3) 用户要管理登录态：「登录公众号 RSS 服务」「登出公众号 RSS」「我的 Feed Key 是什么」「我在公众号订阅工具里登录了吗」「在 mp2rss 里登录」\n  (4) 用户要安装 / 配置 Mp2rss CLI：「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪里」\nversion: 0.1.1\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - mp2rss\n    envVars:\n      - name: MP2RSS_FEED_KEY\n        required: false\n        description: Mp2rss Feed Key；也可由 `mp2rss auth login` 写入配置文件，二者任一即可。\n      - name: MP2RSS_API_URL\n        required: false\n        description: Mp2rss API URL，默认 https://mp2rss.bugcode.dev。\n    homepage: https://mp2rss.bugcode.dev\n    emoji: \"📡\"\n---\n\n# Mp2rss Skill\n\n通过 Mp2rss CLI（Go 二进制 `mp2rss`）将微信公众号转成 RSS / JSON Feed 并管理订阅。本 skill 是路由入口，按用户意图分发到 `references/` 子文档读取详细命令规格。\n\n## ⚠️ Agent 必读约束\n\n### 🔧 运行时前置\n\n所有命令通过本地 `mp2rss` 二进制调用，**不直接打 HTTP**。Agent 不应自己拼 API 请求，统一走 CLI 子命令 + `-o json` 解析。\n\n**Base URL 由 CLI 自动决定**（命令行 flag > 环境变量 > 配置文件 > 默认 `https://mp2rss.bugcode.dev`）。\n\n### 🔑 凭证与登录态\n\n调用任何 `mp2rss mp` 子命令前，**必须先确认登录态**：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `{\"loggedIn\": false}` 时停止调用 mp 子命令，引导用户跑 `mp2rss auth login`，详见 [references/auth.md](references/auth.md)。\n\n凭证优先级（高 → 低）：命令行 `--api-key` flag > `MP2RSS_FEED_KEY` 环境变量 > `~/.mp2rss/config.json` 配置文件。\n\n### 🔢 mpId 是 int64\n\n公众号 ID 是 64 位整数，超出 JavaScript `Number.MAX_SAFE_INTEGER`。Agent 在 JS 环境下解析 `mp list -o json` / `mp articles -o json` 输出时**始终把 mpId 当字符串处理**：\n\n```javascript\nconst safe = text.replace(/\"(mpId)\"\\s*:\\s*(\\d+)/g, '\"$1\":\"$2\"');\nconst data = JSON.parse(safe);\n```\n\nPython / Go / jq 原生支持大整数，无此问题。\n\n### 🚫 反幻觉边界\n\n- **禁止编造 mpId**：所有 mpId 必须来自 `mp list` / `mp search` 的响应，不得凭空构造\n- **禁止跳过订阅参数校验**：`mp subscribe <url>` 的 `<url>` **必须**是 `https://mp.weixin.qq.com/s/...` 文章链接；不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时**反问用户索要任意一篇文章链接**，不要直接尝试\n- **禁止伪造执行结果**：不调用 CLI 不得告诉用户「已订阅」「已删除」\n- **禁止忽略 exit code**：CLI 返回非 0 必须解析 stderr / JSON envelope 并报告用户\n\n### 🔄 错误处理\n\nCLI 错误统一 JSON envelope（见 [references/errors.md](references/errors.md)）：\n\n```json\n{\"error\": {\"message\": \"...\", \"code\": <int>}}\n```\n\nExit code 速查：\n\n| Code | 含义 | Agent 处理 |\n|------|------|-----------|\n| 0 | 成功 | 解析 stdout |\n| 1 | 通用错误（网络） | 报告 + 建议稍后重试 |\n| 2 | 参数错误 | 检查参数；若是 `mp subscribe` 检查 URL 格式 |\n| 3 | 鉴权失败 | 引导跑 `mp2rss auth login`（见 [auth.md](references/auth.md)） |\n| 4 | 资源不存在 | mpId 错或文章 URL 失效 |\n| 5 | 上游不可用 | 报告 + 建议稍后重试 |\n\n---\n\n## 执行流程概览\n\n```\n用户意图 → 路由匹配 → 读对应 references/xxx.md → 构造 mp2rss 子命令 → 执行 → 解析 JSON / 验证 exit code → 返回结果\n               \n\nArchive v0.1.0: 9 files, 15554 bytes\n\nFiles: LICENSE (909b), package.json (774b), README.md (5336b), references/auth.md (3583b), references/errors.md (3595b), references/install.md (2286b), references/mp.md (5536b), SKILL.md (8389b), _meta.json (125b)","readmeExcerpt":"Skill: mp2rss Owner: areyoubugcoder Summary: Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。 **当以下情况使用此 Skill**： (1) 用户要订阅 / 取消订阅 / 列出 / 搜索**微信公众号**：「订阅这个公众号 https://mp.weixin.qq.com/s/...」「我订阅了哪些公众号」「列一下我的公众号 RSS」「搜一下我订阅的财经类公众号」「取消订阅那个号」「把 <公众号名> 从订阅里删了」 (2) 用户要查**公众号历史文章**：「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」「<公众号名> 的历史文章」 (3) 用户要操作 **X（Twitter）账号**：「我订阅了哪些 X 账号」「@elonmusk 最近发了啥」「拉一下某个 X 号的推文 / 长文」（注：X 的订阅 / 取消订阅","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"mp2rss auth status -o json"},{"language":"javascript","snippet":"const safe = text.replace(/\"(mpId)\"\\s*:\\s*(\\d+)/g, '\"$1\":\"$2\"');\n  const data = JSON.parse(safe);"},{"language":"json","snippet":"{\"error\": {\"message\": \"...\", \"code\": <int>}}"},{"language":"text","snippet":"用户意图 → 路由匹配 → 读对应 references/xxx.md → 构造 mp2rss 子命令 → 执行 → 解析 JSON / 验证 exit code → 返回结果\n                                                                                      ↓\n                                                                                  exit ≠ 0 → 按错误码分支处理"},{"language":"text","snippet":"包含 mp.weixin.qq.com/s/ URL              → mp subscribe（参数 = 该 URL）\n「订阅」+ 任何 URL 形态                    → 先校验是不是 mp.weixin.qq.com/s/...，否则反问\n「订阅了哪些 公众号」「我的公众号」          → mp list\n「订阅了哪些 X / Twitter 账号」「我的 X 订阅」 → x list\n「搜公众号」「找一下带 关键词 的公众号」      → mp list -q <kw> 或 mp search <kw>\n「取消订阅 <公众号名>」「删了 <公众号名>」    → 先 mp list -q <名> 确认 mpId，再 mp remove <mpId>\n「<公众号名> 最近发的文章 / 历史文章」        → mp articles <mpId>（先列表确认 mpId）\n「@elonmusk 最近的推文」「<X 账号名> 发了啥」  → 先 x list 拿到 xUserId，再 x posts <xUserId>\n「<X 账号名> 的长文 / Articles」              → 先 x list，再 x articles <xUserId>\n「订阅 / 取消订阅一个 X 账号」               → 引导用户去 Web 控制台「订阅管理 → X」，不要走 CLI\n「登录」「授权」                            → auth login（参考 auth.md 选三种登录模式之一）\n「我的 Key」「登录了吗」「状态」              → auth status -o json\n「登出」「退出登录」                         → auth logout"},{"language":"bash","snippet":"curl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: mp2rss\ndescription: |\n  Mp2rss CLI Skill —— 微信公众号 / X（Twitter）账号转 RSS 订阅与内容管理。\n\n  **当以下情况使用此 Skill**：\n  (1) 用户要订阅 / 取消订阅 / 列出 / 搜索**微信公众号**：「订阅这个公众号 https://mp.weixin.qq.com/s/...」「我订阅了哪些公众号」「列一下我的公众号 RSS」「搜一下我订阅的财经类公众号」「取消订阅那个号」「把 <公众号名> 从订阅里删了」\n  (2) 用户要查**公众号历史文章**：「<公众号名> 最近发了什么」「拉一下 <公众号名> 的文章」「<公众号名> 的历史文章」\n  (3) 用户要操作 **X（Twitter）账号**：「我订阅了哪些 X 账号」「@elonmusk 最近发了啥」「拉一下某个 X 号的推文 / 长文」（注：X 的订阅 / 取消订阅仅在 Web 控制台，CLI 只能列出已订阅与拉内容）\n  (4) 用户要管理**登录态**：「登录公众号 RSS 服务」「登出 mp2rss」「我的 Feed Key 是什么」「我在 mp2rss 里登录了吗」\n  (5) 用户要**安装 / 配置 Mp2rss CLI**：「装 mp2rss」「升级 mp2rss」「mp2rss 配置在哪里」\nversion: 0.2.3\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - mp2rss\n    envVars:\n      - name: MP2RSS_FEED_KEY\n        required: false\n        description: Mp2rss Feed Key；也可由 `mp2rss auth login` 写入配置文件，二者任一即可。\n      - name: MP2RSS_API_URL\n        required: false\n        description: Mp2rss API URL，默认 https://mp2rss.bugcode.dev。\n    homepage: https://mp2rss.bugcode.dev\n    emoji: \"📡\"\n---\n\n# Mp2rss Skill\n\n通过 Mp2rss CLI（Go 二进制 `mp2rss`）把**微信公众号**与 **X（Twitter）账号**转成 RSS / JSON Feed 并管理订阅。本 skill 是路由入口，按用户意图分发到 `references/` 子文档读取详细命令规格。\n\n> **术语提示**：本文档中 **\"X\"** 一律指 X（原 Twitter）平台；用作\"某个公众号\"占位时统一写作 `<公众号名>` 或具名描述，避免与 X 平台混淆。\n\n## ⚠️ Agent 必读约束\n\n### 🔧 运行时前置\n\n所有命令通过本地 `mp2rss` 二进制调用，**不直接打 HTTP**。Agent 不应自己拼 API 请求，统一走 CLI 子命令 + `-o json` 解析。\n\n**Base URL 由 CLI 自动决定**（命令行 flag > 环境变量 > 配置文件 > 默认 `https://mp2rss.bugcode.dev`）。\n\n### 🔑 凭证与登录态\n\n调用任何 `mp2rss mp` / `mp2rss x` 子命令前，**必须先确认登录态**：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `{\"loggedIn\": false}` 时停止后续调用，引导用户跑 `mp2rss auth login`，详见 [references/auth.md](references/auth.md)。\n\n凭证优先级（高 → 低）：命令行 `--api-key` flag > `MP2RSS_FEED_KEY` 环境变量 > `~/.mp2rss/config.json` 配置文件。\n\n### 🔢 mpId 是 int64 / xUserId 是字符串\n\n两种业务键形态不同，**不要混用**：\n\n- **`mpId`**（公众号）：int64 整数。超出 JavaScript `Number.MAX_SAFE_INTEGER`，Agent 在 JS 环境下解析 `mp list / mp articles -o json` 输出时**始终把 mpId 当字符串处理**：\n\n  ```javascript\n  const safe = text.replace(/\"(mpId)\"\\s*:\\s*(\\d+)/g, '\"$1\":\"$2\"');\n  const data = JSON.parse(safe);\n  ```\n\n- **`xUserId`**（X 账号）：API 契约即为字符串（虽然内容是数字串），原样消费即可，不必转换。\n\nPython / Go / jq 原生支持大整数，无 mpId 精度问题。\n\n### 🚫 反幻觉边界\n\n- **禁止编造 mpId / xUserId**：所有业务键必须来自 `mp list` / `mp search` / `x list` 的响应，不得凭空构造\n- **禁止跳过订阅参数校验**：`mp subscribe <url>` 的 `<url>` **必须**是 `https://mp.weixin.qq.com/s/...` 文章链接；不是公众号名、不是二维码、不是公众号主页。识别不到合法文章 URL 时**反问用户索要任意一篇文章链接**，不要直接尝试\n- **禁止伪造执行结果**：不调用 CLI 不得告诉用户「已订阅」「已删除」\n- **禁止忽略 exit code**：CLI 返回非 0 必须解析 stderr / JSON envelope 并报告用户\n- **X 订阅 / 取消订阅必须走 Web 控制台**：CLI 与 API 都不暴露 X 写类端点；用户要订阅 X 账号时**只能引导到 <https://mp2rss.bugcode.dev/>「订阅管理 → X」**，不要尝试构造 CLI 写命令\n\n### 🔄 错误处理\n\nCLI 错误统一 JSON envelope（见 [references/errors.md](references/errors.md)）：\n\n```json\n{\"error\": {\"message\": \"...\", \"code\": <int>}}\n```\n\nExit code 速查：\n\n| Code | 含义 | Agent 处理 |\n|------|------|-----------|\n| 0 | 成功 | 解析 stdout |\n| 1 | 通用错误（网络 / cobra 解析层：缺参、flag 值非法，此类输出裸文本非 JSON / 限流 429 且 envelope `kind: \"rate_limited\"`） | 网络类报告 + 建议稍后重试；解析类修正参数；限流"},{"path":"README.md","content":"# Mp2rss Skill\n\n[![License: MIT-0](https://img.shields.io/badge/License-MIT--0-blue.svg)](https://opensource.org/licenses/MIT-0)\n\n让 AI Agent 帮你管理 **微信公众号** 与 **X（Twitter）账号** 的 RSS 订阅 —— 一句话订阅、自然语言查找、按需读历史文章 / 推文 / 长文。\n\n本目录是 [Mp2rss](https://mp2rss.bugcode.dev) 服务的 OpenClaw Agent Skill 包，随 [`mp2rss` CLI](https://github.com/areyoubugcoder/mp2rss-cli) 同仓库维护（`openclaw/mp2rss/` 子目录），发布到 ClawHub（slug：`mp2rss`）。Claude Code 用户请改用仓库根的 `skills/`（插件市场 / `npx skills add` 安装），见主仓库 README。\n\n---\n\n## ✨ 核心能力\n\n### 微信公众号（MP）\n\n| 能力 | 说明 |\n|------|------|\n| 📡 **一键订阅** | 发一个公众号文章链接（`mp.weixin.qq.com/s/...`），Agent 自动把整个公众号订阅到你的 Feed |\n| 📋 **列表与搜索** | 「我订阅了哪些公众号」「搜一下我订阅的财经类公众号」 |\n| 🗑️ **取消订阅** | 「把 某号 从订阅里删了」，Agent 先核对 mpId 再删 |\n| 📰 **历史文章** | 「某号 最近发了什么」/「拉一下 某号 的文章」 |\n\n### X（Twitter）账号\n\n| 能力 | 说明 |\n|------|------|\n| 🐦 **列出 X 订阅** | 「我订阅了哪些 X 账号」 |\n| 📨 **推文流** | 「@elonmusk 最近发了啥」（Agent 先 `x list` 找到 `xUserId` 再拉推文） |\n| 📝 **长文流** | 「拉一下 某 X 账号的 Articles」 |\n| ⚠️ **订阅 / 取消订阅 X 账号** | **仅在 Web 控制台**（<https://mp2rss.bugcode.dev/>）—— CLI 与 API 都不暴露 X 写类端点，Agent 会引导你去控制台 |\n\n### 通用\n\n| 能力 | 说明 |\n|------|------|\n| 🔐 **登录态管理** | 「我的 Feed Key 是什么」「登录 mp2rss」 |\n| 📤 **结构化输出** | 所有命令支持 `-o json`，Agent 可直接解析做后续处理 |\n\n---\n\n## 💡 使用场景\n\n### 通勤路上看到好公众号\n\n> 👤 订阅这个公众号 https://mp.weixin.qq.com/s/abc123xyz\n>\n> 🤖 已订阅「某公众号」到你的 Feed。\n\n### 不记得订过哪些号\n\n> 👤 我订阅了哪些公众号？\n>\n> 🤖 当前共 42 个订阅。前 20 个：某公众号（最近发文 2 小时前）、另一个号（昨天）……\n\n### 找特定主题\n\n> 👤 我订阅的财经类公众号有哪些\n>\n> 🤖 找到 5 个匹配：财经早知道、第一财经……\n\n### 翻看历史\n\n> 👤 财经早知道 最近发了什么\n>\n> 🤖 最近 10 篇文章：1. xxx 标题（昨天）2. xxx 标题（前天）……\n\n### 不想看了\n\n> 👤 把 财经早知道 从订阅里删了\n>\n> 🤖 确认删除「财经早知道」（mpId 123456）？已删除 ✓\n\n### 看大 V 推文\n\n> 👤 @elonmusk 最近发了啥？\n>\n> 🤖 （先 `x list` 拿到 xUserId 44196397）最近 5 条推文：1. ……\n\n### 想订阅一个 X 账号\n\n> 👤 帮我订阅 @paulg 这个号\n>\n> 🤖 X 账号的订阅 / 取消订阅只能在 Web 控制台操作。打开 https://mp2rss.bugcode.dev/「订阅管理 → X」搜索 paulg 完成订阅；订阅好我就能用 `mp2rss x posts/articles` 帮你拉内容。\n\n---\n\n## 📦 安装\n\n### 前置：装 Mp2rss CLI 二进制\n\nskill 本身只描述如何调用 CLI，所以必须先装 `mp2rss` 二进制（任选其一）：\n\n```bash\n# 方式 A：npm（推荐，跨平台一致）\npnpm add -g @mp2rss/cli\n\n# 方式 B：macOS / Linux 一键脚本\ncurl -fsSL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/scripts/install.sh | sh\n```\n\n也可在 [Releases](https://github.com/areyoubugcoder/mp2rss-cli/releases/latest) 下载对应平台二进制。\n\n### 装 Skill\n\n```bash\n# 方式 A：通过 ClawHub（推荐）\nopenclaw skills install mp2rss\n\n# 方式 B：手动\nmkdir -p ~/.openclaw/workspace/skills/mp2rss\ncd ~/.openclaw/workspace/skills/mp2rss\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/openclaw/mp2rss/SKILL.md -o SKILL.md\ncurl -sL https://raw.githubusercontent.com/areyoubugcoder/mp2rss-cli/main/openclaw/mp2rss/package.json -o package.json\n# 视需要再拉 references/ 子文档\n```\n\n---\n\n## 🔑 授权登录\n\n安装完成后说「登录 mp2rss」，Agent 自动跑 `mp2rss auth login` 走浏览器 loopback 授权。CI / 无头环境用：\n\n```bash\nmp2rss auth login -k <feed-key>            # 直传\nmp2rss auth login --no-browser             # 远程模式，仅打印授权 URL\n```\n\nFeed Key 可在 <https://mp2rss.bugcode.dev/> 登录后查看或重置。配置文件位置 `~/.mp2rss/config.json`。\n\n### 用环境变量配置（可选）\n\n```bash\nexport MP2RSS_FEED_KEY"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7acxx408jk3phdk3326sx5fs86zndf\",\n  \"slug\": \"mp2rss\",\n  \"version\": \"0.2.3\",\n  \"publishedAt\": 1791446520486\n}"},{"path":"references/auth.md","content":"# 认证管理\n\n本文档供 Agent 在用户询问「登录」「登出」「我的 Feed Key 是什么」「我登录了吗」「在 mp2rss 里登录」时按需读取。\n\n## 触发条件\n\n调用任何 `mp2rss mp` 子命令前，**必须先**确认登录态：\n\n```bash\nmp2rss auth status -o json\n```\n\n返回 `loggedIn: false` 时停止后续 mp 调用，引导用户登录后再继续原始请求。\n\n## Log in\n\n```\nmp2rss auth login [-k <feed-key>] [--no-browser]\n```\n\n三种模式：\n\n| 模式 | 命令 | 适用场景 |\n|------|------|---------|\n| 浏览器（默认） | `mp2rss auth login` | 桌面环境；CLI 启动本地 loopback HTTP 服务，打开浏览器登录后回调写入 `~/.mp2rss/config.json` |\n| Feed Key 直传 | `mp2rss auth login -k <feed-key>` | CI / 无头环境；Feed Key 在 https://mp2rss.bugcode.dev/ 登录后获取或重置 |\n| 远程模式 | `mp2rss auth login --no-browser` | 远程 SSH / 无浏览器；CLI 仅打印授权 URL，用户在本地浏览器打开后复制 Feed Key 回填 |\n\n```bash\nmp2rss auth login                          # 默认浏览器\nmp2rss auth login -k gk_live_xxxxxxxx      # 直传\nmp2rss auth login --no-browser             # 远程\n```\n\n### Agent 处理远程模式\n\n`mp2rss auth login --no-browser` 输出形如：\n\n```\n请在浏览器打开下面的链接完成授权：\n\n  https://mp2rss.bugcode.dev/auth/cli?code=...\n\n授权后将页面上显示的 Feed Key 粘贴到此终端：\n```\n\nAgent 应：\n\n1. **完整提取授权 URL** 转发给用户\n2. 提示「请在浏览器打开此链接，登录后把页面上的 Feed Key 粘贴回这里」\n3. 不要替用户决定使用哪个浏览器；不要把 URL 截断或缩短\n\n⚠️ `auth login` **不支持 `-o json`**，输出为纯文本反馈。\n\n## Check status\n\n```\nmp2rss auth status [-o json]\n```\n\n```bash\nmp2rss auth status            # 人类可读\nmp2rss auth status -o json    # Agent 解析\n```\n\n### JSON shape（已登录）\n\n```json\n{\n  \"loggedIn\": true,\n  \"source\": \"config\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\",\n  \"feedKeyMasked\": \"abcdef***\",\n  \"name\": \"张三\",\n  \"email\": \"user@example.com\",\n  \"lastLoginAt\": 1705000000000,\n  \"lastVerifyAt\": 1705000001000\n}\n```\n\n### JSON shape（未登录）\n\n```json\n{\n  \"loggedIn\": false,\n  \"source\": \"none\",\n  \"apiUrl\": \"https://mp2rss.bugcode.dev\"\n}\n```\n\n### 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `loggedIn` | bool | 是否已配置可用凭证 |\n| `source` | string | `\"env\"` / `\"config\"` / `\"none\"` |\n| `apiUrl` | string | 当前生效的 API URL |\n| `feedKeyMasked` | string | 已脱敏 Feed Key（仅前几位 + `***`） |\n| `name` | string? | 账号昵称；仅浏览器登录回调成功时落盘，`-k` / `--no-browser` 流程没有，`omitempty` 省略 |\n| `email` | string? | 账号邮箱；同 `name`，仅浏览器登录流程有 |\n| `lastLoginAt` | int64 | 最近登录时间，unix 毫秒 |\n| `lastVerifyAt` | int64 | 最近一次验证时间，unix 毫秒 |\n\n## Log out\n\n```\nmp2rss auth logout\n```\n\n清空 `~/.mp2rss/config.json` 里的 `feed_key`，保留 `api_url` 等其它配置。\n\n```bash\nmp2rss auth logout\n```\n\n## 凭证优先级\n\n高 → 低：\n\n1. CLI flag：`--api-key <feed-key>`\n2. 环境变量：`MP2RSS_FEED_KEY`\n3. 配置文件：`~/.mp2rss/config.json` 的 `feed_key`\n\nAPI URL 同理：`--api-url` > `MP2RSS_API_URL` > 配置文件 > 默认 `https://mp2rss.bugcode.dev`。\n\n## Agent 注意事项\n\n- 调用 `mp2rss mp` 任何子命令前先 `mp2rss auth status -o json`\n- 时间字段是 unix 毫秒（int64），不是格式化字符串\n- 不要直接读写 `~/.mp2rss/config.json`，统一用 `mp2rss auth ...` 子命令\n- 鉴权错误（exit code 3 / HTTP 401）时引导用户跑 `mp2rss auth login`，不要反复重试\n- `feedKeyMasked` 仅供展示用户身份，**不要试图从掩码还原完整 Key**"},{"path":"references/errors.md","content":"# 错误处理\n\n本文档供 Agent 在 mp2rss 命令返回非零 exit code 或 JSON envelope 含 `error` 字段时按需读取。\n\n## JSON 错误 envelope\n\n任何子命令在 `-o json` 模式下出错时统一返回：\n\n```json\n{\n  \"error\": {\n    \"message\": \"human-readable 错误信息\",\n    \"code\": <int>,\n    \"kind\": \"rate_limited\"\n  }\n}\n```\n\n- `code` 字段是 HTTP 状态码（来自上游 API）或 CLI 自身 exit code\n- `message` 是人类可读描述（中文），可直接转发给用户\n- `kind` 可选，仅在需要特殊处理时出现；目前只有 `rate_limited`（被限流且 CLI 已放弃等待）。没有该字段 = 普通错误\n\n> ⚠️ 例外（实测 CLI 1.1.0）：**cobra 参数解析层**的错误（必填位置参数缺失、flag 值类型非法如 `--page-size abc`）以 exit 1 退出，且**即使带 `-o json` 也输出裸文本到 stderr**，不是 JSON envelope。Agent 解析 JSON 失败时应回退读 stderr 文本。\n\n## Exit codes\n\n| Code | 含义 | 典型场景 | Agent 处理 |\n|------|------|---------|-----------|\n| `0` | 成功 | 命令正常执行 | 解析 stdout |\n| `1` | 通用错误（网络）/ 解析层错误 / **限流** | DNS 失败 / TCP 连不上 / 超时；**必填参数缺失、flag 值非法**（cobra 解析层，裸文本 stderr）；HTTP 429 且 `kind: \"rate_limited\"` | 网络类：报告 + 建议稍后重试；解析类：修正命令参数后重试一次；限流：**不要立刻重试**，把 message 里的解锁时间告诉用户 |\n| `2` | 参数错误（业务校验层） | `mp subscribe` URL 不是 `mp.weixin.qq.com/s/...` / 位置参数格式非法（如 mpId 非数字） | 解析 envelope 给用户具体提示；URL 错就反问用户索要正确文章链接 |\n| `3` | 鉴权失败 | Feed Key 错 / 过期 / 未配置 / HTTP 401 | 引导用户跑 `mp2rss auth login`（见 [auth.md](auth.md)）；**不要反复重试** |\n| `4` | 资源不存在 | mpId 错 / 文章 URL 失效 / **xUserId 未订阅**（X 读类端点要求已订阅）/ HTTP 404 | MP：用 `mp list` 重新核对 mpId 或更换文章链接；X：先 `x list` 确认是否已订阅，未订阅的话引导用户去 Web 控制台「订阅管理 → X」 |\n| `5` | 上游不可用 | API 服务挂 / HTTP 5xx | 报告 + 建议稍后重试 |\n\n## HTTP code 对应\n\nCLI 把上游 HTTP 状态码映射到上面的 exit codes：\n\n| HTTP | Exit | 说明 |\n|------|------|------|\n| 200 | 0 | OK |\n| 400 | 2 | 请求参数错 |\n| 401 | 3 | Feed Key 无效 |\n| 403 | 1 | 权限不足（CLI 未特判 403，落到通用错误；message 会带上游原文） |\n| 404 | 4 | 资源不存在 |\n| 429 | 1 | 限流（每个 Feed Key 60 次/分钟，超限锁 10 分钟）。CLI 按响应 `Retry-After` 等待后**重试一次**；等待时长超过 `--max-retry-wait`（默认 90s）或重试仍 429 → 立即返回，envelope 带 `\"kind\":\"rate_limited\"`，message 含预计解锁时间（本地时间）。另外 CLI 在同一台机器上自动把相邻请求间隔拉到 ≥ 1.2s（`MP2RSS_MIN_INTERVAL_MS`） |\n| 5xx | 5 | 上游错误（CLI 自动退避重试 1 次，即最多发 2 次请求） |\n\n## Agent 处理策略\n\n### 失败重试\n\n| 错误类型 | 重试策略 |\n|---------|---------|\n| Exit 1（网络） | 等待 5 秒后**最多重试一次**；二次失败明确报告网络问题 |\n| Exit 1（解析层：缺参 / flag 值非法） | **不要原样重试**；按 stderr 提示修正命令参数后再执行 |\n| Exit 1 + `kind: \"rate_limited\"`（限流） | **不要立刻重试**；message 里有预计解锁时间，告诉用户并等到那之后再跑；批量任务改为串行 + 每次间隔 ≥ 1.2s |\n| Exit 3（鉴权） | **不要重试**；直接引导 `mp2rss auth login` |\n| Exit 4（不存在） | **不要重试**；引导用户核对 mpId / URL |\n| Exit 5（上游 5xx） | 等待 5 秒后**最多重试一次**；二次失败建议稍后再试 |\n| Exit 2（参数） | **不要重试**；告诉用户具体是哪个参数错了 |\n\n### 错误信息提取\n\n人类可读模式（无 `-o json`）下，错误写到 stderr，Agent 应捕获 stderr 转发给用户。\n\nJSON 模式下，错误 envelope 写到 stdout（保持单一输出流），Agent 解析 `error.message` 和 `error.code` 字段。\n\n### 反幻觉\n\n- **禁止编造错误信息**：所有报告给用户的错误必须来自 CLI 真实输出（stderr 或 JSON envelope）\n- **禁止隐瞒错误**：CLI 返回非零退出码时必须告诉用户，不能装作执行成功\n- **禁止过度解读 message**：`error.message` 直接转发，不要\"翻译\"成自己的描述（容易扭曲原意）\n\n## 常见错误样例\n\n### Feed Key 失效\n\n```bash\n$ mp2rss mp list -o json\n{\"error\":{\"message\":\"鉴权失败：Feed Key 无效或已重置，请重新登录\",\"code\":401}}\n$ echo $?\n3\n```\n\nAgent → 引导 `mp2rss auth login` 而非重试。\n\n### URL 格式错\n\n```bash\n$ mp2rss mp subscribe https://example.com/article -o json\n{\"error\":{\"message\":\"参数错误：subscribe 需要 mp.weix"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":859,"uniquenessScore":44,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T03:05:37.224Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T03:05:37.224Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T05:28:29.290Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}