WooCommerce MCP open source: read-only store access for AI agents
On WooCommerce-to-ERP projects, the same question keeps showing up in kickoff calls: can the AI just check the store? The honest answer is yes - if it cannot break anything. That constraint is why we shipped woocommerce-mcp as open source: a small Model Context Protocol (MCP) server that answers live questions about products, stock, orders, sales, and posts over the official REST APIs, with no writes and no plugin installed on the store.
This article is the release and operations guide for the published package. If you need to design a custom server from scratch (including mutating tools or Workers deployment), use the companion guide Building an MCP server for WooCommerce. For the commercial programme, see MCP server development and WooCommerce ERP integration.
TL;DR
- Package:
@wppoland/woocommerce-mcpon npm (CLI binary still namedwoocommerce-mcp). - Registry:
io.github.wppoland/woocommerce-mcpin the official MCP Registry. - Five read-only tools over WooCommerce / WordPress REST - Read keys only.
- No store-side plugin. MIT, TypeScript, Node 18+.
- Use this when agents need facts from the catalogue and orders; build custom MCP when you need writes or ERP-specific tools.
Why we shipped a read-only MCP server
MCP gives an LLM host (Claude Desktop, Cursor, a custom agent) a typed tools/list surface instead of forcing the model to invent /wp-json/wc/v3/ paths. That is useful. It is also dangerous if every tool can mutate inventory, refunds, or customer data.
On ERP sync work we see two failure modes more often than clever prompt failures:
- Overselling during Black Friday because a write path raced a warehouse feed.
- Accidental status changes when an agent “helpfully” marked orders complete while debugging.
Read-only MCP does not fix bad ERP design. It removes one class of accidental writes from the agent plane. The store remains the system of record through WooCommerce REST. The agent only asks.
We documented the protocol decision in MCP vs REST: when each wins and the auth surface in MCP authentication patterns. This release is the concrete binary you can install today.
What shipped (July 2026)
| Surface | URL / identifier |
|---|---|
| npm | https://www.npmjs.com/package/@wppoland/woocommerce-mcp |
| GitHub | https://github.com/wppoland/woocommerce-mcp |
| MCP Registry | io.github.wppoland/woocommerce-mcp |
| DEV write-up | https://dev.to/wppolandcom/a-read-only-mcp-server-for-woocommerce-what-ai-agents-actually-need-from-a-store-3fk6 |
| Product Hunt | https://www.producthunt.com/products/woocommerce-mcp |
| Show HN | https://news.ycombinator.com/item?id=48815903 |
Version 0.1.1 is the install target. Version 0.1.0 briefly existed as a failed registry stub - a conflicting legacy _auth line in local ~/.npmrc broke that publish. Ignore 0.1.0.
Why the npm name is @wppoland/woocommerce-mcp
The bare name woocommerce-mcp is locked on npm (E403) after another party unpublished it. We publish as @wppoland/woocommerce-mcp. Use that name for npm install / npx. The bin field in package.json still exposes the woocommerce-mcp command, so Claude Desktop and Cursor configs keep the same binary name.
The mcpName in package.json is io.github.wppoland/woocommerce-mcp. That string must match the MCP Registry server.json name field so ownership verification succeeds when you publish with the official mcp-publisher CLI.
Tool surface
| Tool | Purpose | WooCommerce keys |
|---|---|---|
list_products | Search / list products (name, SKU, price, stock, permalink) | yes |
get_product | Full product by id | yes |
list_orders | Recent orders, optional status filter | yes |
sales_report | Totals for week / month / last_month / year | yes |
search_posts | Published posts via public WordPress REST | no |
Everything validates at the MCP boundary and then calls REST. There is no path in this package that creates products, updates stock, refunds orders, or installs plugins.
Questions these tools actually answer
- Which SKUs are at zero stock before a campaign?
- What did we sell last month in net terms the store already reports?
- What were the last twenty processing orders?
- Is the store reachable with the keys we issued?
Those are the questions that appear on ERP integration stand-ups. They are also the questions that do not require write access.
Install and configure
Prerequisites
- Node.js 18 or newer
- A WooCommerce store on HTTPS
- Ability to create REST API keys with Read permission
Install
npm install -g @wppoland/woocommerce-mcp
# or one-shot:
npx @wppoland/woocommerce-mcp
From source:
git clone https://github.com/wppoland/woocommerce-mcp.git
cd woocommerce-mcp
npm install
npm run build
Environment variables
| Variable | Required | Example |
|---|---|---|
WP_URL | yes | https://shop.example.com |
WC_CONSUMER_KEY | for Woo tools | ck_… |
WC_CONSUMER_SECRET | for Woo tools | cs_… |
Create keys under WooCommerce → Settings → Advanced → REST API → Add key. Permission: Read. If someone hands you Read/Write “just in case”, refuse. The package does not need write scopes, and holding unused write scopes is an incident waiting for a compromised laptop.
search_posts works against the public WordPress REST API without Woo keys. That is useful for content agents; it is still not a reason to expose admin cookies to the MCP host.
Claude Desktop / Cursor sketch
Register a stdio server that runs the binary with the three env vars. Exact JSON shapes vary by client version; the invariant is: stdio, env injected by the host, no secrets in the chat transcript.
After connect, ask something falsifiable: “What is the stock for SKU X?” If the agent invents a number without a tool call, your client is not actually wired. If it calls list_products or get_product and returns the store value, you are done for the smoke test.
Example Claude Desktop fragment
Client config formats change; treat this as a shape, not a forever contract:
{
"mcpServers": {
"woocommerce-mcp": {
"command": "woocommerce-mcp",
"env": {
"WP_URL": "https://shop.example.com",
"WC_CONSUMER_KEY": "ck_replace_me",
"WC_CONSUMER_SECRET": "cs_replace_me"
}
}
}
}
Prefer a full path to the binary from npm root -g if your shell PATH inside the desktop app is thinner than your terminal PATH. Cursor and other hosts use similar stdio + env patterns.
Troubleshooting installs
| Symptom | Likely cause | Fix |
|---|---|---|
E403 publishing bare name | Name locked after third-party unpublish | Use @wppoland/woocommerce-mcp |
| Agent answers without tool calls | Server not registered / wrong command | Check client MCP panel; restart host |
| 401 from Woo REST | Wrong keys or HTTP URL | Reissue Read keys; force HTTPS |
| Empty product list | Key for wrong site / staging | Confirm WP_URL matches key site |
| Registry publish 422 on description | Description > 100 characters | Shorten server.json description |
If npm view @wppoland/woocommerce-mcp version returns 404 while npm access still lists the package, you are in the broken-stub state we hit on 0.1.0. Bump the version, remove legacy registry.npmjs.org/:_auth from ~/.npmrc if present, and publish again. Do not tell merchants to install a version you cannot npm pack.
Security model (plain language)
- Keys stay on the MCP host, not in the store as a plugin and not in the model weights.
- Read permission only at the WooCommerce key.
- HTTPS only for
WP_URL. - Treat the MCP client machine as production if it holds live keys - same bar as a CI secret store.
- Rotate keys when a laptop leaves the company or a contractor engagement ends.
MCP does not magically solve auth. Our longer treatment is MCP authentication patterns. For this package, the conservative default is local stdio with Read keys, not a public HTTP MCP endpoint on the open internet.
Threat notes that show up in real reviews
- Laptop theft: Read keys leak catalogue and order metadata. That is still GDPR-relevant. Encrypt disk, use short-lived keys for demos, revoke on offboarding.
- Prompt injection via product descriptions: A malicious product title will not make this package write, but it can steer the model’s speech. Keep untrusted catalogue copy out of high-stakes automation without a human in the loop.
- Confused deputy via shared MCP hosts: One Claude Desktop profile with keys for store A and store B is an accident waiting to happen. Separate profiles or separate machines.
- Log leakage: Some hosts log tool arguments. Assume SKUs and order ids will appear in logs; configure retention accordingly.
None of those are reasons to avoid MCP. They are reasons to treat the host like production.
Where this fits ERP and AI programmes
WPPoland’s nearshore work often wires WooCommerce to wholesaler APIs and ERPs. Agents enter that stack when operations teams want natural-language answers without opening wp-admin. Read-only MCP is the first safe slice:
- Pre-sync checks: “Are we already out of stock on the campaign SKUs?”
- Post-sync audits: “Do yesterday’s orders look like the ERP invoice count?”
- Content ops: “Which posts mention the new collection?” via
search_posts
When you need agents to propose orders or draft refunds, you leave this package and build a custom server with explicit mutating tools, idempotency keys, and human approval gates. That path is the build guide plus typed catalogue tools with Zod.
For stores already drowning in plugin sprawl or AI-built theme debt, fix Core Web Vitals and inventory truth before you add agents. MCP will not rescue a TTFB of 1.8s or a catalogue that disagrees with the warehouse.
How this differs from hosted WordPress MCP experiments
WordPress.com and related ecosystems have been exploring MCP surfaces for managed hosting. Those programmes are valuable, and they are not the same artefact as a self-hosted stdio server you point at your WooCommerce REST keys. Self-hosted MCP keeps credentials and traffic on infrastructure you choose. Hosted MCP keeps convenience on the host’s terms. Pick deliberately; do not assume feature parity.
Glama and similar MCP directories may index the GitHub repo or registry entry. Treat third-party directories as discovery, not as a security boundary. The source of truth for install remains npm + GitHub + the official MCP Registry name.
Comparison: open-source package vs custom MCP
| Need | @wppoland/woocommerce-mcp | Custom MCP server |
|---|---|---|
| Product / order / sales reads | Yes | Yes |
| Blog search | Yes | Optional |
| Writes (refunds, stock edits) | No | You design them |
| Store plugin required | No | Usually no |
| Cloudflare Workers edge deploy | Not this package | Common pattern in our builds |
| ERP-specific tools | No | Yes |
| Official registry listing | Yes (io.github.wppoland/woocommerce-mcp) | You publish your own |
Publishing notes for maintainers
If you fork or publish your own MCP server:
- Put
mcpNameinpackage.jsonmatching the registry namespace (for GitHub auth:io.github.<org>/<name>). - Keep
server.jsondescriptionat 100 characters or fewer - the official registry rejects longer strings with HTTP 422. - Use the
mcp-publisherbinary from modelcontextprotocol/registry releases, not a random npm package named publisher. - Prefer npm names under an
@scopeyou control; bare names can stay permanently locked after unpublish.
We learned the description limit the hard way during the first registry publish attempt. Validation with mcp-publisher validate before publish saves a round trip.
Operational checklist
-
@wppoland/[email protected](or newer) installed - WooCommerce key is Read-only
-
WP_URLis HTTPS and matches the store the keys belong to - Client uses stdio (or another transport you deliberately hardened)
- Smoke test uses a real SKU and a real date range
- Secrets are not pasted into tickets or chat logs
- Team knows this package cannot refund or restock - escalate to humans / ERP for writes
Internal cluster links
- Build path: Building an MCP server for WooCommerce
- Protocol choice: MCP vs REST
- Auth: MCP authentication patterns
- Typed tools: Writing typed catalogue tools with Zod for MCP
- Migration: Migrating an existing WordPress API to MCP
- Service: MCP server development
- Commerce: WooCommerce ERP integration
Practitioner notes from client work
On a mid-size EU fashion WooCommerce store (roughly thirty thousand SKUs, B2B price lists in a separate ERP), the first agent demo that stuck with the merchant was not a chatbot on the storefront. It was Claude Desktop answering “which campaign SKUs are already at zero?” before the email blast. That demo only worked because the MCP server could not adjust stock when the model hallucinated a “fix”.
On a Nordic wholesaler sync, the dangerous request was “mark these as completed if they look paid.” That is exactly the class of tool this open-source package refuses to offer. The agent can list processing orders; a human or a dedicated ERP job completes them.
If your store still uses application passwords with full capabilities for “temporary scripts”, rotate those before you point any MCP host at production. Read keys for this server are cheap to issue and cheap to revoke.
What we will not do in v0.x
- No write tools in the open-source default branch.
- No mandatory store plugin.
- No claim that MCP replaces WooCommerce REST for partner integrations.
- No specific pricing for implementation work - projects are individual quotes through MCP server development.
Feature requests that fit the read-only mandate (refunds summary, coupon status, customer lookup without PII dumps) are open conversation on GitHub. Feature requests that are “just add update_product” will be closed with a pointer to the custom-build guide.
Measuring whether the agent path is worth it
Before you expand beyond read-only tools, measure three things for two weeks:
- How often humans open wp-admin only to answer a stock or order question. If that count is near zero, MCP is a novelty. If it is daily, read tools pay for themselves in attention.
- How often those answers disagree with the ERP. MCP will surface WooCommerce truth, not warehouse truth. If those diverge, fix sync first (WooCommerce ERP integration).
- How often someone asks the agent to change state. That frequency is your roadmap signal for a custom mutating server - not a reason to weaken this package.
GEO and AEO programmes care about citable, structured answers. An MCP tool call that returns stock is more reliable than a model guessing from a scraped HTML page. Pair the agent path with on-site entities and FAQ schema on your commercial pages so public AI systems and private agents are not inventing different product stories.
If you already run a content cluster around MCP on wppoland.com, link this release post from the build guide and from the MCP service pillar so crawlers and citation engines see one coherent story: how to build, when to choose MCP over REST, and which open-source binary to install when five read tools are enough.
Conclusion
@wppoland/woocommerce-mcp is the smallest useful MCP surface we trust in front of a live WooCommerce store: five read tools, official REST underneath, MIT, published to npm and the MCP Registry. Install it when agents need store facts. Build a custom server when agents need store actions.
Start here: https://www.npmjs.com/package/@wppoland/woocommerce-mcp - then wire Read keys, run a smoke question, and keep writes out of the agent path until the programme is ready for them.







