Which AI model to call on the providers you have: model id, price and reason.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Bearer followed by your Rhumb API key (nnm_live_… or nnm_test_…), from rhumbdata.com/app/keys
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
One model by id (`vendor/model`, e.g. `anthropic/claude-sonnet-4.5`): every provider's offering with its price history, capabilities, limits and dates, and the model's quality scores. Counts as one call.
The model's id, `vendor/model`, or an alias of it.
ISO date or time: return the price revision in force then.
Only this provider's offering.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http rhumb https://rhumbdata.com/v1/mcp \ --header 'Authorization: Bearer YOUR_TOKEN'
Headers
Authorization (required): Bearer followed by your Rhumb API key (nnm_live_… or nnm_test_…), from rhumbdata.com/app/keysOne model by id (`vendor/model`, e.g. `anthropic/claude-sonnet-4.5`): every provider's offering with its price history, capabilities, limits and dates, and the model's quality scores. Counts as one call.
| Argument | Type | Description |
|---|---|---|
| at | string | ISO date or time: return the price revision in force then. |
| id* | string | The model's id, `vendor/model`, or an alias of it. |
| provider | string | Only this provider's offering. |
{
"type": "object",
"required": [
"id"
],
"properties": {
"at": {
"type": "string",
"description": "ISO date or time: return the price revision in force then."
},
"id": {
"type": "string",
"description": "The model's id, `vendor/model`, or an alias of it."
},
"provider": {
"type": "string",
"description": "Only this provider's offering."
}
},
"additionalProperties": false
}Every name the other tools accept: tasks, capabilities and their levels, providers, origin groups, budgets and team strategies. Free.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}The catalog's models with each provider's offering, price, capabilities and quality scores, filtered by task, providers and needs. Returns 20 models unless `limit` says otherwise; page with `offset`. Counts as one call.
| Argument | Type | Description |
|---|---|---|
| task | string | Only models for this task. |
| limit | string | Page size, 1–500 (default 20). |
| needs | string | Only offerings with these capabilities. Comma-separated. |
| offset | string | Models to skip (default 0). |
| providers | string | Only offerings on these providers. Comma-separated. |
| include_hidden | string | Include offerings that are never recommended (default false). |
| include_retired | string | Include retired offerings (default false). |
{
"type": "object",
"properties": {
"task": {
"type": "string",
"description": "Only models for this task."
},
"limit": {
"type": "string",
"pattern": "^\\d+$",
"description": "Page size, 1–500 (default 20)."
},
"needs": {
"type": "string",
"description": "Only offerings with these capabilities. Comma-separated."
},
"offset": {
"type": "string",
"pattern": "^\\d+$",
"description": "Models to skip (default 0)."
},
"providers": {
"type": "string",
"description": "Only offerings on these providers. Comma-separated."
},
"include_hidden": {
"enum": [
"true",
"false"
],
"type": "string",
"description": "Include offerings that are never recommended (default false)."
},
"include_retired": {
"enum": [
"true",
"false"
],
"type": "string",
"description": "Include retired offerings (default false)."
}
},
"additionalProperties": false
}The purpose presets `resolve` accepts: named jobs such as reading receipts or a coding agent, each with the task, needs and budget it stands for. Free.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Reads a description of the work (a prompt, tags, attachment types and sizes) into a need, then resolves it as `resolve` does. Use `resolve` when you can state the task or purpose yourself; use this when you only have the user's words. Counts as more than one call.
| Argument | Type | Description |
|---|---|---|
| tags | array | Free tags, e.g. ["vision", "read receipts", "usa", "medium"]. |
| shape | string | As in /v1/resolve, or auto: a team purpose's team and an escalation purpose's ladder; else a team when the reading says several models would help (ensemble_helps), an escalation when the request gives length, else single. |
| device | object | The device's memory, GPU memory and free disk in GB, for local runtimes: facts that become max_memory_gb, max_vram_gb and max_disk_gb unless constraints set them. |
| prompt | string | The request to read. Sent only to the decision model you choose; never stored or logged. |
| decision | object | |
| providers* | array | Required. Provider names, in order of preference for ties. |
| attachments | array | |
Which model to call for a need, on the providers the user has accounts with: the provider's own model id, its price, capabilities and the reason. Give `providers` and a `task` or a `purpose`; add `needs`, `budget`, `origin` and other constraints to narrow it. `shape` asks for a team or an escalation ladder instead of one model. Counts as one call. An answer of `no_candidate` names what ruled every model out and the nearest miss.
| Argument | Type | Description |
|---|---|---|
| task | string | A task, e.g. text.chat. Required unless purpose is given. |
| hours | string | UTC hours you make your calls in, every day, as HH-HH ranges: 09-17, or 22-06 past midnight, or 00-24. A price with cheaper hours then ranks on its average over these hours instead of over a flat week. Comma-separated. |
| needs | string | Required capabilities, optionally with a level: "input.pdf:native". Comma-separated. |
| pages | string | PDF pages per call. |
| roles | string | Team roles: "name:count" pairs, comma-separated (lead:1,workers:4), or a JSON object of role name to { count, task, needs, min_quality, optimize, distinct_vendor_from, distinct_family, judges }. Overrides and extends the strategy's roles. |
| shape | string | single (default, or the purpose's), team (with strategy or roles) or escalation (a ladder of length steps, or one model then a team with strategy or roles). |
We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 13, 2026.
| constraints |
| object |
| Any /v1/resolve query parameter except providers, as strings; these win over the reading. When these and the recognised tags settle the task or purpose and the budget, give needs (even empty), no tag is unrecognised, and no shape is left to the reading, the prompt is not read: the reading is empty and decision.model is local. |
{
"type": "object",
"required": [
"providers"
],
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 50,
"description": "Free tags, e.g. [\"vision\", \"read receipts\", \"usa\", \"medium\"]."
},
"shape": {
"enum": [
"single",
"team",
"escalation",
"auto"
],
"type": "string",
"description": "As in /v1/resolve, or auto: a team purpose's team and an escalation purpose's ladder; else a team when the reading says several models would help (ensemble_helps), an escalation when the request gives length, else single."
},
"device": {
"type": "object",
"properties": {
"disk_gb": {
"type": "number",
"exclusiveMinimum": 0
},
"vram_gb": {
"type": "number",
"exclusiveMinimum": 0
},
"memory_gb": {
"type": "number",
"exclusiveMinimum": 0
}
},
"description": "The device's memory, GPU memory and free disk in GB, for local runtimes: facts that become max_memory_gb, max_vram_gb and max_disk_gb unless constraints set them.",
"additionalProperties": false
},
"prompt": {
"type": "string",
"description": "The request to read. Sent only to the decision model you choose; never stored or logged."
},
"decision": {
"type": "object",
"properties": {
"model": {
"enum": [
"openai",
"local",
"jev"
],
"type": "string",
"description": "openai (default) or local; jev is for internal accounts only."
},
"allow_remote": {
"type": "boolean",
"description": "false keeps the prompt on the server: the local classifier only. When the account turns on \"Keep prompts on Rhumb's server\" in Settings, every request reads this way."
}
},
"additionalProperties": false
},
"providers": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "Required. Provider names, in order of preference for ties."
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"required": [
"type",
"bytes"
],
"properties": {
"type": {
"type": "string",
"description": "MIME type, e.g. image/jpeg. Only type and size are sent, never the file."
},
"bytes": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"pages": {
"type": "integer",
"maximum": 9007199254740991,
"exclusiveMinimum": 0
},
"seconds": {
"type": "number",
"minimum": 0
}
},
"additionalProperties": false
},
"maxItems": 20
},
"constraints": {
"type": "object",
"description": "Any /v1/resolve query parameter except providers, as strings; these win over the reading. When these and the recognised tags settle the task or purpose and the budget, give needs (even empty), no tag is unrecognised, and no shape is left to the reading, the prompt is not read: the reading is empty and decision.model is local.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
}
},
"additionalProperties": false
}| budget | string | Thirds of the market's prices for the task. |
| images | string | Input images per call. |
| length | string | Escalation steps, 1–5 (default 3). |
| origin | string | Model maker countries or groups: "us", "eu", "not:cn". Comma-separated. |
| exclude | string | Model ids, vendors, or provider:model pairs to leave out. Comma-separated. |
| license | string | Accepted open-weight licenses. Comma-separated. |
| purpose | string | A purpose preset id or alias, e.g. read-receipts. |
| currency | string | Adds the typical call converted to this currency, e.g. EUR. |
| optimize | string | cost (default), quality or value. |
| strategy | string | A team strategy preset: its roles and their rules. |
| max_price | string | Hard cap on the typical call, in USD, e.g. 0.002, at the day's highest rate. |
| providers* | string | Required. Provider names you have accounts with, in order of preference for ties. Never keys. Comma-separated. |
| synthesis | string | Add a synthesizer role to the team. |
| origin_mix | string | Team origin rules: "eu:>=1", "cn:<=0", "us:=2". Comma-separated. |
| resolution | string | Image resolution key, e.g. "1k". |
| allow_trial | string | Allow trial offerings, which aren't for production (default false). |
| max_disk_gb | string | Local runtimes: free disk in GB for the weights. |
| max_vram_gb | string | Local runtimes: GPU memory in GB, for a full offload. On Apple silicon send the GPU's share of unified memory (macOS allows about 2/3 by default, 3/4 above 36 GB) and the total as max_memory_gb. |
| min_context | string | Minimum context window in tokens. |
| min_quality | string | Minimum quality score, 0–1. |
| allow_closed | string | Allow models the provider has closed to new accounts. Send true only if your account used them before (default false). |
| input_tokens | string | Expected input tokens per call. |
| service_tier | string |
| allow_preview | string | Allow preview models (default false). |
| audio_seconds | string | Audio seconds per call. |
| max_memory_gb | string | Local runtimes: the device's memory in GB (10^9 bytes). A local offering fits when its weights, KV cache at the request's min_context (8,192 tokens when smaller) and runtime overhead fit. Cloud offerings are not limited. |
| origin_strict | string | Also require a fine-tune's base model maker to match. |
| output_images | string | Generated images per call. |
| output_tokens | string | Expected output tokens per call. |
| prompt_tokens | string | Prompt size, for long-prompt price tiers. |
| video_seconds | string | Video seconds per call. |
| provider_terms | string | Your terms per provider: "openrouter:byok", "gemini:free_tier", "openai:discount:0.2". Comma-separated. |
| quality_margin | string | For optimize=cost: how far below the best score still counts (default 0.05). |
| released_after | string | YYYY-MM-DD. |
| providers_distinct | string | Every team member, or escalation step, on a different provider. |
| cached_input_tokens | string | Input tokens served from the provider's cache. |
{
"type": "object",
"required": [
"providers"
],
"properties": {
"task": {
"type": "string",
"description": "A task, e.g. text.chat. Required unless purpose is given."
},
"hours": {
"type": "string",
"description": "UTC hours you make your calls in, every day, as HH-HH ranges: 09-17, or 22-06 past midnight, or 00-24. A price with cheaper hours then ranks on its average over these hours instead of over a flat week. Comma-separated."
},
"needs": {
"type": "string",
"description": "Required capabilities, optionally with a level: \"input.pdf:native\". Comma-separated."
},
"pages": {
"type": "string",
"pattern": "^\\d+$",
"description": "PDF pages per call."
},
"roles": {
"type": "string",
"description": "Team roles: \"name:count\" pairs, comma-separated (lead:1,workers:4), or a JSON object of role name to { count, task, needs, min_quality, optimize, distinct_vendor_from, distinct_family, judges }. Overrides and extends the strategy's roles."
},
"shape": {
"enum": [
"single",
"team",
"escalation"
],
"type": "string",
"description": "single (default, or the purpose's), team (with strategy or roles) or escalation (a ladder of length steps, or one model then a team with strategy or roles)."
},
"budget": {
"enum": [
"cheap",
"medium",
"premium"
],
"type": "string",
"description": "Thirds of the market's prices for the task."
},
"images": {
"type": "string",
"pattern": "^\\d+$",
"description": "Input images per call."
},
"length": {
"type": "string",
"pattern": "^\\d+$",
"description": "Escalation steps, 1–5 (default 3)."
},
"origin": {
"type": "string",
"description": "Model maker countries or groups: \"us\", \"eu\", \"not:cn\". Comma-separated."
},
"exclude": {
"type": "string",
"description": "Model ids, vendors, or provider:model pairs to leave out. Comma-separated."
},
"license": {
"type": "string",
"description": "Accepted open-weight licenses. Comma-separated."
},
"purpose": {
"type": "string",
"description": "A purpose preset id or alias, e.g. read-receipts."
},
"currency": {
"type": "string",
"description": "Adds the typical call converted to this currency, e.g. EUR."
},
"optimize": {
"enum": [
"cost",
"quality",
"value"
],
"type": "string",
"description": "cost (default), quality or value."
},
"strategy": {
"enum": [
"debate",
"red-team",
"competitive",
"hierarchical",
"expert-panel",
"collaborative"
],
"type": "string",
"description": "A team strategy preset: its roles and their rules."
},
"max_price": {
"type": "string",
"description": "Hard cap on the typical call, in USD, e.g. 0.002, at the day's highest rate."
},
"providers": {
"type": "string",
"description": "Required. Provider names you have accounts with, in order of preference for ties. Never keys. Comma-separated."
},
"synthesis": {
"enum": [
"true",
"false"
],
"type": "string",
"description": "Add a synthesizer role to the team."
},
"origin_mix": {
"type": "string",
"description": "Team origin rules: \"eu:>=1\", \"cn:<=0\", \"us:=2\". Comma-separated."
},
"resolution": {
"type": "string",
"description": "Image resolution key, e.g. \"1k\"."
},
"allow_trial": {
"enum": [
"true",
"false"
],
"type": "string",
"description": "Allow trial offerings, which aren't for production (default false)."
},
"max_disk_gb": {
"type": "string",
"pattern": "^\\d+(\\.\\d+)?$",
"description": "Local runtimes: free disk in GB for the weights."
},
"max_vram_gb": {
"type": "string",
"pattern": "^\\d+(\\.\\d+)?$",
"description": "Local runtimes: GPU memory in GB, for a full offload. On Apple silicon send the GPU's share of unified memory (macOS allows about 2/3 by default, 3/4 above 36 GB) and the total as max_memory_gb."
},
"min_context": {
"type": "string",
"pattern": "^\\d+$",
"description": "Minimum context window in tokens."
},
"min_quality": {
"type": "string",
"description": "Minimum quality score, 0–1."
},
"allow_closed": {
"enum": [
"true",
"false"
],
"type": "string",
"description": "Allow models the provider has closed to new accounts. Send true only if your account used them before (default false)."
},
"input_tokens": {
"type": "string",
"pattern": "^\\d+$",
"description": "Expected input tokens per call."
},
"service_tier": {
"enum": [
"standard",
"batch",
"flex",
"priority"
],
"type": "string"
},
"allow_preview": {
"enum": [
"true",
"false"
],
"type": "string",
"description": "Allow preview models (default false)."
},
"audio_seconds": {
"type": "string",
"pattern": "^\\d+$",
"description": "Audio seconds per call."
},
"max_memory_gb": {
"type": "string",
"pattern": "^\\d+(\\.\\d+)?$",
"description": "Local runtimes: the device's memory in GB (10^9 bytes). A local offering fits when its weights, KV cache at the request's min_context (8,192 tokens when smaller) and runtime overhead fit. Cloud offerings are not limited."
},
"origin_strict": {
"enum": [
"true",
"false"
],
"type": "string",
"description": "Also require a fine-tune's base model maker to match."
},
"output_images": {
"type": "string",
"pattern": "^\\d+$",
"description": "Generated images per call."
},
"output_tokens": {
"type": "string",
"pattern": "^\\d+$",
"description": "Expected output tokens per call."
},
"prompt_tokens": {
"type": "string",
"pattern": "^\\d+$",
"description": "Prompt size, for long-prompt price tiers."
},
"video_seconds": {
"type": "string",
"pattern": "^\\d+$",
"description": "Video seconds per call."
},
"provider_terms": {
"type": "string",
"description": "Your terms per provider: \"openrouter:byok\", \"gemini:free_tier\", \"openai:discount:0.2\". Comma-separated."
},
"quality_margin": {
"type": "string",
"description": "For optimize=cost: how far below the best score still counts (default 0.05)."
},
"released_after": {
"type": "string",
"description": "YYYY-MM-DD."
},
"providers_distinct": {
"enum": [
"true",
"false"
],
"type": "string",
"description": "Every team member, or escalation step, on a different provider."
},
"cached_input_tokens": {
"type": "string",
"pattern": "^\\d+$",
"description": "Input tokens served from the provider's cache."
}
},
"additionalProperties": false
}