Gctools
Command line utilities for working with Ghost content
Install / Use
/learn @TryGhost/GctoolsREADME
GCTools
Command line utilities for working with Ghost content.
Install
git clonethis repo &cdinto it as usual- Run
yarnto install top-level dependencies. - To make
gctoolsaccessible globally, runnpm link- You need to run this after making changes to the codebase to update the global version
- If developing the code,
yarn dev ...is a more suitable command
Usage
To see all available tools, run:
gctools
Interactive Mode
GCTools has an interactive mode which walks you through each tool, without needing to manually type multiple option flags.
gctools i
Available tools include:
zip-splitzip-createjson-splitjson-cleanfetch-assetsdedupe-members-csvcompare-member-csvrandom-postsdelete-postsdelete-pagesadd-tagscombine-tagsadd-previewdelete-tagsdelete-labelsdelete-empty-tagsfind-replacechange-authoradd-authorchange-visibility-postschange-visibility-pageschange-statuschange-rolecomment-notificationsadd-member-comp-subscriptionadd-member-comp-from-csvremove-member-comp-subscriptionadd-member-newsletter-subscriptionmember-newsletter-backupsplit-membersadd-label-to-memberschange-tagspost-tiersset-templatepage-to-postcontent-statsget-postsset-featured-imagesclean-slugsset-podcast
Each of the tools also has a traditional CLI counterpart with more options, detailed below.
zip-split
Split a zip file into smaller zip files of a defined maximum size, while maintaining the directory structure.
# See all available options
gctools zip-split --help
# Split a zip file into as many files needed for them to all be 50mb or below
gctools zip-split /path/to/big-file.zip -M 50
zip-create
Split a large directory into smaller directories of a defined maximum size and zip each, while maintaining the directory structure.
# See all available options
gctools zip-create --help
# Split a large directory into as many files needed for them to all be 50mb or below
gctools zip-create /path/to/big-directory -M 50
json-split
Split a large JSON file into smaller JSON files of a defined maximum size, while retaining meta, tag, and author information.
Output files are saved in a folder named after the source file. For example, splitting big-file.json with --M 50 produces:
big-file/
big-file-posts-00.json
big-file-posts-01.json
...
# See all available options
gctools json-split --help
# Split a JSON file into as many files needed for them to have a maximum of 50 posts per file
gctools json-split /path/to/big-file.json --M 50
json-clean
Clean a JSON file so it only contains content.
# See all available options
gctools json-clean --help
# Clean a JSON file to only contain content
gctools json-clean /path/to/file.json
fetch-assets
Download all available assets from a valid Ghost JSON file create a JSON file with updated image references
# See all available options
gctools fetch-assets --help
# Fetch assets from a valid Ghost JSON file, with `https://example.com` as the base URL
gctools fetch-assets /path/to/file.json https://example.com
dedupe-members-csv
Create new CSV files that only contain new or updated members, by comparing the existing members with the output from the output from @tryghost/migrate.
# See all available options
gctools dedupe-members-csv --help
gctools dedupe-members-csv <existing-members> [new-free] [new-comp] [new-paid]
compare-member-csv
Compare two member CSV files to identify new, updated, and unsubscribed members. This tool is useful for tracking membership changes between two exports.
The tool will generate up to three output files in the same directory as your source files:
new.csv- Members present in the new file but not in the old file (new signups)unsubscribed.csv- Members present in the old file but not in the new file (cancellations/unsubscribes)updated.csv- Members present in both files but with changes (e.g., new Stripe customer ID, label changes, subscription status changes)
# See all available options
gctools compare-member-csv --help
# Compare two member CSV files
gctools compare-member-csv <oldFile> <newFile>
# Compare with verbose output
gctools compare-member-csv <oldFile> <newFile> --verbose
# Example: Compare January and February exports
gctools compare-member-csv /path/to/members-jan-2024.csv /path/to/members-feb-2024.csv
The comparison uses email addresses as the unique identifier. All columns from the original CSV files are preserved in the output files. The tool handles case-insensitive email matching and ignores entries with missing or empty email fields.
What counts as an update:
- Changes to Stripe customer ID
- Changes to subscription status (subscribed_to_emails)
- Changes to complimentary plan status
- Changes to labels
Output:
- The tool displays statistics showing how many new, updated, and unsubscribed members were found
- Output files are only created when there are differences to report
- Files are saved in the same directory as the old/first CSV file
random-posts
Insert a number of posts with random content.
# See all available options
gctools random-posts --help
# Create and insert 10 random posts
gctools random-posts <apiURL> <adminAPIKey>
# Create and insert 3000 random draft posts with 2 tags visible to members only, written by a specific author
gctools random-posts <apiURL> <adminAPIKey> --count 3000 --tag '#random,New World' --status draft --visibility members --author person@dummyemail.com
# Customize the content length and structure
gctools random-posts <apiURL> <adminAPIKey> --count 50 --contentUnit paragraphs --contentCount 5 --titleMinLength 2 --titleMaxLength 6
Available options:
--count(default: 10): Number of posts to create--titleMinLength(default: 3): Minimum words in title--titleMaxLength(default: 8): Maximum words in title--contentUnit(default: paragraphs): Content unit type (paragraphs, sentences, words)--contentCount(default: 10): Number of content units per post--paragraphLowerBound(default: 3): Min sentences per paragraph--paragraphUpperBound(default: 7): Max sentences per paragraph--sentenceLowerBound(default: 3): Min words per sentence--sentenceUpperBound(default: 15): Max words per sentence--author: Author email address--tag(default: #gctools): Comma separated list of tags--status(default: published): Post status (published, draft, scheduled, sent)--visibility(default: public): Post visibility (public, members, paid)--delayBetweenCalls(default: 50): Delay between API calls in ms
delete-posts
Delete all content or content with a specific set of filters, which can be combined.
# See all available options
gctools delete-posts --help
# Delete all posts (⛔️ dangerous!)
gctools delete-posts <apiURL> <adminAPIKey>
# Delete all posts with a specific tag
gctools delete-posts <apiURL> <adminAPIKey> --tag 'hash-testing'
# Delete all published posts
gctools delete-posts <apiURL> <adminAPIKey> --status 'published'
# Delete all draft posts
gctools delete-posts <apiURL> <adminAPIKey> --status 'draft'
# Delete all posts by a specific author
gctools delete-posts <apiURL> <adminAPIKey> --author 'sample-user'
# Delete all posts by a specific author with a specific tag
gctools delete-posts <apiURL> <adminAPIKey> --author 'sample-user' --tag 'hash-testing'
delete-pages
Delete all content or content with a specific set of filters, which can be combined.
# See all available options
gctools delete-pages --help
# Delete all pages (⛔️ dangerous!)
gctools delete-pages <apiURL> <adminAPIKey>
# Delete all pages with a specific tag
gctools delete-pages <apiURL> <adminAPIKey> --tag 'hash-testing'
# Delete all published pages
gctools delete-pages <apiURL> <adminAPIKey> --status 'published'
# Delete all draft pages
gctools delete-pages <apiURL> <adminAPIKey> --status 'draft'
# Delete all pages by a specific author
gctools delete-pages <apiURL> <adminAPIKey> --author 'sample-user'
# Delete all pages by a specific author with a specific tag
gctools delete-pages <apiURL> <adminAPIKey> --author 'sample-user' --tag 'hash-testing'
add-tags
Add a tag to specific posts and pages with a specific set of filters
# Add a tag of 'Testing' to all posts and pages
gctools add-tags <apiURL> <adminAPIKey> --new_tags 'Testing'
# Add a tag of 'Testing' to all posts and pages (same result as above)
gctools add-tags <apiURL> <adminAPIKey> --new_tags 'Testing' --type posts pages
# Add a tag of 'Testing' to all posts only
gctools add-tags <apiURL> <adminAPIKey> --new_tags 'Testing' --type posts
# Add a tag of 'Testing' to all pages only
gctools add-tags <apiURL> <adminAPIKey> --new_tags 'Testing' --type pages
# Add a tag of 'Testing' to
Related Skills
docs-writer
99.5k`docs-writer` skill instructions As an expert technical writer and editor for the Gemini CLI project, you produce accurate, clear, and consistent documentation. When asked to write, edit, or revie
model-usage
341.6kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
project-overview
FlightPHP Skeleton Project Instructions This document provides guidelines and best practices for structuring and developing a project using the FlightPHP framework. Instructions for AI Coding A
ddd
Guía de Principios DDD para el Proyecto > 📚 Documento Complementario : Este documento define los principios y reglas de DDD. Para ver templates de código, ejemplos detallados y guías paso
