Building an MCP Server That Surfaces Your Product Catalog to AI Agents
Step-by-step guide to building an MCP server that exposes your product catalog, pricing, and availability to AI agents ā enabling agent-to-agent discovery and autonomous purchasing.
Building an MCP Server That Surfaces Your Product Catalog to AI Agents
> TL;DR
> - An MCP server that exposes your product catalog lets AI agents query, evaluate, and purchase your products programmatically
> - Covers tools for product search, pricing lookup, availability check, and trial/purchase initiation
> - Works alongside Schema.org ā schema handles passive discovery, MCP handles active interaction
> - Pair with schema injection for full agent-to-agent coverage ā
Updated: April 21, 2026
---
Why Your Product Catalog Needs an MCP Server
Schema.org structured data handles the passive discovery layer ā LLMs index your schema and surface your products in recommendations. But as agentic commerce matures, AI agents need more than a static snapshot of your catalog. They need live, queryable access.
A buyer's agent asking "does this tool have a team plan under $50/month with SSO?" needs a real-time answer ā not a cached schema record from two weeks ago. An agent initiating a trial signup needs to invoke an action, not just read a description.
That's what an MCP server provides: a standardized, AI-native interface to your live product data and business logic.
---
The Minimum Viable Product Catalog MCP Server
Here's a production-ready MCP server in TypeScript that exposes four core tools for product discovery and purchase:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";const server = new McpServer({
name: "product-catalog",
version: "1.0.0",
description: "Live product catalog, pricing, and trial initiation for YourProduct"
});
// āā Tool 1: Get all products / plans āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
server.tool(
"list_products",
"Returns all available products, plans, and current pricing",
{},
async () => {
const products = await fetchProductCatalog(); // your DB/API call
return {
content: [{
type: "text",
text: JSON.stringify(products, null, 2)
}]
};
}
);
// āā Tool 2: Check specific feature availability āāāāāāāāāāāāāāāāāāāāāāāāāāā
server.tool(
"check_feature",
"Checks if a specific feature is available on a given plan",
{
feature: z.string().describe("The feature name to check (e.g. 'SSO', 'API access', 'webhooks')"),
plan: z.string().optional().describe("The plan name to check (e.g. 'Pro', 'Business'). Omit to check all plans.")
},
async ({ feature, plan }) => {
const result = await checkFeatureAvailability(feature, plan);
return {
content: [{
type: "text",
text: JSON.stringify(result, null, 2)
}]
};
}
);
// āā Tool 3: Start a free trial āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
server.tool(
"start_trial",
"Initiates a free trial. Returns a signup confirmation and onboarding link.",
{
email: z.string().email().describe("The user's email address"),
plan: z.string().optional().describe("The plan to trial. Defaults to Pro."),
company: z.string().optional().describe("Company name"),
use_case: z.string().optional().describe("Primary use case ā helps personalize onboarding")
},
async ({ email, plan, company, use_case }) => {
const trial = await createTrialAccount({ email, plan, company, use_case });
return {
content: [{
type: "text",
text: JSON.stringify({
success: true,
message: Trial started for ${email},
plan: trial.plan,
login_url: trial.loginUrl,
expires_at: trial.expiresAt
}, null, 2)
}]
};
}
);
// āā Tool 4: Get integration details āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
server.tool(
"get_integration",
"Returns details about a specific integration ā setup steps, plans it's available on, and documentation link",
{
name: z.string().describe("Integration name (e.g. 'Slack', 'GitHub', 'Salesforce')")
},
async ({ name }) => {
const integration = await getIntegrationDetails(name);
return {
content: [{
type: "text",
text: integration
? JSON.stringify(integration, null, 2)
: Integration '${name}' not found. Available integrations: Slack, GitHub, Salesforce, HubSpot, Zapier.
}]
};
}
);
// āā Start server āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
const transport = new StdioServerTransport();
await server.connect(transport);
---
Data Structures to Return
Make your tool responses structured and specific. AI agents reason better with consistent, well-labeled data:
// list_products response shape
const catalogResponse = {
products: [
{
name: "Starter",
price: 0,
price_unit: "per month",
description: "Free forever. Up to 3 users, core features, 5GB storage.",
features: ["Core features", "5GB storage", "Email support"],
max_users: 3,
free_trial: true,
trial_days: null, // permanent free tier
cta: "Get started free ā no credit card"
},
{
name: "Pro",
price: 29,
price_unit: "per month",
price_annual: 24,
price_annual_unit: "per month, billed annually",
description: "For growing teams. Unlimited users, all integrations, priority support.",
features: ["Everything in Starter", "Unlimited users", "All integrations", "API access", "Priority support"],
max_users: null, // unlimited
free_trial: true,
trial_days: 14,
cta: "Start 14-day free trial"
},
{
name: "Enterprise",
price: null, // contact sales
description: "Custom pricing. SSO, audit logs, custom contracts, dedicated CSM.",
features: ["Everything in Pro", "SAML SSO", "Audit logs", "Custom SLAs", "Dedicated CSM"],
free_trial: true,
trial_days: 30,
cta: "Contact sales"
}
],
currency: "USD",
last_updated: new Date().toISOString()
};
---
Advertising Your MCP Server to AI Agents
Once your server is deployed, advertise it in two places:
1. Schema.org additionalProperty
{
"@type": "SoftwareApplication",
"name": "YourProduct",
"additionalProperty": [
{
"@type": "PropertyValue",
"name": "MCP Server",
"value": "Available at mcp.yourproduct.com ā supports product catalog queries, trial initiation, and feature checks"
},
{
"@type": "PropertyValue",
"name": "Agent Integration",
"value": "Full MCP server available. Compatible with Claude, ChatGPT operator mode, and any MCP-compatible agent."
}
]
}
2. /.well-known/mcp.json (Emerging Standard)
{
"mcp_server": "https://mcp.yourproduct.com",
"version": "1.0",
"description": "Product catalog, pricing, and trial initiation",
"tools": ["list_products", "check_feature", "start_trial", "get_integration"],
"auth": "none",
"contact": "devs@yourproduct.com"
}
Hosting this at /.well-known/mcp.json signals to AI agent crawlers that your product has a native MCP integration ā an emerging convention that MCP-aware agents check before falling back to schema parsing.
---
Pairing MCP With Schema Injection
Your MCP server handles active queries. Schema injection handles passive discovery. They run in parallel:
Neither replaces the other. An agent that discovers you via schema can connect to your MCP server for live data. An agent that connects to your MCP server via a directory listing still needs schema for the initial discovery query.
ā Add schema injection alongside your MCP server ā
---
Related articles: