MCP server
Give an AI agent recall lookups with source links. The server speaks the Model Context Protocol over Streamable HTTP.
| Endpoint | https://api.recallsapi.com/mcp |
|---|---|
| Transport | Streamable HTTP, POST with JSON responses (no SSE stream; GET answers 405). JSON-RPC batches are accepted. |
| Protocol versions | 2025-06-18, 2025-03-26, 2024-11-05 |
| Auth | initialize and tools/list are open. tools/call needs your API key as Authorization: Bearer <key> (or X-API-Key). |
| Metering | Each tool call counts as one call against your daily quota, like a REST call. |
No key yet? Create one with POST /v1/keys (see the quickstart).
Tools
| Tool | Arguments | What it does |
|---|---|---|
check_product | name, brand, upc, model, ndc, lot (at least one) | Is this product recalled? Same matching as /v1/check, with exact, strong or possible confidence, reasons and the agency link. |
search_recalls | query (required), category, since (YYYY-MM-DD), limit (1 to 50, default 10) | Full-text search across all sources. |
check_vehicle | vin, or make, model and year | NHTSA campaigns for a vehicle. Campaigns cover a make, model and year; VIN-specific status is confirmed at nhtsa.gov. |
get_recall | id (for example fda-H-1339-2026) | The full record with every identifier and the source link. |
All four tools are read-only. Each result has a short text summary for the model, with the source link for every recall, and structuredContent holding the same JSON as the REST API. Problems (no input, unknown id, a VIN that cannot be decoded, a missing key) come back as a tool result with isError: true.
Claude Code
Terminal
claude mcp add --transport http recallsapi https://api.recallsapi.com/mcp \
--header "Authorization: Bearer rk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Add --scope user to use it in every project. To share it with a team through .mcp.json without committing the key, reference an environment variable:
.mcp.json
{
"mcpServers": {
"recallsapi": {
"type": "http",
"url": "https://api.recallsapi.com/mcp",
"headers": {
"Authorization": "Bearer ${RECALLSAPI_KEY}"
}
}
}
}
Cursor
~/.cursor/mcp.json (or .cursor/mcp.json in a project)
{
"mcpServers": {
"recallsapi": {
"url": "https://api.recallsapi.com/mcp",
"headers": {
"Authorization": "Bearer ${env:RECALLSAPI_KEY}"
}
}
}
}
Claude Desktop
Claude Desktop starts local servers from its config file, so a small bridge, the open-source mcp-remote package, forwards to the remote server with your key. It needs Node.js installed.
claude_desktop_config.json
{
"mcpServers": {
"recallsapi": {
"command": "npx",
"args": [
"mcp-remote",
"https://api.recallsapi.com/mcp",
"--header",
"Authorization:${AUTH_HEADER}",
"--transport",
"http-only"
],
"env": {
"AUTH_HEADER": "Bearer rk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}
}
On macOS the file is ~/Library/Application Support/Claude/claude_desktop_config.json; on Windows, %APPDATA%\Claude\claude_desktop_config.json. Restart Claude Desktop after editing it. Keep Authorization:${AUTH_HEADER} without a space: some clients do not escape spaces inside args.
Any other client
Any client that speaks Streamable HTTP and can send a header works. The raw exchange:
initialize
curl -s -X POST https://api.recallsapi.com/mcp \
-H "content-type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}'
Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {
"tools": {
"listChanged": false
}
},
"serverInfo": {
"name": "recallsapi",
"title": "recallsapi.com: US product, food, drug, device and vehicle recalls",
"version": "0.1.0"
},
"instructions": "US recall lookups. Use check_product first with whatever the user has (name and brand, barcode, model, NDC, lot); search_recalls for topics; check_vehicle for cars. Always show the source link. Get an API key at https://recallsapi.com."
}
}
tools/call
curl -s -X POST https://api.recallsapi.com/mcp \
-H "Authorization: Bearer $RECALLSAPI_KEY" \
-H "content-type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"check_product","arguments":{"upc":"041548000121"}}}'
Response (structuredContent shortened on this page)
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "1. [exact] Dreyer's Grand Ice Cream Inc.: Outshine Fruit Bars Black Cherry, 6 Bars, 2 (FDA, 2026-08-18). Hazard: Foreign object: products may contain glass pieces Source: https://api.fda.gov/food/enforcement.json?search=recall_number:%22H-1268-2026%22"
}
],
"structuredContent": "(same JSON as GET /v1/check)",
"isError": false
}
}
Notifications such as notifications/initialized get 202 Accepted with no body. Protocol errors use JSON-RPC codes: -32600 invalid request, -32601 unknown method, -32602 unknown tool.
Guidance for agents
- Start with
check_productusing whatever the user has; add the brand whenever you know it. - Show the confidence level and the source link with every match, and say that a match should be confirmed against the agency notice.
- Do not tell the user a product is safe because nothing matched.