MCP Server for Magento 2 — module reference
MCP Server gives AI agents a real API to your store, so they do not have to scrape it. It speaks the Model Context Protocol at one endpoint, /mcp. Claude, ChatGPT-based agents, Gemini and custom shopping assistants get live answers: current prices, real stock and canonical URLs.
Read-only by default. The four built-in tools show what an anonymous shopper already sees, and nothing more. Tools that change data come from separate modules you install on purpose: MCP Checkout for guest checkout, and MCP Reorder for signed-in buyers.
The server supports MCP 2026-07-28 (stateless, no handshake) and every older revision back to 2024-11-05, on the same endpoint.
Tools
| Tool | Arguments | Returns |
|---|---|---|
search_products | query, category_id?, price_min?, price_max?, page?, page_size?, sort? | Items with SKU, name, price, stock, URL, image and short description, plus a total count |
get_product | sku | Full card. For configurable products: each variant with its options, price and stock |
list_categories | parent_id?, depth? (up to 4) | Active category tree with URLs and product counts |
get_store_info | — | Store name, currency, locale, ships-to countries, links to llms.txt and /.well-known/ucp |
Prices use the customer group you choose (default NOT LOGGED IN). Disabled products, products of another website and hidden products look exactly like products that do not exist.
The server also offers MCP prompts — ready-made requests a client can show the shopper: Browse {store}, Find something in {store}, About {store}, and Buy from {store} (only when checkout is installed). A prompt is an offer. The shopper picks it. The model will not start one on its own.
Requirements
| Magento | 2.4.6+ (Open Source, Mage-OS or Adobe Commerce) — magento/framework >=103.0.6 <104 |
|---|---|
| PHP | 8.1 – 8.5 — ~8.1.0||~8.2.0||~8.3.0||~8.4.0||~8.5.0 |
No Redis, no Node sidecar and no outside service is needed.
Installation
composer require angeo/module-mcp-server
bin/magento module:enable Angeo_McpServer
bin/magento setup:upgrade
bin/magento setup:di:compile # production mode only
bin/magento cache:flush
The server is on and read-only after install. Check it:
bin/magento angeo:mcp:tools
bin/magento angeo:mcp:tools search_products -a '{"query":"mug","page_size":3}'
curl -s https://your-store.example/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
| Command | What it does |
|---|---|
bin/magento angeo:mcp:tools | List MCP tools, or call one with JSON arguments |
To test a tool as a signed-in customer from the shell (no token needed): bin/magento angeo:mcp:tools list_my_orders -c buyer@example.com.
Do not cache /mcp
/mcp must never come from Varnish, LiteSpeed or full-page cache. A cached JSON-RPC answer is always wrong. The module sends Cache-Control: no-store, but caches that ignore backend headers need a rule.
Varnish — in vcl_recv, before the built-in logic:
if (req.url ~ "^/mcp($|/|\?)") {
return (pass);
}
LiteSpeed — in .htaccess:
<IfModule LiteSpeed>
RewriteRule ^mcp(/.*)?$ - [E=Cache-Control:no-cache]
</IfModule>
Getting agents to pick your store
A model decides between your tools and its own product search before it calls anything. It looks at three things only: the instructions sent on connect, the tool names, and the tool descriptions. The defaults handle all three:
| Setting | Default | What it does |
|---|---|---|
agent/store_label | store view name | The name a model matches “check Acme” against |
agent/instructions | empty — generated | Built from the store name and the tools that are installed |
agent/anchor_descriptions | Yes | Adds “Applies to the {store} store only.” to each tool |
agent/tool_titles | Yes | Adds titles such as “Search Acme products” for the permission screen |
Set the store label to the name customers know you by. “Default Store View” gives a model nothing to match. “Acme Outdoor” does.
Be realistic: a cold question such as “find me a grey backpack”, with no shop named, often goes to a general product search. Questions that reliably reach your connector are about cart state, about the merchant (returns, shipping countries), or follow-ups after a first successful call. A good demo starts with list_categories or get_store_info.
Authentication
Public read-only mode is the default. To require a token for everything:
- Go to System → Extensions → Integrations → Add New Integration. Give it only the MCP Server Agent Access resource.
- Activate it and copy the Access Token.
- Set Require Bearer Token to Yes.
- Agents send
Authorization: Bearer <token>.
Revoking the integration cuts access at once. Only an Integration token passes this check. Customer and admin tokens do not.
Signed-in customers (2.3.0)
Some tools act for one shopper — their orders, their cart. Turn on Security → Accept Customer Tokens.
| Setup | Headers |
|---|---|
| Production: a connector acts for the shopper | Authorization: Bearer <integration token> and X-Customer-Token: amc_… (an MCP-only token from account linking) |
| Testing only: Claude Code or MCP Inspector talks to the store directly | Authorization: Bearer <customer token>, with Accept Storefront Customer Tokens (testing) on |
An ordinary Magento customer token can change addresses and read all orders through REST and GraphQL. The MCP specification says a server must not accept tokens that were not issued for it. An amc_ token works only at /mcp, only next to the Integration token of its connector, and stops when the shopper disconnects. A token that does not verify gives HTTP 401. It never falls back to anonymous.
Account linking (2.4.0)
Magento has no refresh token for customers, and customer tokens last one hour. Account linking solves this without the connector ever seeing a password:
- The connector sends the shopper’s browser to
GET /mcp/linkwithredirect_uri,stateand a PKCEcode_challenge(S256). - The shopper signs in on your store and approves on a page that names the connector.
- The store redirects back with a one-time code (valid two minutes, PKCE only).
- The connector calls
POST /mcp/link/exchangeand gets a long-lived grant and a firstamc_token. - When the token expires, it calls
POST /mcp/link/tokenwith the grant.
| Endpoint | Body | Answer |
|---|---|---|
POST /mcp/link/exchange | code, code_verifier, redirect_uri | grant, customer_token, expires_in, customer_label |
POST /mcp/link/token | grant | customer_token, expires_in |
POST /mcp/link/revoke | grant | {"ok": true} |
All three need the Integration token. Only SHA-256 hashes of codes and grants are stored. A grant works only with the Integration that redeemed it. redirect_uri must match your list exactly. Shoppers can see and disconnect assistants under My Account → AI assistants. The approval page cannot be framed.
Set it up under Account Linking: turn it on, add the connector’s redirect URI (for mcp.angeo.dev: https://mcp.angeo.dev/authorize/linked) and the name shoppers should see.
Browser origins
Requests with an unknown Origin header get HTTP 403. This protects against DNS rebinding. Your store’s own URLs are always allowed. AI platforms connect server to server, without Origin. To use a browser tool such as MCP Inspector, add its origin (for example http://localhost:6274) under Allowed Browser Origins.
Protocol versions
| Revision | How the version is chosen |
|---|---|
| 2026-07-28 | No handshake. Each request names its version in _meta and in the MCP-Protocol-Version header. server/discover returns versions, capabilities and instructions. |
| 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05 | initialize handshake |
For 2026-07-28 the headers must match the body. A mismatch gives HTTP 400 with error -32020. Missing headers are also refused while Strict MCP Headers is on (the default). Turn it off only for a proxy that drops them. An unknown version gives 400 with -32022. GET and DELETE on /mcp give 405. Older clients see no change.
Connecting an agent
For Claude Desktop or Claude Code, add the endpoint to .mcp.json:
{
"mcpServers": {
"my-store": { "type": "http", "url": "https://your-store.example/mcp" }
}
}
The claude.ai custom connector screen uses OAuth, not static tokens. For a token-protected store, put an OAuth layer in front of /mcp (such as mcp.angeo.dev), or test with Claude Code or MCP Inspector. Step-by-step connection guides for Claude, ChatGPT and Perplexity are in the MCP Checkout user guide.
The “Add to Claude” button
A Magento widget lets a shopper connect your store to Claude in one click. Place it from Content → Widgets. First set Claude Connector → Connector URL to the HTTPS address from your MCP provider. This is not your own /mcp path, which has no OAuth. Without a valid URL the button renders nothing.
Configuration reference
All settings are under Stores → Configuration → Angeo → MCP Server. The table shows each field, its config path (for bin/magento config:set) and its default value.
General (3)
| Setting | Config path | Default |
|---|---|---|
| Enable MCP Server | angeo_mcp/general/enabled | Yes |
| Require Bearer Token | angeo_mcp/general/require_token | No |
| Log Agent Calls | angeo_mcp/general/log_calls | Yes |
Claude Connector (2)
| Setting | Config path | Default |
|---|---|---|
| Connector URL | angeo_mcp/connector/url | — |
| Connector Name | angeo_mcp/connector/label | — |
Agent presentation (4)
| Setting | Config path | Default |
|---|---|---|
| Store name for agents | angeo_mcp/agent/store_label | — |
| Agent instructions (override) | angeo_mcp/agent/instructions | — |
| Add store name to tool descriptions | angeo_mcp/agent/anchor_descriptions | Yes |
| Generate tool titles | angeo_mcp/agent/tool_titles | Yes |
Catalog (3)
| Setting | Config path | Default |
|---|---|---|
| Price Customer Group | angeo_mcp/catalog/customer_group_id | 0 |
| Default Page Size | angeo_mcp/catalog/default_page_size | 10 |
| Max Page Size | angeo_mcp/catalog/max_page_size | 50 |
Security (4)
| Setting | Config path | Default |
|---|---|---|
| Rate Limit (requests/minute) | angeo_mcp/security/rate_limit_per_minute | 60 |
| Accept Customer Tokens | angeo_mcp/security/customer_auth | No |
| Accept Storefront Customer Tokens (testing) | angeo_mcp/security/storefront_customer_tokens | No |
| Allowed Browser Origins | angeo_mcp/security/allowed_origins | — |
Account Linking (4)
| Setting | Config path | Default |
|---|---|---|
| Enable Account Linking | angeo_mcp/linking/enabled | No |
| Connector Redirect URIs | angeo_mcp/linking/redirect_uris | — |
| Connector Name Shown to Shoppers | angeo_mcp/linking/client_label | — |
| MCP Token Lifetime (minutes) | angeo_mcp/linking/token_lifetime | 60 |
Protocol (2)
| Setting | Config path | Default |
|---|---|---|
| Strict MCP Headers | angeo_mcp/protocol/strict_headers | Yes |
| Tool List Cache Hint (seconds) | angeo_mcp/protocol/list_ttl_seconds | 300 |
The call log (var/log/angeo_mcp_agent.jsonl) records time, tool, user agent, duration, caller kind and protocol era. Never payloads, ids or tokens.
Cron and stored data
| Job | Cron group | Schedule |
|---|---|---|
angeo_mcp_purge_link_codes | default | 17 * * * * |
| Table | What it holds | Columns |
|---|---|---|
angeo_mcp_link_code | Angeo MCP: one-time account-link codes | code_hash, customer_id, website_id, redirect_uri, code_challenge, expires_at, used |
angeo_mcp_customer_grant | Angeo MCP: connectors a customer allowed to act for them | grant_id, customer_id, website_id, consumer_id, client_label, secret_hash, created_at, last_used_at, revoked_at |
angeo_mcp_access_token | Angeo MCP: short-lived MCP-only customer tokens | token_hash, grant_id, expires_at |
Adding your own tools
Implement Angeo\McpServer\Api\ToolInterface and add it to the registry:
<type name="Angeo\McpServer\Model\Tool\ToolRegistry">
<arguments>
<argument name="tools" xsi:type="array">
<item name="my_tool" xsi:type="object">Vendor\Module\Tool\MyTool</item>
</argument>
</arguments>
</type>
Prompts work the same way, through Angeo\McpServer\Api\PromptInterface and PromptRegistry. Tools get the caller through CallerContextInterface. They never take a customer id from arguments.
FAQ
Is my store data public with this module?
Only what an anonymous shopper already sees: enabled, visible products of the current website, at the price of the group you choose. Turn on Require Bearer Token to limit access to approved agent platforms.
Can agents place orders?
Not with this module alone. It is read-only. Ordering comes from MCP Checkout (guest checkout) or MCP Reorder (filling a signed-in buyer’s cart, without placing the order).
Why do I get wrong answers from /mcp?
Usually a cache in front of the store. Add a pass rule for /mcp in Varnish or LiteSpeed. A cached JSON-RPC answer is always wrong.
Can I add my store to claude.ai directly?
Without a token, yes: add https://your-store/mcp as a custom connector. With Require Bearer Token on, claude.ai needs OAuth, so you need an OAuth layer such as mcp.angeo.dev in front.
Which MCP versions are supported?
2026-07-28 and every revision back to 2024-11-05, on the same endpoint. Older clients keep using the initialize handshake.
Related
- MCP Checkout — guest cart and checkout tools for AI agents, with server-side limits
- MCP Reorder — reorder and quick order into a signed-in buyer's own cart (B2B)
- UCP Checkout over MCP — the same UCP checkout as five MCP tools
- WebMCP — store tools for AI agents in the shopper's browser (Chrome WebMCP)
- AI Agent Activity — report on AI agent calls, crawler visits, fake bots and agent-built orders
- MCP configuration reference
- MCP and agentic commerce glossary
- MCP account linking — definition
- All module reference pages · Compatibility matrix
This page was written from the README.md, composer.json and etc/*.xml files of tag 2.4.0, read on 16 October 2026. Settings, commands and defaults come straight from that code. If a newer release is out, the README on GitHub wins.