indextkn MCP server
Officialby indextkn
README.md
# indextkn MCP server
Live list prices for 900+ AI models across 17 providers, as MCP tools.
indextkn polls every provider's public price page on a five-minute cycle and
normalises what it finds into one catalogue: who sells a model, what each
charges per million tokens, what the context window and cache rates actually
are, and how confident the reading is. This server puts that catalogue in
front of an agent, so a question about cost is answered from today's published
prices instead of from a model's memory.
**Endpoint:** `https://mcp.indextkn.com/mcp` (Streamable HTTP)
**Auth:** your indextkn API key as a bearer token. Free at <https://indextkn.com>,
with 3,000 requests per month per account.
## Connect
### Claude Code
```sh
claude mcp add --transport http indextkn https://mcp.indextkn.com/mcp \
--header "Authorization: Bearer itk_live_your_key"
```
### Claude Desktop, Cursor, and other hosts that take JSON
```json
{
"mcpServers": {
"indextkn": {
"type": "http",
"url": "https://mcp.indextkn.com/mcp",
"headers": { "Authorization": "Bearer itk_live_your_key" }
}
}
}
```
### Locally, over stdio
For a host that spawns servers as child processes, run this repo directly. The
key comes from the environment rather than a header, which is what the MCP
authorization spec prescribes for stdio:
```json
{
"mcpServers": {
"indextkn": {
"command": "bun",
"args": ["run", "/path/to/indextkn-mcp/src/stdio.ts"],
"env": { "INDEXTKN_API_KEY": "itk_live_your_key" }
}
}
}
```
## Tools
Every tool is read-only and idempotent, and is annotated as such, so a host can
auto-approve the whole set.
| Tool | What it answers |
| --- | --- |
| `list_models` | Which models exist, who sells each, and the exact ids every other tool takes. Supports `search`, `lab`, `provider`, `modality`, and paging. |
| `get_model` | One model in full, with every provider's offer: prices, context window, max output, accuracy status, source URL. |
| `get_prices` | The current price of every matching offer. Needs at least one of `model`, `provider` or `lab`. |
| `compare_providers` | The price spread for one model across providers: cheapest, dearest, median, and the ratio between them. |
| `calculate_cost` | What a token workload costs on every provider that sells the model, cheapest first. Step-up price tiers are applied automatically. |
| `list_providers` | The seller catalogue with live counts and what kind of seller each is. |
| `list_labs` | The lab catalogue, meaning who built the models. |
Two prompts ship with it: **cheapest-provider** (compare and recommend) and
**estimate-monthly-cost** (price a month of usage, then show what caching
would change).
### What a real answer looks like
`compare_providers` on `openai/gpt-oss-120b`:
```
openai/gpt-oss-120b: gpt-oss-120b | 8 provider(s) | USD per 1M_tokens
input: min $0.03 (openrouter), max $0.15 (azure), median $0.15, spread 5x
output: min $0.17 (openrouter), max $0.6 (azure), median $0.6, spread 3.53x
cheapest input first:
openrouter: in $0.03, out $0.17, cache-read $0.03
deepinfra: in $0.037, out $0.17
vertex: in $0.09, out $0.36
fireworks: in $0.15, out $0.6, cache-read $0.015
groq: in $0.15, out $0.6
...
```
Renderings are plain ASCII. Fields are separated by `|`, and a value the
provider does not publish reads `n/a`.
### Read the numbers correctly
- **`null` is not `0`.** A `null` price means the provider publishes none. `0`
means free. Never substitute one for the other.
- **Every offer carries a `status`.** `accurate` passed validation.
`checking` and `suspicious` are provisional, so confirm at `source_url`.
`partial` means the seller publishes only one price leg, so any total costed
from it comes out short. `failed` means an automated check could not confirm
the price at all.
- **A `partial` result from `calculate_cost` is a lower bound, not a bargain.**
It means the provider publishes no price for a component you asked about.
- **Model-level `context` is the best any provider offers.** The number on an
offer is what that seller actually serves, and is often smaller. Size a
request against the offer.
- **These are published list prices, collected automatically.** `source_url` on
every offer is the page it was read from. Confirm anything you are about to
spend money on.
## How it is built
The server is a stateless facade over the indextkn REST API. It holds no
database, no cache and no credentials of its own:
```
MCP client --Bearer itk_live_...--> mcp.indextkn.com --same key--> api.indextkn.com
```
Each HTTP request builds its own server instance bound to that request's
caller, so two concurrent callers can never see each other's data. Responses
are deliberately not cached: indextkn meters every request against the
caller's own monthly plan, so a shared cache would both under-count usage and
serve one user's entitlement to another.
What this server adds on top of the API is paging, a local substring `search`,
descriptions written for a model rather than for a developer, and error
messages phrased as next steps. An upstream error that names a REST path is
rewritten to name the tool that reaches it, and an exhausted quota tells the
agent to stop rather than to retry.
Built on the official [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
(`@modelcontextprotocol/server` v2), which serves both the `2026-07-28`
protocol revision and 2025-era clients from the same tool definitions.
The security posture, covering the Host and Origin guards, why an API key is
the right credential here, and what is deliberately not implemented, is in
[SECURITY.md](SECURITY.md).
## Develop
```sh
bun install
bun test # 45 tests: a real MCP client driving the real handler
bun run typecheck
bun run dev # http://localhost:8080/mcp
```
Local runs allow a loopback `Host` and a plaintext `INDEXTKN_API_BASE`, so you
can point the server at a price API running on your own machine. Both are
refused when `NODE_ENV=production`. Every setting is documented in
[.env.example](.env.example).
Poke at it with the MCP inspector:
```sh
bunx @modelcontextprotocol/inspector
```
## Deploy
Railway, from this repo root. `railway.toml` and the `Dockerfile` are the whole
configuration. Point the service's domain at `mcp.indextkn.com`, and set
`MCP_ALLOWED_HOSTS` if you also serve a preview domain. There are no secrets to
set.
## License
MIT. See [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues