{"id":301514,"date":"2026-07-14T01:05:16","date_gmt":"2026-07-14T01:05:16","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/corsen-context\/"},"modified":"2026-10-22T23:43:36","modified_gmt":"2026-10-22T23:43:36","slug":"corsen-context","status":"publish","type":"plugin","link":"https:\/\/ms.wordpress.org\/plugins\/corsen-context\/","author":23482461,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.5.18","stable_tag":"1.5.18","tested":"7.1.3","requires":"6.0","requires_php":"8.0","requires_plugins":null,"header_name":"Corsen Context","header_author":"Corsen AI","header_description":"Universal AI Context Layer for WordPress with llms.txt and MCP server.","assets_banners_color":"0c314e","last_updated":"2026-10-22 23:43:36","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/corsen.ai","header_plugin_uri":"https:\/\/github.com\/CorsenAI\/corsen-context","header_author_uri":"https:\/\/corsen.ai","rating":0,"author_block_rating":0,"active_installs":100,"downloads":1739,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.2.0":{"tag":"1.2.0","author":"corsenai","date":"2026-07-14 01:05:06","revision":3606822},"1.2.1":{"tag":"1.2.1","author":"corsenai","date":"2026-07-22 16:22:03","revision":3618951},"1.3.0":{"tag":"1.3.0","author":"corsenai","date":"2026-08-29 23:17:17","revision":3671932},"1.3.1":{"tag":"1.3.1","author":"corsenai","date":"2026-08-30 07:49:58","revision":3672175},"1.4.0":{"tag":"1.4.0","author":"corsenai","date":"2026-08-30 11:33:22","revision":3672460},"1.5.14":{"tag":"1.5.14","author":"corsenai","date":"2026-09-02 14:35:06","revision":3678186},"1.5.16":{"tag":"1.5.16","author":"corsenai","date":"2026-09-03 09:42:42","revision":3679465},"1.5.18":{"tag":"1.5.18","author":"corsenai","date":"2026-10-22 23:43:36","revision":3760650}},"upgrade_notice":{"1.5.18":"<p>The public credit line is now off by default (Settings &gt; Corsen Context &gt; Show Credit turns it back on). In-page agents get readable tool errors, llms.txt reads naturally, and caches survive consent and analytics cookies.<\/p>","1.5.17":"<p>Fixes the <code>\/llms.txt<\/code> rewrite rule staying registered while the feature is disabled, which could block another plugin&#039;s <code>llms.txt<\/code>. The readme now documents WebMCP setup.<\/p>","1.5.16":"<p>The agent conduct policy now spells out the allowed purchase path (cart, checkout, account creation) next to the human-only rules, so a well-behaved agent completes what the owner permits and hands the rest to a person.<\/p>","1.5.15":"<p>Closes the last author-enumeration leak: blocked author archives no longer print the author&#039;s nicename in the 404 page title or Open Graph tags.<\/p>","1.5.14":"<p>Hardens JSON-LD retrieval, unifies owner visibility vetoes across every reader, fixes section-id collisions, completes private-data cleanup, and aligns WordPress Abilities output schemas with actual results.<\/p>","1.5.9":"<p>The MCP route&#039;s 405 answer to GET now advertises <code>POST<\/code> only, as the MCP transport specification requires; WordPress Core had rebuilt the <code>Allow<\/code> header from every registered method.<\/p>","1.5.8":"<p>Adds the Control Center, the WordPress Abilities API surface, two opt-in extension tools (product data, expert requests) and a bounded audit log. Everything new defaults to OFF; the four core read-only tools and the public contract are unchanged.<\/p>","1.4.1":"<p>Removes the experimental form write surface and strengthens strict MCP\/WebMCP contract validation. Existing legacy form shortcodes render nothing.<\/p>","1.2.1":"<p>Security and reliability update. <code>\/llms-full.txt<\/code> is now disabled by default; review and enable it explicitly if the bounded full-content export is desired.<\/p>","1.1.0":"<p>Security update: fixes SSRF fail-open, PHP crash on large content, rate limiter bugs. Adds WP-Cron cleanup and max_pages admin setting. Recommended for all users.<\/p>","1.0.0":"<p>Initial release with MCP-style JSON-RPC and llms.txt publishing.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3760650,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3760650,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3760650,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3760650,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3760650,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3760650,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"landingPage\":\"\\\/wp-admin\\\/options-general.php?page=corsen-context-control\",\"preferredVersions\":{\"php\":\"8.3\",\"wp\":\"latest\"},\"phpExtensionBundles\":[\"kitchen-sink\"],\"steps\":[{\"step\":\"login\",\"username\":\"admin\",\"password\":\"password\"},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"corsen-context\"},\"options\":{\"activate\":true}},{\"step\":\"setSiteOptions\",\"options\":{\"blogname\":\"Corsen Context preview\",\"blogdescription\":\"llms.txt, MCP endpoint and WebMCP tools for AI agents\"}},{\"step\":\"runPHP\",\"code\":\"<?php require_once '\\\/wordpress\\\/wp-load.php'; update_option( 'permalink_structure', '\\\/%postname%\\\/' ); flush_rewrite_rules( true );\"}]}"}},"all_blocks":[],"tagged_versions":["1.2.0","1.2.1","1.3.0","1.3.1","1.4.0","1.5.14","1.5.16","1.5.18"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3760650,"resolution":"1","location":"assets","locale":"","width":1280,"height":800},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3760650,"resolution":"2","location":"assets","locale":"","width":1280,"height":800},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3760650,"resolution":"3","location":"assets","locale":"","width":1280,"height":800},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3760650,"resolution":"4","location":"assets","locale":"","width":1280,"height":800},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3760650,"resolution":"5","location":"assets","locale":"","width":1280,"height":800}},"screenshots":{"1":"The Control Center: one card per surface (MCP endpoint, llms.txt, WebMCP, llms-full.txt) with live badges, behind a single master switch.","2":"Tools agents can call: one card per tool with an exposed, needs-config or off badge; extension tools stay off until you enable them.","3":"The settings page with the Agent Access panel: which surfaces are on, which tools and content types agents can see.","4":"The \"Rules for AI agents\" page rendered by the [corsen_agent_policy] shortcode from the same policy table as llms.txt and the tool descriptions.","5":"The dashboard widget: AI context status, indexed item count, llms.txt link and the canonical MCP endpoint."}},"plugin_section":[262246],"plugin_tags":[2353,246305,244604,242115,258453],"plugin_category":[],"plugin_contributors":[271431],"plugin_business_model":[],"class_list":["post-301514","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-ai","plugin_tags-ai-agents","plugin_tags-llms-txt","plugin_tags-mcp","plugin_tags-webmcp","plugin_contributors-corsenai","plugin_committers-corsenai"],"banners":{"banner":"https:\/\/ps.w.org\/corsen-context\/assets\/banner-772x250.png?rev=3760650","banner_2x":"https:\/\/ps.w.org\/corsen-context\/assets\/banner-1544x500.png?rev=3760650","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/corsen-context\/assets\/icon.svg?rev=3760650","icon":"https:\/\/ps.w.org\/corsen-context\/assets\/icon.svg?rev=3760650","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/corsen-context\/assets\/screenshot-1.png?rev=3760650","caption":"The Control Center: one card per surface (MCP endpoint, llms.txt, WebMCP, llms-full.txt) with live badges, behind a single master switch."},{"src":"https:\/\/ps.w.org\/corsen-context\/assets\/screenshot-2.png?rev=3760650","caption":"Tools agents can call: one card per tool with an exposed, needs-config or off badge; extension tools stay off until you enable them."},{"src":"https:\/\/ps.w.org\/corsen-context\/assets\/screenshot-3.png?rev=3760650","caption":"The settings page with the Agent Access panel: which surfaces are on, which tools and content types agents can see."},{"src":"https:\/\/ps.w.org\/corsen-context\/assets\/screenshot-4.png?rev=3760650","caption":"The \"Rules for AI agents\" page rendered by the [corsen_agent_policy] shortcode from the same policy table as llms.txt and the tool descriptions."},{"src":"https:\/\/ps.w.org\/corsen-context\/assets\/screenshot-5.png?rev=3760650","caption":"The dashboard widget: AI context status, indexed item count, llms.txt link and the canonical MCP endpoint."}],"raw_content":"<!--section=description-->\n<p><strong>Corsen Context<\/strong> publishes a bounded overview of selected public WordPress content and provides four core read-only content tools through a JSON-RPC endpoint. Five further extension tools are opt-in and owner-controlled: <code>get_product<\/code> (live price, stock, images and variants via WooCommerce, plus an <code>agentPurchase<\/code> policy the agent must respect), <code>get_sections<\/code> (a page outline plus one bounded section per call), <code>get_structured_data<\/code> (typed JSON-LD blocks), <code>check_agent_access<\/code> (reads the result of the owner's latest agent-access self-test) and <code>request_expert_call<\/code> (a human-only expert intake, annotated readOnlyHint:false and refused server-side for AI callers with error code human_only). 1.5.0 also registers the enabled tools through the experimental WebMCP browser API when the site owner opts in and the browser exposes that API, and through the WordPress Abilities API on WordPress 6.9 or newer.<\/p>\n\n<h4>What it does<\/h4>\n\n<p>The plugin provides three separate surfaces, with one implementation behind all of them:<\/p>\n\n<ol>\n<li><p><strong>Static Layer<\/strong> \u2014 Generates <code>\/llms.txt<\/code> with a structured overview of selected public content. An optional, bounded <code>\/llms-full.txt<\/code> export can be enabled in settings.<\/p><\/li>\n<li><p><strong>Dynamic Layer<\/strong> \u2014 Exposes the enabled tools through a <strong>Model Context Protocol (MCP)<\/strong> JSON-RPC endpoint at the canonical URL generated by WordPress. The four core tools and four WordPress read extensions are read-only; the optional human-only expert intake is explicitly non-read-only and refuses agent calls server-side. The endpoint targets protocol version 2025-11-25 with JSON responses and no server-sent event stream.<\/p><\/li>\n<li><p><strong>In-Page Layer (opt-in)<\/strong> \u2014 Registers the enabled tools through WebMCP <code>document.modelContext<\/code>, including explicit per-tool annotations. Serving the bridge does not enable WebMCP in every browser: a compatible browser\/client and, where applicable, current trial enrollment or a development flag are also required.<\/p><\/li>\n<\/ol>\n\n<h4>WebMCP: your tools inside the browser<\/h4>\n\n<p>WebMCP is the draft browser API (<code>document.modelContext<\/code>) through which a page offers tools to an AI agent running in the browser: Chrome with WebMCP enabled, or an agent client with built-in support such as ChatGPT's in-app browser. With Corsen Context, your WordPress site offers in the page the same read-only tools it already serves over MCP: <code>search_site<\/code>, <code>get_page_content<\/code>, <code>list_content<\/code>, <code>get_sitemap<\/code>, plus any extension tool you enable.<\/p>\n\n<ul>\n<li><strong>Nothing to code<\/strong> - the plugin enqueues the registration script with the tool definitions; every tool call goes back to your site's own MCP endpoint, so the browser never reimplements a tool.<\/li>\n<li><strong>Annotated and bounded<\/strong> - each tool carries a title plus <code>readOnlyHint<\/code> and <code>untrustedContentHint<\/code> annotations, and the human-only expert tool is marked <code>consequentialHint<\/code> so a browser agent asks before calling it; the bridge stays same-origin, sends no cookies, visitor credentials or API key, and refuses to register inside frames. Tool errors reach the agent as structured results (<code>error_code<\/code>, message, handoff URL) rather than a bare exception.<\/li>\n<li><strong>Opt-in<\/strong> - off until you enable it under Settings &gt; Corsen Context. An optional origin-trial token field emits Chrome's first-party meta tag for public deployments.<\/li>\n<\/ul>\n\n<p>To try it: enable WebMCP in Settings &gt; Corsen Context; open the site over HTTPS as a top-level page in a browser that exposes the API (Chrome 149 or newer with <code>chrome:\/\/flags\/#enable-webmcp-testing<\/code>, the Chrome origin trial that runs from Chrome 149 to 156, or an agent client with built-in support); check <code>typeof document.modelContext === 'object'<\/code> in DevTools; then ask the agent to search the site and read one page. WebMCP is experimental and browser support changes; the <a href=\"https:\/\/github.com\/CorsenAI\/corsen-context\/blob\/main\/docs\/WEBMCP-BROWSER-SETUP.md\">browser setup guide<\/a> tracks the current paths.<\/p>\n\n<h4>Key Features<\/h4>\n\n<ul>\n<li><strong>Three surfaces, one contract<\/strong> \u2014 static <code>\/llms.txt<\/code>, a read-only MCP endpoint, and opt-in WebMCP in-page tools expose the same owner-selected content; the heavier <code>\/llms-full.txt<\/code> export and the WebMCP bridge are opt-in.<\/li>\n<li><strong>WebMCP bridge<\/strong> \u2014 registers the enabled tools through <code>document.modelContext<\/code> with per-tool annotations, same-origin and credential-free; optional origin-trial token setting.<\/li>\n<li><strong>MCP 2025-11-25 target<\/strong> \u2014 Supports <code>initialize<\/code>, <code>ping<\/code>, <code>tools\/list<\/code>, <code>tools\/call<\/code>, <code>resources\/list<\/code>, <code>resources\/read<\/code>, and <code>notifications\/initialized<\/code>. The endpoint returns JSON responses and does not provide server-sent event streaming.<\/li>\n<li><strong>4 core read-only tools<\/strong> \u2014 <code>search_site<\/code>, <code>get_page_content<\/code>, <code>list_content<\/code>, <code>get_sitemap<\/code>; every other surface tool is an opt-in extension, off by default.<\/li>\n<li><strong>SEO integration<\/strong> \u2014 Reads Yoast SEO and Rank Math metadata for better descriptions.<\/li>\n<li><strong>Request controls<\/strong> \u2014 Rate limiting, strict input validation, same-site content URL checks, defensive MCP response headers, and optional API-key authentication.<\/li>\n<li><strong>Admin settings page<\/strong> \u2014 Choose public post types, exclude paths, set rate limits, toggle surfaces, and select any subset of the tools.<\/li>\n<li><strong>Control Center<\/strong> (Settings &gt; Corsen Context Control) \u2014 one card per surface and tool, honest exposed\/needs-config\/off badges, a per-tool \"hide from in-page agents\" switch, what-agents-see preview, and a bounded local audit log (transport, outcome, error code, per-tool totals) with a one-click purge.<\/li>\n<li><strong>Dashboard widget<\/strong> \u2014 See your AI context status at a glance.<\/li>\n<li><strong>Bounded generation<\/strong> \u2014 Total item and output-byte limits protect the optional full-content export.<\/li>\n<li><strong>Content safety<\/strong> \u2014 Drafts, private posts, password-protected posts, excluded paths, and content vetoed by the exposure filter are not served.<\/li>\n<li><strong>Credit line (opt-in)<\/strong> \u2014 an optional \"Powered by Corsen Context\" line in generated files, off by default.<\/li>\n<\/ul>\n\n<h4>Published Endpoints and Discovery Hints<\/h4>\n\n<p>When the corresponding settings are enabled, Corsen Context publishes:<\/p>\n\n<ol>\n<li><strong>robots.txt<\/strong> \u2014 An <code>MCP:<\/code> line containing the canonical endpoint URL generated by WordPress<\/li>\n<li><strong>llms.txt<\/strong> \u2014 When MCP is enabled, the generated file includes its canonical endpoint URL; the separate promotional credit is opt-in and off by default<\/li>\n<li><strong>HTML head<\/strong> \u2014 <code>&lt;link rel=\"mcp\"&gt;<\/code> link element added automatically<\/li>\n<li><strong>Direct URL<\/strong> \u2014 <code>\/llms.txt<\/code> remains available to clients that know the convention<\/li>\n<\/ol>\n\n<p>These are project discovery hints, not universally consumed standards. They do not guarantee that a search engine or client will discover or use the endpoint.<\/p>\n\n<h4>Requirements<\/h4>\n\n<ul>\n<li>WordPress 6.0 or higher<\/li>\n<li>PHP 8.0 or higher<\/li>\n<li>A web-server configuration that routes the published <code>\/llms.txt<\/code> path to WordPress. Pretty permalinks are recommended for this static path. The MCP REST endpoint itself uses WordPress's canonical URL and can use the <code>?rest_route=\/corsen-context\/v1\/mcp<\/code> form with Plain permalinks.<\/li>\n<\/ul>\n\n<p>WebMCP additionally needs a browser and agent\/client that implement the evolving API. Chrome's development flag and public origin-trial path can change; follow the current <a href=\"https:\/\/github.com\/CorsenAI\/corsen-context\/blob\/main\/docs\/WEBMCP-BROWSER-SETUP.md\">browser setup guide<\/a>.<\/p>\n\n<h4>Part of a Bigger Ecosystem<\/h4>\n\n<p>Corsen Context is an open-source project by <a href=\"https:\/\/corsen.ai\">Corsen AI<\/a>. The project also provides TypeScript packages for Node.js, Next.js, and Astro, plus a reference Express server. WordPress uses this dedicated PHP plugin.<\/p>\n\n<ul>\n<li><a href=\"https:\/\/github.com\/CorsenAI\/corsen-context\">GitHub Repository<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/CorsenAI\/corsen-context#readme\">Full Documentation<\/a><\/li>\n<\/ul>\n\n<!--section=installation-->\n<h4>From WordPress.org (published stable channel)<\/h4>\n\n<ol>\n<li>Go to Plugins &gt; Add New in your WordPress admin<\/li>\n<li>Search for \"Corsen Context\"<\/li>\n<li>Click \"Install Now\" then \"Activate\"<\/li>\n<li>Visit Settings &gt; Corsen Context and review the exposed post types, paths, and surfaces.<\/li>\n<\/ol>\n\n<p>Check the version displayed by WordPress.org before installation. A stable version older than 1.5.14 does not contain the complete current Control Center, extension-tool hardening, and Abilities API schemas documented here.<\/p>\n\n<h4>Manual release installation<\/h4>\n\n<ol>\n<li>Obtain the GitHub release asset for version 1.5.18, or build a ZIP from <code>packages\/wordpress-plugin\/corsen-context<\/code> in the public repository at tag <code>v1.5.18<\/code>.<\/li>\n<li>The ZIP must contain one top-level <code>corsen-context<\/code> folder with <code>corsen-context.php<\/code>, <code>includes\/<\/code>, <code>uninstall.php<\/code>, and <code>readme.txt<\/code>; do not upload the monorepo ZIP.<\/li>\n<li>Go to Plugins &gt; Add New &gt; Upload Plugin, upload that plugin ZIP, and activate it.<\/li>\n<li>Confirm version 1.5.18 on the Plugins screen, then review Settings &gt; Corsen Context before enabling WebMCP.<\/li>\n<\/ol>\n\n<h4>After Activation<\/h4>\n\n<p>With the default settings, activation publishes:<\/p>\n\n<ul>\n<li><code>\/llms.txt<\/code> \u2014 Visit <code>https:\/\/yoursite.com\/llms.txt<\/code> to see it<\/li>\n<li>MCP endpoint \u2014 Copy the exact URL displayed under Settings &gt; Corsen Context or exposed by the site's MCP discovery hints<\/li>\n<li><p>Dashboard widget \u2014 Check your admin dashboard<\/p>\n\n<p>\/llms-full.txt is not enabled by default. WebMCP is also opt-in and requires a compatible browser\/client in addition to the WordPress setting.<\/p><\/li>\n<\/ul>\n\n<p><strong>Important:<\/strong> Do not construct the MCP endpoint by appending <code>\/wp-json\/<\/code>. WordPress commonly returns <code>https:\/\/yoursite.com\/wp-json\/corsen-context\/v1\/mcp<\/code>, but Plain permalinks can return <code>https:\/\/yoursite.com\/?rest_route=\/corsen-context\/v1\/mcp<\/code>, and a site can filter the REST prefix. Use the URL displayed by the plugin or published in <code>robots.txt<\/code>, the HTML <code>&lt;link rel=\"mcp\"&gt;<\/code>, or the generated <code>\/llms.txt<\/code> when MCP is enabled. If the separate <code>\/llms.txt<\/code> path is unavailable, review the site's rewrite and permalink configuration.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20is%20webmcp%2C%20and%20how%20is%20it%20different%20from%20mcp%3F\"><h3>What is WebMCP, and how is it different from MCP?<\/h3><\/dt>\n<dd><p>MCP (Model Context Protocol) lets an AI client outside the page call your site's tools over HTTP. WebMCP is the browser-side counterpart: the page registers tools with <code>document.modelContext<\/code>, and an agent running inside the browser calls them. Corsen Context serves the same read-only tools on both; WebMCP adds no write access and no new data.<\/p><\/dd>\n<dt id=\"what%20is%20mcp%3F\"><h3>What is MCP?<\/h3><\/dt>\n<dd><p>Model Context Protocol is an open protocol for communication between AI applications and external systems. Corsen Context targets the 2025-11-25 protocol version for its read-only JSON-RPC endpoint.<\/p><\/dd>\n<dt id=\"what%20is%20llms.txt%3F\"><h3>What is llms.txt?<\/h3><\/dt>\n<dd><p>A proposed convention where websites place a <code>\/llms.txt<\/code> file containing a structured Markdown overview. Support varies by client and search engine, so it should be treated as an additional publishing surface rather than an indexing guarantee.<\/p><\/dd>\n<dt id=\"is%20my%20content%20safe%3F\"><h3>Is my content safe?<\/h3><\/dt>\n<dd><p>The plugin limits output to selected public post types and rejects draft, pending, private, password-protected, trashed, or excluded content. Site owners can also veto individual posts with the <code>corsen_context_can_expose_post<\/code> filter. As with any public export, review the selected post types and exclusions before enabling it on a site with membership or conditional-visibility plugins.<\/p><\/dd>\n<dt id=\"does%20this%20slow%20down%20my%20site%3F\"><h3>Does this slow down my site?<\/h3><\/dt>\n<dd><p>When MCP is enabled, normal pages receive a small discovery link. When WebMCP is also enabled, the plugin emits an origin-trial meta tag if configured, a short inline configuration with the tool definitions, and one deferred script file that browsers cache. Generated metadata may use bounded WordPress transients for anonymous requests that carry no WordPress session cookie (consent, analytics or CDN cookies do not disable that cache). Rendered page content is not placed in the shared MCP cache, and <code>\/llms-full.txt<\/code> uses item, byte, and generation-lock limits. Measure representative pages on your own hosting rather than assuming zero impact.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20page%20builders%3F\"><h3>Does it work with page builders?<\/h3><\/dt>\n<dd><p>By default, Corsen Context reads stored public content without executing <code>the_content<\/code>, dynamic blocks, or shortcodes. This avoids accidentally exporting personalized output. Site owners can opt into full rendering with the <code>corsen_context_render_mode<\/code> filter; full-rendered output is never stored in the shared content cache. Compatibility depends on the page builder and should be tested on the site.<\/p><\/dd>\n<dt id=\"can%20i%20control%20which%20content%20is%20exposed%3F\"><h3>Can I control which content is exposed?<\/h3><\/dt>\n<dd><p>Yes. In Settings &gt; Corsen Context you can:<\/p>\n\n<ul>\n<li>Choose which post types to include (pages, posts, products, custom types)<\/li>\n<li>Exclude specific URL paths<\/li>\n<li>Choose which tools MCP, WebMCP and the Abilities API advertise and allow (extension tools stay off until you enable them)<\/li>\n<li>Hide any tool from in-page (WebMCP) agents while keeping it available over MCP, per tool, from the Control Center or the settings page<\/li>\n<li>Disable MCP, llms.txt, or the entire plugin<\/li>\n<\/ul><\/dd>\n<dt id=\"does%20it%20work%20with%20woocommerce%3F\"><h3>Does it work with WooCommerce?<\/h3><\/dt>\n<dd><p>The standard public <code>product<\/code> post type can be selected. The plugin exports its stored public content under the same rendering and exclusion rules as other post types. Themes, product add-ons, memberships, prices, variations, and dynamic shortcodes can change what a visitor sees, so test the required WooCommerce fields and visibility rules on the target site before claiming compatibility. When you enable it, the <code>get_product<\/code> extension tool additionally serves live price, sale, stock, image, and (for variable products) variant data through WooCommerce APIs; it requires WooCommerce to be active and the product post type to be selected.<\/p><\/dd>\n<dt id=\"how%20do%20i%20protect%20the%20mcp%20endpoint%3F\"><h3>How do I protect the MCP endpoint?<\/h3><\/dt>\n<dd><p>You can set an API key by defining <code>CORSEN_CONTEXT_API_KEY<\/code> in your <code>wp-config.php<\/code>:<\/p>\n\n<pre><code>define('CORSEN_CONTEXT_API_KEY', 'your-secret-key-here');\n<\/code><\/pre>\n\n<p>Server-side requests must then include <code>X-MCP-Key: your-secret-key-here<\/code> or <code>Authorization: Bearer your-secret-key-here<\/code>.<\/p>\n\n<p>The supplied WebMCP bridge intentionally sends no key, cookies, or visitor credentials. Do not embed the key in page source. Use either a public, read-only, rate-limited endpoint for WebMCP or a key-protected endpoint for configured server-side MCP clients with WebMCP disabled.<\/p><\/dd>\n<dt id=\"how%20do%20i%20enable%20webmcp%20in%20a%20browser%3F\"><h3>How do I enable WebMCP in a browser?<\/h3><\/dt>\n<dd><p>Enable WebMCP in Settings &gt; Corsen Context, then use a browser and agent\/client that implement the experimental API. Serving the registration script alone is not enough. For local Chrome testing, follow the current documented flag. For a public trial, enroll the exact HTTPS origin and use its current, unexpired token. See the <a href=\"https:\/\/github.com\/CorsenAI\/corsen-context\/blob\/main\/docs\/WEBMCP-BROWSER-SETUP.md\">browser setup and verification guide<\/a>.<\/p>\n\n<p>An origin-trial token is delivered to browsers and is not an MCP credential. Successful registration also does not prove the endpoint or content policy: execute <code>search_site<\/code>, pass one result to <code>get_page_content<\/code>, and inspect the grounded answer.<\/p><\/dd>\n<dt id=\"is%20there%20a%20credit%20line%20in%20the%20generated%20files%3F\"><h3>Is there a credit line in the generated files?<\/h3><\/dt>\n<dd><p>Not unless you ask for it. The \"Powered by Corsen Context\" line is off by default and only appears in <code>\/llms.txt<\/code> and <code>\/llms-full.txt<\/code> after you check \"Show Credit\" in Settings &gt; Corsen Context. Installs that still had the earlier default are switched off once by this update; the checkbox turns it back on.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.5.18 - 2026-10-23<\/h4>\n\n<ul>\n<li>Listing: tested up to WordPress 7.1 (run on WordPress 7.1.3), a Screenshots section, and a shorter 1.5.9 upgrade notice.<\/li>\n<li>The \"Powered by Corsen Context\" credit line in <code>\/llms.txt<\/code> and <code>\/llms-full.txt<\/code> is now opt-in and off by default, and the <code>X-Powered-By<\/code> header is gone from plugin responses (plugin directory guideline 10). Existing installs are switched off once; the \"Show Credit\" checkbox turns the line back on.<\/li>\n<li>WebMCP: tool errors reach in-page agents as structured results (error code, message, handoff URL) instead of a bare <code>OperationError<\/code>; the human-only expert tool carries <code>consequentialHint: true<\/code>; every tool has a <code>title<\/code>; the settings page and the Control Center say that WebMCP needs HTTPS and name the Chrome 149 to 156 origin trial.<\/li>\n<li>MCP: <code>tools\/list<\/code> uses the MCP annotation vocabulary and advertises <code>outputSchema<\/code>; tool errors carry the extension's extra fields in <code>structuredContent<\/code>; the OPTIONS preflight is only answered while MCP is enabled.<\/li>\n<li>The WebMCP bridge is a script file enqueued in the footer instead of an inline block: about 10 KB less per page view, and browsers cache it.<\/li>\n<li><code>llms.txt<\/code> reads naturally (no more escaped periods, hyphens or parentheses) and follows the llmstxt.org layout.<\/li>\n<li>Caching and queries: consent, analytics and CDN cookies no longer disable the shared llms.txt and tool caches (new <code>corsen_context_shared_cache_safe<\/code> filter); the list, search and sitemap queries are lighter; the settings upgrade check no longer runs on every request.<\/li>\n<li>Admin, policy and dashboard strings are translatable; uninstall cleans every site of a multisite network.<\/li>\n<li>Governance: the audit log records the transport (<code>mcp<\/code>, <code>webmcp<\/code>, <code>abilities<\/code>) and the error code of every call, with per-transport and per-tool totals in the Control Center; any tool can be hidden from in-page agents while staying on MCP; an optional <code>corsen_context_webmcp_output_budget<\/code> filter bounds in-page page results.<\/li>\n<\/ul>\n\n<h4>1.5.17 - 2026-10-17<\/h4>\n\n<ul>\n<li>Fix: the <code>\/llms.txt<\/code> and <code>\/llms-full.txt<\/code> rewrite rules are registered only while the corresponding surface is enabled, stale rules are dropped from the generated rule set, and the rules are refreshed when the setting changes. A disabled <code>\/llms.txt<\/code> previously kept owning the route and could answer 404 in place of another plugin's <code>llms.txt<\/code>. Reported with a fix by suhakaralar (#10, #11).<\/li>\n<li>Readme and plugin description now present WebMCP as one of the three surfaces (static <code>llms.txt<\/code>, MCP endpoint, in-page WebMCP tools) with setup and verification steps; tags updated.<\/li>\n<\/ul>\n\n<h4>1.5.16 - 2026-09-03<\/h4>\n\n<ul>\n<li>Agent conduct policy states what an agent may do, not only what it must not: for a product whose <code>agentPurchase<\/code> is <code>allowed<\/code>, an agent acting for its user may complete the store's ordinary checkout, including creating the customer account it requires; everything outside those explicit per-product permissions stays human-only, and the agent is told to stop and report the page URL to its user. The same sentence is rendered in <code>llms.txt<\/code>, the <code>[corsen_agent_policy]<\/code> page, the machine-readable policy JSON, the <code>get_product<\/code> description, and the default per-product reason.<\/li>\n<\/ul>\n\n<h4>1.5.15 - 2026-09-03<\/h4>\n\n<ul>\n<li>\"Hide user enumeration\" now flips anonymous author archives to 404 on <code>pre_handle_404<\/code>, inside <code>WP::main()<\/code> and before the <code>wp<\/code> action, instead of on <code>template_redirect<\/code>. The previous hook returned the right status but SEO plugins and <code>wp_get_document_title()<\/code> had already resolved the author, so the 404 page's <code>&lt;title&gt;<\/code> and Open Graph tags still printed the author's nicename and archive URL. The queried user is also dropped from the main query, and the integration test now asserts the document title, <code>is_author()<\/code>, and the queried object.<\/li>\n<\/ul>\n\n<h4>1.5.14 - 2026-09-02<\/h4>\n\n<ul>\n<li><code>get_structured_data<\/code> now uses WordPress's safe HTTP transport, refuses redirects, and caps the loopback response while downloading it. Stored markup is capped before parsing, JSON-LD clips stay valid UTF-8, multi-type entities are counted correctly, duplicate blocks no longer create a false truncation flag, and every returned block now stays within the documented byte budget.<\/li>\n<li>WordPress Abilities output schemas now match the executor: <code>search_site<\/code> declares <code>rank<\/code>, sitemap fields reflect its actual payload, nullable product values are explicit, and the section and structured-data schemas include their real optional fields.<\/li>\n<li>All WordPress extension readers now honor the same membership and visibility veto filter as the four core tools. Section ids reserve the synthetic <code>top<\/code> entry and ignore heading-like lines inside fenced code. The expert handoff requires an owner-configured same-origin form URL, and uninstall\/purge removes the complete private expert inbox (including trashed requests), agent-access snapshot, lock, and product policy metadata.<\/li>\n<li>Extension input schemas now match their validators (required URIs, exact slug-or-URI product selection, and bounded section offsets), including Unicode-aware string limits. The agent-access check validates real llms.txt\/MCP response shapes and is described honestly as a same-site loopback using representative bot User-Agent strings, not a full external-agent test.<\/li>\n<li>Product purchase policy can be managed on every WooCommerce product edit screen as well as the first 50-product quick editor. Invalid stored states fail closed, policy summaries honor every owner visibility veto, and human-handoff copy no longer claims that Corsen Context intercepts browser form submissions.<\/li>\n<\/ul>\n\n<h4>1.5.13 - 2026-09-01<\/h4>\n\n<ul>\n<li>Policy honesty + hardening (second independent review): the REST meta <code>auth_callback<\/code> no longer calls <code>edit_post_meta<\/code> (which re-entered itself for registered protected meta) and checks <code>edit_post<\/code> instead, as Core documents. The agent head banner renders only when the MCP channel is actually enabled \u2014 a disabled channel is never advertised. Long owner reasons are truncated without requiring mbstring. <code>llms.txt<\/code> opens with \"START HERE for AI agents\" and its policy block now distinguishes the server-enforced expert handoff (<code>human_only<\/code>) from the per-product <code>agentPurchase<\/code> contract instruction; the plugin exposes no purchase tool and never intercepts human checkout. The human-only form notice is generated from the same table (<code>[corsen_human_only_notice]<\/code>), so the form copy is the wire copy.<\/li>\n<\/ul>\n\n<h4>1.5.12 - 2026-09-01<\/h4>\n\n<ul>\n<li>Governed-agent policy: one server-side policy table composes the relevant MCP\/WebMCP descriptions, <code>llms.txt<\/code>, an HTML head banner for parsers, and the <code>[corsen_agent_policy]<\/code> page. <code>request_expert_call<\/code> becomes <strong>human-only by policy<\/strong>: it stays advertised so an agent can read the rule, but every schema-valid invocation is refused with error code <code>human_only<\/code> plus a handoff URL before any throttle or storage side effect. <code>get_product<\/code> output carries <code>agentPurchase<\/code> (<code>allowed<\/code>|<code>forbidden<\/code>) and <code>agentPurchaseReason<\/code> from owner-set product meta, and the tool description states that a forbidden product must be handed to a human, never checked out by the agent. OPTIONS preflight matching also tolerates <code>rest_route<\/code> and atypical permalink prefixes.<\/li>\n<\/ul>\n\n<h4>1.5.11 - 2026-09-01<\/h4>\n\n<ul>\n<li><code>tools\/list<\/code> now emits WebMCP annotations (<code>readOnlyHint<\/code> per tool; <code>request_expert_call<\/code> is explicitly <code>readOnlyHint: false<\/code>) on the MCP transport, so SECURITY.md's claim is backed on the wire and not only in the in-page bridge. <code>get_sections<\/code> documents <code>\"top\"<\/code> and now always lists and resolves it, even as a zero-byte intro. When \"Hide user enumeration\" is on, <code>\/?author=N<\/code> and <code>\/author\/{login}<\/code> archives also answer 404 to anonymous visitors instead of leaking logins through the classic doors. The MCP route's OPTIONS preflight is answered by the plugin (<code>POST, OPTIONS<\/code>, no credentials) instead of core advertising every verb.<\/li>\n<\/ul>\n\n<h4>1.5.10 - 2026-09-01<\/h4>\n\n<ul>\n<li><code>get_product(slug)<\/code> integrity: slug lookups verify the stored <code>post_name<\/code> and apply the same owner exposure policy as URL lookups. A stale or excluded slug now returns not-found instead of silently serving a different product (found by external live audit).<\/li>\n<li><code>get_sections<\/code> outline integrity: outline entries are an index (<code>id<\/code>, <code>level<\/code>, <code>heading<\/code>, <code>bytes<\/code>) and no longer embed each section's markdown, which had made the \"cheap\" outline larger than <code>get_page_content<\/code> of the same page. Section ids are collision-free even against literal <code>-N<\/code> suffixes, and byte-budget chunks never split a UTF-8 codepoint.<\/li>\n<li>Control Center save integrity: the form now posts <code>hide_user_enumeration<\/code> and <code>credit<\/code> explicitly (they were silently switched off by every Control Center save), and a deliberately empty content-type selection persists as \"expose nothing\" instead of silently reverting to <code>post,page<\/code>.<\/li>\n<\/ul>\n\n<h4>1.5.9 - 2026-09-01<\/h4>\n\n<ul>\n<li>MCP route <code>Allow<\/code> header: the 405 GET answer now advertises <code>POST<\/code> only. WordPress Core was overwriting it with the route's registered methods (<code>POST, GET, OPTIONS<\/code>); a <code>rest_post_dispatch<\/code> filter at priority 20 now wins after core's own filter.<\/li>\n<\/ul>\n\n<h4>1.5.8 - 2026-09-01<\/h4>\n\n<ul>\n<li>Agent-access self-test: the MCP probe now really sends JSON-RPC headers (<code>Content-Type: application\/json<\/code>, <code>Accept<\/code>, <code>MCP-Protocol-Version<\/code>) so the endpoint answers 200 instead of 415; a test asserts the probe's own headers so the fix cannot silently vanish again.<\/li>\n<\/ul>\n\n<h4>1.5.7 - 2026-09-01<\/h4>\n\n<ul>\n<li><code>check_agent_access<\/code> routing fix: the MCP server's tool-call switch now dispatches the tool (it was advertised by <code>tools\/list<\/code> but returned \"Tool not found\" on call); a server-level regression test covers end-to-end routing for the tool.<\/li>\n<\/ul>\n\n<h4>1.5.6 - 2026-09-01<\/h4>\n\n<ul>\n<li>Control Center now carries a card for every registered tool. Previously <code>get_sections<\/code> and <code>get_structured_data<\/code> had no card, so saving the Control Center form dropped them from the enabled set - a real owner-footgun, now covered by a regression test that fails if any tool lacks its card.<\/li>\n<\/ul>\n\n<h4>1.5.5 - 2026-09-01<\/h4>\n\n<ul>\n<li>Version bump only in practice: the probe-header fix announced here did not make it into that build (the edit silently failed to apply and no test covered it); it actually ships in 1.5.8 with a header-assertion test.<\/li>\n<\/ul>\n\n<h4>1.5.4 - 2026-09-01<\/h4>\n\n<ul>\n<li>New opt-in tool <code>check_agent_access<\/code>: agents read the owner's latest same-site loopback result using representative ClaudeBot, ChatGPT-User and GPTBot User-Agent strings. A pass requires the expected llms.txt marker or a valid MCP tools\/list response. It is a read-only snapshot with zero arguments and never triggers egress itself.<\/li>\n<li>Control Center \"Agent surface loopback check\": one nonce-protected action re-fetches the public llms.txt and MCP endpoint. It can reveal User-Agent-based CDN\/WAF rules, but does not reproduce an external agent's IP, TLS fingerprint or full headers. No credentials are sent, only bounded result metadata is stored, and runs are limited to one per five minutes.<\/li>\n<\/ul>\n\n<h4>1.5.3 - 2026-09-01<\/h4>\n\n<ul>\n<li>New owner-toggled extension tools, outside the cross-runtime contract and\nfail-closed by default: get_sections (a flat outline with byte sizes, then\none 8192-byte section per call with byte-offset pagination, so a large page\nno longer blows an agent's budget or gets truncated mid-answer) and\nget_structured_data (the page's own JSON-LD typed blocks, sanitized and\nsize-bounded; empty means \"no schema\", as a fact, not an error).<\/li>\n<li>The markdown converter now renders HTML tables as GitHub-flavored pipe\ntables instead of flattened text soup.<\/li>\n<\/ul>\n\n<h4>1.5.2 - 2026-09-01<\/h4>\n\n<ul>\n<li>Successful tool results now carry MCP structuredContent (typed JSON; list\nresults wrapped under items) and the in-page bridge returns the object\ninstead of a JSON string. The legacy text part is kept for compatibility.<\/li>\n<li>MCP-Protocol-Version: missing header now falls back to 2025-03-26 as the\nStreamable HTTP spec requires; released revisions are accepted.<\/li>\n<li>Unknown tools no longer default to readOnlyHint true: unregistered means\ntreat-as-writable until declared.<\/li>\n<li>search_site reports an honest positional rank instead of a fake score of 1.<\/li>\n<li>WooCommerce cart\/checkout\/account\/terms pages are excluded from every\nmachine surface automatically, even when the page post type is selected.<\/li>\n<li>New opt-in REST hardening: hide \/wp\/v2\/users enumeration from anonymous\nagents (logged-in requests unaffected).<\/li>\n<li>HTTP Link rel=\"mcp\" discovery header on frontend responses.<\/li>\n<li>Control Center can now purge the private expert-request inbox (the pruning\npromise is finally wired to a button).<\/li>\n<\/ul>\n\n<h4>1.5.1 - 2026-09-01<\/h4>\n\n<ul>\n<li>Product lists (list_content type=product) now carry compact commercial fields\n(slug, price, currency, inStock, image) when get_product is exposed: one call\nreplaces one-per-product round-trips.<\/li>\n<li>get_product images are structured objects {url, width, height, alt} so agents\ncan reason about photos without downloading them.<\/li>\n<li>Machine-readable error codes (invalid_params, not_found, rate_limited,\nnot_configured, inbox_full) in structuredContent on every MCP tool error.<\/li>\n<li>Rate-limited expert submissions return retry_after seconds and a Retry-After\nHTTP header instead of a blind \"try again later\".<\/li>\n<\/ul>\n\n<h4>1.5.0 - 2026-09-01<\/h4>\n\n<ul>\n<li>Feature: Control Center page (Settings &gt; Corsen Context Control) \u2014 one card per surface and tool with exposed \/ needs-config \/ off badges, a what-agents-see preview built from the actually exposed tool list, and one-click audit log purge.<\/li>\n<li>Feature: WordPress Abilities API integration \u2014 on WordPress 6.9+ each enabled tool is registered as an ability sharing the exact MCP input schemas and the single server-side executor; inert on older WordPress.<\/li>\n<li>Feature: opt-in <code>get_product<\/code> extension tool \u2014 live price, sale, stock status\/quantity, images, categories and up to 20 variants via WooCommerce APIs, behind the site's post-type policy and publish\/password checks. Off by default; not part of the cross-runtime manifest contract.<\/li>\n<li>Feature as originally introduced: opt-in <code>request_expert_call<\/code> accepted private owner-side submissions. Since 1.5.12, MCP and WebMCP execution is human-only and every schema-valid call is refused with <code>human_only<\/code> plus a handoff URL before any side effect.<\/li>\n<li>Feature: bounded local audit log \u2014 one row per tool call (name, argument fingerprint, hashed IP, outcome, duration), with a hard 500-row cap. Entries older than 30 days are pruned when WP-Cron runs; the site admin can purge at any time. Raw arguments and raw IPs are never stored.<\/li>\n<li>Security: settings sanitization falls back to the four core tools \u2014 a request that omits the tool selection can never enable extension tools implicitly.<\/li>\n<li>Quality: 116 PHP unit tests (499 assertions) covering the extension gates, throttle, secret rejection, private filing, and manifest parity; WordPress coding standards pass clean.<\/li>\n<\/ul>\n\n<h4>1.4.1 - 2026-08-30<\/h4>\n\n<ul>\n<li>Security: tool inputs now reject wrong types, unknown properties, fractions, and out-of-range values instead of coercing them; the published JSON Schemas carry the same explicit bounds.<\/li>\n<li>Security: the in-page WebMCP bridge rejects invalid or cross-origin endpoints before registration or fetch and handles both synchronous and Promise-based registration failures.<\/li>\n<li>Privacy: removed the experimental declarative form renderer, submission handler, and stored-submission module. Legacy shortcodes render nothing and are removed from public snippets.<\/li>\n<li>Control: saving an explicitly empty Agent Tools selection now keeps all four tools disabled instead of silently restoring them.<\/li>\n<\/ul>\n\n<h4>1.4.0 - not released - 2026-08-30<\/h4>\n\n<ul>\n<li>Experimental: prototyped declarative WebMCP forms and bounded submission storage. This write surface was withdrawn before release and removed in 1.4.1, leaving four read-only public-content tools.<\/li>\n<\/ul>\n\n<h4>1.3.1 - 2026-08-30<\/h4>\n\n<ul>\n<li>Fix: when a browser supplies an AbortSignal to execute(), the WebMCP bridge forwards it so cancellation can abort the in-flight MCP request.<\/li>\n<\/ul>\n\n<h4>1.3.0 - 2026-08-30<\/h4>\n\n<ul>\n<li>Feature: WebMCP support (opt-in) - registers enabled read-only tools through document.modelContext, with an optional Chrome origin-trial token field. The in-page bridge forwards calls to the existing MCP endpoint, sends no credentials, stays same-origin, and refuses to register inside frames.<\/li>\n<li>Feature: Agent Tools setting - choose which tools are advertised and callable over MCP and registered through WebMCP.<\/li>\n<li>Feature: Agent Access panel - the settings page now states at a glance which surfaces are on, which tools and content types agents can see, which paths are hidden, and that agents are read-only.<\/li>\n<li>Quality: WebMCP tool annotations (read-only, untrusted content) are kept in sync with the repository-wide tool manifest by automated parity tests.<\/li>\n<\/ul>\n\n<h4>1.2.1 - 2026-07-21<\/h4>\n\n<ul>\n<li>Security: Enforced the global kill switch across llms.txt, llms-full.txt, MCP routes, discovery tags, and dashboard state.<\/li>\n<li>Security: Safe rendering no longer executes <code>the_content<\/code>, dynamic blocks, or shortcodes by default; full rendering is explicit opt-in and never shared-cacheable.<\/li>\n<li>Security: Added same-origin browser checks, HMAC cache\/rate-limit keys, conservative path normalization, Markdown URL neutralization, and an exposure veto filter.<\/li>\n<li>Security: Disabled llms-full.txt by default and added global item, byte, cache-safety, regeneration-lock, and background-generation controls.<\/li>\n<li>Privacy: Author display names are omitted by default and can be enabled separately.<\/li>\n<li>MCP: Added protocol-version validation, 202 notification responses, GET\/POST transport handling, bounded resources pagination, signed cursors, and prompt-injection trust-boundary notices.<\/li>\n<li>Quality: Added PHP unit\/integration tests and made WordPress coding standards blocking in CI.<\/li>\n<li>Documentation: Replaced unsupported universal-discovery, zero-overhead, page-builder, and full-compliance claims with precise behavior and limitations.<\/li>\n<li>Routing: Keeps <code>\/llms.txt<\/code> and <code>\/llms-full.txt<\/code> free of canonical trailing-slash redirects and refreshes rewrite rules once per plugin version.<\/li>\n<\/ul>\n\n<h4>1.2.0 - 2026-07-13<\/h4>\n\n<ul>\n<li>Security: Rate limiter now uses REMOTE_ADDR by default; forwarding headers (X-Forwarded-For\/X-Real-IP) are only trusted behind a proxy you opt into via CORSEN_CONTEXT_TRUST_PROXY. Closes a spoofable rate-limit bypass.<\/li>\n<li>Security: Rate limiter uses the object cache's atomic INCR when a persistent cache (Redis\/Memcached) is present, preventing burst overshoot.<\/li>\n<li>Security: Rate limiting now runs before authentication, so the API key can't be brute-forced unthrottled.<\/li>\n<li>Security: resources\/read and get_page_content now validate the URI resolves to a same-site, non-excluded, http(s) URL before returning content.<\/li>\n<li>Security: Settings sanitization restricts post types to publicly-registered types.<\/li>\n<li>Performance: MCP tool responses are cached (transients) and invalidated when content changes \u2014 bounds compute on the public endpoint.<\/li>\n<li>Fix: resources\/list preserves query strings in resource URIs (parity with the core library).<\/li>\n<li>Improvement: Configurable enabled tool set via the corsen_context_enabled_tools filter.<\/li>\n<li>Improvement: Loads the plugin text domain so strings are translatable.<\/li>\n<li>Improvement: Uninstall now also clears cached MCP response transients.<\/li>\n<\/ul>\n\n<h4>1.1.0 - 2026-04-12<\/h4>\n\n<ul>\n<li>Security: SSRF protection now fails closed when DNS resolution fails<\/li>\n<li>Security: Fixed PHP ReDoS crash on large HTML payloads (preg_replace null safety)<\/li>\n<li>Security: Fixed rate limiter TTL renewal bug that converted per-minute into per-session limits<\/li>\n<li>Fix: Added max_pages setting to admin UI (was only configurable in code)<\/li>\n<li>Fix: Uninstall now cleans up all rate-limit transients from database<\/li>\n<li>Improvement: Added hourly WP-Cron garbage collector for expired rate-limit transients<\/li>\n<li>Improvement: Better rate limit window tracking with remaining TTL preservation<\/li>\n<\/ul>\n\n<h4>1.0.0 - 2026-04-08<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<li>Read-only MCP-style JSON-RPC endpoint with 4 tools<\/li>\n<li><code>initialize<\/code>, <code>ping<\/code>, <code>notifications\/initialized<\/code> support<\/li>\n<li><code>tools\/list<\/code>, <code>tools\/call<\/code>, <code>resources\/list<\/code>, <code>resources\/read<\/code><\/li>\n<li>llms.txt and llms-full.txt generation with auto-caching<\/li>\n<li>Admin settings page with post type selection and path exclusion<\/li>\n<li>Dashboard widget showing AI context status<\/li>\n<li>Yoast SEO and Rank Math metadata integration<\/li>\n<li>Rate limiting (configurable, default 100 req\/min)<\/li>\n<li>Private-address checks for URL validation helpers<\/li>\n<li>Defensive security headers on MCP responses<\/li>\n<li>Optional API key authentication (timing-safe comparison)<\/li>\n<li>Cache invalidation on post save\/delete<\/li>\n<li><code>&lt;link rel=\"mcp\"&gt;<\/code> link element in HTML head<\/li>\n<li>Clean uninstall (removes all options and transients)<\/li>\n<\/ul>","raw_excerpt":"Owner-controlled AI access to your public content: llms.txt, a read-only MCP endpoint, and opt-in WebMCP tools for agents in the browser.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/301514","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=301514"}],"author":[{"embeddable":true,"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/corsenai"}],"wp:attachment":[{"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=301514"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=301514"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=301514"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=301514"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=301514"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ms.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=301514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}