JW · Josh Weir
Writing · 2026-05-14 · 12 min

How I built the agent-readiness layer for a small studio (in a weekend)

Late on a Tuesday I scored 1 out of 13 on the agent-readiness audit. By Sunday I scored 13 of 13. Here is the exact fix sequence, the gotchas that nearly killed it, and a 7-step playbook you can run over a weekend.

Late on a Tuesday I ran the Cloudflare "Is Your Site Agent-Ready?" audit on my own site. I scored 1 out of 13. I run a studio that ships agent-ready websites for clients. The irony was sharp enough to skip dinner over, so I cleared the weekend and rebuilt the whole readiness layer from the ground up. By Sunday evening joshweir.uk scored 13 out of 13. This is exactly what I did, what nearly killed it, and how you can do the same.

Why I bothered

The way people find work is changing fast. Five years ago a prospect typed three words into Google, scrolled a results page, clicked a blue link. Today an increasing share of that journey happens inside an LLM. Someone asks Claude or ChatGPT or Perplexity "who builds agent-ready WordPress sites in the UK", the model reasons over its training data plus live web context, and surfaces names. If you are not in that surfaced set you are not in the consideration set.

Agent surfacing rewards machine-readability of three things: who you are, what you do, and how an agent can act on your behalf. That last bit is the new one. A model that quotes you is useful. A model that can introduce a prospect to you, or initiate a booking on your behalf, is a sales channel. If you are an operator running a small studio, you should care.

What "agent-ready" actually means

The audit I failed checks 13 specific signals across four tiers.

Tier 1 (findable): the basics. A live robots.txt, a valid sitemap.xml, reachable HTML pages that return real 200s and real 404s.

Tier 2 (agent-discoverable): structured signals. Schema.org markup, a working /.well-known/ directory, an OpenAPI document if you expose anything programmatic.

Tier 3 (agent-native): the bit most sites skip. A skills index in machine-readable form. A model context protocol endpoint. A licence declaration telling LLMs how they may use your content.

Tier 4 (client-agent capable): the bit almost no sites do. Per-client surfaces, authenticated agent access, audit logging.

For a personal brand site the realistic target is Tier 3. For a studio with paying clients, Tier 4 is where the real differentiation lives.

The starting point

When I ran the audit on joshweir.uk, here is what was actually broken.

The REST API was dead. A network-layer plugin that ships an under-construction page was intercepting every request to /wp-json/* and returning a holding page instead of the WordPress REST output. The audit could not see any of the structured data WordPress was generating.

There was a static index.html shadow. Somewhere in a previous deploy, a literal index.html file had been dropped into the web root. Apache served that instead of letting WordPress route the request. The site looked fine to a human visitor. To a crawler asking for the home page as a structured document, it was an inert static page with no schema.

The 404 was a soft 404. When you asked for a non-existent URL, the site returned a styled 404 page with a 200 OK status code. Crawlers and agents treat 200s as "this is a real resource", which means every typo or stale URL got indexed as a working page. The fix was a status_header(404) call at the right hook priority. The wrong priority and WordPress overrides you back to 200.

That was the starting point. One of thirteen checks passed. The rest were either blocked by the REST API issue or absent entirely.

The fix sequence

Order mattered. You cannot install the readiness module if the REST API is dead, and you cannot test the readiness module if the 404 is lying about its status code. Four layers, in order.

Layer 1: REST API restoration

Two things had to go. The static index.html got deleted from the web root. The under-construction-page plugin got deactivated. A targeted .htaccess rewrite confirmed WordPress was getting every request that did not match a real file. After a Cloudflare cache purge, curl -I https://joshweir.uk/wp-json/wp/v2/posts returned a real JSON response.

Layer 2: Soft-404 fix

A tiny mu-plugin hooked into template_redirect at priority 1. If the requested URL resolved to a 404 template, it called status_header(404) before anything else could override it. Tested with three deliberately wrong URLs. Each one returned 404, not 200. Cloudflare cached the 404 responses with a short TTL so subsequent requests stayed honest.

Layer 3: Module installation

The agent-readiness module went in as a mu-plugin, joshweir-agent-readiness.php, 1262 lines. It registers eight /.well-known/* endpoints, an OpenAPI document, a skills index, a model context protocol endpoint, and the Web Bot Auth JWKS for signed agent requests. Every endpoint is generated on the fly from PHP, no cached files. The module respects an internal allow-list of skills and emits the same skill format used by the canonical studio spec, so the data is portable across sites.

Layer 4: Verification

I wrote an audit script that hits each of the 13 checks the same way the Cloudflare audit does, and runs locally so I can iterate without burning external rate limits. The script lives in my vault, runs in under three seconds, and emits a JSON report. When the report shows 13 of 13 PASS, the site is agent-ready.

By Sunday afternoon the script returned 13 of 13. I held my breath, ran the Cloudflare audit one more time, and got the same answer.

The module itself

The mu-plugin does six things.

/robots.txt is replaced with a generated version that includes Content Signals declarations. Explicit grants and refusals for different categories of automated traffic. AI training crawlers get one signal. Live agent traffic on behalf of users gets a different one. Generic search crawlers get the usual treatment. The rules are stated in machine form, not buried in legal pages no model will read.

/.well-known/api-catalog lists every programmatic endpoint the site exposes, following RFC 9727.

/.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server declare how authenticated agent access works. For a personal brand site these are minimal. For a studio offering per-client agent access they are load-bearing.

/.well-known/agent-skills/index.json is the heart of the readiness layer. A machine-readable index of every skill I credibly offer. Each entry has a name, a description, an authority claim, and a recommended action with a link. When an LLM is asked "who does X" and X matches one of those skills, my entry is one of the candidates the model can quote.

/.well-known/mcp/server-card.json declares a model context protocol surface. The actual MCP endpoint lives at /wp-json/joshweir/v1/mcp and speaks JSON-RPC. It exposes a small set of tools. List the pillars. Get a specific guide. Submit a discovery call request. Nothing destructive on the personal brand variant.

An OpenAPI document at /openapi.json describes those tools in standard OpenAPI 3.1 form, so agents that prefer OpenAPI to MCP can consume the same surface.

That is the module. About a thousand lines of PHP, no external dependencies, no custom database tables. Drop it into wp-content/mu-plugins/, edit roughly ten constants at the top, and you have a Tier 3 readiness layer.

The gotchas that nearly killed it

Three things ate the most hours.

WordPress redirect_canonical is louder than you think. When a request comes in for /.well-known/foo, WordPress's canonical redirect filter sees a URL with no matching post and issues a 301 to the closest match. That 301 fires before the mu-plugin's rewrite rules get to run. The fix is a redirect_canonical filter at priority 1 that bypasses canonicalisation for any URL starting with /.well-known/ or /openapi.json. The priority is the trick. At priority 10 the redirect has already happened.

Mode-600 file permissions silently break Apache. When you upload theme files with scp, the destination defaults are not predictable. I ended up with three theme files at mode 600. Apache running as www-data cannot read mode-600 files. The symptom is not a clean error, it is a 403 that Cloudflare then caches, and the site looks like it has lost its styling without telling you why. The HTML wrapper still returns 200 because the wrapper itself is readable. Every scp deploy now ends with an explicit chmod 644 *.css *.js *.php and a Cloudflare cache purge.

Per-domain PHP-FPM pool opcache requires a restart, not a reload. When you change a mu-plugin you can systemctl reload php-fpm and it appears to work. Sometimes it does. Often opcache holds the old bytecode and your "fix" silently does nothing. The reliable pattern is systemctl restart for the specific pool, followed by a cache purge at the CDN edge.

Those three gotchas, plus a couple of smaller ones around Cloudflare cache rules, accounted for maybe sixty percent of the weekend.

The audit script

The audit script is the most reusable thing I built. It is around 400 lines of Python, hits all 13 endpoints in parallel, validates each response against the spec, and emits a JSON report.

The structure is simple. A check function for each of the 13 signals. A test harness that runs them, captures pass/fail with a reason string, and writes the report. A CLI mode that prints a coloured summary. A JSON mode for CI integration.

I run it before every deploy. It catches mode-600 file permission issues, broken rewrite rules, accidental plugin reactivations, and Cloudflare cache misbehaviour. The whole readiness layer is one bad deploy away from breaking, and the script is what keeps it honest.

What this gets me

Three concrete things.

Skill discoverability. Any LLM that crawls the agent-skills index now knows what I do at a finer granularity than my home page bio. When someone asks "who builds agent-ready WordPress in the UK", I have a structured claim on the table. I do not control whether the model surfaces me, but I am no longer invisible.

Structured citations. When an LLM does quote me, the readiness layer includes a licence declaration asking for attribution back to weirdigital.media and joshweir.uk. Whether models honour that is mixed. The signal is at least present.

Agent-driven introductions. The MCP endpoint exposes a submit_discovery_call tool. An agent acting for a prospect can call that tool with a name, an email, and a problem statement. That call lands in a structured intake. The surface exists for when prospects' agents actually use it.

What is next

Two designs are sitting in the vault, both scoped, neither built.

Phase 22 is agentic commerce. Open agent-driven purchase on three productised SKUs. The MCP endpoint gains a checkout tool. A webhook lands the payment, creates a client record, kicks off the project. Retainer work stays human-gated because consultative sales benefit from a real conversation.

Phase 23 is per-client MCP. Each client gets a scoped MCP surface at a per-client subdomain. Their agent can read their projects, their invoices, their KPI dashboards. Write access is restricted to "task requests" that queue for operator approval. Audit logging on every call. Bundled free in the top retainer tier, optional setup fee on lower tiers.

Both are design-complete and waiting for capacity. Neither is on the joshweir.uk roadmap because the personal brand site does not need them. They live on the studio site.

A 7-step playbook for operators

If you want to do this on your own site over a weekend, here is the order.

  1. Run the audit first. Whichever readiness audit you trust, run it on your live site before you change anything. Capture the score. You need a baseline.
  2. Fix the REST API. Make sure /wp-json/wp/v2/posts returns real JSON. If a plugin is intercepting it, deactivate the plugin. If a static file is shadowing WordPress, delete the file.
  3. Fix soft 404s. Add a tiny mu-plugin that calls status_header(404) at template_redirect priority 1 when the requested URL is a 404. Verify with three deliberately bad URLs.
  4. Install the readiness module. Either copy the canonical studio module or write a minimal one yourself. Eight /.well-known/* endpoints, an OpenAPI doc, a skills index, an MCP server card, the MCP endpoint itself.
  5. Handle the redirect_canonical filter. Bypass canonicalisation for any URL starting with /.well-known/ or /openapi.json. Priority 1 on the filter.
  6. Write the audit script. A check function per signal, a JSON report, a CLI mode. Run it after every deploy.
  7. Purge the CDN cache, run the audit again, fix what fails, repeat. Most of the iterative work is here. Budget for it.

That is the whole sequence. Two long evenings if you are fast, a full weekend if you are not.

FAQ

How much does this cost? In direct outlay, almost nothing. WordPress mu-plugin, your own time, and a CDN you probably already have. The cost is in hours.

Do I need a fancy stack? No. I run the studio's readiness layer on the same boring WordPress that hosts the marketing site. The trick is in the configuration, not the platform.

Will agents actually use this in 2026? Some will. Production-ready agent traffic is increasing every quarter. The cost to be ready is small enough that waiting for certainty is the wrong call.

Does it help my Google SEO? Indirectly. Structured data, clean status codes, and a healthy REST API all feed back into traditional search signals. The agent layer is additive, not a replacement.

Can you do this for me? Yes. The studio offers a fixed two-week sprint that takes a site from wherever it is to a Tier 3 readiness layer with a verifying audit script. Details and current availability live at the studio's playbook hub.

If you want to read the sister piece on what a full self-hosted infrastructure stack looks like for a solo founder, head to Self-hosted infrastructure stack for solo founders. If you want to see the live skills index in action, the skills overview is the place. If you want the brand context for why I build this way, the about page covers it.

There is a parallel discipline worth borrowing from here. The discipline of operational facilities-management treats every building as a measurable, auditable, continuously improved system. Web infrastructure benefits from exactly the same posture. Treat your site as an operational asset, not a marketing campaign, and the readiness layer becomes obvious rather than exotic.


Built by Weir Digital Media. I am the operator behind the studio, and I write at joshweir.uk about what I learn shipping infrastructure for clients and for myself.

Need this built for you?

The studio offers a fixed two-week sprint to take a site from wherever it is to a Tier 3 agent-readiness layer with a verifying audit script. For operators who would rather buy the expertise than build it.

Get in touch More writing