npm.io
1.0.0 • Published 4h agoCLI

polyblog

Licence
Apache-2.0
Version
1.0.0
Deps
5
Size
122 kB
Vulns
0
Weekly
0

polyblog

Command-line access to your multilingual blogs on app.polyblog.io: articles and their locale versions, blog settings, AI article generation, topic research from Reddit and RSS sources, sitemap inspection, AI cover images, and a scheduled publishing autopilot.

Install

npm install -g polyblog   # global install
npx polyblog --help       # or run without installing

Requires Node.js 18 or newer.

Quick start

polyblog login            # opens the browser to authorize the CLI
polyblog blogs list       # your blogs with their ids
polyblog articles list --blogId YOUR_BLOG_ID
Found 2 blog(s):
1. Example Blog (example.com) (64a1f2c9e4b0a1b2c3d4e5f6)
2. Example Docs (64a1f2c9e4b0a1b2c3d4e5f7)

Authentication

polyblog login starts a temporary localhost server, opens your browser to app.polyblog.io, and receives the session tokens on the redirect back. Tokens are stored in ~/.polyblog/ and reused by every later command; polyblog logout clears them. A command run without a valid session prints "Please login first" and starts the browser flow by itself.

The three AI image commands (articles generate-image, articles generate-cover, blogs generate-cover) call the OpenAI API directly from your machine and additionally require an OPENAI_API_KEY environment variable — your own key, billed to your OpenAI account. Everything else, including full article generation, runs server-side and needs no key.

Commands

Session
polyblog login    # log in via browser; tokens land in ~/.polyblog/
polyblog logout   # clear the stored session
Articles
polyblog articles list --blogId <blogId>        # 10 most recent (-n/--limit, -l/--locale, -s/--slug, --published)
polyblog articles get <idOrSlug>                # raw JSON for one article (--json; -l for slug+locale lookup)
polyblog articles get                           # raw JSON array (--json, -n, -l, -s, --published, --blogId)
polyblog articles read <idOrSlug>               # formatted view with content as plain text (-l)
polyblog articles add --title "..." --content "..." --blogId <blogId> -l en
polyblog articles update <idOrSlug> --title "..." --content-file ./content.md
polyblog articles delete <articleId>            # permanent

add creates a draft unless --published is passed; missing --title, --content or blog id fall back to interactive prompts. Other add flags: --format (markdown or html), --slug, --description, --author, --categories (comma-separated). update preserves every field you do not pass; --published true publishes, --published false unpublishes, and --categories replaces the whole list.

Generated articles
polyblog articles generate --topic "How to localize a SaaS blog" --angle "practical checklist"
polyblog articles generate --topic-id <topicIdeaId> --locale en --auto-publish
polyblog articles generate --topic "..." --no-images --no-persist   # inspect without saving

Writes a complete SEO article server-side — LLM text, sitemap-validated internal links, and images unless --no-images — and saves it as a draft unless --auto-publish is passed. Spends paid model usage on every call, including with --no-persist. Requires a blog id (--blog-id or polyblog.json) and either --topic or --topic-id.

AI images
polyblog articles generate-cover <articleId> --prompt "..."    # sets the article cover
polyblog articles generate-image --prompt "..." --slug my-img  # standalone image, prints its URL
polyblog blogs generate-cover <blogIdOrName> --prompt "..."    # sets the blog cover

All three require OPENAI_API_KEY in the environment. Without --prompt, cover generation derives one from the article or blog title.

Blogs
polyblog blogs list                              # id, name, domain per blog
polyblog blogs get <blogIdOrName>                # raw JSON (omit the argument for all blogs)
polyblog blogs read <blogIdOrName>               # formatted: locales, domain, quality minimums
polyblog blogs create <name>                     # create a new blog
polyblog blogs update-cover <blogIdOrName> ./cover.png   # upload a local image (jpg/jpeg/png/webp)
Autopilot
polyblog blogs set-autopilot <blogIdOrName> --enabled --cadence weekly --day-of-week 1 --hour 8
polyblog blogs set-autopilot <blogIdOrName> --disabled
polyblog blogs run-autopilot <blogIdOrName> --dry-run   # shows which topic idea would be picked
polyblog blogs run-autopilot <blogIdOrName>             # generates and saves one article now

The autopilot publishes one generated article per tick from the highest-scored saved topic idea. --cadence is daily, weekly or monthly; --hour is UTC 0-23; weekly adds --day-of-week 0-6 (0=Sun), monthly --day-of-month 1-28. Articles are saved as drafts unless --auto-publish is set (--no-auto-publish reverts to drafts). Flags merge into the existing autopilot configuration. run-autopilot without --dry-run spends paid model usage exactly like articles generate.

Topics
polyblog topics refresh --since-hours 168 --min-score 5   # fetch + score new candidates
polyblog topics list --status new --min-score 6           # saved ideas (--json, --limit, --blog-id)
polyblog topics dismiss <id>                              # mark an idea dismissed
polyblog topics use <id> [articleId]                      # mark used, optionally linking the article
polyblog blogs set-topic-sources <blogIdOrName> --reddit selfhosted,seo --rss "https://example.com/feed"

refresh fetches the blog's configured Reddit/RSS sources, scores candidates with a paid model, dedupes against published articles, and saves ideas at or above --min-score (further flags: --limit-per-source, --per-source-cap, --blog-id). set-topic-sources replaces the whole Reddit or RSS list it is given; --clear removes both.

Sitemap
polyblog sitemap urls --locale en --max-urls 100   # URLs from <customDomain>/sitemap.xml (--json, --blog-id)

Lists the URLs of the blog's public sitemap — the same set the article generator validates internal links against. Requires the blog to have a custom domain configured.

Skills
polyblog skills list           # names and descriptions of the bundled agent guides
polyblog skills get polyblog   # print a bundled SKILL.md to stdout

Configuration

A polyblog.json in the directory you run the CLI from supplies the default blog and organization:

{ "organizationId": "64a1f2c9e4b0a1b2c3d4e5f6", "blogId": "64a1f2c9e4b0a1b2c3d4e5f7" }

An optional topicSources.json beside it overrides the topic sources used by topics refresh for that run (keys: audience, reddit, rss).

Environment variables:

  • POLYBLOG_API_URL overrides the API endpoint — only needed against a non-production deployment.
  • OPENAI_API_KEY is required only by the three AI image commands.

Usage with AI agents

Install the Polyblog agent skills — polyblog (this CLI) and multilingual-editorial-workflow (the MCP-based editorial workflow) — for Claude Code, Cursor, Codex, and any other agent that supports the Skills standard:

npx skills add polyblog-io/skills

The same guides ship inside the npm package, version-matched to the installed CLI:

polyblog skills list           # what is bundled
polyblog skills get polyblog   # the CLI guide matching this version

Or paste this into your AGENTS.md / CLAUDE.md:

## Blog publishing

Use the `polyblog` CLI for blog content: articles and their translations,
AI article generation, topic research, and autopilot publishing. Run
`npx polyblog skills get polyblog` for the full guide, and
`polyblog --help` for the command reference. Log in once with
`polyblog login`.

Prefer a connector? The Polyblog MCP server at https://mcp.polyblog.io/mcp exposes the same data as tools for Claude, ChatGPT, and any MCP-capable host — see polyblog.io/developers.

License

Apache-2.0

Keywords