- Name:
ghst - Purpose: TypeScript CLI for managing Ghost CMS instances.
- Status: Active TypeScript CLI with tests and fixture-backed Ghost Admin API mocks covering the current command surface (
auth,comment,post,page,tag,member,newsletter,tier,offer,label,webhook,user,image,theme,site,socialweb,stats,setting,migrate,config,api,mcp,completion). - Documentation split:
README.md: install + usage only (end-user docs)CONTRIBUTING.md: cloning, local development, testing, and contribution workflow
- Node:
22.13+,24.x,26.x(.nvmrcdefaults to24;package.jsonengines allow all three) - Package manager:
pnpm 11.x - Language: TypeScript (ESM)
- Build:
tsup - Test:
vitest - Lint: oxlint
- Format: oxfmt
nvm use
corepack enable
pnpm install
pnpm lint
pnpm run format:check
pnpm typecheck
pnpm test
pnpm build- Dev CLI:
pnpm dev --help - CLI help:
node dist/index.js --help - CLI version:
node dist/index.js -v - Build:
pnpm build - Typecheck:
pnpm typecheck - Test:
pnpm test - Lint:
pnpm lint(oxlint) - Format check:
pnpm run format:check(oxfmt) - Check committed Ghost fixtures offline:
pnpm fixtures:ghost:check
- Keep
README.mdfocused on installing and usingghst; avoid repository development setup there. - Keep all contributor/source-development instructions in
CONTRIBUTING.md. - Keep command/action/flag docs in sync across:
README.mdAGENTS.md- tests and command/runtime coverage
- When docs describe package installation UX, document intended published usage unless explicitly asked to note current publication status.
- Entrypoint:
src/index.ts - Commands:
src/commands/* - Core libs:
src/lib/* - Validation schemas:
src/schemas/* - Tests:
tests/* - CI workflows:
.github/workflows/*
ghst auth login|status|list|switch|logout|link|tokenghst comment list|get|thread|replies|likes|reports|hide|show|deleteghst post list|get|create|update|delete|publish|schedule|unschedule|copy|bulkghst page list|get|create|update|delete|copy|bulkghst tag list|get|create|update|delete|bulkghst member list|get|create|update|delete|import|export|bulkghst newsletter list|get|create|update|bulkghst tier list|get|create|update|bulkghst offer list|get|create|update|bulkghst label list|get|create|update|delete|bulkghst webhook create|update|delete|events|listenghst user list|get|meghst image uploadghst theme list|upload|activate|validate|devghst site infoghst socialweb status|enable|disable|profile|profile-update|search|notes|reader|notifications|notifications-count|posts|likes|followers|following|post|thread|follow|unfollow|like|unlike|repost|derepost|delete|note|reply|blocked-accounts|blocked-domains|block|unblock|block-domain|unblock-domain|uploadghst stats overview|web|growth|posts|email|postghst setting list|get|setghst migrate wordpress|medium|substack|csv|json|exportghst config show|path|list|get|setghst api [endpointPath](supports--paginate,--include-headers,--field|-f)ghst mcp stdio|httpghst completion <bash|zsh|fish|powershell>(bash,zsh,fish, orpowershell)
postspagestagsmemberscommentssitesettingsusersapisearchsocialwebstats
post create|updatesupports--markdown-file,--markdown-stdin,--html-raw-file, and--from-json.page create|updatemirrors the sharedpostfields:--slug,--tags,--from-json,--markdown-file,--markdown-stdin, and--html-raw-file. Onpage update,--slugis the lookup key when no positional<id>is given; withpage update <id> --slug <new-slug>the positional id is the lookup and--slugsets a new slug (rename).comment listdefaults to site-wide admin moderation semantics and includes replies unless--top-level-onlyis passed.comment getuses Ghost Admin's moderation read include set, andcomment threadmirrors the Admin moderation sidebar by combining the selected comment read with the filtered thread query.comment hide|show|deletemap to Ghost Admin comment status transitions (hidden,published,deleted).- Destructive commands require the global
--enable-destructive-actionsflag;--yesonly skips confirmation where confirmation is still required. auth logoutrequires--enable-destructive-actionswhen removing configured sites and confirmation when removing all configured sites; non-interactive all-site removal also requires--yes.auth linkrequires--enable-destructive-actionsand confirmation before replacing an existing project link; non-interactive use requires--yes, and relinking updates the discovered project config within the enclosing repo.- Interactive destructive confirmations emit
GHST_AGENT_NOTICE:lines on stderr instructing cooperative agents to ask the user for approval before continuing. post publish|schedule|updatesupports--newsletter,--email-segment, and--email-only.post deletesupports either<id>or--filter(requires--enable-destructive-actions; non-interactive delete also requires--yes).post bulksupports--actionplus compatibility aliases--update/--deleteand update fields including--add-tagand--authors.member list --statuscomposes with--filter.member export --output,stats ... --csv --output, andmigrate export --outputrefuse to overwrite an existing file.member update --expirysupports complimentary tier expiry when used with--tier.member bulkkeeps--actionand supports compatibility aliases--update,--delete,--labels,--yes.tier list --includeis supported.bulksubcommands exist for the mutable resources that support batch updates:post,page,tag,member,newsletter,tier,offer,label.webhook listenexplicitly requires--public-urlplus--forward-to; no implicit tunnel mode.stats webandstats post ... webuse Ghost Admin stats routes where available, plus analytics reads for datasets Ghost does not wrap directly.socialwebuses the existing staff-token Admin API flow to mint a short-lived identity JWT from/ghost/api/admin/identities/, then uses that bearer token against/.ghost/activitypub/v1/*.socialwebrequires an Owner/Admin staff token and is limited to Ghost's staff-authenticated social web tooling; neither the CLI nor MCP expose public federation endpoints.socialweb deleterequires--enable-destructive-actionsand confirmation; non-interactive use also requires--yes.stats growthclips broader Ghost member/MRR/subscription histories client-side to the selected window when upstream endpoints cannot express the full range.stats post ... growthclips Ghost lifetime post-growth history client-side to the selected window.- Ghost analytics semantics:
sourceandutm_*filters are session-scoped, while post/member-status filters are hit-scoped. - MCP now exposes first-class stats tools via the
statstool group rather than requiring rawghost_api_requestcalls. - MCP now exposes first-class comment moderation tools via the
commentstool group, including list/get/thread/replies/likes/reports/hide/show/delete. - MCP now exposes first-class social web tools via the
socialwebtool group, covering status/profile/feed/interaction/moderation/upload flows. - MCP
tools/listexposesghst/toolGroupandghst/toolGroupTitlemetadata for clients that can render grouped tools. - MCP tools also carry standard
annotations.readOnlyHint/destructiveHintso compliant clients (e.g. Claude Desktop) group them into read-only vs write/delete buckets natively; reads setreadOnlyHint: true, non-destructive writes setdestructiveHint: falseexplicitly, deletes setdestructiveHint: true, and the rawghost_api_requestpassthrough is left unhinted. - MCP tools accept an optional
siteargument for per-call targeting of configured site aliases; when omitted, existing config resolution order is preserved. - MCP includes
ghost_site_listfor safe configured-alias discovery without exposing stored credentials. api [endpointPath]only accepts resource-relative paths or canonical Ghost API paths within the selected API root.api [endpointPath]allows ordinaryPOST/PUT/PATCHwrites by default;DELETErequests and overwrite/import routes (e.g.POST /db/) require--enable-destructive-actions.--jq <filter>is a full jq interpreter (@jq-tools/jq) applied to the JSON response envelope (likegh --jq); use.posts[]to reach records, and invalid filters exit withUSAGE_ERROR.mcp httprequires--unsafe-public-bindfor non-loopback hosts and--cors-originaccepts one exact origin only.- MCP includes dedicated tools such as
ghost_post_schedule,ghost_image_upload,ghost_member_import,ghost_newsletter_list,ghost_tier_list,ghost_offer_list,ghost_site_list,ghost_theme_upload, andghost_webhook_create.
- Explicit
--site - Explicit
--url+--staff-token - Env
GHOST_URL+GHOST_STAFF_ACCESS_TOKEN - Project link
.ghst/config.json - Active site in
~/.config/ghst/config.json
- User config:
~/.config/ghst/config.json - Project link file:
.ghst/config.json - Example env vars:
.env.example - Contributor guide:
CONTRIBUTING.md - License:
LICENSE
- Keep command handlers thin; move logic into
src/lib. - Validate all command input with Zod before network calls.
- Map API/validation failures to
ExitCodeinsrc/lib/errors.ts. - Preserve CLI contract:
ghst <resource> <action>. - Do not introduce breaking command/interface changes without updating docs/tests.
After any non-trivial change, run:
pnpm lint && pnpm run format:check && pnpm typecheck && pnpm test && pnpm buildWhen changing Ghost API fixtures or fixture-backed mocks, also run:
pnpm fixtures:ghost:check- Ghost Admin API version defaults to
v6.0. - JWT auth uses
{id}:{secret}staff access token withaud: /admin/and 5-minute expiry. - Fixture capture/check scripts target Ghost Admin API responses only.
- Fixture coverage includes the copy, bulk, listen, and social web endpoint usage exercised by command and runtime tests.
- Source migration commands use Ghost-maintained
@tryghost/mg-*packages and build Ghost JSON imports uploaded via/db.