unlimited-tavily-mcp
by d1alect-tech
README.md
# unlimited-tavily-mcp
A local [Model Context Protocol](https://modelcontextprotocol.io) server that fronts the official [Tavily remote MCP](https://mcp.tavily.com) and spreads your tool calls across **multiple API keys**.
One Tavily key hits its rate limit? The proxy moves to the next one, transparently.
## How it works
- **Round-robin** — each call goes to the next ready key in the pool.
- **Rate-limited keys (429/432)** enter a cooldown and rejoin automatically. 432 is Tavily's plan usage-limit status (`This request exceeds your plan's set usage limit`) — it is treated like a rate limit because other keys in the pool usually still have quota. A `Retry-After` header from Tavily is honored when present.
- **Invalid keys (401/403)** are disabled for the lifetime of the process.
- **No blind retries** — ambiguous network and server errors are returned as-is so paid operations (search, extract, crawl) are never duplicated.
- **Live key reload** — add a key to the keys file while the server runs; it joins the pool without a restart. Keys are identified only by a short SHA-256 fingerprint; they are never logged.
- **Full tool pass-through** — `tavily_search`, `tavily_extract`, `tavily_crawl`, `tavily_map`, `tavily_research`, including progress notifications for long research calls.
## Requirements
- [Bun](https://bun.sh) — it runs the TypeScript source directly, no build step needed.
- One or more Tavily API keys.
## Setup
```sh
git clone https://github.com/d1alect-tech/unlimited-tavily-mcp.git
cd unlimited-tavily-mcp
bun install
```
Create the keys file (default location: `~/.config/opencode/secrets/tavily.keys`):
```sh
mkdir -p ~/.config/opencode/secrets
cp tavily.keys.example ~/.config/opencode/secrets/tavily.keys
```
Put one key per line. Blank lines and `#` comments are ignored. Duplicates are dropped.
## Use with OpenCode
Add the block from [`opencode.example.jsonc`](opencode.example.jsonc) to your `opencode.jsonc`, pointing the second command argument at your checkout:
```jsonc
"mcp": {
"tavily": {
"type": "local",
"command": ["bun", "/absolute/path/to/unlimited-tavily-mcp/src/index.ts"],
"enabled": true,
"timeout": 970000
}
}
```
## Configuration
| Environment variable | Default | Purpose |
|---|---|---|
| `TAVILY_API_KEYS_FILE` | `~/.config/opencode/secrets/tavily.keys` | Path to the key pool file |
| `TAVILY_MCP_URL` | `https://mcp.tavily.com/mcp/` | Upstream MCP endpoint (HTTPS enforced) |
Run standalone (speaks MCP over stdio, so any MCP client works):
```sh
bun src/index.ts
```
## Development
```sh
bun run test # type-checks and runs the node:test suite (30 tests)
```
## Security
Keys are read from a file outside the repo and never appear in logs — a `tvly-*` redactor guards every error path. See [SECURITY.md](SECURITY.md).
## License
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessUnresponsive