---
title: WebMCP for WordPress — AI Agent Communication Protocol — citelayer®
url: https://citelayer.ai/docs/webmcp/
date: 2026-02-25
---

# WebMCP for WordPress — AI Agent Communication Protocol

Why This Matters
----------------

WebMCP (Web Model Context Protocol) is an emerging standard for AI-agent-to-website communication, based on Google Chrome’s MCP proposal. It gives AI agents a single, predictable URL to learn everything about your site — what it offers, what endpoints are available, and what content it serves.

Think of it as a service manifest. Before an agent browses your products or reads your content, it checks your WebMCP endpoint to understand the full picture. Citelayer® implements this as a `.well-known` endpoint, following the convention established by other web standards like `robots.txt` and `security.txt`.

How It Works
------------

Citelayer registers a WordPress rewrite rule that maps the `.well-known/mcp/context.json` URL to a dynamic handler. When a request hits this URL, WordPress processes it internally and returns a JSON response with your site’s information, capabilities, and available endpoints.

- Endpoint: `yoursite.com/.well-known/mcp/context.json`
- Implemented via WordPress rewrite rule — no physical file needed
- Returns structured JSON with site info, capabilities, and endpoint URLs
- CORS-enabled for cross-origin access
- Cached with a 7-day transient for performance

Endpoint
--------

### GET /.well-known/mcp/context.json

Returns the full WebMCP context for your site. The response structure adapts based on whether WooCommerce is active.

#### Standard WordPress Response

On a regular WordPress site (without WooCommerce), you get a clean baseline response:

```
{
  "mcp_version": "1.0",
  "site": {
    "name": "Your Site Name",
    "description": "Your site tagline",
    "url": "https://yoursite.com",
    "type": "website",
    "platform": "WordPress"
  },
  "capabilities": [
    "llms_txt",
    "schema_org",
    "markdown"
  ],
  "endpoints": {
    "llms_txt": "/llms.txt",
    "schema": "/wp-json/citelayer/v1/schema"
  }
}
```

This tells AI agents that your site supports [llms.txt](/docs/llms-txt/), [Schema.org](/docs/schema-json-ld/) structured data, and [markdown content output](/docs/markdown-for-agents/). It also provides the endpoint URLs where agents can access each feature.

#### WooCommerce Response

When WooCommerce is active, the response expands significantly:

```
{
  "mcp_version": "1.0",
  "site": {
    "name": "Your Store Name",
    "description": "Your store tagline",
    "url": "https://yourstore.com",
    "type": "ecommerce",
    "platform": "WooCommerce"
  },
  "capabilities": [
    "llms_txt",
    "schema_org",
    "markdown",
    "product_catalog",
    "ucp_v1",
    "semantic_search",
    "cart_operations"
  ],
  "endpoints": {
    "llms_txt": "/llms.txt",
    "schema": "/wp-json/citelayer/v1/schema",
    "products": "/wp-json/citelayer/v1/products",
    "search": "/wp-json/citelayer/v1/search",
    "cart": "/wp-json/citelayer/v1/cart"
  },
  "content": {
    "languages": ["en"],
    "currency": "USD",
    "product_count": 142,
    "primary_categories": [
      "Electronics",
      "Clothing",
      "Home & Garden",
      "Sports",
      "Books"
    ]
  }
}
```

Key differences with WooCommerce:

- **site.type** changes from `"website"` to `"ecommerce"`
- **site.platform** changes from `"WordPress"` to `"WooCommerce"`
- **capabilities** gains four entries: `product_catalog`, `ucp_v1`, `semantic_search`, and `cart_operations`
- **endpoints** adds `products`, `search`, and `cart` URLs
- **content** object appears with your store’s languages, currency, total product count, and top 5 product categories

### Response Headers

Every response includes these headers:

- `X-Citelayer-Version` — The installed plugin version
- `Access-Control-Allow-Origin: *` — Allows requests from any origin
- `Cache-Control: public, max-age=604800` — Tells clients and CDNs to cache for 7 days
- `Content-Type: application/json; charset=utf-8`

Configuration
-------------

WebMCP is enabled by default. You control it through the Citelayer settings page or programmatically with a filter.

- **Admin setting:** Toggle WebMCP on or off in Citelayer → Settings
- **Filter:** `citelayer_enable_webmcp` — return `false` to disable
- **Default:** Enabled

When you disable WebMCP, Citelayer does not register any hooks or rewrite rules for this feature. This is a clean deactivation — no leftover routes, no error responses, no performance overhead.

```
// Disable WebMCP programmatically
add_filter( 'citelayer_enable_webmcp', '__return_false' );
```

**Note:** After enabling or disabling WebMCP, flush your permalink settings (Settings → Permalinks → Save Changes) to update the rewrite rules.

Verify It Works
---------------

After activating Citelayer, confirm that WebMCP is serving correctly.

### In Your Browser

Visit `https://yoursite.com/.well-known/mcp/context.json` directly. You should see the JSON response with `mcp_version`, your site info, and the capabilities list.

### With cURL

```
curl -s https://yoursite.com/.well-known/mcp/context.json | jq .
```

Check the response headers:

```
curl -I https://yoursite.com/.well-known/mcp/context.json
```

Look for `X-Citelayer-Version`, `Access-Control-Allow-Origin: *`, and `Cache-Control: public, max-age=604800` in the output.

### Troubleshooting

If you get a 404, flush your permalinks. Go to Settings → Permalinks and click Save Changes. This forces WordPress to regenerate rewrite rules, including the WebMCP route.

### “WebMCP Endpoint Not Reachable”

Seeing this warning in your WordPress admin?

> ⚠️ WebMCP endpoint not reachable. The WebMCP endpoint at `/.well-known/mcp/context.json` is not accessible. If you are using Nginx, the server configuration must be adjusted. The endpoint is available as a fallback at `?citelayer_webmcp=1`.

**What’s happening:** Nginx tries to locate `/.well-known/mcp/context.json` as a physical file on the server. When the file doesn’t exist, Nginx returns a 404 error—*before* WordPress even boots. The WebMCP plugin never gets a chance to handle the request.

**The fix:** You need to teach Nginx to pass all requests under `/.well-known/mcp/` to WordPress, instead of looking for a physical file.

---

### Nginx Configuration (Step-by-Step)

Add this location block to your Nginx configuration:

```
# Standard WordPress block (existing)
location / {
    try_files $uri $uri/ /index.php?$args;
}

# NEW: Explicitly pass .well-known to WordPress
location ~ ^/\.well-known/mcp/ {
    try_files $uri $uri/ /index.php?$args;
}
```

**Where does this go?**

- Self-managed servers: `/etc/nginx/sites-available/your-domain.conf` or `/etc/nginx/nginx.conf`
- Managed hosting: Contact your host or server admin—this cannot be changed through WordPress

**After making changes:**

```
# 1. Test configuration (important!)
sudo nginx -t

# 2. Reload Nginx (zero downtime)
sudo systemctl reload nginx
```

**Note:** If you already have a `location ~ ^/\.well-known/` block (e.g., for Let’s Encrypt), add the MCP block *inside* or *after* it—or extend the existing block to include the rewrite.

---

### Fallback Endpoint (Available Immediately)

If you don’t have direct server access or your host won’t modify the configuration: The fallback works *always*, without any rewrite rules.

**URL:**

```
https://your-domain.com/?citelayer_webmcp=1
```

This URL returns *identical JSON* to the standard endpoint. The only difference: It’s not available at the canonical path `/.well-known/mcp/context.json`.

**When to use:**

- Immediate test whether the plugin works at all
- Hosting environments without Nginx access
- Temporary solution until your server admin updates the rewrite rules

---

### Testing Methods

Verify your configuration (or diagnose issues) with these three tests:

#### 1. Browser Test (Standard Endpoint)

```
https://your-domain.com/.well-known/mcp/context.json
```

**Expected result:** JSON output with `mcpVersion`, `endpoints`, `authentication`—no 404, no redirect to homepage.

#### 2. Browser Test (Fallback Endpoint)

```
https://your-domain.com/?citelayer_webmcp=1
```

**Expected result:** *Identical* JSON to Test 1—confirms the plugin is working.

#### 3. Terminal Test (HTTP Status)

```
curl -I https://your-domain.com/.well-known/mcp/context.json
```

**Expected result:** `HTTP/2 200` (or `HTTP/1.1 200`)

---

### Common Errors

ErrorCauseSolution**404 Not Found**Nginx not passing to WordPressAdd location block for `/.well-known/mcp/`**403 Forbidden**Nginx blocking hidden directories (`.` prefix)Explicit location rule to allow `.well-known`**Blank page**PHP error or plugin inactiveCheck WordPress error log, verify plugin status**Redirect to homepage**Rewrite rule missing or misplacedInsert location block *after* standard WordPress block**JSON offered as download**Missing Content-Type headerNormal—curl/browser still display correctly---

### Hosting-Specific Notes

**Shared Hosting (All-Inkl, HostEurope, etc.):**

- Nginx configuration usually not directly editable
- Use fallback endpoint `?citelayer_webmcp=1`
- Or: Contact support with the location block template above

**Cloud Hosting (AWS, GCP, Azure):**

- Check load balancer or reverse proxy settings
- May need additional rewrite rules in cloud configuration

**WordPress Managed Hosting (Raidboxes, Kinsta, WP Engine):**

- Contact support—this is standard for enterprise plugins
- Often pre-configured; 404 usually indicates caching layer

**Docker/Containers:**

- Modify Nginx config in container or mount as volume
- For `docker-compose`: Config change requires `docker-compose restart`

---

### Still Having Issues?

If all tests fail:

1. **Check plugin status:** Is Citelayer WebMCP activated?
2. **Flush permalinks:** WordPress Admin → Settings → Permalinks → “Save Changes”
3. **Clear caches:** Object cache, page cache, CDN cache (Cloudflare, etc.)
4. **Enable debug log:** `wp-config.php` → `define('WP_DEBUG_LOG', true);`
5. **Check server logs:** `/var/log/nginx/error.log` or hosting panel

The fallback endpoint `?citelayer_webmcp=1` is your fastest diagnostic: If that works, the problem is definitely in your Nginx rewrite configuration—not the plugin.

Technical Details
-----------------

### Caching

The WebMCP response is cached as a WordPress transient named `citelayer_webmcp_context` with a 7-day TTL. This keeps the endpoint fast even on high-traffic sites.

The cache is automatically invalidated when:

- A WooCommerce product is created, updated, or deleted
- The `blogname` option changes (site title)
- The `blogdescription` option changes (site tagline)
- The `woocommerce_currency` option changes

You do not need to manually clear the cache. Citelayer hooks into these events and deletes the transient automatically.

### Rewrite Rule

Citelayer adds a rewrite rule that maps the `.well-known` URL to WordPress’s internal routing:

```
^.well-known/mcp/context.json$ → index.php?citelayer_webmcp=1
```

This means WordPress handles the request through its standard query system. No `.htaccess` edits, no Nginx location blocks — it works out of the box on any WordPress host.

### Language Detection

The `content.languages` array in the WooCommerce response detects your site’s configured languages. Citelayer supports two multilingual plugins:

- **WPML** — Uses `icl_get_languages()` to list active languages
- **Polylang** — Uses `pll_languages_list()` to list active languages

If neither plugin is active, the languages array contains the site’s default locale.

### Customizing the Response

Use the `citelayer_webmcp_context` filter to modify the full context object before it is cached and served.

```
add_filter( 'citelayer_webmcp_context', function( $context ) {
    // Add a custom capability
    $context['capabilities'][] = 'custom_api';

    // Add a custom endpoint
    $context['endpoints']['custom'] = '/wp-json/myplugin/v1/data';

    // Add contact information
    $context['site']['support_email'] = 'help@yoursite.com';

    return $context;
} );
```

Since the filter runs before caching, your modifications are stored in the transient and served on subsequent requests without re-running the filter. When the cache invalidates (product update, settings change), the filter runs again with fresh data.

### CORS and Cache Headers

The endpoint sends `Access-Control-Allow-Origin: *` to allow access from any domain. This is required for AI agents that make cross-origin requests from browser-based environments. The `Cache-Control: public, max-age=604800` header tells CDNs and browsers to cache the response for 7 days, matching the server-side transient TTL.

Related
-------

- [UCP Discovery](/docs/ucp-discovery/) — A complementary discovery protocol via REST API, focused on capability flags
- [Schema.org Structured Data](/docs/schema-json-ld/) — Machine-readable product and organization data referenced in WebMCP capabilities
- [Hooks &amp; Filters](/docs/hooks-filters/) — All available filters including `citelayer_webmcp_context` and `citelayer_enable_webmcp`
- [llms.txt](/docs/llms-txt/) — The text-based site manifest referenced in WebMCP’s endpoint list
