AI-powered blog generation and WordPress publishing for technical writers.
BrewPress turns topics, notes, git diffs, and GitHub PRs into structured technical blog posts, then publishes them to any WordPress site via the REST API.
- Generates drafts from a topic, notes, or a local git diff using Gemini Flash
- Captures proof screenshots of terminal output for code-heavy posts
- Extracts SEO metadata — title, slug, meta description, keywords, tags
- Runs a deterministic review loop — no accidental publishes
- Publishes to WordPress as a draft first — live only when you say
--live - Adapts to your site's voice via a tone fingerprint (
brewpress calibrate)
pip install brewpressOr install from source:
git clone https://github.com/your-org/brewpress.git
cd brewpress
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[gemini]"cp .env.example .env
# Edit .env and fill in your credentials| Variable | Required | Description |
|---|---|---|
WP_URL |
Yes | Your WordPress URL (must be https://) |
WP_USERNAME |
Yes | WordPress username |
WP_APP_PASSWORD |
Yes | Application Password from WP Admin |
GOOGLE_API_KEY |
Yes (draft) | Google AI Studio key |
BREWPRESS_SITE_NAME |
No | Human name of your site, used in AI prompts (default: my technical blog) |
BREWPRESS_SITE_FOCUS |
No | Topic focus for draft generation (default: backend development) |
brewpress doctorThis verifies Python version, env vars, WordPress connectivity, and the Gemini package.
# From a topic
brewpress draft --topic "Java 21 virtual threads in practice"
# From a git diff
brewpress draft --diff path/to/changes.diff --topic "what changed"
# From notes
brewpress draft --topic "Spring Boot caching" --notes "We replaced Caffeine with Redis"brewpress review # display current draft
brewpress approve-content # step 1 of 2
brewpress approve-publish # step 2: saves as WordPress draft
brewpress approve-publish --live # publishes livebrewpress revise "shorten the introduction and add a TL;DR"
brewpress reject --reason "off topic"brewpress calibrateFetches your 20 most recent posts and writes a tone fingerprint to ~/.brewpress/tone.json. Future drafts automatically use this fingerprint.
brewpress suggest --topic "spring boot" "ai agents" --count 5| Command | Description |
|---|---|
brewpress doctor |
Check environment and connectivity |
brewpress draft |
Generate a new blog post draft |
brewpress review |
Display the current draft |
brewpress approve-content |
Approve content (step 1 of 2) |
brewpress approve-publish |
Send to WordPress (step 2 of 2) |
brewpress revise <instruction> |
Revise and reset approvals |
brewpress reject |
Discard the current draft |
brewpress calibrate |
Build tone fingerprint from your site |
brewpress suggest |
Suggest topics using trend signals |
draft → [review] → approve-content → approve-publish
↑ |
revise ←──────────────────────────
approve-publishalways creates a WordPress draft by default.- Add
--liveto publish immediately. - Rejecting from
APPROVED_STEP_2requires--force.
BrewPress is site-agnostic. Set two optional env vars to ground drafts in your site's identity:
BREWPRESS_SITE_NAME="Acme Engineering Blog"
BREWPRESS_SITE_FOCUS="distributed systems and platform engineering"Run brewpress calibrate to layer in your actual writing style on top.
- Log in to WordPress Admin.
- Go to Users → Profile → Application Passwords.
- Create a new Application Password named
brewpress. - Copy the generated password (spaces included) into
WP_APP_PASSWORD.
BrewPress uses the WordPress REST API (/wp-json/wp/v2/) — no plugins required.
HTTPS is enforced. Credentials are never sent over plain HTTP.
The included workflows run on every push and PR:
- CI (
.github/workflows/ci.yml): lint + test matrix across Python 3.11, 3.12, 3.13 - Release (
.github/workflows/release.yml): builds sdist, wheel, and native binaries for Linux, macOS, Windows on everyv*.*.*tag
To add WordPress credentials to CI, store them as repository secrets under Settings → Secrets → Actions:
WP_URL,WP_USERNAME,WP_APP_PASSWORD,GOOGLE_API_KEY