A Cloudflare Worker that acts as an MCP (Model Context Protocol) proxy for the Tavily API. It provides the same tools as the official Tavily MCP server, but with an API key pool — automatically rotating through multiple Tavily keys and selecting the one with the most remaining credit.
- MCP Server — Streamable HTTP transport at
POST /mcp, compatible with any MCP client - 4 Tavily Tools —
tavily-search,tavily-extract,tavily-crawl,tavily-map - API Key Pool — Multiple Tavily API keys stored in Cloudflare KV; each request picks the key with the highest remaining credit
- Key Management API — HTTP endpoints to add/delete keys and query their status
- Auth Protected — All endpoints (except health check) require an
x-api-keyheader
| Method | Path | Description |
|---|---|---|
POST |
/mcp |
MCP Streamable HTTP endpoint (tool calls) |
POST |
/api/keys |
Add a Tavily API key to the pool |
DELETE |
/api/keys |
Remove a Tavily API key from the pool |
GET |
/api/keys |
List all keys and their remaining credits |
GET |
/ |
Health check (no auth required) |
All endpoints except GET / require the x-api-key header matching your configured AUTH_KEY.
- Node.js v18+
- Wrangler CLI (
npm install -g wrangler) - A Cloudflare account
# Install dependencies
npm install
# Set your auth key for local dev (already in .dev.vars)
# AUTH_KEY=test-secret-key
# Start local server
npm run devWrangler simulates KV locally — no Cloudflare account needed for development.
-
Create a KV namespace:
npx wrangler kv namespace create KV
-
Update
wrangler.toml— replaceYOUR_KV_NAMESPACE_IDwith the real ID from step 1. -
Set the auth secret:
npx wrangler secret put AUTH_KEY
-
Deploy:
npm run deploy
-
Add Tavily API keys to the pool:
curl -X POST https://your-worker.workers.dev/api/keys \ -H "Content-Type: application/json" \ -H "x-api-key: your-auth-key" \ -d '{"apiKey": "tvly-xxx"}'
With mcp-remote (for clients like Cursor, Claude Desktop, etc.):
{
"mcpServers": {
"tavily-proxy": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://your-worker.workers.dev/mcp",
"--header", "x-api-key:${AUTH_KEY}"
],
"env": {
"AUTH_KEY": "your-auth-key"
}
}
}
}# Add a key (auto-queries remaining credit from Tavily)
curl -X POST https://your-worker.workers.dev/api/keys \
-H "Content-Type: application/json" \
-H "x-api-key: your-auth-key" \
-d '{"apiKey": "tvly-xxx"}'
# List all keys and credits
curl https://your-worker.workers.dev/api/keys \
-H "x-api-key: your-auth-key"
# Delete a key
curl -X DELETE https://your-worker.workers.dev/api/keys \
-H "Content-Type: application/json" \
-H "x-api-key: your-auth-key" \
-d '{"apiKey": "tvly-xxx"}'- When a tool is called,
KV.list()retrieves all stored API keys - The key with the largest remaining credit is selected
- The request is proxied to
api.tavily.comusing that key - After the call, the estimated credit cost is deducted locally in KV
- When a key is added via
/api/keys, its real remaining credit is fetched from Tavily's/usageendpoint
ISC