Counterhand MCP connects your WooCommerce store to AI assistants through the Model Context Protocol (MCP) — with security as the first-class feature. It is free, open source (GPL) and self-hosted: nothing about your store passes through a third-party service.
Home page and documentation: counterhand.app.
Your store gets a clean MCP endpoint at https://yourstore.com/mcp. Assistants connect through a browser consent flow (OAuth 2.1) — no tokens to copy. When an assistant connects, your browser opens a consent screen where you, as a store administrator, choose exactly what it may do and approve.
Every group is a separate switch in Settings, with read and write as separate axes. A fresh install exposes Products, Orders and Reports, read-only — everything else is off until you turn it on, and upgrading never widens what your store exposes.
Tools delegate to WooCommerce’s own REST controllers, so validation, stock handling and HPOS compatibility behave exactly like the standard API. Their input schemas are read from those controllers at runtime rather than copied into this plugin, so a WooCommerce update that adds a field surfaces it automatically, and one that removes a field cannot leave a tool advertising it.
Each tool offers the ten or so fields that matter rather than all hundred WooCommerce declares, which keeps assistants accurate. When one of the rest is needed, describe_woocommerce_fields returns the full list for any tool — and writes accept those extra fields directly.
Visibility is decided by WooCommerce too: before a tool is offered, this plugin runs WooCommerce’s own permission check for that endpoint. A shop manager therefore sees a different set of tools from an administrator, without this plugin keeping a list of who may do what.
Chat with your store, inside WooCommerce. Ask questions in plain language from wp-admin and the assistant looks the answer up with the same tools an outside app would use. On WordPress 7.0 and later it uses the AI model WordPress already manages under Settings Connectors, so this plugin never handles an API key. On older WordPress, connect Claude, ChatGPT, Gemini or a local Ollama model with your own key — the Chat tab tests it before saving, so a wrong key is caught immediately.
Connect AI apps you already use. The Connect AI apps tab shows one URL to paste into Claude, ChatGPT, Claude Code or any other MCP client — one click installs it into Cursor and VS Code. There is no token to create and nothing to copy back: the app identifies itself with its own published address (CIMD), and you approve exactly what it may do on a consent screen in your browser. No local proxy, no Node.js required.
WooCommerce ships an experimental MCP server behind a feature flag, authenticated with REST API keys and covering a handful of product and order abilities. Counterhand adds what a self-hosted store still lacks: OAuth 2.1 browser consent instead of copied keys, the whole WooCommerce and WordPress surface (coupons, customers, reports, shipping, tax, settings, posts and pages), per-connection scopes with one-click revocation, confirmation-gated risky writes, an audit log, and the in-admin chat. The two can run side by side.
Counterhand is free for every store, with no paid tier and no locked features. Development and support are funded by GitHub Sponsors. The source is on GitHub — issues and pull requests are welcome.
The plugin contacts no server of its own, collects no usage data and phones no telemetry home. It makes no outbound request until you ask it to — see the “External services” section below for exactly which services can be contacted, what is sent and when. Nothing is sent to the author of this plugin, ever.
This plugin does not depend on any service of its own. It never contacts the plugin author, and it sends no analytics or telemetry anywhere. Every outbound request below happens only as a direct result of something you do in wp-admin, and most stores will only ever use one of them.
The “Chat” tab lets a store administrator ask questions about the store in plain language. Answering a question means sending it to an AI model, so this is the one feature that transmits store data to a third party. It is used only when you open the Chat tab and send a message; if you never use the chat, no request is ever made to any of these services.
On WordPress 7.0 and later the chat uses the AI model WordPress itself manages under Settings Connectors, so this plugin never handles the API key and the provider is whichever one you configured in WordPress. On earlier WordPress versions, you choose a provider on the Chat tab and supply your own API key.
What is sent, and when: only when an administrator sends a chat message (and on each follow-up step of answering it) the plugin transmits, to the provider you chose: your message text, the earlier messages in that chat conversation, the list of enabled tool definitions (tool names, descriptions and argument schemas), and the results of any tool the model calls to answer you. Those tool results contain your store’s data — for example product, order, customer or report records the model looked up in order to answer. A short system instruction accompanies the request, authenticated with your own API key (or, on WordPress 7.0 and later, by WordPress’s connector, so this plugin never sees the key). Nothing is sent on a schedule or in the background.
There is one other, smaller request: when you save an API key on the Chat tab, the plugin sends a single “ping” message to the provider to check the key works before storing it, so a wrong key is reported immediately. That check contains no store data.
The provider you select determines the destination:
https://api.anthropic.com. Terms of service, privacy policy.https://api.openai.com. Terms of use, privacy policy.https://generativelanguage.googleapis.com. Terms of service, privacy policy.http://localhost:11434 by default). No data leaves your machine and no account or key is needed.Choosing Ollama or a self-hosted custom endpoint means the chat sends no store data to any third party.
When an AI assistant connects to your store, it identifies itself with a Client ID Metadata Document (CIMD) — a URL it publishes, as required by the MCP authorization specification. To show you on the consent screen which app is actually asking for access, the plugin fetches that URL once and caches the result.
What is sent, and when: an ordinary HTTP GET to the URL the connecting app supplied, at the moment someone starts a connection. It carries no store data, no personal data and no credentials — only the request itself. The URL must be HTTPS, and the request goes through WordPress’s own safe HTTP function, so private-network and loopback addresses are refused. The destination is not fixed: it is whichever app you are connecting (for example https://claude.ai/... for Claude or https://chatgpt.com/... for ChatGPT), so the applicable terms are those of the AI app you chose to connect. If the document cannot be fetched or does not match, the connection is refused.
On WordPress 7.0 and later, the Chat tab can install the official “AI Provider for Anthropic”, “AI Provider for OpenAI” or “AI Provider for Google” plugin for you. This happens only when an administrator with permission to install plugins clicks the matching button. WordPress then fetches the plugin from the WordPress.org plugin directory the same way Plugins Add New does, subject to the WordPress.org privacy policy. No store data is sent; the API key for the provider is entered afterwards on WordPress’s own Settings Connectors screen.
The “Connect AI apps” tab reports whether your MCP endpoint is actually reachable and advertising OAuth discovery. To find out, the plugin requests your own site’s URLs (/mcp and /.well-known/oauth-protected-resource) over HTTP.
This is not a third-party service: the request goes to your own domain and no data leaves your server’s control. It runs only while an administrator is viewing that tab.
That tab also shows documentation links for Claude, ChatGPT, Cursor and VS Code, and “add to editor” buttons. These are ordinary links and buttons in your browser — the plugin makes no request to those sites, and nothing is sent unless you click through.