1 vulnerable plugin, 23 plugin and theme updates pending
client-b.com runs acme-forms 2.4.1, which has a known cross-site scripting issue fixed in 2.4.3. 23 plugin and theme updates are pending across 4 sites.
Every Monday: pending plugin, theme and core updates per WordPress site, plugins with known vulnerabilities, and Site Health tests that fail.
Reads
You get
The card on the right is a sample. Yours shows your own numbers and updates in place every run.
What lands on your board
client-b.com runs acme-forms 2.4.1, which has a known cross-site scripting issue fixed in 2.4.3. 23 plugin and theme updates are pending across 4 sites.
An agency with twenty client sites, or a company with a marketing site and two microsites, has the same Monday chore: log in to each dashboard, look at the update count, and hope nothing on the list has a security advisory. The site that gets skipped is the one with the outdated forms plugin.
The agent checks each site through WP-CLI or the REST API, lists what needs updating, looks up installed plugin versions against a vulnerability database, and runs the Site Health background tests. It reports; it does not update anything, since updates on client sites deserve a person and a backup.
With WP-CLI over SSH: wp plugin list --fields=name,status,version,update,update_version --format=json, the same for wp theme list, and wp core check-update --format=json. Run against each site, for example with aliases (wp @client-a ...).
Without SSH, GET /wp-json/wp/v2/plugins with an administrator's application password returns plugin, status and version but not update availability; compare each version with https://api.wordpress.org/plugins/info/1.2/?action=plugin_information&request[slug]=<slug>.
For each plugin, query a vulnerability database such as the WPScan API (GET https://wpscan.com/api/v3/plugins/<slug> with Authorization: Token token=<key>) and flag the plugin when the installed version is below a vulnerability's fixed_in. Cache results by slug and version to stay within the daily quota.
Call the background tests as an administrator: GET /wp-json/wp-site-health/v1/tests/background-updates, loopback-requests, https-status, dotorg-communication and page-cache. Keep results whose status is critical or recommended, with their label.
Vulnerable plugins first, with the fixed version. Then pending updates per site (inactive plugins marked, since they should often be deleted), core status, and failing Site Health tests.
With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.
Pick your agent, where the data comes from and how to schedule it; the commands below follow.
One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.
shellcurl -fsSL https://briefkin.dev/skills/wordpress-plugin-updates-and-site-health/install | shAsk Claude Code:
promptRun the wordpress-plugin-updates-and-site-health skillOr paste the prompt instead of installing:
promptFor each of my WordPress sites, read only: list plugins and themes with installed version and available update (WP-CLI: wp plugin list and wp theme list with --fields=name,status,version,update,update_version --format=json, and wp core check-update; or the REST API /wp/v2/plugins compared with api.wordpress.org plugin info). Check each plugin version against the WPScan API and flag any installed version below a vulnerability's fixed_in. Run the Site Health background tests through /wp-json/wp-site-health/v1/tests/ (background-updates, loopback-requests, https-status, dotorg-communication, page-cache) and keep critical and recommended results. Report vulnerable plugins first, then pending updates per site with inactive ones marked, then Site Health issues. Do not update or change anything.Mondays at 9:00, from cron on any machine where Claude Code is signed in:
crontab0 9 * * 1 claude -p "Run the wordpress-plugin-updates-and-site-health skill"Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.
Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a report card. How setup works
SKILL.md---
name: wordpress-plugin-updates-and-site-health
description: "Every Monday: pending plugin, theme and core updates per WordPress site, plugins with known vulnerabilities, and Site Health tests that fail. Use when the user asks for this, or when it runs on a schedule."
---
# WordPress plugin updates and site health check
Every Monday: pending plugin, theme and core updates per WordPress site, plugins with known vulnerabilities, and Site Health tests that fail.
An agency with twenty client sites, or a company with a marketing site and two microsites, has the same Monday chore: log in to each dashboard, look at the update count, and hope nothing on the list has a security advisory. The site that gets skipped is the one with the outdated forms plugin.
The agent checks each site through WP-CLI or the REST API, lists what needs updating, looks up installed plugin versions against a vulnerability database, and runs the Site Health background tests. It reports; it does not update anything, since updates on client sites deserve a person and a backup.
## Two ways to get the data
Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.
## Route A: API or MCP server
### What you need
- SSH access with WP-CLI on each server, or an administrator account per site with an application password (Users > Profile > Application Passwords).
- A vulnerability data API key, such as a free WPScan API token, in `WPSCAN_API_TOKEN`.
If something is missing, say what and stop; do not invent numbers.
### Steps
1. **List plugins, themes and core** (WordPress): With WP-CLI over SSH: `wp plugin list --fields=name,status,version,update,update_version --format=json`, the same for `wp theme list`, and `wp core check-update --format=json`. Run against each site, for example with aliases (`wp @client-a ...`).
2. **Or use the REST API** (WordPress): Without SSH, `GET /wp-json/wp/v2/plugins` with an administrator's application password returns `plugin`, `status` and `version` but not update availability; compare each `version` with `https://api.wordpress.org/plugins/info/1.2/?action=plugin_information&request[slug]=<slug>`.
3. **Check for known vulnerabilities**: For each plugin, query a vulnerability database such as the WPScan API (`GET https://wpscan.com/api/v3/plugins/<slug>` with `Authorization: Token token=<key>`) and flag the plugin when the installed version is below a vulnerability's `fixed_in`. Cache results by slug and version to stay within the daily quota.
4. **Run Site Health tests** (WordPress): Call the background tests as an administrator: `GET /wp-json/wp-site-health/v1/tests/background-updates`, `loopback-requests`, `https-status`, `dotorg-communication` and `page-cache`. Keep results whose `status` is `critical` or `recommended`, with their `label`.
5. **Report per site**: Vulnerable plugins first, with the fixed version. Then pending updates per site (inactive plugins marked, since they should often be deleted), core status, and failing Site Health tests.
## Route B: the browser
### What you need
- Signed in to each site's wp-admin as an Administrator; the person completes any 2FA plugin prompt first. One browser profile per client login works best.
If something is missing, say what and stop; do not invent numbers.
### Steps
Start at https://example.com/wp-admin/update-core.php. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.
1. **Open Updates on each site**: Replace `example.com` with each site in your list and open **Dashboard** > **Updates**. The page shows the WordPress core status at the top, then the **Plugins** and **Themes** sections with the installed and new version of everything that has an update.
2. **Mark inactive plugins**: Open **Plugins** > **Installed Plugins** and click the **Update Available** filter. Rows without a blue background are inactive; note those, since an inactive plugin with pending updates is usually one to delete rather than update.
3. **Check Site Health**: Open **Tools** > **Site Health**, **Status** tab. Read the items under **Critical issues** and **Recommended improvements** with their titles; the loopback, HTTPS, background updates and page cache tests live here.
4. **Look up vulnerabilities**: For each plugin with an update, open `https://wpscan.com/plugins/<slug>` (the slug is the folder name shown under **View details** on the Plugins page) and check whether a listed vulnerability affects the installed version and which version fixed it. Sites with Jetpack Protect or a similar scanner show the same under its menu.
5. **Report per site**: Vulnerable plugins first with the fixed version, then pending plugin, theme and core updates per site with inactive ones marked, then Site Health items. Click nothing that says Update.
Note: Each site is a separate login, so an agency with twenty sites is better served by WP-CLI aliases. The Updates page only knows about plugins that report updates to WordPress; premium plugins with their own licensing can show as current while a newer version exists.
## The report
- **Vulnerable plugins**: site, plugin, installed version, fixed version, severity.
- **Pending updates** per site: plugins, themes and core, inactive ones marked.
- **Site Health**: critical and recommended items per site.
- One line per site on what to update first.
## Post it to Briefkin
When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.
```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
-H "authorization: Bearer $BRIEFKIN_TOKEN" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"v": 1,
"event_id": "wordpress-plugin-updates-and-site-health/<date of this run, e.g. 2026-10-16>",
"item_key": "wordpress-plugin-updates-and-site-health",
"project": "Acme Agency",
"source": "WordPress plugin updates and site health check skill",
"kind": "update",
"title": "1 vulnerable plugin, 23 plugin and theme updates pending",
"summary": "**client-b.com** runs **acme-forms 2.4.1**, which has a known cross-site scripting issue fixed in 2.4.3. **23** plugin and theme updates are pending across 4 sites.",
"work_state": "blocked",
"widget": [
{
"type": "Table",
"props": {
"columns": [
"Site",
"Plugins",
"Themes",
"Core",
"Site Health"
],
"align": [
"left",
"right",
"right",
"left",
"left"
],
"rows": [
[
"client-a.com",
6,
1,
"Up to date",
"Good"
],
[
"client-b.com",
9,
0,
"Update available",
"1 critical"
],
[
"client-c.com",
3,
1,
"Up to date",
"2 recommended"
],
[
"example.com",
2,
1,
"Up to date",
"Good"
]
]
}
},
{
"type": "Log",
"props": {
"lines": [
{
"text": "client-b.com: acme-forms 2.4.1 vulnerable (XSS), fixed in 2.4.3",
"level": "error"
},
{
"text": "client-b.com: Site Health critical, loopback request failed",
"level": "warn"
},
{
"text": "client-c.com: 2 inactive plugins with updates, consider removing",
"level": "info"
}
]
}
}
]
}
JSON
```
Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.
## Run it on a schedule
Suggested: Mondays at 9:00 (`0 9 * * 1`). From cron, with the agent signed in on that machine:
```bash
0 9 * * 1 claude -p "Run the wordpress-plugin-updates-and-site-health skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```
Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/wordpress-plugin-updates-and-site-health#schedule
Source: https://briefkin.dev/skills/wordpress-plugin-updates-and-site-health
SSH access with WP-CLI on each server, or an administrator account per site with an application password (Users > Profile > Application Passwords).
A vulnerability data API key, such as a free WPScan API token, in WPSCAN_API_TOKEN.
https://public-api.wordpress.com/wpcom/v2/mcp/v1. Turn on MCP access under Preferences > AI and MCP in your WordPress.com account, then sign in with OAuth 2.1 and choose Read only on the authorization page. WordPress.com is in Claude's connector directory, and the URL works in any MCP client, such as Claude Code with claude mcp add --transport http wordpress-com https://public-api.wordpress.com/wpcom/v2/mcp/v1. It's included on paid plans; free sites get it for their first 30 days (docs)./wp-json/mcp/mcp-adapter-default-server. Connect with @automattic/mcp-wordpress-remote and an Application Password (WP_API_URL, WP_API_USERNAME, WP_API_PASSWORD), or locally through WP-CLI with wp mcp-adapter serve --server=mcp-adapter-default-server --user=<user>. Only abilities a plugin marks as public are exposed.WP_URL, WP_USERNAME and WP_APP_PASSWORD; requests use basic auth over HTTPS. Published posts need no authentication at all.Run reports as a dedicated user with the lowest role that sees what they need: Editor for other people's drafts and comment moderation, Administrator only if the report lists plugins and updates.
Because an update can break a client site, and the safe order (backup, staging, update, check) needs a person. The report tells you which sites need attention and which update is urgent; WP-CLI's wp plugin update <name> is one command when you are ready.
Yes, through the REST API with an application password, which every site on WordPress 5.6 or later supports unless a security plugin turned it off. Update availability then comes from comparing versions with the WordPress.org plugin directory, so premium plugins sold elsewhere show as unknown.
No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a report card, so you can glance at it instead of asking again.
Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.
Yes. Switch the data source to "Your browser" and the steps change to the WordPress pages themselves: the agent opens example.com/wp-admin/update-core.php in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.
Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.
Free during the open beta. No card.