Category: Tech

  • WordPress MCP in Practice: What Worked and What Didn’t

    Diagram showing an AI agent talking to the MCP Adapter, which dispatches to a bounded set of registered abilities, which act on WordPress core

    We just wired up WordPress’s official MCP Adapter on this site so an AI agent (Claude Code) can manage content and theming through structured tool calls instead of ad hoc scripts. Here’s what stood out after actually using it end to end.

    Pros

    • It’s a core-backed standard, not a hack. The Abilities API landed in WordPress core as of 6.9, and the MCP Adapter is an official WordPress.org project layered on top of it — not a third-party plugin bolting AI access onto WordPress from the outside.
    • Bounded by design. Instead of exposing arbitrary code execution, you register specific, named abilities (“create a draft post,” “switch the active theme”) with their own input schemas and permission checks. It replaced a much riskier pattern we were using before — dropping one-off PHP scripts into the webroot, running them once, and deleting them.
    • Uses standard WordPress auth. Application Passwords, the same mechanism WordPress already ships for REST API access — no new auth system to trust.
    • Self-describing. A discover-abilities call lists everything available; get-ability-info returns full input/output schemas per ability. An agent (or a person) can figure out what’s possible without reading source code.
    • Extensible in a few lines. Registering a new ability is a single wp_register_ability() call with a label, schema, permission callback, and execute callback — a handful of these covered posts and themes for this site.

    Cons / friction points

    • Silent breakage on default permalinks. This site was still on WordPress’s default “Plain” permalink structure, which broke /wp-json/ routing in a confusing way — requests didn’t 404, they fell through and served the homepage HTML instead of a JSON error. Easy to misdiagnose as an auth or server problem when it’s actually a permalink setting.
    • New MCP servers don’t hot-load into a running session. After registering the server, tool calls failed until the client (Claude Code) was fully restarted — a new subagent within the same running process wasn’t enough. There’s no in-session refresh.
    • “Connected” can be misleading. Connection-status checks confirmed the transport handshake succeeded, not that tool definitions had actually loaded for a given session — those turned out to be two different things.
    • Almost nothing is exposed out of the box. Past a handful of read-only meta/site-info abilities, there’s no built-in “create a post” or “manage plugins” capability — every real content-management action had to be hand-written as a custom plugin.
    • The scoping responsibility shifts to you. Because abilities are so easy to register, it’s tempting to expose more than necessary. We deliberately kept post creation limited to drafts (never direct publish) and left anything resembling arbitrary command execution out entirely — that discipline has to be applied by whoever writes the abilities, the framework won’t stop you from registering something dangerous.

    Verdict

    Worth it. The rough edges were all discoverable and fixable in one sitting, and the end state — a small, auditable set of named, schema-checked actions — is a meaningfully better security posture than the file-drop workaround it replaced.

  • Introducing VHSP: A Security-First Approach to Multi-Tenant Hosting

    Diagram comparing a breach spreading across shared hosting to a breach contained within one VHSP tenant container

    We’re building VHSP — the Virtual Hosting Service Platform — a self-hosted alternative to traditional hosting control panels, designed from the ground up around a single priority: keeping every customer’s site and mailbox genuinely isolated from every other customer’s.

    The hosting industry has largely settled on shared-daemon architectures, where every tenant’s web and mail traffic flows through the same PHP process pool, the same mail server, the same database engine. It’s efficient, and it’s what most panels — cPanel, Plesk, and newer entrants alike — are built on. It’s also a single point of failure: when one tenant’s site is compromised, the blast radius is defined by how well that shared daemon happens to be hardened, not by any wall between customers.

    VHSP takes a different approach. Every tenant gets their own containers — their own web process, their own mail service, their own database — running in isolation from every other tenant on the platform. If one site is compromised, the damage stops at that container’s edge.

    What that looks like in practice

    A few of the ideas driving the build:

    • Per-tenant everything. Web, mail, and database each run in their own container per customer, rather than sharing a single multi-tenant engine.
    • Self-service, without a shared attack surface. Customers manage their own mail users, files, and site settings through their own container’s admin tools — not through a shared control panel that, if breached, would expose every tenant at once.
    • Defense in depth by default. Hardened-by-default configurations, with customers able to opt into more permissive settings for specific needs, deliberately and with clear tradeoffs — not the other way around.
    • Centralized detection, decentralized blast radius. Security monitoring and abuse detection operate at the shared edge of the platform, so suspicious activity can be caught platform-wide — without requiring tenants to trust each other or share a runtime.

    None of this is about chasing the cheapest possible hosting density. It’s a deliberate tradeoff: more isolation, at the cost of some efficiency, because the cost of a shared-tenant breach is so much higher than the cost of a few extra containers.

    Where things stand

    VHSP is currently in active development, being built and tested against real workloads to validate the approach before it goes anywhere near production traffic. This site is one of the environments we’re using to do exactly that.

    More to come as the platform matures.