Coming soon! The Kael'Nyrin Scrolls: The Atlas Edict

WordPress website connected to OpenWebUI through digital circuitry

Captain Walker

MCP connection to WordPress via OpenWebUI

AI, AI models, connection, connector, Docker, MCP, OpenWebUI, software, web, wordpress

Estimated reading time at 200 wpm: 15 minutes

MCP — the Model Context Protocol — is a standard that lets AI models interact directly with external services. Instead of copying and pasting between a chat window and an application, the AI reaches into the application itself. It can read data, create content, update settings, and extract information — all through natural conversation.

Whether or not you agree our Fat Disclaimer applies

WordPress powers a vast number of websites. Until recently, managing a WordPress site meant logging into the admin panel and clicking through menus, or hiring a developer to write custom integrations. MCP changes that. With the WordPress MCP Adapter plugin installed on a site, the entire site becomes accessible (on permission) to any AI model that supports tool calling. Posts, categories, tags, SEO metadata, code snippets, redirections — all available through a single endpoint.

OpenWebUI is a self-hosted AI interface that runs in Docker. It connects to multiple AI providers — DeepSeek, GLM, OpenAI-compatible APIs, local models via Ollama — and lets users switch between them freely. Since version 0.6.31, OpenWebUI supports MCP Streamable HTTP connections. This means a user running OpenWebUI in Docker on a Windows 11 computer can connect directly to their WordPress site and work with it through whichever AI model they choose.

The practical reach is broad. A site owner could ask the AI to draft a post, set its SEO title and meta description, assign categories and tags, and check for broken redirections — all without opening the WordPress dashboard. Someone with a large archive of published content could pull metadata across hundreds of posts, filter by category or date range, and extract structured summaries. A small team could use it for content audits, SEO analysis, or bulk updates to post metadata.

The connection is model-agnostic. The same MCP endpoint serves any model running in OpenWebUI. A cheap, fast model handles routine lookups. A more capable model handles complex analysis or longer content generation. The user picks the right tool for the job. The site tools remain the same regardless.

What follows is a practical account of setting up this connection, including the problems encountered and how they were resolved.

Objective

Many WordPress sites accumulate large volumes of content over months and years. Extracting useful information from that archive typically means reading through posts manually or writing custom database queries.

An MCP connection changes this. With the AI connected directly to the site, a user can pull a metadata index of every published post — title, date, category, tags, excerpt — in a single request. From there, the content can be filtered by category, narrowed by date range, and explored post by post. The AI reads the full content of each selected post and produces structured output: summaries, key points, thematic analysis, or whatever the user asks for.

This is not limited to text extraction. The same connection supports content auditing (finding posts with missing SEO metadata or miscategorised content), bulk review (scanning dozens of posts for recurring themes or gaps), and structured data collection (pulling specific facts, figures, or references from across an archive into a single document).

The objective of this project was to establish a working MCP connection from OpenWebUI running in Docker on a Windows 11 computer to a live WordPress site, and to verify that the full range of read and write capabilities worked end to end. What follows documents how that was done, what went wrong along the way, and how each problem was resolved.

The setup

The connection has three components: the WordPress site with the MCP Adapter plugin installed, the OpenWebUI instance running in Docker, and the authentication layer between them.

WordPress side

The WordPress MCP Adapter plugin must be installed and activated on the site. This plugin registers an MCP endpoint on the site’s REST API. The default endpoint path is /wp-json/mcp/mcp-adapter-default-server. No additional configuration of the plugin is needed — once activated, it exposes the full set of abilities automatically. The abilities available depend on which compatible plugins are active on the site.

Letting the MCP in

The site must also have Application Passwords enabled. This is a core WordPress feature available from WordPress 5.6 onwards. To create one, navigate to Users → Profile and scroll to the Application Passwords section. Enter a name for the password (something identifiable, such as “OpenWebUI MCP”) and click Add New. WordPress generates a password in the format xxxx xxxx xxxx xxxx xxxx xxxx. Copy this immediately — it is shown only once. The spaces are part of the password and must be included when encoding it.

Authentication encoding

OpenWebUI sends the credentials as an HTTP Basic Authentication header. This requires the username and application password to be combined and base64-encoded.

In PowerShell on Windows 11, the encoding command is:

[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("YourUsername:xxxx xxxx xxxx xxxx xxxx xxxx"))

This outputs a base64 string. The string is then placed into a JSON header value with the Basic prefix and a space before the encoded string:

{"Authorization": "Basic YOUR_BASE64_STRING_HERE"}

The word Basic followed by a single space before the base64 string is essential. Without it, WordPress does not recognise the header as Basic Authentication and returns a 401 Unauthorized response regardless of whether the credentials are correct.

OpenWebUI side: Integration

What’s happening here, is that an integration with MCP is being created. Integration is categorised as a ‘Tool’ in OpenWebUI. Tools can be called into a conversation (chat) with AI as and when needed.

OpenWebUI must be version 0.6.31 or later to support MCP connections. The current v0.11.1 is highly recommended. The connection is configured under Settings → Admin (in the left sidebar, scroll to the bottom) → Integrations → External Tool Servers.

Click the + to add a new connection. The key fields are:

  • Type: Click the type selector (which defaults to “OpenAPI”) and change it to MCP Streamable HTTP.
  • Name and ID: Any identifiable label.
  • URL: The full endpoint URL, e.g. https://www.example.com/wp-json/mcp/mcp-adapter-default-server
  • Auth: Set to None. Authentication is handled via the Headers field instead, because OpenWebUI’s auth dropdown does not include a Basic Auth option.
  • Headers: Paste the JSON header string: {"Authorization": "Basic YOUR_BASE64_STRING_HERE"}

Save the connection. OpenWebUI will register the MCP server. To verify, open a new chat with any model, click the grid icon near the chat input bar, and look under Tools. The connection name should appear with a toggle. Switch it on, and the model gains access to all abilities exposed by the WordPress MCP Adapter.

The connection is model-agnostic. Any model available in OpenWebUI — DeepSeek, GLM, Ollama-hosted local models, or any OpenAI-compatible API — can use the same MCP tools once the toggle is activated in the chat. There is no per-model configuration.

Investigated and ruled out

Several potential causes of authentication failure were investigated during the setup. Each was systematically tested and eliminated. They are recorded here because anyone following this process on a different hosting environment may encounter them as genuine blockers rather than false leads.

All In One WP Security (AIOS) — REST API blocking

AIOS includes a setting labelled “Disallow unauthorised REST requests” under WP Security → Firewall → WP REST API settings. When enabled, it blocks all REST API access for requests that do not carry a WordPress login cookie. Application Passwords authenticate via HTTP headers, not cookies, so AIOS rejects them before WordPress can validate the credentials. The symptom is a 403 Forbidden response.

This was a real factor in this project and must be addressed. However, it was not the root cause of the 401 Unauthorized errors encountered. Even with AIOS fully deactivated, authentication still failed. The setting must ultimately be toggled off (or the relevant REST route whitelisted, if AIOS offers that option in the version installed) for the MCP connection to work.

AIOS — Application Password disabling

AIOS has the ability to disable WordPress Application Passwords entirely as a security hardening measure. When disabled, the Application Password entries still appear in the user profile, but authentication against them silently fails. This was checked and confirmed not to be active on the site in question.

Cloudflare

Cloudflare sits in front of many WordPress sites and can interfere with authentication headers. Certain WAF rules or security settings may strip or reject Authorization headers. In this case, Cloudflare was considered as a suspect but was not confirmed as a blocker. The issue was resolved at the server level before Cloudflare needed to be investigated further. It remains worth checking if authentication fails on a Cloudflare-proxied site after all server-side fixes have been applied.

Apache-style header passthrough

The standard fix for Authorization header problems on Apache servers is a .htaccess rewrite rule:

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

This rule was already present in the site’s .htaccess within the WordPress block. On a genuine Apache installation, this would have been sufficient. On a LiteSpeed server — which processes .htaccess files but handles PHP via its own LSAPI module rather than Apache’s mod_php or CGI — this rule alone does not pass the header through to PHP. The fix that actually worked is documented in the next section.

The actual fix

Two separate issues caused authentication to fail. Both had to be resolved before the connection worked.

LiteSpeed and the Authorisation header

The site runs on a LiteSpeed web server with PHP handled via the LSAPI module. LiteSpeed processes .htaccess files for compatibility with Apache configurations, but its internal handling of HTTP headers differs. Specifically, the Authorization header sent by the client was being silently dropped by LSAPI before PHP received the request. WordPress never saw the credentials at all, so it returned a 401 Unauthorized response every time.

The Apache-style rewrite rule RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] was already in the .htaccess file. On a genuine Apache server, this would pass the header through. On LiteSpeed, it has no effect on LSAPI’s header handling.

The fix is a single directive added to the top of the .htaccess file, above all other blocks (including any managed blocks from LiteSpeed Cache or security plugins):

CGIPassAuth on

This tells LiteSpeed to pass the Authorization header through to PHP unchanged. It is a permanent addition. Removing it will break any authentication mechanism that relies on HTTP headers, including WordPress Application Passwords.

The directive must sit outside any managed block. Plugins such as LiteSpeed Cache mark their .htaccess sections with warnings not to edit the contents. Placing CGIPassAuth on inside a managed block risks it being silently overwritten the next time the plugin updates its configuration.

The Basic prefix

The HTTP Basic Authentication scheme requires the Authorization header to carry the word Basic followed by a space before the base64-encoded credentials. The correct format is (for example)

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

If the Basic prefix is missing and only the base64 string is sent, WordPress does not recognise the header as an authentication attempt. The request is treated as unauthenticated and returns a 401 response. No error message in the response body distinguishes this from a wrong-password failure.

This is easy to overlook when manually constructing the header. The base64 encoding step produces a string. The natural impulse is to paste that string directly into the Authorization field. The prefix must be added explicitly. In the OpenWebUI Headers field, the complete JSON must read:

{"Authorization": "Basic YOUR_BASE64_STRING"}

Not:

{"Authorization": "YOUR_BASE64_STRING"}

Both issues had to be resolved together. Either one alone would still produce a 401.

AIOS configuration for coexistence

All In One WP Security (AIOS) is a widely used security plugin. Most of its protections — brute force login prevention, file permission hardening, firewall rules, user enumeration blocking — are unaffected by the MCP connection and should remain enabled.

The one setting that conflicts is “Disallow unauthorised REST requests” under WP Security → Firewall → WP REST API settings. When this toggle is on, AIOS intercepts all incoming REST API requests and checks for a WordPress login cookie. Requests authenticated via Application Passwords carry an Authorization header but no cookie. AIOS treats them as unauthorised and blocks them with a 403 Forbidden response before WordPress has the chance to validate the credentials.

The simplest resolution is to toggle this setting off. This allows Application Password authentication to reach WordPress normally. All other AIOS protections remain active and unaffected.

AIOS describes a route whitelisting feature on the same settings page, which would in theory allow specific REST API paths (such as /mcp/mcp-adapter-default-server) to bypass the block while keeping it enforced for all other routes. Whether this option is available depends on the version of AIOS installed. Some versions display a list of registered routes below the role toggles; others do not. If the whitelist is available, adding the MCP adapter route there is the more precise approach — it keeps the REST API locked down for everything except the MCP connection.

The security trade-off is modest. The REST API block is a defence-in-depth measure. WordPress Application Passwords are themselves a controlled authentication mechanism — they are per-user, revocable, and scoped to the REST API. The site remains protected by its login credentials, AIOS firewall rules, and all other hardening measures. Disabling the REST API block does not expose the site to unauthenticated access; it simply allows authenticated requests via headers rather than requiring cookie-based sessions.

What the connection provides

Once the MCP connection is established, the AI model discovers all available abilities automatically. No manual configuration of individual tools is required. The abilities depend on which compatible plugins are installed on the WordPress site. The following is the full set discovered on a site running WordPress 7.1 with the MCP Adapter, WPCode, SEOPress, and Akismet plugins active.

Core

Site information, authenticated user profile, and runtime environment details (PHP version, database server, WordPress version). Useful for diagnostics and confirming the connection is working.

Posts

The most immediately useful set. Metadata retrieval returns title, status, date, categories, tags, and excerpt for every post on the site in a single call. Individual posts can be read in full by ID. New draft posts can be created. Existing posts can be updated — both content and metadata (categories, tags, excerpts). Draft posts can be listed separately. This covers the full read-write cycle for content management.

SEOPress

A broad set of abilities covering on-page SEO. For individual posts: reading and updating SEO titles, meta descriptions, robots/indexing directives, social media metadata (Open Graph and X/Twitter cards), and structured data (schema.org markup). For the site as a whole: content analysis and scoring, global title and meta templates, technical SEO audits, and redirection management (listing, creating, updating, and deleting redirections). AI-powered suggestions for SEO titles, meta descriptions, and image alt text are available as non-destructive previews — they generate suggestions without saving them, leaving the decision to the user.

MCP Adapter

The adapter’s own meta-abilities: discovering all registered abilities, retrieving the detailed schema for any individual ability, and executing any ability by name. These are what the AI uses internally to navigate the toolset. They are rarely called directly by the user but are the mechanism that makes the entire connection work.

Conclusion: What the connection enables

The value of this setup is not in any single capability. It is in the combination of a conversational interface, direct access to site data, and the freedom to choose which AI model does the work.

A site owner with years of published content can treat their archive as a queryable resource. Instead of scrolling through pages of posts in the WordPress dashboard, they ask the AI to list everything in a given category, filter by date, and read specific articles. The AI produces summaries, identifies themes, or extracts specific data points — whatever the user needs. The content never leaves the site until the AI reads it on request. There is no bulk export, no third-party indexing service, no additional plugin beyond the MCP Adapter itself.

Content creation works in the other direction. A user can ask the AI to draft a post, review and refine it through conversation, and then push the finished draft directly to WordPress — with categories, tags, excerpt, and SEO metadata set in the same session. The post appears in the dashboard ready for a final check and publication. The entire cycle from idea to draft-in-WordPress happens without opening the admin panel.

SEO work that is normally tedious becomes conversational. Checking which posts lack meta descriptions, generating suggestions, reviewing robots directives across a set of pages, auditing redirections for broken links — all of this can be done through natural language requests. The AI reads the current state, suggests changes, and applies them on confirmation.

The model-agnostic design keeps costs under control. Routine tasks — listing posts, checking metadata, retrieving site information — consume relatively few tokens. A cheap, fast model handles them efficiently. More demanding work — reading and summarising long articles, producing structured analyses across many posts, drafting substantial content — can be routed to a more capable model simply by switching the model selector in OpenWebUI. The MCP tools remain the same across all models. The user pays only for the intelligence they need for each task.

The setup also scales. The same OpenWebUI instance can hold MCP connections to multiple WordPress sites. Each connection has its own endpoint, credentials, and tool toggle. A user managing several sites can switch between them in the same interface, using the same models, without separate dashboards or logins.

What began as a connection between two pieces of software becomes, in practice, a conversational control panel for a WordPress site — or several. The admin dashboard does not disappear. But for a growing range of tasks, it becomes unnecessary.