# MCP Server for Magento 2  -  module reference

> Give AI agents live, read-only access to your Magento 2 catalog over MCP 2026-07-28. Tools, prompts, tokens, account linking, cache rules.

Source: https://angeo.dev/docs/modules/mcp-server/
Updated: 2026-10-17

Module reference

# MCP Server for Magento 2  -  module reference

Covers `angeo/module-mcp-server` 2.4.0 - Checked 16 October 2026 - MIT licensed

**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](https://modelcontextprotocol.io) 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](https://angeo.dev/docs/modules/mcp-checkout/) for guest checkout, and [MCP Reorder](https://angeo.dev/docs/modules/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.

Package`angeo/module-mcp-server`Latest version2.4.0 (released 2026-10-02)Magento2.4.6+PHP8.1 - 8.5LicenseMIT, freeLinks[GitHub](https://github.com/angeo-dev/module-mcp-server) - [Packagist](https://packagist.org/packages/angeo/module-mcp-server) - [Changelog](https://github.com/angeo-dev/module-mcp-server/blob/main/CHANGELOG.md) - [Module page](https://angeo.dev/modules/mcp-server/) - [User guide](https://angeo.dev/docs/mcp/)

**On this page**

1. Tools
2. Requirements
3. Installation
4. Do not cache /mcp
5. Getting agents to pick your store
6. Authentication
7. Protocol versions
8. Connecting an agent
9. Configuration reference
10. Cron and stored data
11. Adding your own tools
12. FAQ
13. Related

## 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:

1. Go to **System -> Extensions -> Integrations -> Add New Integration**. Give it only the **MCP Server Agent Access** resource.
2. Activate it and copy the **Access Token**.
3. Set **Require Bearer Token** to *Yes*.
4. 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:

1. The connector sends the shopper's browser to `GET /mcp/link` with `redirect_uri`, `state` and a PKCE `code_challenge` (S256).
2. The shopper signs in **on your store** and approves on a page that names the connector.
3. The store redirects back with a one-time code (valid two minutes, PKCE only).
4. The connector calls `POST /mcp/link/exchange` and gets a long-lived **grant** and a first `amc_` token.
5. When the token expires, it calls `POST /mcp/link/token` with 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](https://angeo.dev/docs/mcp-checkout/).

### 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](https://angeo.dev/docs/modules/mcp-checkout/)  -  guest cart and checkout tools for AI agents, with server-side limits
- [MCP Reorder](https://angeo.dev/docs/modules/mcp-reorder/)  -  reorder and quick order into a signed-in buyer's own cart (B2B)
- [UCP Checkout over MCP](https://angeo.dev/docs/modules/ucp-checkout-mcp/)  -  the same UCP checkout as five MCP tools
- [WebMCP](https://angeo.dev/docs/modules/webmcp/)  -  store tools for AI agents in the shopper's browser (Chrome WebMCP)
- [AI Agent Activity](https://angeo.dev/docs/modules/agent-activity/)  -  report on AI agent calls, crawler visits, fake bots and agent-built orders
- [MCP configuration reference](https://angeo.dev/docs/mcp/)
- [MCP and agentic commerce glossary](https://angeo.dev/docs/mcp-glossary/)
- [MCP account linking  -  definition](https://angeo.dev/mcp-account-linking-definition/)
- [All module reference pages](https://angeo.dev/docs/modules/) - [Compatibility matrix](https://angeo.dev/docs/compatibility/)

This page was written from the `README.md`, `composer.json` and `etc/*.xml` files of [tag 2.4.0](https://github.com/angeo-dev/module-mcp-server/tree/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.
