Everything so far has run against a local WordPress environment, likely wp-env, with
loose defaults that are fine for development and genuinely unsafe in production. This
final lesson is a deliberate checklist of what actually changes when this same server
starts serving real traffic on a real domain, not new features, just the operational
discipline the earlier lessons assumed you’d add later.
A working MCP server from the previous lessons, tested locally over both HTTP and STDIO. Access to your production hosting environment and its HTTPS/TLS configuration.
Step 1: HTTPS is not optional
Every request to your HTTP transport endpoint carries an Application Password in an
Authorization header (Basic auth), plus, once a session starts, an Mcp-Session-Id
value that’s effectively a bearer credential for that session. Over plain HTTP, both are
readable to anything sitting on the network path between client and server. Locally,
against wp-env on localhost, that risk is close to theoretical. In production, it is
not. Every production MCP server endpoint needs to be served over HTTPS, full stop, the
same standard you’d hold any other authenticated REST API to.
Step 2: What actually changes between wp-env and production
| Aspect | Local (wp-env) | Production |
|---|---|---|
| Transport | Both HTTP and STDIO, freely, since you control the machine | HTTP is the realistic option for remote clients; STDIO via WP-CLI generally only makes sense if the AI client runs on the same server or over SSH, since it needs direct shell and file-system access to the install |
—user for STDIO / transport permission callback for HTTP | Often admin, for convenience | A dedicated, least-privileged account created specifically for MCP access, not a shared admin login |
| Error visibility | WP_DEBUG commonly on, errors visible directly | WP_DEBUG off publicly; rely on the adapter’s error handler logging (ErrorLogMcpErrorHandler by default) to your server’s error log instead |
| Application Passwords | Created once, rarely rotated | Scoped to a specific purpose, rotated on a schedule, and revoked immediately if a client integration is retired |
Step 3: Application Password hygiene as an ongoing practice
Application Passwords don’t expire on their own, they’re valid until explicitly revoked. Treat the one your MCP client uses as a credential with a lifecycle, not a one-time setup step:
Revoking one is done the same way it was created, from the user’s profile screen in wp-admin (Users → Profile → Application Passwords), or programmatically if you’re managing this at scale across many sites.
Step 4: A concrete pre-launch checklist
Test it
Run the same session-based curl sequence from Lesson 6, against the production
domain, and confirm it fails correctly over plain HTTP if you try it (most hosts will
simply refuse the connection or redirect):
# File: terminal, sanity check against production
curl -s -D - -X POST \
"https://yoursite.com/wp-json/my-plugin/content-mcp" \
--user "mcp-integration-user:xxxx xxxx xxxx xxxx xxxx xxxx" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"prod-check","version":"1.0.0"}}}'
Confirm the response includes an Mcp-Session-Id header and a successful
initialize result, using the dedicated integration user’s Application Password, not
your own.
The single most common shortcut that turns into a real incident: generating an Application Password on a personal administrator account to get a production integration working quickly, then never circling back to create a dedicated, least-privileged account for it. If that Application Password ever leaks, whoever has it has your full administrator capabilities, not just whatever the MCP server’s abilities were meant to expose. The dedicated-user step in this lesson’s checklist is not optional polish, it’s the difference between a leaked credential being a contained problem and a full site compromise.
Recap
Deploying an MCP server to production is mostly discipline you’ve already learned how to apply, HTTPS enforced without exception, a dedicated least-privileged user instead of a shared admin account, Application Passwords treated as credentials with a rotation and revocation lifecycle, and every ability’s visibility and annotations reviewed rather than left at whatever was convenient locally. You now have a complete, working, secured MCP server built entirely on the official Abilities API and MCP Adapter. From here, Connect AI Assistants & Agents to WordPress covers pointing real clients, Claude Desktop, Cursor, and ChatGPT, at a server like this one and turning it into a working conversational assistant.
Resources & further reading
- MCP Adapter repository, GitHub
- Application Passwords integration guide, make.wordpress.org
- Model Context Protocol specification
- Abilities API reference, developer.wordpress.org