TrustRails standardises messy retailer feeds into one predictable source: 26,000+ deduplicated UK electronics products across 7 retailers. Connect an agent over MCP, or query the REST API and SDK directly.
Save weeks of integration time and focus on building your project, not babysitting product feeds.
Two ways to connect an agent, both live today. Use the hosted endpoint if your client supports remote MCP servers over HTTP; use the npm package if it only supports local (stdio) servers. That includes the free tier of Claude Desktop.
https://trustrails.app/api/mcp: MCP over JSON-RPC 2.0, no API key required. Only tool calls count toward the rate limit: 50/hour per IP and per MCP session (Claude connectors, which share Anthropic's IPs, get a higher per-IP ceiling).
Claude Code:
claude mcp add --transport http trustrails https://trustrails.app/api/mcp
Cursor (.cursor/mcp.json):
{
"mcpServers": {
"trustrails": {
"url": "https://trustrails.app/api/mcp"
}
}
}Claude Desktop: remote HTTP servers are added under Settings → Connectors → Add custom connector, pasting the URL above (paid plans). On the free plan, or for any client without remote MCP support, use the npm package below instead.
@trustrails/mcp-server calls the same public API over HTTP, run locally via npx. Add this block to Claude Desktop's claude_desktop_config.json or Cursor's .cursor/mcp.json:
{
"mcpServers": {
"trustrails": {
"command": "npx",
"args": ["-y", "@trustrails/mcp-server"],
"env": {
"TRUSTRAILS_API_KEY": "mcp-public-2026"
}
}
}
}Or for Claude Code:
claude mcp add trustrails -e TRUSTRAILS_API_KEY=mcp-public-2026 -- npx -y @trustrails/mcp-server
| Env var | Default |
|---|---|
| TRUSTRAILS_API_KEY | mcp-public-2026 |
| TRUSTRAILS_BASE_URL | https://trustrails.app |
Tools (identical on both):
search_products filters by query, brand, category, price range, and hard spec constraints (memory_gb, storage_gb, screen_in, resolution_p, refresh_hz, power_w, wifi_gen), each checked per product: matched, or unverified and never a match. total counts the products that match every constraint and unverified_total the unverified products that passed the other filters. Set a category or brand with constraints. If candidates_truncated is true, the first 2,000 candidates were checked and more exist: add a brand or category, or a narrower query, and search again. Set lite=true for trimmed results: id, title, brand, price, currency, availability, image_url, purchase_url, offer_count, attributes (every known spec, without sources) and, with constraints, constraint_status. availability is in_stock, low_stock, out_of_stock or unknown, and offer_count lets agents surface cross-retailer price comparisons.get_product returns structured attributes (each confirmed, inferred or conflicting, with its retailer sources; search results carry them too, so compare specs from search and call this only for your final 1-3 picks, and only for what search lacks), the retailer's own description, availability, delivery time, and every retailer offer for one product ID (price, availability, stock when the retailer supplies a unit count, and buy link), in stock first, then cheapest. Search results carry only the best offer's purchase_url (cheapest in stock).Install first:
npm install @trustrails/sdk
import TrustRails from "@trustrails/sdk";
const trustrails = new TrustRails(process.env.TRUSTRAILS_KEY);
// The SDK sets Authorization: Bearer <TRUSTRAILS_KEY> automatically
async function main() {
// Use query to refine within brand + category (model lines, variants, series names)
const res = await trustrails.search({
brand: "Samsung",
category: "TVs",
query: "qled", // narrows to Samsung QLED TVs specifically
maxPrice: 1000,
});
console.log(res.products);
// [{
// id: "samsung-qled-001",
// title: "Samsung 55\" QLED 4K Smart TV",
// brand: "Samsung",
// price: 799,
// currency: "GBP",
// availability: "in_stock",
// category: "TVs",
// product_type: "product",
// ...
// offer_count: 3,
// }]
}
main();curl -s "https://trustrails.app/api/search?brand=Samsung&category=TVs&query=qled&max_price=1000" \ -H "Authorization: Bearer $TRUSTRAILS_KEY"
When to use query: Use it to refine within a brand and category - model lines, series names, variants, or model numbers. Examples: query="qled", query="neo", query="WH-1000XM5". Never put category names (query="tablet" → use category="Tablets"), brand names, product family names (MacBook, Galaxy, ThinkPad), or prices in query - use the brand, category, and min_price/max_price filters instead.
See Auth & rate limits below for keys, rate limits, and contact options. Or try the Live Explorer (no auth required).
| Endpoint | Description | Example |
|---|---|---|
| GET /api/search | Search products. Returns product objects, or trimmed ones with lite=true (id, title, brand, price, currency, availability, image_url, purchase_url, offer_count, attributes without sources). Results carry every known structured spec in attributes (with sources unless lite); for your final 1-3 picks, the retailer's description, delivery time and every offer (search carries only the best offer's purchase_url, cheapest in stock), use /api/product/{id}. Pass hard spec requirements in constraints as a JSON string, URL-encoded once as a query parameter, with a category or brand (bad input returns 400). Constrained searches return constraint_status per result | /api/search?brand=HP&category=Laptops&lite=true /api/search?brand=Apple&category=Laptops&lite=true&constraints=%7B%22memory_gb%22%3A%7B%22gte%22%3A24%7D%7D |
| GET /api/product/{id} | Full details: structured attributes, the retailer's description, availability, delivery, and every retailer offer (in stock first, then cheapest) | /api/product/usb001 |
| POST /api/mcp | MCP protocol endpoint (JSON-RPC 2.0). No auth required. Exposes search_products and get_product as tools. | see MCP quickstart above |
| GET /api/health | Check API status (no auth) | /api/health |
/api/search, /api/product/{id}) require an Authorization: Bearer <key> header. The public key mcp-public-2026 works out of the box./api/mcp) and Explorer endpoints need no key at all, but are still rate limited.tools/call), not the handshake, at 50/hour per IP and per MCP session. Over the limit, a tool call returns a tool error (isError: true) telling the AI when to retry, plus a Retry-After header. REST and Explorer responses carry X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers./api/health is open and not rate limited.Errors return a flat JSON object with an error string:
401 Unauthorized
{
"error": "Unauthorized"
}429 Rate limited
{
"error": "Rate limit exceeded",
"resetAt": "2026-09-24T15:00:00.000Z"
}400 Validation error
{
"error": "Invalid min_price parameter"
}