mcpField
P
paragraph-cli

paragraph-cli

github.com/paragraph-xyz营销与增长439 次安装5 天前更新
代码仓库

关于 paragraph-cli

paragraph-cli 是用于管理 Paragraph Web3 发布与新闻简报平台的命令行技能,涵盖文章、草稿、订阅者和数据分析等,并提供 JSON 输出及发布、邮件发送等操作的安全控制。

主要功能

  1. 01管理文章与内容草稿
  2. 02配置出版物
  3. 03管理订阅者
  4. 04搜索文章与博客
  5. 05查询出版物数据分析
  6. 06管理代币与用户

适用场景

  1. 01创建和查看出版物文章
  2. 02准备社交平台及新闻简报草稿
  3. 03导入或管理订阅者名单
  4. 04查看出版物互动指标

MCP 相关

README 建议 MCP 兼容客户端使用 Paragraph MCP 服务。它提供托管远程服务和本地服务,向客户端开放文章、内容、出版物、订阅者、代币、搜索、数据分析等工具。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/paragraph-xyz/skill --skill paragraph-cli

安装后在 Claude Code 中输入/paragraph-cli确认已加载。

详细介绍

Paragraph CLI

Paragraph 的 CLI——一个 web3 发布和新闻简报平台。可用于管理帖子、草稿内容、出版物、订阅者和代币。

如需直接通过 HTTP 或 SDK 访问而无需安装任何内容,请改用 paragraph-api 技能。

MCP 服务(推荐用于兼容 MCP 的客户端)

如果你的客户端支持 MCP,建议使用 Paragraph MCP 服务,而不是 CLI,以获得更集成的体验。

远程服务(推荐)

使用托管服务 mcp.paragraph.com,无需安装或管理 API 密钥。通过浏览器中的 Paragraph 账户进行身份验证。

claude mcp add paragraph --transport http https://mcp.paragraph.com/mcp

对于其他客户端,请在 MCP 配置中添加 https://mcp.paragraph.com/mcp 作为服务 URL。

本地服务

如果你更倾向于在本地运行服务(需要 Node.js 18+):

claude mcp add paragraph -- npx @paragraph-com/mcp

本地模式需要通过 PARAGRAPH_API_KEY 环境变量提供 API 密钥,或使用 CLI 执行 paragraph login。

MCP 服务提供 29 个工具(帖子、内容、出版物、订阅者、代币、搜索、动态、用户、个人信息、分析、邮件),并与 CLI 共用身份验证。请参阅完整文档。

近期新增的工具包括:create-content / list-content / get-content / update-content / archive-content / restore-content(草稿形式的 X 帖子、LinkedIn 帖子、新闻简报和 X Articles——仅创建草稿,不会发送)、send-custom-email(向收件人列表发送 Markdown 邮件——需要出版物批准)、update-publication(设置、精选帖子、置顶帖子、邮件通知开关)、remove-subscriber(按电子邮件地址或钱包地址永久删除订阅者)、update-post 支持使用 publishedAt 回填发布日期,且 update-post 支持使用 imageUrl(设置或替换封面图片)和 clearImage(移除现有封面)。

CLI 设置

全局安装:

npm install -g @paragraph-com/cli

进行身份验证——登录后密钥会保存到 ~/.paragraph/config.json:

paragraph login --token <api-key>
echo "$PARAGRAPH_API_KEY" | paragraph login --with-token

或者跳过登录,通过环境变量为每条命令传入密钥:

PARAGRAPH_API_KEY=<api-key> paragraph post list --json

验证:paragraph whoami --json

使用约定

  • 始终使用 --json 获取可解析的输出。数据输出到 stdout,状态和错误输出到 stderr。
  • 在 delete 命令中始终使用 --yes,跳过确认提示。
  • 在执行 delete、publish 和 archive 前使用 --dry-run,预览操作内容。
  • 使用标志,而不只是位置参数。 每个标识符都支持 --id,方便串联命令。
  • 从文件创建或更新帖子时,通过 stdin 传递内容: cat draft.md | paragraph post create --title "My Post"
  • 使用 --limit 和 --cursor 分页。 JSON 响应包含 pagination.cursor 和 pagination.hasMore。
  • 不要使用交互式登录。 非交互式身份验证请使用 --token 或 --with-token。
  • 运行命令前检查身份验证。 运行 paragraph whoami --json 以验证凭据是否有效。
  • 未经用户明确批准,不得发布。 发布会使内容上线,并可选择向订阅者发送邮件。
  • 默认创建草稿。 post create 会创建草稿。只有在用户提出要求时才调用 post publish。
  • content 命令不会发送内容。 它们只会将内容写入出版物的资料库;作者会在 Paragraph 应用中发送内容。不要告诉用户内容已经发送。
  • 未经用户明确批准,不得发送自定义邮件。 paragraph email send 会发送真实邮件,且无法撤回。先拟好主题和正文;实际发送前使用 --dry-run 预览筛选结果。如果收到 403,请告知用户“此出版物尚未获准发送自定义邮件”,然后停止——不要重试。
  • 遵守速率限制。 如果收到 RATE_LIMITED,请等待后重试。分页请求之间避免紧密循环。

命令

帖子
# Create a draft
paragraph post create --title "My Post" --file ./post.md --tags "web3,defi" --json
paragraph post create --title "My Post" --text "# Hello World" --subtitle "A subtitle" --json
cat content.md | paragraph post create --title "My Post" --json

# List
paragraph post list --json
paragraph post list --status draft --limit 20 --json
paragraph post list --status scheduled --json
paragraph post list --publication <slug-or-id> --json

# Get (by ID, URL, or @pub/slug)
paragraph post get --id <post-id> --json
paragraph post get @my-blog/post-slug --json

# Extract a single field
paragraph post get --id <post-id> --field markdown > post.md
paragraph post get --id <post-id> --field title

# Update
paragraph post update --id <id-or-slug> --title "New Title" --json
paragraph post update --id <id-or-slug> --text "Updated content" --subtitle "New subtitle" --json
paragraph post update --id <id-or-slug> --file ./updated.md --tags "new,tags" --json

# Backdate (publishedAt sticks across re-publishes — useful for imported content)
paragraph post update --id <id-or-slug> --published-at "2024-01-01T00:00:00Z" --json

# Set/replace cover image (URL is fetched + re-hosted on Paragraph's CDN)
paragraph post update --id <id-or-slug> --image-url https://example.com/cover.jpg --json

# Remove the existing cover image
paragraph post update --id <id-or-slug> --clear-image --json

# Publish
paragraph post publish --id <id-or-slug> --json
paragraph post publish --id <id-or-slug> --newsletter --json

# Revert to draft
paragraph post draft --id <id-or-slug> --json

# Archive
paragraph post archive --id <id-or-slug> --json

# Schedule a post for future publication
paragraph post schedule --id <id-or-slug> --at "2026-05-01T09:00:00Z" --json
paragraph post schedule --id <id-or-slug> --at "2026-05-01T09:00:00Z" --newsletter --json

# Cancel a scheduled publication
paragraph post unschedule --id <id-or-slug> --json

# Create and schedule in one step
paragraph post create --title "Launch Day" --file ./post.md --schedule-at "2026-05-01T09:00:00Z" --newsletter --json

# Preview destructive actions
paragraph post delete --id <id-or-slug> --dry-run --json
paragraph post publish --id <id-or-slug> --dry-run --json

# Delete
paragraph post delete --id <id-or-slug> --yes --json

# Send test newsletter email
paragraph post test-email --id <post-id> --json

# Browse
paragraph post feed --limit 10 --json
paragraph post by-tag --tag web3 --limit 20 --json
内容

起草短篇内容:X 帖子和串文、LinkedIn 帖子、单封邮件以及 X Articles。这些命令只会起草内容,不会发布、发送邮件或安排发布时间。长篇帖子使用 paragraph post。

--kind 的值为 tweet、linkedin、newsletter 或 x_article,正文参数则根据类型而定:tweet 使用 --tweet(可重复,每条串文推文使用一次),newsletter 使用 --subject 和 --preheader,x_article 使用 --headline 和 --canonical-url。长篇文本通过 --text、--file 或标准输入提供。草稿仅包含文本;媒体必须在应用中添加。

# Create
paragraph content create --kind tweet --title "Launch note" --text "We shipped it." --json
paragraph content create --kind tweet --title "Thread" --tweet "First." --tweet "Second." --json
paragraph content create --kind linkedin --title "Launch note" --file ./post.md --json
paragraph content create --kind newsletter --title "October update" --subject "What we shipped" --file ./body.md --json
paragraph content create --kind x_article --title "Editor rewrite" --headline "Why we rebuilt the editor" --file ./article.md --json
cat post.md | paragraph content create --kind linkedin --title "Launch note" --json

# List (--status defaults to all, which excludes archived pieces)
paragraph content list --json
paragraph content list --kind tweet --status draft --limit 50 --json
paragraph content list --status archived --json

# Get, with its body
paragraph content get <id> --json
paragraph content get <id> --field body

# Update — the body is replaced, not merged. Read it first.
paragraph content update <id> --title "Launch note, second pass" --json
paragraph content update <id> --text "Rewritten, and shorter." --json

# Archive and restore
paragraph content archive <id> --dry-run --json
paragraph content archive <id> --json
paragraph content restore <id> --json

已有排队发送任务的内容无法编辑正文(必须在应用中取消排期),但始终可以重命名。JSON 中的 lockedReason 会说明原因;若内容可编辑,则该值为 null。

内容组

一个组将帖子及其衍生内容归为同一身份——帖子、由其改编的串文、LinkedIn 版本和新闻简报。作者在 Content 下看到的是一个单独的堆叠行。

改编帖子时,请将起草的内容与它归为一组,否则作者会得到彼此无关、互不关联的草稿。

# Get or create a post's group. Safe to repeat: the same ID comes back.
paragraph content bucket create <post-id> --json

# Draft into it
BUCKET=$(paragraph content bucket create <post-id> --json | jq -r .bucketId)
paragraph content create --kind tweet --title "Thread" --tweet "First." --bucket "$BUCKET" --json

# Group a draft made before the group existed
paragraph content update <id> --bucket "$BUCKET" --json

# Read a group and everything already made from its post
paragraph content bucket get <bucket-id> --json

# Find a post's group without creating one (bucketId is null when there is none)
paragraph content bucket for-post <post-id> --json

# List every group, most recently active first
paragraph content bucket list --limit 50 --json

起草前先读取内容组,避免重复创建已有的版本。每个成员的 kind 会说明在哪里读取:post 使用 paragraph post get,content 使用 paragraph content get。kind 为 other 的成员属于 Paragraph 内容组,但 CLI 无法获取。

如果某项内容已与另一个帖子分组,系统会拒绝操作,而不是将其移动——请告知用户在应用中取消分组。从组中移除内容也需要在应用中完成。

出版物
paragraph publication get --id <slug-or-id-or-domain> --json

# Update settings (only provided fields change). The publication ID must
# match the publication that owns your API key — run `paragraph whoami` to
# look it up.
paragraph publication update <publication-id> --name "My Blog" --theme-color purple-600 --json

# Featured post: a post ID, or one of "latest" | "popular" | "disabled"
paragraph publication update <publication-id> --featured-post latest --json

# Pinned posts (replaces the existing list, max 50, IDs must belong to this publication)
paragraph publication update <publication-id> --pinned-post-ids id1,id2,id3 --json

# Owner email-notification toggles (key=value pairs).
# Allowed keys: newComment, newSubscriber, newPaidSubscriber, newContentCollected.
paragraph publication update <publication-id> --email-notifications newSubscriber=true,newComment=false --json

# Apply a full settings body from a JSON file. Explicit flags override file values.
paragraph publication update <publication-id> --from-json ./settings.json --json
搜索
paragraph search post --query "ethereum" --json
paragraph search blog --query "web3" --json
订阅者
paragraph subscriber list --limit 100 --json
paragraph subscriber count --publication <id> --json
paragraph subscriber add --email [email protected] --json
paragraph subscriber add --wallet 0x1234...abcd --json
paragraph subscriber import --csv ./subscribers.csv --json

# Remove (hard delete, irreversible — prompts for confirmation; use --yes to skip)
paragraph subscriber remove --email [email protected] --yes --json
paragraph subscriber remove --wallet 0x1234...abcd --yes --json
Coins
paragraph coin get --id <id-or-address> --json
paragraph coin popular --limit 10 --json
paragraph coin search --query "ethereum" --json
paragraph coin holders --id <id-or-address> --limit 50 --json
paragraph coin quote --id <id-or-address> --amount <wei> --json
用户
paragraph user get --id <user-id-or-wallet> --json
分析

针对出版物的分析架构运行只读 SQL。系统会自动限定为拥有 API 密钥的出版物——请勿在 WHERE 子句中添加博客筛选条件。

# Discover tables and columns
paragraph analytics schema --json
paragraph analytics schema --table post_analytics_summary --json

# Run a query
paragraph analytics query --sql "SELECT title, total_views, open_rate FROM post_analytics_summary ORDER BY total_views DESC LIMIT 5" --json

# Read SQL from a file or stdin
paragraph analytics query --file ./query.sql --json
echo "SELECT active_subscriber_count FROM blog_subscriber_counts" | paragraph analytics query --json

优先使用预聚合视图(post_analytics_summary、subscriber_engagement_scores、blog_subscriber_counts),而非原始表——这些视图的响应时间不到一秒,且能满足大多数报告需求。仅允许使用 SELECT/WITH,不得使用分号,最多返回 10,000 行,语句超时时间为 30s。

自定义邮件

从你的出版物向你指定的收件人列表发送一封一次性 Markdown 邮件。邮件会分别发送给每位收件人,并且必须附带退订页脚。

适用于:

  • 向定向细分受众发送邮件——“给所有打开了我上一篇文章的人发邮件”“给我最活跃的 50 位订阅者发送跟进邮件”“联系这份精心筛选的 20 位读者名单”。通过 paragraph analytics query 或 paragraph subscriber list 创建细分受众。
  • 向作者本人发送通知——“订阅者达到 1,000 人时给我发邮件”“每周发送分析摘要”。如有需要,使用 paragraph whoami 查询作者的邮箱。
  • 联系非订阅者邮箱地址——一份会议联系人 CSV、媒体名单,或介绍朋友的朋友。收件人可以来自任何地方,不必列在 paragraph subscriber list 中。(此前已退订的用户仍会被标记为 suppressed。)
  • 重新联系不活跃的订阅者——“给过去 90 天内没有打开邮件的所有人发邮件。”通过 paragraph analytics query 查询 subscriber_engagement_scores 或 newsletter_metrics,找出相应细分受众。
  • 发送草稿供少数协作者审阅——“把这份提案草稿发给我的 3 位共同作者征求反馈。”需要给出版物所有者以外的人发邮件时,使用此功能;paragraph post test-email 只会发送给所有者。

请勿将此功能用于群发新闻邮件。 若要向所有订阅者发送一篇文章,请使用 paragraph post publish --newsletter(或 paragraph post create ... --newsletter)。这是新闻邮件发送流程;email send 用于向你指定的定向名单发送邮件。

Paragraph 必须先批准出版物,才能使用自定义邮件;不符合条件的出版物会收到 403。每次调用最多可发送给 10,000 位收件人。发送前务必先向用户确认——邮件会实际发出,且无法撤回。

# Send (prompts for confirmation; pass --yes to skip)
paragraph email send --subject "Hello" --body "# Hi" --to [email protected] --yes --json

# Read body from a file
paragraph email send --subject "Update" --body-file ./body.md --to [email protected] --to [email protected] --yes --json

# Comma-separated recipients (--to is repeatable)
paragraph email send --subject "Update" --body-file ./body.md --to "[email protected],[email protected]" --yes --json

# Pipe body via stdin
cat body.md | paragraph email send --subject "Update" --to [email protected] --yes --json

# Dry run — preview the accepted/skipped split without sending
paragraph email send --subject "Update" --body "# Hi" --to [email protected] --dry-run --json

JSON 响应包含 accepted(已加入发送队列)和 skipped;每位被跳过的收件人都带有一个 reason:invalid(地址格式错误)、suppressed(此前已退订)或 scheduling_failed(队列失败——这是唯一可以安全重试的原因)。

身份验证
paragraph login --token <api-key>
echo "<api-key>" | paragraph login --with-token
paragraph whoami --json
paragraph logout

JSON 响应格式

分页列表(注意:CLI 会将条目包装在 data 下;REST API 和 SDK 则使用 items):

{
  "data": [{ "id": "...", "title": "..." }],
  "pagination": { "cursor": "abc123", "hasMore": true }
}

单个条目:

{ "id": "...", "title": "...", "markdown": "..." }

变更操作:

{ "id": "...", "status": "published" }

错误(输出到 stderr):

{ "error": "Not found.", "code": "NOT_FOUND", "status": 404 }

错误代码:UNAUTHORIZED、FORBIDDEN、NOT_FOUND、RATE_LIMITED、SERVER_ERROR、REQUEST_FAILED、CLIENT_ERROR、UNKNOWN。

常见用法

在一个流程中创建并发布
ID=$(paragraph post create --title "My Post" --file ./post.md --json | jq -r '.id')
paragraph post publish --id "$ID" --newsletter --json
将所有文章导出为 Markdown
paragraph post list --limit 100 --json | jq -r '.data[].id' | while read id; do
  SLUG=$(paragraph post get --id "$id" --json | jq -r '.slug')
  paragraph post get --id "$id" --field markdown > "${SLUG}.md"
done
分页获取所有订阅者
CURSOR=""
while true; do
  RESULT=$(paragraph subscriber list --limit 100 ${CURSOR:+--cursor "$CURSOR"} --json)
  echo "$RESULT" | jq '.data[]'
  CURSOR=$(echo "$RESULT" | jq -r '.pagination.cursor // empty')
  HAS_MORE=$(echo "$RESULT" | jq '.pagination.hasMore')
  [ "$HAS_MORE" = "true" ] || break
done

环境变量

变量用途
PARAGRAPH_API_KEYAPI 密钥(跳过登录)
PARAGRAPH_API_URL自定义 API 基础 URL
PARAGRAPH_NON_INTERACTIVE设为 1 以强制使用 CLI 模式
CI设为 true 以强制使用 CLI 模式

故障排除

身份验证错误

如果命令失败并返回 UNAUTHORIZED:

# Check if logged in
paragraph whoami --json

# Re-authenticate
paragraph login --token <api-key>

CLI 会在收到 401 时自动清除已存储的凭据。如果凭据已被撤销,请重新登录。

速率限制

如果收到 RATE_LIMITED,请等待后重试。错误中会包含 429 状态码。避免紧密循环请求——分页请求之间应加入延迟。

命令挂起

如果命令似乎一直在等待,可能是在等待标准输入。请确保通过 --text、--file 或管道向标准输入传递内容。如果标准输入已通过管道连接但没有数据到达,CLI 会在 30 秒后超时。

安装后找不到 CLI
npm install -g @paragraph-com/cli
# Verify
npx paragraph --version

评论

支持 Markdown