MCP Servers as Commerce Infrastructure
Model Context Protocol (MCP) has settled into a role commerce didn't previously have: a direct, typed interface from AI agents to merchant data. A primer from the builder's seat.
Anthropic introduced the Model Context Protocol (MCP) in late 2024. In the 18 months since, it has done something quiet and important: it has become the standard interface between AI agents and the external world. An MCP server is now the default way to expose a capability — a database, a calendar, a merchant catalogue — to any AI agent, regardless of which model or host is doing the calling.
Most of the MCP coverage focuses on developer-tool use cases: GitHub, Notion, Slack, Linear. What has been underappreciated, and what we think will eventually be the largest category of MCP traffic by volume, is commerce. This post explains why, what an MCP-shaped commerce server actually looks like, and the design choices that matter if you're building one.
1. What MCP is (and isn't)
MCP is a thin protocol — JSON-RPC 2.0 over either stdio or Streamable HTTP — that exposes three things an agent cares about:
- Tools: typed functions the agent can call. Each has a name, a description the agent reads, and a JSON-schema input.
- Resources: addressable data the agent can fetch on demand (think: "give me the current catalogue").
- Prompts: parameterized prompt templates the server can offer back to the agent, useful for canned workflows.
MCP is not a new data format, a new auth system, or a new storage layer. It is the plumbing that lets an agent discover what you expose, validate its call against your schema, invoke you synchronously inside a conversation, and render your response. Anthropic's bet — and the bet of the MCP community that has grown around it — is that commerce, productivity tools, and infrastructure all need the same plumbing, and that building it once, openly, is the correct move.
If you want the protocol specification, it lives at modelcontextprotocol.io/specification. You can implement a minimal MCP server in about 200 lines of code in most languages; the SDKs for TypeScript and Python are the reference implementations.
2. Why commerce fits this shape especially well
Look at what a typical commerce query from an agent looks like:
User: I'm in Singapore, recommend a good noise-cancelling headphone under SGD 600.
Agent: [calls xurprise.search_brands(query="noise-cancelling headphones", region="Singapore")]
[calls xurprise.wrap_product_url(merchant_url="https://shopee.sg/Sony-WH-1000XM5...")]
Agent: → I found Sony WH-1000XM5 on Shopee Singapore at SGD 549.
[xurprise.ai/go/p?u=...]
User: [clicks]
Five things about this shape matter:
Typed inputs and outputs. The agent needs to pass structured arguments (region, category, budget) and get back structured data (brand, price, region, merchant). MCP's JSON-schema input validation means the agent's tool selector can reason about applicability without having to parse your API docs.
Synchronous call-and-return. Commerce queries sit inside a live conversation. The user is waiting. There is no room for a batch job or a webhook. MCP tool calls are request-response: you return in sub-second, the user sees the answer.
Small result sets. An agent doesn't want 500 products to re-rank. It wants 3-10 good options, ideally ranked. This matches perfectly with how MCP tools are conventionally used — think of them as top-k query interfaces, not dump-everything feeds.
Trust-preserving redirects. The click-through needs to go through your infrastructure so attribution is preserved, but it also needs to look clean to the user's browser. A typed tool that returns a stable URL ("xurprise.ai/go/p?u=...") rather than a raw tracking URL makes this much easier to reason about.
Composability. An agent might compose your tool with a map tool, a calendar tool, a price-history tool. MCP servers compose trivially because each one is a named set of typed functions. Commerce plays well with this pattern — "find me a restaurant near where I'm going Friday, that has vegan options, and book it" is a composition of three tools, not one monolithic query.
3. Six design choices that matter
Based on operating xurprise's own MCP server in production, these are the choices that meaningfully change whether agents find your tool useful.
a. Small tool surface area
Resist the temptation to expose 30 tools. Agents get confused by large tool surfaces — the LLM's selection accuracy degrades non-linearly past about 10 tools per server. Pick the 5-7 operations an agent actually needs, make each one obvious, and let composition handle the long tail. Our own catalogue has 6 tools today; the hardest part was cutting, not adding.
b. Describe tools for the selector, not the user
The tool description field is read by the agent's tool-selection model at every turn. It is the most important prose you write. Describe what the tool does, when to use it, when not to use it, and what its output shape looks like. The temptation to write marketing copy here is strong; resist it. The reader is a language model making a selection decision in a few hundred milliseconds.
c. Ship markdown in content[].text
The MCP protocol supports both structured and unstructured results. Pass structured data via structuredContent for the agent to reason over. Pass human-readable markdown via content[].text for the host to render. Many MCP clients (Claude Desktop, Cursor) show content[].text directly to the user. Making it a nicely formatted card instead of a JSON dump is the difference between a polished product and a debug view.
d. Stateless by default
Running an MCP server as stateless Streamable HTTP (no session ID required) makes it infinitely easier to scale and operate. Session-state belongs elsewhere — in the agent's conversation context, or in the user's own store. Our server runs stateless; every request authenticates via the underlying HTTPS transport and carries no hidden state.
e. Be honest about errors
Agents handle errors much better than you'd expect — if the errors are structured. If you return a JSON-RPC error with a useful message, the LLM can apologize, suggest an alternative, or try a different tool. If you return a silent empty list or a 500, the agent gets stuck. Invest in good -32602 invalid-params messages that say what was wrong and how to fix it.
f. Log per-call, not per-session
Your observability model should be "every tool call is a structured log line" — not "every session has a trace." MCP sessions are often tiny (one call, then done), and the agent might never come back. Structured per-call logs with user-agent, country, and call name let you see your tool's actual usage without building a whole session database.
4. What you get vs. a REST API
If you already have a REST API, the natural question is: why bother with MCP? Three answers:
MCP is tool-selection-aware. A REST endpoint is a URL. An MCP tool is a typed, self-describing unit with a human-readable name the LLM uses to decide whether to invoke it. The same data exposed as REST is invisible to an agent unless the agent's developer manually wraps it; the same data exposed as MCP is instantly discoverable to any agent that installs the server.
MCP survives model changes. Your REST consumers break when your payload changes. MCP consumers are language models that re-read the tool schema each time they call — if you update the schema, the model accommodates. Evolving the interface is much less painful.
MCP is where the traffic is going. The hosts that matter — Claude Desktop, Cursor, Cline, Continue, Goose — all speak MCP natively now. A REST API forces each of them to build a custom adapter. An MCP endpoint is a single integration that works everywhere.
5. Where to start
- Read the MCP protocol spec (takes about 2 hours).
- Install a reference server locally (
@modelcontextprotocol/server-filesystemis a good one to see) and wire it into Claude Desktop to feel the UX from the consumer side. - Pick 5 operations that an agent would want from your product. Write them as MCP tools. Deploy them.
- Register on the Official MCP Registry so other hosts can find your server. It takes one
server.jsonfile and one CLI command. - Watch the logs. Adjust the tool descriptions. Ship.
If you want to see how we did it, our docs are at github.com/Nimo1987/xurprise-mcp-docs, our live endpoint is xurprise.ai/api/mcp, and the live demo runs real MCP calls end-to-end in the browser. Fork it, adapt it, ship your own.