Calling it over MCP
https://inspired.jetskibay.com/mcp speaks the Model Context Protocol over the
Streamable HTTP transport, JSON responses only, pinned to revision
2026-07-28. It declares one capability — tools — and implements three.
Connecting
Authenticate every request with your Inspired API key, as a bearer token or as
x-api-key:
POST /mcp HTTP/1.1
Host: inspired.jetskibay.com
Authorization: Bearer isk_…
Content-Type: application/json
The credential is checked on every request, including initialize and
tools/list: there is no anonymous discovery. A key whose allowance is spent can
still list tools and collect a read it already paid for, exactly as polling stays
free over HTTP — only start_visual_search is refused.
What the transport does not implement, and answers 405 for rather than
pretending: GET /mcp (no SSE stream to open), DELETE /mcp (no session to
terminate), and JSON-RPC batching. resources/list and prompts/list answer
-32601; only tools is declared in initialize.
list_focus_domains
No arguments. Free. Returns every subject the pipeline can shop for, with the aliases each accepts.
{ "name": "list_focus_domains", "arguments": {} }
structuredContent is { defaultDomain, domains: [{ id, label, description, aliases, example, default }] }.
Call this first when you do not already know which domain fits the photo. The
default is fashion.
start_visual_search
Starts a durable read and returns immediately. Spends one request from the calling key's allowance.
| Argument | Notes |
| --- | --- |
| image | The photograph as base64, with or without a data: prefix. JPG, PNG, WEBP or GIF, up to 10 MB decoded. |
| imageMediaType | Required unless image is a data: URL that names its own type. |
| pinterestUrl | A public Pinterest pin URL, instead of image. |
| domain | A domain id or alias. Omit for fashion. |
| focus | Up to 160 characters narrowing what to look for. |
Send exactly one of image or pinterestUrl. Unknown arguments are refused
rather than ignored, so a misspelling fails loudly.
{
"name": "start_visual_search",
"arguments": {
"image": "/9j/4AAQSkZJRgABAQ…",
"imageMediaType": "image/jpeg",
"domain": "furniture"
}
}
structuredContent is { ok, requestId, status, statusUrl, pollAfterMs, requestsRemaining }. Keep the requestId: it is the only handle on the read,
and only your key can collect it.
get_visual_search
Collects a read. Free to call, any number of times.
{ "name": "get_visual_search", "arguments": { "requestId": "3f0c8a5e-…" } }
While it runs, structuredContent is { ok, requestId, status: "queued" | "running", pollAfterMs, progress, items: [{ id, name, status }] }. Respect
pollAfterMs; it is 3000 today.
When it finishes, structuredContent is:
{
"ok": true,
"requestId": "3f0c8a5e-…",
"status": "complete",
"domain": "furniture",
"focus": "",
"summary": "Found 3 clearly visible furniture items.",
"itemCount": 3,
"matchCount": 24,
"items": [
{
"id": "piece-1",
"name": "floor lamp",
"description": "Slim brass floor lamp with a white cone shade",
"imageUrl": "https://inspired.jetskibay.com/api/inspire/jobs/3f0c8a5e-…/assets/piece-1.webp",
"candidates": [
{
"title": "Brass arc floor lamp",
"link": "https://shop.example/brass-arc-lamp",
"price": "€149",
"imageUrl": "https://images.example/lamp.jpg",
"source": "example.com"
}
]
}
],
"moodBoard": { "available": true, "mediaType": "image/webp", "note": "…" }
}
A read that failed comes back as a tool error — isError: true — carrying the
reason, not as a silent empty result.
Why the images are links
The HTTP job response embeds every cutout and the mood board as base64 data
URLs, which is right for a client writing files and wrong for a model's context
window. Over MCP each cutout is an HTTPS URL instead, and the mood board is
described rather than inlined. To read the bytes, fetch
GET /api/v1/jobs/{requestId} with your key and use grid.imageDataUrl and
items[].imageDataUrl.
Candidate images are hosted by the retailers and by Google, not by Inspired, and may expire without notice.
A whole read, end to end
initialize → protocolVersion 2026-07-28
notifications/initialized → 202
tools/list → three tools
tools/call list_focus_domains {} → furniture is what you want
tools/call start_visual_search {image…} → requestId, 9 requests left
tools/call get_visual_search {requestId} → running, poll in 3s
… a few minutes …
tools/call get_visual_search {requestId} → complete, 3 objects, 24 matches
The worked shell version of this is in the examples, as mcp-session.sh.
Errors
Transport and protocol problems are JSON-RPC errors:
| Code | Means |
| --- | --- |
| -32700 | The body was not JSON. |
| -32600 | Not a JSON-RPC message, a batch, a body over the size ceiling, or an unauthenticated request (HTTP 401). |
| -32601 | Unknown method, or one of the capabilities this server does not declare. |
| -32602 | Unknown tool name, or arguments that was not an object. |
| -32603 | The server failed. |
Problems with the work itself are tool results with isError: true and a
structuredContent.code: invalid_arguments, quota_exhausted,
start_failed, not_found, read_failed, internal_error. This is deliberate
— a model can read a tool error and decide what to do, where a JSON-RPC error is
the runtime's problem and usually never reaches the model.
Published by Inspired. Fictional brand, working prototype.