AutoScribe releases
A WordPress plugin for auto-generating and auto-publishing WordPress posts.
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/johnjanney/autoscribe/releases/download/v1.18.0/autoscribe-1.18.0.zipReadme
AutoScribe
A WordPress plugin that generates and publishes posts from scheduled AI prompts.
A prompt is a custom post type holding instructions, a schedule, a provider and model, a monthly spend cap, and the taxonomy and SEO settings for whatever it produces. When a prompt's schedule fires, AutoScribe asks the configured model for a topic, checks that topic against what the site has already published, generates the article, optionally generates a featured image, sanitizes everything, and inserts the post as a draft or publishes it.
| Version | 1.18.0 |
| Requires WordPress | 6.4 |
| Requires PHP | 8.1 |
| License | GPL-2.0-or-later |
| Tested against | PHP 8.1, 8.2, 8.3 |
Documentation
| Document | What's in it |
|---|---|
| INSTRUCTIONS.md | How to install, configure, and use the plugin |
| CHANGELOG.md | Release history and the versioning policy |
| DECISIONS.md | Why the plugin is built the way it is |
| CONTRIBUTING.md | Development setup, standards, and the release process |
You are responsible for what gets published
This plugin writes articles with a large language model and can publish them to a live site without a human reading them first. Models state things that are wrong with complete confidence, and no amount of prompting reliably prevents it.
The safe default is on: every prompt starts in review mode, holding its output as a draft. There is also a global Force human review switch in Settings that overrides every prompt at once and cannot be bypassed by a manual run or a WP-CLI argument.
If you turn automatic publishing on, the output is yours — legally, editorially, and reputationally. Treat that as a deliberate decision rather than a default.
What it does
- Two independent provider slots. Text from Anthropic, OpenAI, Google, or DeepSeek; images from OpenAI or Google. They are chosen separately, because Anthropic and DeepSeek generate no images and a single provider setting would make Claude-plus-Nano-Banana impossible.
- Six schedule types, including "the second Tuesday of the month". Daylight saving, month ends, and leap days are handled by the calendar, not guessed.
- Structured output with validation. The model returns one JSON object, which is validated against a schema; a malformed reply gets exactly one repair attempt before the run is abandoned.
- Everything is sanitized before it reaches the database. Script, style, and
iframe blocks are removed with their contents, dangerous URI schemes are
rejected, and the body goes through
wp_kses_post(). - Web search grounding through each provider's own server-side search tool, with the source URLs recorded on the run.
- Duplicate-topic avoidance that rejects a repeat before paying to write the article, not after.
- SEO metadata through Yoast, Rank Math, or SEOPress, detected at runtime.
- Monthly spend caps, per prompt and site-wide, enforced before any paid call.
- A run log with status, tokens, estimated spend, and a retry action.
Installing
Download the plugin zip from the latest release and install it through Plugins → Add New → Upload Plugin. The file is named for the version you are downloading — this link stays correct when the version does not.
A git clone into wp-content/plugins will not work on its own — the
plugin has Composer dependencies that are not committed. Run composer install --no-dev in the plugin directory, or use the release zip, which has them
bundled.
Full setup, including the cron configuration that schedules actually depend on, is in INSTRUCTIONS.md.
Troubleshooting a failed run
The Run Log says why a run stopped, in the plugin's own words. Where that is not enough — "the provider returned HTTP 400" does not name the field the provider objected to, and "the response was not valid JSON" does not show what arrived instead — turn on Debug mode, under Diagnostics on the Settings screen.
While it is on, the plugin keeps what the providers actually returned: the endpoint, the status, how long the call took, the response body, and the run and step it belonged to. A rejected request keeps what was sent as well, because that is the other half of the answer. Model output that fails the schema is kept with the reason it failed. Run the prompt that is failing, then read the log at the bottom of the same screen.
This exists because the usual answer does not work here. error_log() writes to
debug.log, and a good deal of managed WordPress hosting offers no shell to read
it with; the runs that fail are the scheduled ones, which happen inside an Action
Scheduler worker while nobody is watching. So the capture goes to the database
and is read back in wp-admin, where you already are.
Turn it off when you have what you need. API keys are never recorded — all four providers authenticate in a header, headers are never passed to the capture, and anything key-shaped that a provider quotes back inside an error message is blanked before storage. What is recorded is article text, and on a grounded run the material the model fetched from the web. That sits in the options table like any other option, and the options table is in every database backup.
The log holds the most recent 30 exchanges and trims itself, response bodies are shortened, and inline images are dropped rather than stored, so leaving it on costs storage rather than unbounded storage. It does not autoload. There is a Clear debug log button beside it, and uninstalling removes it.
Debug mode changes what the plugin stores, never what it sends. It adds no request and no recipient.
Third-party services
AutoScribe sends data to third-party AI providers. It cannot do its job otherwise. This section lists every external endpoint the plugin contacts, what is sent, and when.
Nothing is sent until you supply an API key and a prompt configured to use that provider. A site with no keys configured makes no external requests at all.
Text generation
Exactly one text provider is contacted per prompt run — whichever that prompt is configured to use.
| Provider | Endpoints contacted |
|---|---|
| Anthropic | https://api.anthropic.com/v1/messageshttps://api.anthropic.com/v1/models/{model} |
| OpenAI | https://api.openai.com/v1/responseshttps://api.openai.com/v1/models/{model} |
https://generativelanguage.googleapis.com/v1beta/interactionshttps://generativelanguage.googleapis.com/v1beta/models/{model} |
|
| DeepSeek | https://api.deepseek.com/chat/completionshttps://api.deepseek.com/models |
The models endpoints are read-only capability checks. An administrator
contacts them by pressing "Test connection" on the Settings screen. They confirm
that the model ID still exists, so that a retirement surfaces as a clear message
on that screen. They send no site content, and they are not contacted during a
generation run — a run does not preflight its model.
Sent on a generation call:
- The system prompt and user prompt stored on the prompt post, verbatim. Whatever you type into a prompt is sent to the provider.
- The requested article's target word count, as an output token ceiling.
- The JSON schema the response must conform to.
- Titles and topic keys of your own recently published, drafted, pending, and scheduled posts. The topic-proposal call sends these so the model can avoid proposing something the site already covers. The number included is the prompt's look-back setting. Only titles and topic keys — never post bodies.
- On a rejected proposal, the title that collided, so the re-ask can name it.
- On a malformed response, the model's own previous reply, so the repair call can correct it.
- Your API key, in the provider's authentication header.
- A
User-Agentheader of the formAutoScribe/{version} (+https://your-site.example/). This contains your site's URL and is sent on every request, including the capability checks.
If a prompt has grounding enabled and the provider supports it, that provider's own web search tool runs server-side on the provider's infrastructure. The provider then reaches sites of its own choosing; AutoScribe has no visibility into and no control over which.
Image generation
Contacted only when a prompt is configured to generate a featured image.
| Provider | Endpoints contacted |
|---|---|
| OpenAI | https://api.openai.com/v1/images/generationshttps://api.openai.com/v1/models/{model} |
https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContenthttps://generativelanguage.googleapis.com/v1beta/models/{model} |
Sent: an image description derived from the generated article, the requested
size, your API key, and the same User-Agent header carrying your site URL. The
generated image is returned to your server and sideloaded into the media
library; it is not hot-linked.
What is never sent
- Existing post bodies, page content, or any other stored content beyond the titles and topic keys described above.
- User accounts, email addresses, comments, or any personal data.
- WordPress options, settings, or database contents.
- Anything at all beyond the endpoints listed above. AutoScribe contacts no analytics, telemetry, licensing, or update service of its own.
Their terms, not ours
Data you send becomes subject to the receiving provider's terms and privacy policy, including whatever retention and model-training practices those set out. Read them before configuring a provider:
- Anthropic — https://www.anthropic.com/legal/consumer-terms · https://www.anthropic.com/legal/privacy
- OpenAI — https://openai.com/policies/terms-of-use · https://openai.com/policies/privacy-policy
- Google — https://ai.google.dev/gemini-api/terms · https://policies.google.com/privacy
- DeepSeek — https://platform.deepseek.com/downloads/DeepSeek%20Terms%20of%20Use.html · https://cdn.deepseek.com/policies/en-US/deepseek-privacy-policy.html
Retention and training-use defaults differ substantially between these providers and change over time. If that matters for your content, verify the current terms directly rather than relying on this list.
Uninstalling
Deleting the plugin removes its table, its options, its capabilities, and every prompt. It does not remove the posts and images it generated — those are your content.
Three meta keys are deliberately left behind so you can act on that content
later: _autoscribe_generated on every generated attachment, _autoscribe_run_id
on every generated post, and _autoscribe_topic_key on every generated post.
The first two are how you tell generated content apart from the rest of the site.
The third is what duplicate avoidance compares against, so keeping it means a
reinstall does not propose every topic again.
Read the full README on GitHub →
Releases
| Tag | Published | Asset | Downloads |
|---|---|---|---|
| v1.18.0 | Aug 23, 2026 | autoscribe-1.18.0.zip | 0 |
| v1.17.0 | Aug 23, 2026 | autoscribe-1.17.0.zip | 0 |
| v1.16.0 | Aug 23, 2026 | autoscribe-1.16.0.zip | 0 |
| v1.15.1 | Aug 21, 2026 | autoscribe-1.15.1.zip | 0 |
| v1.15.0 | Aug 21, 2026 | autoscribe-1.15.0.zip | 0 |
| v1.14.0 | Aug 20, 2026 | autoscribe-1.14.0.zip | 0 |
| v1.13.4 | Aug 20, 2026 | autoscribe-1.13.4.zip | 0 |
| v1.13.3 | Aug 20, 2026 | autoscribe-1.13.3.zip | 0 |
| v1.13.2 | Aug 20, 2026 | autoscribe-1.13.2.zip | 0 |
| v1.13.1 | Aug 20, 2026 | autoscribe-1.13.1.zip | 0 |
| v1.13.0 | Aug 20, 2026 | autoscribe-1.13.0.zip | 0 |
| v1.12.0 | Aug 20, 2026 | autoscribe-1.12.0.zip | 0 |
| v1.11.0 | Aug 20, 2026 | autoscribe-1.11.0.zip | 0 |
| v1.10.0 | Aug 20, 2026 | autoscribe-1.10.0.zip | 0 |
| v1.9.0 | Aug 20, 2026 | autoscribe-1.9.0.zip | 0 |
| v1.8.0 | Aug 20, 2026 | autoscribe-1.8.0.zip | 2 |
| v1.7.0 | Aug 20, 2026 | autoscribe-1.7.0.zip | 1 |
| v1.6.0 | Aug 20, 2026 | autoscribe-1.6.0.zip | 2 |
| v1.5.0 | Aug 20, 2026 | autoscribe-1.5.0.zip | 1 |
| v1.4.0 | Aug 20, 2026 | autoscribe-1.4.0.zip | 1 |
| v1.3.0 | Aug 20, 2026 | autoscribe-1.3.0.zip | 1 |
| v1.2.0 | Aug 20, 2026 | autoscribe-1.2.0.zip | 0 |
| v1.1.3 | Aug 19, 2026 | autoscribe-1.1.3.zip | 0 |
| v1.1.2 | Aug 19, 2026 | autoscribe-1.1.2.zip | 0 |
| v1.1.1 | Aug 19, 2026 | autoscribe-1.1.1.zip | 0 |