Token导航 LogoToken导航

Agent Skill · 研究检索

commafeed-api(commafeed API 搜索)

用于辅助 API 设计、接口文档、请求响应结构和服务集成说明。它适合让 Agent 梳理 endpoint、生成 OpenAPI 草稿、检查字段命名、整理错误码或辅助前后端联调。使用时需要确认真实业务语义、鉴权方式、分页和错误处理规则;涉及生成接口文档时,应避免凭空补字段,最好从现有代码、schema 或接口样例中提取事实。

commafeed-api 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证信息还不明确,第三方扫描有未通过项,按安装量在研究检索类的 73,675 个 Skill 里排第 69,749。

总安装 216周安装 9GitHub Stars 2下载 72核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:commafeed-api(commafeed API 搜索)
来源仓库:https://github.com/biggora/claude-plugins-registry
仓库路径:skills/commafeed-api
安装命令:
npx skills add https://github.com/biggora/claude-plugins-registry --skill commafeed-api
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/biggora/claude-plugins-registry --skill commafeed-api

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

commafeed-api 用于辅助 API 设计、接口文档和请求响应结构梳理。适用于 OpenAPI 草稿生成、字段命名检查和前后端联调支持。通过 npx skills add 命令从指定 GitHub 仓库安装并使用该技能。

使用前需配置 COMMAFEED_HOST、COMMAFEED_USER 和 COMMAFEED_PASS 环境变量。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/commafeed-api

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/biggora/claude-plugins-registry --skill commaf…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

commafeed-api 怎么安装?

在终端执行 npx skills add https://github.com/biggora/claude-plugins-registry --skill commafeed-api。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

commafeed-api 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

commafeed-api 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

commafeed-api 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

commafeed-api 用的人多吗?

公开数据是累计安装 216 次,近一周安装 9 次,下载 72 次,GitHub 2 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

commafeed-api 安全吗?

第三方扫描有未通过项,风险较高。除非你确认过源码,否则不建议直接安装到常用环境。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
commafeed-api

commafeed API 搜索 · 本页

2162接触敏感数据未明确未通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

CommaFeed REST API Skill

Interact with a self-hosted CommaFeed RSS reader instance via its REST API.

Environment Variables (REQUIRED)

Before making any API calls, ensure these environment variables are set:

VariableDescriptionExample
COMMAFEED_HOSTCommaFeed instance URL (with protocol, no trailing slash)https://commafeed.example.com
COMMAFEED_USERCommaFeed usernameadmin
COMMAFEED_PASSCommaFeed passwordsecretpass
export COMMAFEED_HOST="https://commafeed.example.com"
export COMMAFEED_USER="admin"
export COMMAFEED_PASS="your-password"

If these are not set, ask the user to provide them before proceeding.

Authentication

All requests use HTTP Basic Auth:

curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/category/get" | jq .

Every request pattern below assumes:

  • Base URL: $COMMAFEED_HOST/rest
  • Auth: -u "$COMMAFEED_USER:$COMMAFEED_PASS"
  • Content-Type: application/json (for POST requests with JSON body)

Helper alias for examples:

CF="curl -s -u $COMMAFEED_USER:$COMMAFEED_PASS"

API Endpoints

Categories

MethodPathDescription
GET/rest/category/getGet root category tree (all categories + subscriptions)
POST/rest/category/addAdd a new category
POST/rest/category/modifyRename or move a category
POST/rest/category/deleteDelete a category
POST/rest/category/collapseCollapse/expand a category in the UI
GET/rest/category/entriesGet entries for a category
GET/rest/category/entriesAsFeedGet category entries as RSS/Atom XML
POST/rest/category/markMark all entries in a category as read
GET/rest/category/unreadCountGet unread count per subscription
Get category tree (all subscriptions)

Returns the full tree: root category with nested children and feed subscriptions.

curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/category/get" | jq .

Response — Category object:

{
  "id": "all",
  "name": "All",
  "children": [
    {
      "id": "10",
      "parentId": "all",
      "name": "Tech",
      "children": [],
      "feeds": [
        {
          "id": 42,
          "name": "Hacker News",
          "feedUrl": "https://news.ycombinator.com/rss",
          "feedLink": "https://news.ycombinator.com",
          "iconUrl": "/rest/feed/favicon/42",
          "unread": 15,
          "categoryId": "10",
          "position": 0,
          "newestItemTime": "2026-03-07T10:30:00Z",
          "errorCount": 0,
          "lastRefresh": "2026-03-07T10:00:00Z",
          "nextRefresh": "2026-03-07T10:15:00Z"
        }
      ],
      "expanded": true,
      "position": 0
    }
  ],
  "feeds": [],
  "expanded": true,
  "position": 0
}
Add a category
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"name": "Technology", "parentId": "all"}' \
  "$COMMAFEED_HOST/rest/category/add" | jq .

Request body — AddCategoryRequest:

  • name (string, required, max 128 chars) — category name
  • parentId (string, optional) — parent category ID, omit for root level

Response: category ID (integer).

Modify a category
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"id": 10, "name": "Tech News", "parentId": "all", "position": 0}' \
  "$COMMAFEED_HOST/rest/category/modify"

Request body — CategoryModificationRequest:

  • id (integer, required) — category ID
  • name (string) — new name
  • parentId (string) — new parent category ID
  • position (integer) — position in parent
Delete a category
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"id": 10}' \
  "$COMMAFEED_HOST/rest/category/delete"

Request body — IDRequest:

  • id (integer, required) — category ID
Get category entries
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/category/entries?id=all&readType=unread&limit=20&order=desc" | jq .

Query parameters:

  • id (required) — category ID, "all" for all feeds, or "starred" for starred entries
  • readType (required) — all or unread
  • limit (integer, default 20, max 1000) — entries per page
  • offset (integer, default 0) — pagination offset
  • order (string, default desc) — desc or asc
  • newerThan (long) — Unix timestamp in ms, only entries newer than this
  • keywords (string) — search filter
  • tag (string) — filter by tag
  • excludedSubscriptionIds (string) — comma-separated subscription IDs to exclude

Response — Entries object:

{
  "name": "All",
  "entries": [
    {
      "id": "feed/42:entry/abc123",
      "guid": "https://example.com/article-1",
      "title": "Article Title",
      "content": "<p>Article HTML content...</p>",
      "author": "John Doe",
      "date": "2026-03-07T09:00:00Z",
      "insertedDate": "2026-03-07T09:05:00Z",
      "url": "https://example.com/article-1",
      "feedId": "42",
      "feedName": "Example Feed",
      "feedUrl": "https://example.com/rss",
      "feedLink": "https://example.com",
      "iconUrl": "/rest/feed/favicon/42",
      "read": false,
      "starred": false,
      "markable": true,
      "tags": [],
      "categories": "tech, news",
      "rtl": false,
      "enclosureUrl": null,
      "enclosureType": null,
      "mediaThumbnailUrl": null
    }
  ],
  "timestamp": 1741339200000,
  "hasMore": true,
  "offset": 0,
  "limit": 20,
  "errorCount": 0,
  "ignoredReadStatus": false
}
Get unread counts
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/category/unreadCount" | jq .

Response — array of UnreadCount:

[
  {"feedId": 42, "unreadCount": 15},
  {"feedId": 55, "unreadCount": 3}
]
Mark category as read
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"id": "all", "olderThan": 1741339200000, "read": true}' \
  "$COMMAFEED_HOST/rest/category/mark"

Request body — MarkRequest:

  • id (string, required) — category ID or "all"
  • read (boolean) — true to mark read, false for unread
  • olderThan (long) — timestamp, mark only entries older than this
  • insertedBefore (long) — mark only entries inserted before this
  • keywords (string) — filter by keywords
Collapse/expand category
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"id": 10, "collapse": true}' \
  "$COMMAFEED_HOST/rest/category/collapse"

Feed Subscriptions

MethodPathDescription
POST/rest/feed/subscribeSubscribe to a feed
POST/rest/feed/unsubscribeUnsubscribe from a feed
POST/rest/feed/modifyModify subscription (rename, move, filter)
GET/rest/feed/get/{id}Get subscription details
POST/rest/feed/fetchFetch feed info by URL (preview before subscribing)
GET/rest/feed/refreshAllQueue all feeds for refresh
GET/rest/feed/entriesGet entries for a specific feed
GET/rest/feed/entriesAsFeedGet feed entries as RSS/Atom XML
POST/rest/feed/markMark feed entries as read
GET/rest/feed/favicon/{id}Get feed favicon
GET/rest/feed/exportExport all subscriptions as OPML
POST/rest/feed/importImport subscriptions from OPML file
Subscribe to a feed
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/rss",
    "title": "Example Blog",
    "categoryId": 10
  }' \
  "$COMMAFEED_HOST/rest/feed/subscribe" | jq .

Request body — SubscribeRequest:

  • url (string, required) — feed URL
  • title (string, required) — display name
  • categoryId (integer) — target category ID

Response: subscription ID (integer).

Unsubscribe from a feed
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"id": 42}' \
  "$COMMAFEED_HOST/rest/feed/unsubscribe"
Modify a subscription
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 42,
    "name": "New Feed Name",
    "categoryId": 10,
    "position": 0,
    "filter": "title.contains(\"important\")",
    "pushNotificationsEnabled": false,
    "autoMarkAsReadAfterDays": 30
  }' \
  "$COMMAFEED_HOST/rest/feed/modify"

Request body — FeedModificationRequest:

  • id (integer, required) — subscription ID
  • name (string) — new display name
  • categoryId (integer) — move to a different category
  • position (integer) — position in category
  • filter (string) — CEL expression to auto-mark entries as read
  • pushNotificationsEnabled (boolean) — enable push notifications
  • autoMarkAsReadAfterDays (integer) — auto-mark read after N days (null to disable)
Get subscription details
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/feed/get/42" | jq .

Response — Subscription object:

{
  "id": 42,
  "name": "Hacker News",
  "message": null,
  "errorCount": 0,
  "lastRefresh": "2026-03-07T10:00:00Z",
  "nextRefresh": "2026-03-07T10:15:00Z",
  "feedUrl": "https://news.ycombinator.com/rss",
  "feedLink": "https://news.ycombinator.com",
  "iconUrl": "/rest/feed/favicon/42",
  "unread": 15,
  "categoryId": "10",
  "position": 0,
  "newestItemTime": "2026-03-07T10:30:00Z",
  "filter": null,
  "pushNotificationsEnabled": false,
  "autoMarkAsReadAfterDays": null
}
Fetch feed info (preview)
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/rss"}' \
  "$COMMAFEED_HOST/rest/feed/fetch" | jq .

Request body — FeedInfoRequest:

  • url (string, required, 1–4096 chars) — feed URL to probe

Response — FeedInfo: title, url, link for the discovered feed.

Refresh all feeds
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/feed/refreshAll"
Note: Returns 429 Too Many Requests if called too frequently.
Get feed entries
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/feed/entries?id=42&readType=unread&limit=50&order=desc" | jq .

Query parameters (same pattern as category entries):

  • id (required) — subscription ID
  • readType (required) — all or unread
  • limit (integer, default 20, max 1000)
  • offset (integer, default 0)
  • order — desc or asc
  • newerThan (long) — Unix timestamp in ms
  • keywords (string) — search filter

Response: Entries object (same structure as category entries).

Mark feed as read
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"id": "42", "read": true}' \
  "$COMMAFEED_HOST/rest/feed/mark"
OPML Export
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/feed/export" -o subscriptions.opml

Response: OPML XML file.

OPML Import
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -F "file=@subscriptions.opml" \
  "$COMMAFEED_HOST/rest/feed/import"
Note: Uses multipart/form-data, not JSON.

Entries (individual entry operations)

MethodPathDescription
POST/rest/entry/markMark a single entry as read/unread
POST/rest/entry/markMultipleMark multiple entries at once
POST/rest/entry/starStar/unstar an entry
POST/rest/entry/tagSet tags on an entry
GET/rest/entry/tagsGet all user tags
Mark entry as read/unread
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"id": "feed/42:entry/abc123", "read": true}' \
  "$COMMAFEED_HOST/rest/entry/mark"

Request body — MarkRequest:

  • id (string, required) — entry ID
  • read (boolean) — true = read, false = unread
Mark multiple entries
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{
    "requests": [
      {"id": "feed/42:entry/abc123", "read": true},
      {"id": "feed/42:entry/def456", "read": true}
    ]
  }' \
  "$COMMAFEED_HOST/rest/entry/markMultiple"
Star/unstar an entry
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "feed/42:entry/abc123",
    "feedId": 42,
    "starred": true
  }' \
  "$COMMAFEED_HOST/rest/entry/star"

Request body — StarRequest:

  • id (string, required) — entry ID
  • feedId (integer, required) — feed subscription ID
  • starred (boolean, required) — true to star, false to unstar
Tag an entry
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{
    "entryId": 12345,
    "tags": ["important", "read-later"]
  }' \
  "$COMMAFEED_HOST/rest/entry/tag"

Request body — TagRequest:

  • entryId (integer, required) — entry ID
  • tags (array of strings, required) — tags to assign (replaces existing)
Get all user tags
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/entry/tags" | jq .

Response: array of tag strings.


User Profile & Settings

MethodPathDescription
GET/rest/user/profileGet user profile
POST/rest/user/profileUpdate user profile
POST/rest/user/profile/deleteAccountDelete own account
GET/rest/user/settingsGet user settings
POST/rest/user/settingsSave user settings
Get profile
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/user/profile" | jq .

Response — UserModel:

{
  "id": 1,
  "name": "admin",
  "email": "admin@example.com",
  "apiKey": "abc-123-def-456",
  "enabled": true,
  "admin": true
}
Update profile
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{
    "currentPassword": "old-pass",
    "newPassword": "new-pass",
    "newEmail": "new@example.com"
  }' \
  "$COMMAFEED_HOST/rest/user/profile"

Request body — ProfileModificationRequest:

  • currentPassword (string, required) — current password for verification
  • newPassword (string) — new password
  • newEmail (string) — new email
  • newApiKey (boolean) — true to regenerate API key
Get settings
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/user/settings" | jq .

Response — Settings:

{
  "language": "en",
  "readingMode": "unread",
  "readingOrder": "desc",
  "showRead": true,
  "scrollMarks": true,
  "scrollSpeed": 400,
  "scrollMode": "if_needed",
  "customCss": "",
  "customJs": "",
  "entriesToKeepOnTopWhenScrolling": 1,
  "starIconDisplayMode": "always",
  "externalLinkIconDisplayMode": "always",
  "markAllAsReadConfirmation": true,
  "markAllAsReadNavigateToNextUnread": false,
  "customContextMenu": true,
  "mobileFooter": false,
  "unreadCountTitle": true,
  "unreadCountFavicon": true,
  "disablePullToRefresh": false,
  "primaryColor": null,
  "sharingSettings": {
    "email": false,
    "gmail": false,
    "facebook": false,
    "twitter": false,
    "tumblr": false,
    "pocket": false,
    "instapaper": false,
    "buffer": false
  }
}

Settings enums:

  • readingMode: all, unread
  • readingOrder: asc, desc
  • scrollMode: always, never, if_needed
  • starIconDisplayMode / externalLinkIconDisplayMode: always, never, on_desktop, on_mobile
Save settings
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{
    "language": "en",
    "readingMode": "unread",
    "readingOrder": "desc",
    "showRead": false,
    "scrollMarks": true
  }' \
  "$COMMAFEED_HOST/rest/user/settings"

Server Info

MethodPathDescription
GET/rest/server/getGet server information (no auth required)
GET/rest/server/proxyProxy an image through the server
Get server info
curl -s "$COMMAFEED_HOST/rest/server/get" | jq .

Response — ServerInfo:

{
  "announcement": "",
  "version": "5.x.x",
  "gitCommit": "abc1234",
  "loginPageTitle": "CommaFeed",
  "allowRegistrations": false,
  "googleAnalyticsTrackingCode": null,
  "smtpEnabled": false,
  "demoAccountEnabled": false,
  "websocketEnabled": true,
  "websocketPingInterval": 15000,
  "treeMode": "unread"
}
Proxy image
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/server/proxy?u=https://example.com/image.png" \
  -o proxied-image.png

Admin Endpoints

Require ADMIN role.
MethodPathDescription
GET/rest/admin/metricsGet server metrics
GET/rest/admin/user/getAllList all users
GET/rest/admin/user/get/{id}Get user by ID
POST/rest/admin/user/saveCreate or update a user
POST/rest/admin/user/deleteDelete a user
Get server metrics
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/admin/metrics" | jq .
List all users
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/admin/user/getAll" | jq .

Response: array of UserModel.

Get user by ID
curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/admin/user/get/1" | jq .
Create / update user
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "newuser",
    "password": "securepass123",
    "email": "user@example.com",
    "enabled": true,
    "admin": false
  }' \
  "$COMMAFEED_HOST/rest/admin/user/save"

Request body — AdminSaveUserRequest:

  • name (string, required) — username
  • password (string) — password (required for new users)
  • email (string) — email address
  • enabled (boolean, required) — account active
  • admin (boolean, required) — admin role
Delete user
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"id": 5}' \
  "$COMMAFEED_HOST/rest/admin/user/delete"

Registration & Password Reset

MethodPathDescription
POST/rest/user/registerRegister new account (if allowed)
POST/rest/user/initialSetupCreate initial admin (first-run only)
POST/rest/user/passwordResetRequest password reset email
POST/rest/user/passwordResetCallbackConfirm password reset with token
Register
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "name": "newuser",
    "password": "mypassword",
    "email": "user@example.com"
  }' \
  "$COMMAFEED_HOST/rest/user/register"

Request: name (3–32 chars), password, email (all required).


Common Patterns

List all feeds with unread counts

curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/category/get" | \
  jq '[.. | .feeds? // empty | .[] | {id, name, unread, feedUrl}]'

Get all unread entries across all feeds

curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/category/entries?id=all&readType=unread&limit=100" | \
  jq '.entries[] | {title, url, feedName, date}'

Get starred entries

curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/category/entries?id=starred&readType=all&limit=50" | \
  jq '.entries[] | {title, url, starred, date}'

Search entries by keyword

curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/category/entries?id=all&readType=all&keywords=kubernetes&limit=50" | \
  jq '.entries[] | {title, url, feedName}'

Mark all entries as read

# Get current timestamp
TS=$(date +%s)000
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d "{\"id\": \"all\", \"read\": true, \"olderThan\": $TS}" \
  "$COMMAFEED_HOST/rest/category/mark"

Subscribe to a feed and put it in a category

# 1. Fetch feed info to verify URL
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://blog.example.com/feed"}' \
  "$COMMAFEED_HOST/rest/feed/fetch" | jq .

# 2. Subscribe
curl -s -X POST \
  -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://blog.example.com/feed",
    "title": "Example Blog",
    "categoryId": 10
  }' \
  "$COMMAFEED_HOST/rest/feed/subscribe" | jq .

Export OPML backup

curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/feed/export" -o "commafeed-backup-$(date +%Y%m%d).opml"

Paginate through all entries

OFFSET=0
LIMIT=100
while true; do
  RESPONSE=$(curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
    "$COMMAFEED_HOST/rest/category/entries?id=all&readType=all&limit=$LIMIT&offset=$OFFSET")

  COUNT=$(echo "$RESPONSE" | jq '.entries | length')
  HAS_MORE=$(echo "$RESPONSE" | jq '.hasMore')

  echo "$RESPONSE" | jq '.entries[] | {title, date, feedName}'

  if [ "$HAS_MORE" = "false" ] || [ "$COUNT" -eq 0 ]; then
    break
  fi

  OFFSET=$((OFFSET + LIMIT))
done

Get entries by tag

curl -s -u "$COMMAFEED_USER:$COMMAFEED_PASS" \
  "$COMMAFEED_HOST/rest/category/entries?id=all&readType=all&tag=important&limit=50" | \
  jq '.entries[] | {title, url, tags}'

Node.js Example

const COMMAFEED_HOST = process.env.COMMAFEED_HOST;
const COMMAFEED_USER = process.env.COMMAFEED_USER;
const COMMAFEED_PASS = process.env.COMMAFEED_PASS;

const AUTH = 'Basic ' + Buffer.from(`${COMMAFEED_USER}:${COMMAFEED_PASS}`).toString('base64');

async function cfApi(method, path, body = null) {
  const url = `${COMMAFEED_HOST}/rest${path}`;
  const options = {
    method,
    headers: {
      'Authorization': AUTH,
      'Content-Type': 'application/json',
    },
  };
  if (body) options.body = JSON.stringify(body);
  const res = await fetch(url, options);
  if (!res.ok) throw new Error(`CommaFeed API ${res.status}: ${await res.text()}`);
  const text = await res.text();
  return text ? JSON.parse(text) : null;
}

// Get all subscriptions
const tree = await cfApi('GET', '/category/get');
console.log(tree);

// Get unread entries
const entries = await cfApi('GET', '/category/entries?id=all&readType=unread&limit=20');
for (const e of entries.entries) {
  console.log(`[${e.feedName}] ${e.title} — ${e.url}`);
}

// Subscribe to a feed
const subId = await cfApi('POST', '/feed/subscribe', {
  url: 'https://example.com/rss',
  title: 'Example Feed',
});
console.log('Subscribed, ID:', subId);

// Star an entry
await cfApi('POST', '/entry/star', {
  id: entries.entries[0].id,
  feedId: parseInt(entries.entries[0].feedId),
  starred: true,
});

Python Example

import os
import requests

COMMAFEED_HOST = os.environ["COMMAFEED_HOST"]
COMMAFEED_USER = os.environ["COMMAFEED_USER"]
COMMAFEED_PASS = os.environ["COMMAFEED_PASS"]

AUTH = (COMMAFEED_USER, COMMAFEED_PASS)
HEADERS = {"Content-Type": "application/json"}

def cf_api(method, path, json=None):
    url = f"{COMMAFEED_HOST}/rest{path}"
    resp = requests.request(method, url, auth=AUTH, headers=HEADERS, json=json)
    resp.raise_for_status()
    return resp.json() if resp.text else None

# Get category tree
tree = cf_api("GET", "/category/get")
for cat in tree["children"]:
    print(f"Category: {cat['name']}")
    for feed in cat["feeds"]:
        print(f"  {feed['name']} — unread: {feed['unread']}")

# Get unread entries
entries = cf_api("GET", "/category/entries?id=all&readType=unread&limit=20")
for e in entries["entries"]:
    print(f"[{e['feedName']}] {e['title']}")

# Subscribe to a feed
sub_id = cf_api("POST", "/feed/subscribe", {
    "url": "https://example.com/rss",
    "title": "Example Feed",
})
print(f"Subscribed, ID: {sub_id}")

# Export OPML
resp = requests.get(f"{COMMAFEED_HOST}/rest/feed/export", auth=AUTH)
with open("backup.opml", "w") as f:
    f.write(resp.text)

Error Handling

CodeMeaning
200Success
400Bad request (missing/invalid fields)
401Not authorized (wrong credentials)
403Forbidden (insufficient role — need ADMIN)
404Resource not found (wrong feed/entry/category ID)
429Too many requests (refreshAll rate limit)
500Server error

Implementation Notes

  • Always read COMMAFEED_HOST, COMMAFEED_USER, COMMAFEED_PASS from environment variables — never hardcode
  • Authentication is HTTP Basic Auth, not API key headers
  • The /rest/server/get endpoint does not require authentication
  • Entry IDs follow the format feed/{feedId}:entry/{guid} — preserve them as strings
  • Timestamps are in milliseconds (Unix epoch) for newerThan / olderThan parameters
  • OPML import uses multipart/form-data, all other POST endpoints use application/json
  • The readType parameter is required for entry listing endpoints
  • Maximum limit is 1000 entries per request — use offset + hasMore for pagination
  • id=all means all feeds, id=starred means starred entries in category endpoints
  • Tags replace the full tag list on an entry — send the complete desired set
  • CEL filter expressions on subscriptions auto-mark non-matching entries as read

平台分布

Codex

38.78%
按下载量换算28

Claude

28.37%
按下载量换算20

Cursor

17.02%
按下载量换算12

Gemini CLI

8.94%
按下载量换算6

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

未通过

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills