# Raise a WordPress site's PageSpeed score with OpenClaw

> Raising a WordPress PageSpeed score with OpenClaw means telling an always-on agent to preview and then apply an xSpeed optimization pass through xSpeed Hub, and keeping unattended runs to reads.

Page: https://xspeedcache.com/agent/openclaw/optimize-site/
Last updated: October 2026

OpenClaw is an always-on agent, so you reach it whenever you like instead of opening a session. You tell it the goal: the store score has slipped, preview an xSpeed pass. It resolves the site with list_sites and calls optimize_site with dry_run on. You get the plan back, and the site is unchanged. Read it, change the level if you want, and tell it to apply. The real pass applies each setting one at a time, checks the page after each, and undoes anything that breaks it, taking up to two minutes per site.

The feature that makes OpenClaw different is automations, and it needs care with this job. The Hub has no scheduler of its own for agent prompts, so any timed run comes from OpenClaw. Keep timed runs to reads: have an automation call get_score_history, compare the stored scores, and tell you when they drop. Do not schedule optimize_site to run alone. An unattended pass has nobody to read the plan or to open the pages afterwards, and a read-only connection (a connection token with Read-only everywhere on, or a Viewer sign-in) would refuse even the dry run, because the Hub counts optimize_site as a write.

When the alert comes in, bring the pass into a conversation. If you do ask for several sites, optimize_site accepts site all. The Hub's confirm-once instruction names purge, toggle, settings and preloader writes, not optimize_site, so for a fleet-wide pass your own approval is the gate: ask OpenClaw to list the sites it will touch and wait for your go-ahead. With a target score, the rounds are shared across the call, so a large fleet gets fewer rounds each, and the result says so. Afterward, check the verify URLs in a browser, because the plugin cannot run JavaScript.

## Set up OpenClaw once

### 1. Put your sites in xSpeed Hub

Sign in at app.xspeedcache.com with Google or email; the Hub is free and has no site cap. Then connect each WordPress site from its own dashboard: click Connect Hub in the xSpeed Cache top bar, then Connect via xSpeed Hub. Each site needs the free xSpeed Cache plugin.

### 2. Save xSpeed Hub as an MCP server

Run this on the machine that hosts your OpenClaw Gateway. Set the transport to streamable-http: OpenClaw falls back to SSE when you leave it out. With --auth oauth the command saves the server without a connection test, because sign-in has to happen first.

```bash
openclaw mcp add xspeedhub \
  --url https://app.xspeedcache.com/xspeed/mcp \
  --transport streamable-http \
  --auth oauth
```

### 3. Sign in with openclaw mcp login

OpenClaw prints an authorization URL and listens on a loopback address for the callback. Open the URL, sign in to xSpeed Hub and approve; the token exchange finishes by itself. There is no token to paste. If your browser is on another machine, copy the code from the redirect and pass it back with openclaw mcp login xspeedhub --code. Then check the connection.

```bash
openclaw mcp login xspeedhub
openclaw mcp doctor xspeedhub --probe
```

Full setup: https://xspeedcache.com/agent/openclaw/

### Before you send a prompt that changes something

Reads change nothing on your sites, though contact_support emails xSpeed support. Writes run once your connection allows them, so your client's approval prompt and a read-only connection (the token's Read-only everywhere switch, or a Viewer sign-in) are the gates that matter. OpenClaw gives you two client-side gates, and the Hub adds none. First, openclaw mcp tools xspeedhub --include limits which tools exist for the agent, so a list of read tools keeps every write out of reach. Second, when the Codex runtime runs your agent turns, MCP tool approvals follow the session's permission posture, and the default full-permission posture does not prompt. openclaw mcp configure xspeedhub --approval prompt asks on every call, and Allow Always saves a grant for that one tool with any arguments. OpenClaw's docs describe that per-call prompt for the Codex runtime; with its own embedded runtime, use the tool filter to decide what the agent can call. The Hub has no confirmation step of its own.

## Prompts

- Every Monday, use xSpeed Hub to read the stored PageSpeed history for each site and tell me which scores dropped. Do not change anything.
- The store score dropped. With xSpeed Hub, preview an optimization at the standard level and wait for me.
- Using xSpeed Hub, preview the same pass for every site in my workspace, and tell me how long it will take.

## Example session

```
You: The store score dropped overnight. Preview an xSpeed Hub pass, standard level.
  → get_score_history(site: store) [read-only]: mobile score down 6 points since last week
  → optimize_site(site: store, aggressiveness: standard, dry_run: true) [dry run]: plan: 4 settings to apply (defer JS, CSS minify, lazy-load images, compression), nothing changed
Agent: The history shows a drop of 6 points on mobile. The plan is script deferral, CSS minify, lazy-loading and compression. Nothing has changed. Apply it to store?
You: Yes, apply it.
  → optimize_site(site: store, aggressiveness: standard) [changes site]: applied 3, undone 1 (defer JS broke the cart button, reverted), unfixable: 1 new hotlinked banner
Agent: Three settings are on: CSS minify, lazy-loading and compression. Script deferral broke the cart button, so the Hub undid it. The new hotlinked banner on the unfixable list may explain part of the drop, and caching cannot fix it. Open the home page in a browser and check the console, then tell me what you see.
```

## How it works

1. **See where the site stands**: The agent reads get_score_history for the last stored scores and list_modules for which modules exist on that site and what state they are in. Neither changes anything.
2. **Preview with dry_run**: optimize_site with dry_run: true returns the plan: each change and its tier, what would be skipped (already on, or needing a higher aggressiveness) and what it cannot fix. Nothing is applied. The tool description tells the agent to prefer this before the first real run on a site you have not optimized before.
3. **Apply it**: optimize_site without dry_run applies the plan. aggressiveness is safe (removals and server-side changes only), standard (the default) or aggressive, which includes settings known to break some themes and should be opted into deliberately. A run can take up to about 2 minutes per site.
4. **Look at the site afterwards**: When changes were applied, the result carries verify_urls and a note. The site checks its own HTML and reverts anything that breaks it, but it cannot run JavaScript, so verified: true does not prove the page works in a browser. The Hub tells the agent to open those URLs and check the page renders and the console is clean, or to tell you which URLs to check.
5. **Reach for a number only if you named one**: target_score (1 to 100, Pro sites only) turns one pass into repeated rounds toward that score, up to max_rounds, with 3 as the most per site. Each round is a real PageSpeed measurement and up to about 2 minutes. The result says why it stopped, and diminishing returns means what is left is outside what caching can reach.
6. **Critical CSS on Pro sites**: generate_critical_css generates above-the-fold CSS so the first screen can paint without waiting for the full stylesheets. It needs the Pro Critical CSS module on that site, and the site answers with an unknown-tool error without it. Pages are rebuilt with it on their next build, so the agent purges the cache afterwards.

## Reference

| | |
| --- | --- |
| Main tool | optimize_site (write): measure, apply one setting at a time, verify, undo what breaks, re-measure |
| Preview | dry_run: true returns the plan and changes nothing |
| aggressiveness | safe, standard (default) or aggressive |
| Every site at once | site: "all" or a list of handles, one result per site, sites run one after another; the Hub's confirm-once instruction does not name optimize_site, so your client's prompt is the gate |
| Time | Up to about 2 minutes per site |
| target_score | 1 to 100; needs Pro on the site; without it the site runs one pass and says so |
| max_rounds | Up to 3 per site; only sent along with target_score; 12 rounds in total per call |
| Wide fan-out with a target | Each site gets fewer rounds, and the result carries a note saying so |
| Result fields | applied, skipped, reverted, unfixable, score, verified, rounds; verify_urls after a run that changed something |
| Already tuned site | Returns "everything is already on" plus what it cannot fix; that is an answer, not a failure |
| Critical CSS | generate_critical_css (write), Pro Critical CSS module required; purge_cache afterwards |
| Read-only connection | optimize_site and generate_critical_css are refused; dry_run is still a write call, so it is refused too. Applies to the connection token with Read-only everywhere on and to a Viewer sign-in, not to other OAuth sign-ins |

## Rules

- Run dry_run first. optimize_site changes live site settings as soon as your connection allows writes. The tool description tells the agent to preview first on a site that has not been optimized, but that is guidance, so your client's approval prompt and a read-only connection (the connection token with Read-only everywhere on, or a Viewer sign-in) are the real gates.
- Keep aggressive for a deliberate choice. It includes settings known to break some themes, and the agent should say so before using it.
- After a run that changed something, open the pages in verify_urls. The HTML checks cannot run JavaScript, so a page can pass them and still be broken in a browser. Do not call a run safe because verified is true.
- Relay the unfixable list. When a site is already tuned, the honest answer is that caching is done and the rest is page weight, hotlinked images or DOM size. The agent should not retry the tool or claim a gain it did not make.
- Only ask for target_score when you want the site driven to a number. Each round costs a real PageSpeed measurement, and a plain "make it faster" is one pass.

## Good to know with OpenClaw

Keep scheduled OpenClaw automations to read tools, such as get_score_history, so they report and never apply. A write run on a timer has no approval exchange, no one to read the plan, and no one to open the verify URLs, and the Hub runs a write as soon as the connection allows it. Give the job a tool allowlist that names only reads, and give any automation you leave unattended a connection token with Read-only everywhere on, because an OAuth sign-in gets the scopes it asks for. In a conversation, OpenClaw's own gate is its tool filter, which can leave optimize_site out of reach. When the Codex runtime runs your turns, the default full-permission posture does not prompt, so set the server to prompt on every call, and note that Allow Always on optimize_site covers the preview and the real pass alike. Bring the real optimization pass into a conversation where you are present.

## More prompts for this job

They work in any client connected to xSpeed Hub.

- Ask xSpeed Hub to preview what optimize_site would change on shop with a safe pass. Do not apply anything.
- Use xSpeed Hub to optimize the blog site with the standard pass, then give me the pages to check by hand.
- With xSpeed Hub, get docs to a mobile PageSpeed score of 90 if you can, and tell me why it stopped if it does not get there.
- Use xSpeed Hub to show me what optimize_site would do on every site, as a dry run, and list which sites have the most left to change.
- Use xSpeed Hub to generate critical CSS for shop, then purge the cache so the pages are rebuilt with it.
- With xSpeed Hub, optimize shop, then compare the new PageSpeed score with the last stored one.
- Using xSpeed Hub, what could optimize_site not fix on the shop site?

## Frequently asked questions

### Can OpenClaw run an xSpeed optimization on a schedule?

Its automations scheduler can run a prompt on a timer, but you should not schedule this one. An unattended run has no one to read the preview or check the pages. Schedule reads such as get_score_history, give the job a tool allowlist, and run the optimization yourself when an alert arrives.

### Can OpenClaw optimize every site in my workspace in one request?

Yes, optimize_site accepts every site in one workspace in a single call and returns a result per site. The Hub's confirm-once instruction does not name optimize_site, so your own approval is the gate: ask OpenClaw to list the sites first and wait for your go-ahead. A target score shares its rounds across the call.

### What does optimize_site actually do?

It measures the site, applies the recommended xSpeed settings one at a time, checks that the page still renders after each change, and undoes any change that breaks it. It then reports what was applied, skipped and reverted, and what it could not fix. It reaches caching and asset delivery only.

### Should I run a dry run first?

Yes, especially on a site you have not optimized before. dry_run: true returns the plan, what would be skipped and what cannot be fixed, and changes nothing. The tool description tells the agent to prefer it, but nothing forces it, so say so in your prompt if you want a preview.

### Can I tell it to get my site to a score of 90?

Yes, with target_score, on a site that has xSpeed Pro. It repeats measure, apply and re-measure for up to 3 rounds per site and stops early when rounds stop helping, saying why. On a Free site the score target is ignored and you get a single pass with a note that no iterative tuner is installed.

### Why did it say everything is already on?

That is a real answer. The settings it can apply were already enabled, so there was nothing to change. The result also lists what it could not fix, such as page weight, images hosted on another domain or DOM size, and those need changes outside a caching plugin.

### Does the agent check that my pages still work?

The site checks its own HTML after each change and reverts anything that breaks it, but it cannot run JavaScript. After a run that changed something, the Hub tells the agent to open the returned verify_urls and check the page renders and the console is clean, or to give you the URLs to check yourself.

### Does generate_critical_css work on a Free site?

No. It needs the Pro Critical CSS module on that site, and without it the site answers with an unknown-tool error. On a Pro site, purge the cache afterwards, because pages already cached were built without the critical CSS.

## Raise the PageSpeed score with other agents

[Claude Code](https://xspeedcache.com/agent/claude-code/optimize-site/) · [Claude](https://xspeedcache.com/agent/claude/optimize-site/) · [Claude Cowork](https://xspeedcache.com/agent/claude-cowork/optimize-site/) · [ChatGPT](https://xspeedcache.com/agent/chatgpt/optimize-site/) · [Codex](https://xspeedcache.com/agent/codex/optimize-site/) · [Cursor](https://xspeedcache.com/agent/cursor/optimize-site/) · [GitHub Copilot in VS Code](https://xspeedcache.com/agent/github-copilot/optimize-site/) · [Windsurf](https://xspeedcache.com/agent/windsurf/optimize-site/) · [Gemini CLI](https://xspeedcache.com/agent/gemini-cli/optimize-site/) · [Antigravity](https://xspeedcache.com/agent/antigravity/optimize-site/) · [Zed](https://xspeedcache.com/agent/zed/optimize-site/) · [Kiro](https://xspeedcache.com/agent/kiro/optimize-site/) · [OpenCode](https://xspeedcache.com/agent/opencode/optimize-site/) · [Hermes Agent](https://xspeedcache.com/agent/hermes-agent/optimize-site/) · [Grok Build](https://xspeedcache.com/agent/grok-build/optimize-site/) · [ChatGPT dots](https://xspeedcache.com/agent/chatgpt-dots/optimize-site/) · [Grok](https://xspeedcache.com/agent/grok/optimize-site/) · [Grok Bot](https://xspeedcache.com/agent/grok-bot/optimize-site/) · [Muse](https://xspeedcache.com/agent/muse/optimize-site/) · [Manus](https://xspeedcache.com/agent/manus/optimize-site/) · [Kimi Code](https://xspeedcache.com/agent/kimi/optimize-site/) · [Paperclip](https://xspeedcache.com/agent/paperclip/optimize-site/) · [NanoClaw](https://xspeedcache.com/agent/nanoclaw/optimize-site/)

## More with OpenClaw

- [Purge the WordPress cache with OpenClaw](https://xspeedcache.com/agent/openclaw/purge-cache/)
- [Find out why WordPress pages are not cached with OpenClaw](https://xspeedcache.com/agent/openclaw/troubleshoot-cache/)
- [Scan a website for speed problems with OpenClaw](https://xspeedcache.com/agent/openclaw/speed-scan/)
- [Run and track PageSpeed tests with OpenClaw](https://xspeedcache.com/agent/openclaw/pagespeed-tests/)
- [Tune WordPress cache settings with OpenClaw](https://xspeedcache.com/agent/openclaw/cache-settings/)
- [Warm the WordPress cache with OpenClaw](https://xspeedcache.com/agent/openclaw/preload-cache/)
- [Set up the Redis object cache with OpenClaw](https://xspeedcache.com/agent/openclaw/object-cache/)
- [Manage Cloudflare caching with OpenClaw](https://xspeedcache.com/agent/openclaw/cloudflare/)
- [Manage every WordPress site at once with OpenClaw](https://xspeedcache.com/agent/openclaw/fleet/)

## Documentation

- How to generate Critical CSS: https://xspeedcache.com/docs/critical-css/
- Performance recommendations: https://xspeedcache.com/docs/performance-recommendations/
- How to run a speed test: https://xspeedcache.com/docs/external-score/
- Free vs Pro: what is included: https://xspeedcache.com/docs/free-vs-pro/
