Tavily Hikari is a Rust + Axum proxy for Tavily's MCP endpoint. It multiplexes multiple API keys, anonymizes upstream traffic, stores full audit logs in SQLite, and ships with a React + Vite web console for realtime visibility.
Looking for the Chinese documentation? Check
README.zh-CN.md.
exhausted until the next UTC month or manual recovery./mcp traffic is tunneled upstream; sensitive headers are stripped or rewritten. See docs/high-anonymity-proxy.md.request_logs persists method/path/query, upstream responses, error payloads, and the list of forwarded/dropped headers.web/ visualizes key health, request logs, and admin actions (soft delete, restore, reveal real keys).ghcr.io/ivanli-cn/tavily-hikari:<tag> with prebuilt web assets.Client → Tavily Hikari (Axum) ──┬─> Tavily upstream (/mcp) ├─> SQLite (api_keys, request_logs) └─> Web SPA (React/Vite)
api_keys + request_logs.web/dist or via Vite dev server).# Start backend (high port recommended during dev)
cargo run -- --bind 127.0.0.1 --port 58087
# Optional: start SPA dev server
cd web && npm ci && npm run dev -- --host 127.0.0.1 --port 55173
# Register Tavily keys via admin API (ForwardAuth headers depend on your setup)
curl -X POST http://127.0.0.1:58087/api/keys \
-H "X-Forwarded-User: admin@example.com" \
-H "X-Forwarded-Admin: true" \
-H "Content-Type: application/json" \
-d '{"api_key":"key_a"}'
Visit http://127.0.0.1:58087/health for a health check or http://127.0.0.1:55173 for the console. Keys should be managed via the admin API or SPA instead of environment variables.
docker run --rm \
-p 8787:8787 \
-v $(pwd)/data:/srv/app/data \
ghcr.io/ivanli-cn/tavily-hikari:latest
The container listens on 0.0.0.0:8787, serves web/dist, and persists data in /srv/app/data/tavily_proxy.db. Once it is up, register keys via the admin API/console.
docker compose up -d
# Seed initial keys (requires ForwardAuth headers)
curl -X POST http://127.0.0.1:8787/api/keys \
-H "X-Forwarded-User: admin@example.com" \
-H "X-Forwarded-Admin: true" \
-H "Content-Type: application/json" \
-d '{"api_key":"key_a"}'
The stock docker-compose.yml exposes port 8787 and mounts a tavily-hikari-data volume. Override any CLI flag with additional environment variables if needed.
| Flag / Env | Description |
|---|---|
--keys / TAVILY_API_KEYS | Optional helper for bootstrapping or local experiments. In production, prefer the admin API/UI to manage keys. |
--upstream / TAVILY_UPSTREAM | Tavily MCP upstream (default https://mcp.tavily.com/mcp). |
--bind / PROXY_BIND | Listen address (default 127.0.0.1). |
--port / PROXY_PORT | Listen port (default 8787). |
--db-path / PROXY_DB_PATH | SQLite file path (default tavily_proxy.db). |
--static-dir / WEB_STATIC_DIR | Directory for static assets; auto-detected if web/dist exists. |
--forward-auth-header / FORWARD_AUTH_HEADER | Request header that carries the authenticated user identity (e.g., Remote-Email). |
--forward-auth-admin-value / FORWARD_AUTH_ADMIN_VALUE | Header value that grants admin privileges; leave empty to disable. |
--forward-auth-nickname-header / FORWARD_AUTH_NICKNAME_HEADER | Optional header for displaying a friendly name in the UI (e.g., Remote-Name). |
--admin-mode-name / ADMIN_MODE_NAME | Override nickname when ForwardAuth headers are missing. |
--admin-auth-forward-enabled / ADMIN_AUTH_FORWARD_ENABLED | Boolean switch to enable ForwardAuth checks (default true). |
--admin-auth-builtin-enabled / ADMIN_AUTH_BUILTIN_ENABLED | Boolean switch to enable built-in admin login (cookie session) (default false). |
--admin-auth-builtin-password-hash / ADMIN_AUTH_BUILTIN_PASSWORD_HASH | Built-in admin password hash (PHC string, recommended). |
--admin-auth-builtin-password / ADMIN_AUTH_BUILTIN_PASSWORD | Built-in admin password (deprecated; prefer password hash). |
--dev-open-admin / DEV_OPEN_ADMIN | Boolean flag to bypass admin checks in local/dev setups (default false). |
If --keys/TAVILY_API_KEYS is supplied, the database sync logic adds or revives keys listed there and soft deletes the rest. Otherwise, the admin workflow fully controls key state.
| Method | Path | Description | Auth |
|---|---|---|---|
GET | /health | Liveness probe. | none |
GET | /api/summary | High-level success/failure stats and last activity. | none |
GET | /api/keys | Lists short IDs, status, and counters. | Admin |
GET | /api/logs?page=1 | Recent proxy logs (paginated, default 20 per page). | Admin |
POST | /api/tavily/search | Tavily /search proxy via Hikari key pool (Cherry Studio, etc.). | Hikari token |
POST | /api/keys | Admin: add/restore a key. Body { "api_key": "..." }. | Admin |
DELETE | /api/keys/:id | Admin: soft-delete key by short ID. | Admin |
GET | /api/keys/:id/secret | Admin: reveal the real Tavily key. | Admin |
Tavily Hikari also exposes a Tavily HTTP façade so Cherry Studio and other HTTP clients can talk to Tavily through Hikari’s key pool and per-token quotas instead of calling Tavily directly.
https://<your Hikari host>/api/tavilyth-<id>-<secret> created from the user dashboardCherry Studio setup:
th-xxxx-xxxxxxxxxxxx) from the Tavily Hikari user dashboard and copy it.https://<your Hikari host>/api/tavily (for local dev it is usually http://127.0.0.1:58087/api/tavily).th-xxxx-xxxxxxxxxxxx value), not your Tavily official API key.Do not put your Tavily API key directly into Cherry Studio. Always route traffic through Hikari by using its access token.
For the full HTTP proxy design and acceptance criteria, see docs/tavily-http-api-proxy.md.
exhausted status is triggered automatically when upstream returns 432; scheduler skips those keys until UTC month rollover or manual recovery.request_logs captures request metadata, upstream payloads, and dropped/forwarded header sets for postmortem analysis.docs/high-anonymity-proxy.md.Tavily Hikari relies on a zero-trust/ForwardAuth proxy to decide who can operate admin APIs. Configure the following environment variables (or CLI flags) to match your identity provider:
export ADMIN_AUTH_FORWARD_ENABLED=true
export FORWARD_AUTH_HEADER=Remote-Email
export FORWARD_AUTH_ADMIN_VALUE=admin@example.com
export FORWARD_AUTH_NICKNAME_HEADER=Remote-Name
FORWARD_AUTH_HEADER. If its value equals FORWARD_AUTH_ADMIN_VALUE, the caller is treated as an admin and can hit /api/keys/* privileged endpoints.FORWARD_AUTH_NICKNAME_HEADER (optional) is surfaced in the UI to show who is operating the console. When absent, the backend falls back to ADMIN_MODE_NAME (if provided) or hides the nickname.DEV_OPEN_ADMIN=true, but never enable it in production.If you cannot (or do not want to) run a ForwardAuth gateway, Tavily Hikari can expose a built-in admin login page backed by an HttpOnly cookie session.
export ADMIN_AUTH_BUILTIN_ENABLED=true
echo -n 'change-me' | cargo run --quiet --bin admin_password_hash
export ADMIN_AUTH_BUILTIN_PASSWORD_HASH='<phc-string>'
# Optional: disable ForwardAuth entirely if you are not using it.
export ADMIN_AUTH_FORWARD_ENABLED=false
hikari_admin_session) and unlocks admin-only APIs + /admin.ADMIN_AUTH_BUILTIN_PASSWORD_HASH (PHC string) and use a strong password.Max-Age, default 14 days). Restarting the process logs users out.X-Forwarded-Proto: https (or Forwarded: proto=https) so the backend can mark the session cookie as Secure.Deployment example (Caddy as gateway): see examples/forwardauth-caddy/.
scripts/write-version.mjs stamps the build version into the UI during CI releases.npm run dev proxies /api, /mcp, and /health to the backend to avoid CORS hassle during development.Operator and integration views of Tavily Hikari.



Tavily Hikari speaks standard MCP over HTTP and works with popular clients:
Example (Codex CLI — ~/.codex/config.toml):
experimental_use_rmcp_client = true [mcp_servers.tavily_hikari] url = "https://<your-host>/mcp" bearer_token_env_var = "TAVILY_HIKARI_TOKEN"
Then set the token and verify:
export TAVILY_HIKARI_TOKEN="<token>" codex mcp list | grep tavily_hikari
rust-toolchain.toml.cargo fmt, cargo clippy -- -D warnings, cargo test --locked --all-features, cargo run -- --help.npm ci, npm run dev, npm run build (runs tsc -b + vite build).lefthook install to enable automatic cargo fmt, cargo clippy, npx dprint fmt, and npx commitlint --edit on every commit..github/workflows/ci.yml runs lint/tests/build..github/workflows/release.yml runs after main CI succeeds and publishes tags, GitHub Releases, and GHCR images.Releases are label-driven:
type:patch, type:minor, type:major, type:docs, or type:skip.channel:stable or channel:rc.main and CI passes, the release workflow computes the next stable semver (X.Y.Z) and publishes:
channel:stable): latest, vX.Y.Zchannel:rc): vX.Y.Z-rc.<sha7> (no latest)/mcp, /api/*, and static assets; everything else returns 404.docs/high-anonymity-proxy.md when operating in high-anonymity environments.tavily_proxy.db via volumes or external storage and export request_logs for compliance if needed.Distributed under the MIT License. Keep the license notice intact when copying or distributing the software.