What it does
The catalogue query. Filters are the same ones the store page uses, against the same rows, so an agent and a browser cannot be shown different answers. The filter worth reaching for is `capability`: "which products can read a profile" is a better question than "which products mention research".
Arguments
| Name | Type | Required | Meaning |
|---|---|---|---|
| q | string | no | Substring matched against slug, name and tagline |
| outcome | string | no | Outcome category: sales, recruiting, content, networking, data, operations. Accepts a list. |
| kind | string | no | What it is: agent, skill, workflow, kit, mcp. Accepts a list. |
| tier | string | no | Price tier: free, skill, kit, hosted, team. Accepts a list. |
| status | string | no | How much we stand behind it: verified, community, beta, deprecated. Accepts a list. |
| risk | string | no | Risk level: low, medium, high. Accepts a list. |
| automation_method | string | no | How it acts: official-api, user-session, human-in-the-loop, read-only. Accepts a list. |
| capability | string | no | Only products declaring this capability id, e.g. "linkedin.search_people" |
| max_price_cents | number | no | Ceiling in cents. Products priced on request are excluded, because we do not know that they fit under it. |
| sort | string | no | name (default), price_asc, price_desc or newest |
| limit | number | no | How many products, 1–50 (default 20) |
| offset | number | no | Skip this many, for paging |
This table is generated from the literal inputSchema that tools/list returns, so what your client sees and what this page says are the same object:
{
"type": "object",
"properties": {
"q": {
"type": "string",
"description": "Substring matched against slug, name and tagline"
},
"outcome": {
"type": "string",
"description": "Outcome category: sales, recruiting, content, networking, data, operations. Accepts a list."
},
"kind": {
"type": "string",
"description": "What it is: agent, skill, workflow, kit, mcp. Accepts a list."
},
"tier": {
"type": "string",
"description": "Price tier: free, skill, kit, hosted, team. Accepts a list."
},
"status": {
"type": "string",
"description": "How much we stand behind it: verified, community, beta, deprecated. Accepts a list."
},
"risk": {
"type": "string",
"description": "Risk level: low, medium, high. Accepts a list."
},
"automation_method": {
"type": "string",
"description": "How it acts: official-api, user-session, human-in-the-loop, read-only. Accepts a list."
},
"capability": {
"type": "string",
"description": "Only products declaring this capability id, e.g. \"linkedin.search_people\""
},
"max_price_cents": {
"type": "number",
"description": "Ceiling in cents. Products priced on request are excluded, because we do not know that they fit under it."
},
"sort": {
"type": "string",
"description": "name (default), price_asc, price_desc or newest"
},
"limit": {
"type": "number",
"description": "How many products, 1–50 (default 20)"
},
"offset": {
"type": "number",
"description": "Skip this many, for paging"
}
}
}Request
Paste this, swap the key, and you have called the tool.
curl -s https://topclozer.com/api/mcp \
-H "Authorization: Bearer tcz_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_products",
"arguments": { "outcome": "sales", "max_price_cents": 4900, "sort": "price_asc" }
}
}'Returns
{ catalog_published, count, total, offset, outcomes, products[] }. `count` is this page, `total` is the whole filtered set. Each product is the stored row plus price, url, capabilities[], planned_capabilities[] and risk_summary.
The payload arrives inside an MCP content block — one text block whose body is this JSON, pretty-printed. Parse the string; there is no structured-content field.
{
"catalog_published": true,
"count": 1,
"total": 1,
"offset": 0,
"outcomes": { "sales": 2, "recruiting": 1 },
"products": [
{
"slug": "linkedin-sdr-kit",
"name": "LinkedIn SDR Kit",
"tagline": "From an ICP to approved first messages.",
"outcome": "sales",
"kind": "kit",
"tier": "kit",
"price_cents": 4900,
"currency": "usd",
"status": "verified",
"seller_id": "topclozer",
"risk": "medium",
"automation_method": "human-in-the-loop",
"version": "1.0.0",
"price": "$49",
"url": "https://topclozer.com/agents/linkedin-sdr-kit",
"planned_capabilities": ["planned.crm_push"],
"capabilities": []
}
]
}Worth knowing
Deprecated products are excluded unless `status` names them. A product priced on request has price_cents null and is left out of a max_price_cents search rather than assumed to be cheap. `outcomes` counts the whole catalogue, not the filtered page, so it can drive a facet list.
Limits
No request limit. This tool reads the workspace database and costs nothing to serve. The limits that bite in this product are the sending controls — per-sender weekly invite caps, the warm-up ramp, the working-hours window and a randomised gap between actions — and no tool can raise them.
Related tools
get_product
One product in full: capabilities, risk, price, and whether this workspace has bought or installed it
search_capabilities
Search what TopClozer products can actually do, and what performs each capability today
install_product
Record an installation of a product into an AI client or the hosted runner. Writes a row; runs nothing.
All 21 tools are listed on the tool index. Connecting a client is on the Claude setup page, and the protocol details are on the server page.