=== Advocate MCP Structured Data === Contributors: cameronjmcewan Tags: schema, structured data, json-ld, localbusiness, seo Requires at least: 6.0 Tested up to: 7.1 Requires PHP: 7.4 Stable tag: 2.5.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Publishes your Advocate business profile as LocalBusiness JSON-LD in your site's head, refreshed automatically. == Description == Search engines and AI assistants read structured data to understand what a business is, where it is, and what it offers. This plugin puts your Advocate business profile into your site's `` as JSON-LD, server-side, so crawlers that do not run JavaScript can read it. You maintain one profile on Advocate. This site follows it — there is nothing to re-enter here when your hours, address, or services change. **Background profile updates.** The profile is fetched in the background, never while a visitor is waiting for a page. If Advocate is unreachable and a profile was downloaded successfully before, the plugin uses it for up to 24 hours from its last validated download. It then pauses structured data until a valid download succeeds. Unknown-age caches from older versions also pause until refreshed. Your site keeps working. == External services == This plugin connects to Advocate (https://app.advocatemcp.com), a service run by Advocate MCP LLC. An Advocate account and a published business profile are required to publish structured data. Advocate offers paid service plans; review current plans at https://app.advocatemcp.com/pricing before subscribing. Installing or connecting this plugin does not subscribe you or charge you. **Account connection.** Only after an administrator clicks Connect Advocate, the browser opens Advocate with this website's public address, its WordPress admin return address, and a random temporary state value. You sign in or create an account, choose your business, and confirm. WordPress receives only the public business identifier and website, never your Advocate password or account token. A new business stays private until you complete onboarding and choose to publish. HTTPS is required, and the public website and WordPress admin must have the same origin (their paths may differ). Manual setup remains available. The following profile and page-view requests require a configured Business ID. Directory packages make no plugin-initiated Advocate request before connection or configuration. Self-hosted ZIP packages additionally check the public update manifest described below, independently of configuration. **1. Fetching your profile.** On a background refresh, about hourly, the plugin requests `https://app.advocatemcp.com/api/biz//jsonld`. Only your Business ID is sent. The reply is the JSON-LD this plugin prints. It is data, not code — nothing is downloaded and run. This never happens while a visitor is waiting for a page. **2. Reporting page views.** After a page has finished sending, the plugin posts to `https://app.advocatemcp.com/api/edge/plugin-beacon` to report that one page view happened. It sends your Business ID, your site's hostname, the path of the page viewed with the query string removed, the visitor's browser or crawler user-agent string, the installed plugin version, and a SHA-256 hash of the visitor's IP address. A hash is not a guarantee of anonymity. The raw IP address is never sent. The request does not block, so it cannot delay or break a page. This is what lets your Advocate dashboard show visits and AI-crawler reads on your own site. Directory packages do not load a remote page script. The plugin also adds a few tags to your pages' `` (and a `Link` response header) naming Advocate's MCP endpoint for your business, and sends requests for your site's `/.well-known/mcp.json` to Advocate's description of it, only when your site would otherwise answer that address with a "not found" page. These are data; nothing is sent anywhere. To stop profile fetching and page-view reporting, clear the Business ID or deactivate the plugin. Turning publishing off also stops scheduled page-view reporting. Page/CDN cache hits do not run PHP and are not measured by this plugin. **Self-hosted distribution updates.** Direct ZIP packages contain an updater that periodically requests `https://app.advocatemcp.com/wordpress-plugin/advocatemcp-structured-data.json` with the plugin version in its user-agent, even before a Business ID is set. A copy installed before 2.5.0 lives in the `advocate-agent` folder and requests `https://app.advocatemcp.com/wordpress-plugin/advocate-agent.json` instead; both addresses offer this same release. The manifest can offer a plugin ZIP from the same service. Directory packages omit this updater and use WordPress.org's standard plugin update mechanism. Advocate's terms of service: https://app.advocatemcp.com/terms Advocate's privacy policy: https://app.advocatemcp.com/privacy == Installation == 1. Install and activate Advocate MCP Structured Data. If using a directory release, use Plugins → Add New. If using a downloaded ZIP, use Upload Plugin. 2. Open Settings → Advocate and choose **Connect Advocate**. Sign in or create your Advocate account, choose the business, and confirm the website. 3. Complete onboarding in Advocate if your business is new. Publication and any subscription are separate choices; connecting the plugin does not publish. 4. For a published profile, open WordPress setup in Advocate and select **Check connection** to observe whether the latest profile is on your site. A download prepared in your Advocate account can still configure a matching website automatically. Existing settings are kept, including disabled publishing. To use manual setup, enter the Business ID (the final part of the Advocate profile URL) in Settings → Advocate. Automatic connection preserves an existing disabled publishing setting; enable it explicitly when you are ready. A connection attempt expires after two hours. If it expires, your WordPress account/site changes, or somebody edits these plugin settings while you are away, start Connect Advocate again. Existing settings are kept on a refused callback. The first profile update runs in the background; Refresh now retries it. == Frequently Asked Questions == = Where can I get help? = Use the contact form at https://app.advocatemcp.com/contact or email support@advocatemcp.com. = I already use Yoast or Rank Math. Should I use both? = Probably not both for the same business. Two descriptions of one business on one page can confuse crawlers. The settings page warns you when it detects another SEO plugin — ask Advocate which one to keep. = How quickly does a profile edit reach my site? = The plugin checks for updates about once an hour. Choose Refresh now to check sooner. Cached pages may need to be cleared before they show the update. Automatic checks run through WordPress scheduled tasks (WP-Cron), which only run when your site is visited or when your host triggers them, so there is no fixed delivery deadline. "Refresh now" checks immediately; a successful check updates this plugin's own copy of the profile, not caches in front of your site. = What happens if Advocate is down? = The saved profile can appear on newly generated pages for up to 24 hours after its last validated download. Failed retries do not extend that time. After that, publishing pauses until a valid download succeeds. The settings page shows the pause and offers Refresh now. This uses the WordPress server clock; keep it synchronized. It does not guarantee a deadline across clock changes. Page/CDN caches may still contain older HTML and must be cleared separately. This is an outage-age limit, not an authenticated remote withdrawal signal. Updating the downloadable ZIP does not update existing installed copies; replace the installed plugin through your normal WordPress update procedure. = Does this support WordPress multisite? = Activate and configure Advocate separately on each site. New network activation is refused, and one business is never configured for all sites. Public website path and nondefault port must match as well as hostname. Deactivation clears that site's refresh tasks and cached profile while preserving its settings; reactivation needs a fresh download. Uninstall removes plugin settings too. When two copies of the plugin are installed (see the 2.5.0 changelog), the notice appears on each site's own Plugins screen, not on the network Plugins screen. A network-wide delete of the earlier copy restores settings only when this copy is loaded in that Network Admin request, that is, active on the main site; if it is active only on sub-sites, nothing is saved anywhere. Legacy network deactivation cleans the current network, while uninstall checks all networks because plugin files are shared. Automatic cleanup is limited to 100 sites. A larger scope is refused before any site is changed. A database or cache failure stops cleanup with an error; resolve it and retry. Completed sites may already be cleaned. Neither operation purges existing page/CDN HTML. = How does an administrator remove Advocate from more than 100 sites? = Use a maintenance window and a verified backup. Stop incoming PHP/cron work and drain existing workers first; older plugin code does not honor the new inactive marker. Inventory every site across every network. Use WP-CLI with `--skip-plugins=advocatemcp-structured-data` to deactivate the plugin on every network and any separately active site without loading its bounded automatic hooks. Keep the plugin files in place until every site's cleanup is verified. For each site URL in that inventory, run the following with the current source installed (a copy installed before 2.5.0 uses the `advocate-agent` folder and main file name in both places). Replace the example URL. This reuses the plugin's per-site cleanup, then removes settings only after that cleanup succeeds. Stop on any error: wp --url='https://example.com/site/' --skip-plugins=advocatemcp-structured-data eval ' require WP_PLUGIN_DIR . "/advocatemcp-structured-data/advocatemcp-structured-data.php"; advocate_deactivate_site(); $missing = new stdClass(); foreach ( [ "advocate_agent_settings", "advocate_setup_import", "advocate_setup_notice", "advocate_connect_attempt", "advocate_lifecycle" ] as $key ) { delete_option( $key ); if ( get_option( $key, $missing ) !== $missing ) { WP_CLI::error( "Cleanup failed for " . $key . "; resolve storage errors and retry." ); } } WP_CLI::success( "Advocate data and refresh tasks cleared for this site." );' Retain a successful receipt for every site and verify that no Advocate refresh task or plugin data remains. Only then remove the shared plugin directory and clear page/CDN caches. A site-level Delete button does not bypass the global 100-site uninstall preflight. This operator procedure still requires a staging rehearsal for your WordPress/WP-CLI and cache configuration. == Changelog == = 2.5.0 = * Renamed to Advocate MCP Structured Data (slug `advocatemcp-structured-data`) for the WordPress.org plugin directory. A copy that updates in place keeps its settings, cached profile and scheduled refreshes unchanged. Switching from the earlier `advocate-agent` folder to this one by deactivating the old copy clears its cached profile and refresh schedule, as any deactivation does; this copy downloads the profile again within a minute of activation. * Values read from the request (the visitor's user agent, address and path, and the account connection callback's method and query) pass through WordPress sanitizers before use. Translations load through WordPress itself. * A site holding both the earlier `advocate-agent` folder and this one can activate only one; the active copy says so on the Plugins screen. Switch in this order: deactivate the earlier copy, activate this one, and only then delete the earlier copy — while this copy is active it puts back anything the earlier copy's uninstall removes. Deleting the earlier copy before this one is active removes the settings. Deleting this copy while the earlier one is installed leaves the settings for it. = 2.4.0 = * Publishes a per-business pointer to Advocate's MCP server alongside the structured data: ``/`` discovery tags, a schema.org WebAPI block, and a `Link` response header. The render path still performs no I/O. * Directory packages do not load a remote page script. * `/.well-known/mcp.json` on this site redirects to Advocate's manifest for this business, only when nothing else on the site answers that address. = 2.3.0 = * Connect an Advocate account without copying a Business ID; preserve disabled publishing and refuse stale, expired, wrong-user or wrong-site callbacks. * Consume each connection and apply settings together; replay cannot overwrite later local settings. Keep new business profiles private through onboarding. * Prepare an explicit directory package without the self-hosted update channel or business-specific setup data; preserve direct-distribution compatibility. * Describe account connection, plugin-version reporting, service plans and update requests accurately. Compatibility metadata reflects tested versions only. = 2.2.2 = * Self-hosted update channel: the plugin now carries an `Update URI` header and checks Advocate's version manifest for new releases, so WordPress offers updates without a WordPress.org listing. Update packages are requested only from app.advocatemcp.com over HTTPS. * The traffic beacon reports the installed plugin version so Advocate can show which version each site runs. = 2.2.1 = * Pause newly generated structured data after 24 hours without a validated profile download, including unknown-age legacy caches; show the pause in settings. Failed refreshes cannot renew the deadline. * Validate the public site path and port on downloaded and cached profiles, including every supplied identity anchor. * Refuse new network activation, bound legacy multisite cleanup, clear every refresh event and fence late refresh workers across deactivation/reactivation. * Preserve cleanup retry state and report storage failures before uninstall can remove the inactive marker. Page/CDN cache removal remains an operator step. = 2.2.0 = * Downloads prepared in Advocate can configure the business automatically on the matching website. Existing business settings and disabled publishing are preserved. Generic downloads still support manual setup. = 2.1.0 = * After a page has been sent, the plugin now tells Advocate one page view happened (which page, which browser or crawler), so your Advocate dashboard can show visits and AI-crawler reads on your own site. The visitor's IP address never leaves your server — only a one-way hash is sent. Nothing about this waits on Advocate or can slow a visitor down. = 2.0.0 = * The profile is now fetched in the background. Earlier versions could make a visitor wait up to five seconds when the cache was cold. * Failed fetches are remembered briefly instead of retried on every page view. * The block is no longer added to 404, search, or feed pages. * Warns when another SEO plugin is already publishing business schema. * Refuses to publish a profile that is anchored to a domain other than this one. * The settings page reports what was last published and when. * Setup is one field. The Agent Query URL and Business Name fields are gone. * Removed `/.well-known/mcp.json`. It advertised endpoints that no longer exist. = 1.1.0 = * Structured data injection. = 1.0.0 = * Initial release.