Developers
Swervie is a cross-retailer product catalog. Its MCP server gives an AI assistant one consolidated, scored answer per product: duplicate listings collapsed, comparable specs, live prices, and a buy link for every seller. Answers are precomputed, so no language model runs while serving a request — responses are deterministic and fast.
Add it to any MCP client that supports remote servers. In a client that takes a JSON config:
{
"mcpServers": {
"swervie": {
"url": "https://swervie.xyz/mcp"
}
}
}The server sends instructions on initialize that teach the agent the call flow, so no prompt engineering is needed on your side. Each initialize response carries an Mcp-Session-Id header; echoing it is optional and used only for usage counting. The legacy endpoint https://us-central1-swervie-prod.cloudfunctions.net/mcp serves the same server.
Recommended flow: search_products for a normal shopping question. Use find_category then browse_category when the agent wants explicit control of filters, and get_products only when it needs full offers, review evidence, or provenance.
| Tool | Inputs | What it does |
|---|---|---|
search_products read-only | query, sort?, limit? (1-50), cursor?, user_signature? | The one-call path. Resolves the category, parses price bounds and spec constraints from free text, and returns the ranked shelf plus an interpretation receipt. |
find_category read-only | query, user_signature? | The matching category and its filter contract: every filterable spec with type, units, allowed values and importance, plus budget / mid / premium price bands. |
browse_category read-only | category, filters[]? ({dimension, equals | min | max | any_of}), sort?, limit? (1-50), cursor?, user_signature? | One ranked row per product, duplicate seller listings already collapsed: price, price band, buy_url and buy_seller, image, star rating, key specs. |
get_products read-only | ids[] (1-25), user_signature? | Full detail: every spec with its provenance, review-derived ratings with verbatim evidence quotes, and every seller offer with price and buy_url. |
record_selection write, non-destructive | product_id or product_ids[], action?, category?, user_signature? | Records which product the user considered or chose. Improves later rankings, especially for a returning user_signature. |
submit_feedback write, non-destructive | feedback (max 2,000 chars, rejected not truncated), kind?, tool?, category?, product_ids[]?, user_signature? | Sends a problem report (wrong spec, stale price, bad match, missed duplicate, missing product) to a human review queue. |
Sort options are value (default), quality, and price_asc. Lists page with next_cursor. Every tool carries MCP annotations: the four read tools are readOnlyHint: true; the two write tools are destructiveHint: false. Nothing a tool does can buy, change, or delete anything a user owns.
search_products, browse_category, and get_products also link an interactive results view (MCP Apps, io.modelcontextprotocol/ui). Hosts without that extension ignore it and get the same data as JSON text.
MCP=https://swervie.xyz/mcp
H=(-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream")
# 1. Handshake: server info, capabilities, and agent instructions
curl -s -X POST $MCP "${H[@]}" -d '{"jsonrpc":"2.0","id":1,
"method":"initialize","params":{"protocolVersion":"2025-06-18",
"capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}'
# 2. List the tools
curl -s -X POST $MCP "${H[@]}" -d '{"jsonrpc":"2.0","id":2,
"method":"tools/list"}'
# 3. Answer a shopping question in one call
curl -s -X POST $MCP "${H[@]}" -d '{"jsonrpc":"2.0","id":3,
"method":"tools/call","params":{"name":"search_products",
"arguments":{"query":"65 inch OLED TV under $1500","limit":3}}}'The third call returns the shelf as JSON text content, trimmed here:
{
"category": "Televisions",
"interpretation": {
"category": "Televisions",
"match_quality": "strong",
"resolved_child": "OLED TVs",
"price_max_cents": 150000,
"filters": [
{"dimension": "Screen Size", "min": 65, "source": "65 inch"},
{"dimension": "Display Technology", "equals": "OLED", "source": "OLED"}
],
"unparsed_tokens": []
},
"total_matching": 3,
"next_cursor": "1",
"card_specs": [{"name": "Screen Size", "unit": "inches"},
{"name": "Display Technology"}, {"name": "Resolution"}, "..."],
"rows": [
{
"id": "x867BnXduwLjzQUsOKzf",
"title": "Panasonic Z8BAP 77\" OLED 4K Smart Fire TV, 144Hz",
"brand": "Panasonic",
"price_usd": 1399.99,
"swervie_score": 70.8,
"price_band": "premium",
"buy_url": "https://us-central1-swervie-prod.cloudfunctions.net/go?p=...",
"buy_seller": "amazon",
"star_rating": 4.7,
"star_rating_count": 111,
"attributes": {"Screen Size": 77, "Display Technology": "OLED",
"Refresh Rate": 144, "HDMI 2.1 Support": true}
}
],
"disclosure": "Swervie may earn a commission when a shopper buys ..."
}interpretation is the receipt for how the query was understood: the category, the filters parsed from the text (each with its source words), and unparsed_tokens for anything that did not become a filter. Soft preferences like “quiet” land there and do not reorder rows — weigh them yourself.match_quality is strong, partial, or weak. On weak the category itself is suspect and rows are withheld; tell the user rather than presenting the shelf.swervie_score is 0-100, higher is better; price_band is budget, mid, or premium for that category.card_specs lists the specs each product card shows, in order. Present specs in that order for every product so comparisons line up.buy_url is a Swervie redirect to the seller named in buy_seller. The purchase happens on the seller's site.disclosure text wherever you show buy links. Some links earn Swervie a commission; commissions never affect rankings, scores, or which products are shown (see the affiliate disclosure).find_category query has no matching category, the response says so and the request is queued as demand for a new category.Every tool accepts an optional user_signature, a pseudonymous id that lets rankings learn from a returning user's choices across sessions and assistants. Every tool works without it.
// id = the user's most stable identifier, normalized:
// lowercase, trimmed; email preferred, with +tags stripped
user_signature = "sv1-" + sha256hex("swervie/v1|" + id).slice(0, 24)"sv1r-" + a random UUID stored for that user. Never send a fresh random value per session.| Scope | Per minute | Per day |
|---|---|---|
| Per user_signature, or per IP when none is sent | 60 | 2,000 |
| Per IP, across all signatures | 300 | 20,000 |
| Partner key (default) | 600 | 100,000 |
Requests without a user_signature share their IP's 60-per-minute limit, so a platform serving many users from a few addresses should send signatures or use a partner key. Over the limit, the server answers HTTP 429 with a Retry-After header and a JSON-RPC error.
Assistant platforms whose traffic leaves from shared IP addresses can ask for a partner key. Send it as Authorization: Bearer svk_… or X-Swervie-Api-Key: svk_…. It replaces the shared IP ceiling with the partner's own quota (adjustable per partner) while the per-signature limit keeps users fair within it. An unknown or revoked key is served at the anonymous tier, never refused. Keys are stored only as hashes. Email info@plum-app.com to request one.
user_signature — no account, email, device id, or conversation history.submit_feedback is stored for human review.See the privacy policy and terms.
/api/ucp/mcp with standard search_catalog / lookup_catalog.Questions, partner keys, outages, or catalog corrections: info@plum-app.com. Agents can also report bad results in-band with submit_feedback. Swervie is built and operated by Plum Applications, Inc. More about the catalog on the about page.