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.
- Public docs site: ivanli-cn.github.io/tavily-hikari
- Storybook: ivanli-cn.github.io/tavily-hikari/storybook.html
- Local docs-site:
cd docs-site && bun install --frozen-lockfile && bun run dev - Local Storybook:
cd web && bun install --frozen-lockfile && bun run storybook
- Run
bun install --frozen-lockfileonce in the primary worktree. The rootpreparescript installs the sharedpost-checkouthook and refresheslefthookcommit hooks when thelefthookbinary is available onPATH. - The first checkout into a linked worktree now performs a best-effort bootstrap: copy missing root
.env/.env.*files from the primary worktree, install missing root /web/docs-siteBun dependencies, and runcargo fetch --locked. - Automatic bootstrap never blocks checkout. Missing
lefthook,bun,cargo, or source env files only emit warnings. - For an explicit repair, run
bun run worktree:setup. It forces the same bootstrap steps again and fails only when an available restore command itself fails. - The bootstrap intentionally does not restore
*.db,web/dist,web/storybook-static,downloads/, browser caches, Playwright install state, or other runtime artifacts.
- Key pool with fairness – SQLite keeps last-used timestamps and assigns each access token a short‑lived “home” key; new or expired affinities are resolved via least‑recently‑used selection across active keys to keep wear balanced.
- Short IDs and secret isolation – every Tavily key receives a 4-char nanoid. The real token is only retrievable via admin APIs/UI.
- Health-aware routing – status code 432 automatically marks keys as
exhausteduntil the next UTC month or manual recovery. - High-anonymity forwarding – outbound Tavily HTTP, Rebalance MCP HTTP, and Control MCP requests now share strict header allowlists; Tavily HTTP strips
User-Agent,X-Project-IDis policy-controlled (accessTokenby default), and Control MCP only sends a configuredUser-Agentwhen the administrator explicitly sets one. Seedocs/high-anonymity-proxy.md. - Segmented reconciliation for anonymized billing – when
accessTokenmode is active and both rebalance switches are enabled, Hikari records real(token, key, period)usage, actively closes Research in bounded background sweeps, settles each full business period once, and applies signed quota adjustments back to the original window. - Full audit trail –
request_logspersists method/path/query, upstream responses, error payloads, and the list of forwarded/dropped headers. - Operator UI – the SPA in
web/visualizes key health, request logs, and admin actions (soft delete, restore, reveal real keys). - Admin system status –
/admin/system-settings/statusshows the configured/effective upstream identity policy, activation gates, settlement queue state, current-day reconciliation coverage, per-Key cooldown diagnostics, and recent adjustments without exposing raw upstream credentials. - Path-based web console routes – the user console now uses
/console,/console/dashboard,/console/tokens, and/console/tokens/:id; homepage token bootstrap intentionally remains hash-based (/#<token>or/#<token-id>) so full tokens never move into path/query logging surfaces. - Split PWA identities – the public/user web app installs from
/,/console,/login, and/registration-paused, while the admin web app installs only from/admin/*; both can reopen their shell offline, but live data and mutations stay network-only. - Repo-local Relay Mesh brand assets – the favicon, touch icons, public/admin PWA icons, and docs-site logo all derive from checked-in approved Relay Mesh lockup/icon assets, so the brand layer stays consistent without runtime image/CDN dependencies.
- CI + Release – GitHub Actions runs lint/tests; releases are driven by PR intent labels and publish
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)
- Backend: Rust 2024 edition, Axum, SQLx, Tokio, Clap.
- Data: SQLite single-file DB with
api_keys+request_logs. - Frontend: React 18, TanStack Router, Tailwind CSS, shadcn/ui (Radix), Vite 5 (served from
web/distor via Vite dev server).
# Start backend (high port recommended during dev)
DEV_OPEN_ADMIN=true cargo run -- --bind 127.0.0.1 --port 58087
# Optional: start SPA dev server
cd web && bun install --frozen-lockfile && bun run --bun dev -- --host 127.0.0.1 --port 55173
# Register Tavily keys via admin API in local dev mode
curl -X POST http://127.0.0.1:58087/api/keys \
-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.
Run the SPA with browser-local API and SSE mocks when you need to show the product without a backend, database, or real Tavily upstream:
scripts/start-web-demo.shThe demo listens on http://127.0.0.1:55174 by default. It serves the normal Public,
User Console, Admin, Login, and Registration Paused pages while VITE_DEMO_MODE=true
intercepts /api/* and /mcp inside the browser.
docker run --rm \
-p 8787:8787 \
-v $(pwd)/data:/srv/app/data \
ghcr.io/ivanli-cn/tavily-hikari:latestThe 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.
GitHub Releases attach Linux tar.gz builds for linux/amd64 and linux/arm64, plus matching SHA256 files. The release binary carries the web UI inside the executable, so you do not need a separate web/dist directory at runtime.
docker compose up -d
# Seed initial keys after enabling an admin auth mode.
curl -X POST http://127.0.0.1:8787/api/keys \
-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 endpoint (default https://mcp.tavily.com/mcp); path-prefixed reverse-proxy URLs are supported. |
--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). |
--log-format / RUNTIME_LOG_FORMAT |
Runtime log formatter (json by default, text for fallback grep workflows). |
--low-quota-depletion-threshold / LOW_QUOTA_DEPLETION_THRESHOLD |
Remaining-credit threshold for keeping 432-exhausted upstream keys out of normal monthly pools (default 15). |
--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 legacy ForwardAuth checks (default false; full legacy header config auto-enables it). |
--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). |
--linuxdo-oauth-enabled / LINUXDO_OAUTH_ENABLED |
Enable Linux DO Connect OAuth2 login for end users (default false). |
--linuxdo-oauth-client-id / LINUXDO_OAUTH_CLIENT_ID |
Linux DO OAuth2 client ID (connect.linux.do app). |
--linuxdo-oauth-client-secret / LINUXDO_OAUTH_CLIENT_SECRET |
Linux DO OAuth2 client secret. |
--linuxdo-oauth-authorize-url / LINUXDO_OAUTH_AUTHORIZE_URL |
OAuth2 authorize endpoint (default https://connect.linux.do/oauth2/authorize). |
--linuxdo-oauth-token-url / LINUXDO_OAUTH_TOKEN_URL |
OAuth2 token endpoint (default https://connect.linux.do/oauth2/token). |
--linuxdo-oauth-userinfo-url / LINUXDO_OAUTH_USERINFO_URL |
OAuth2 user profile endpoint (default https://connect.linux.do/api/user). |
--linuxdo-oauth-scope / LINUXDO_OAUTH_SCOPE |
OAuth scope (default user). |
--linuxdo-oauth-redirect-url / LINUXDO_OAUTH_REDIRECT_URL |
Frontend callback URL on this service (for example https://tavily.ivanli.cc/console/oauth/linuxdo/callback). |
--linuxdo-oauth-refresh-token-crypt-key / LINUXDO_OAUTH_REFRESH_TOKEN_CRYPT_KEY |
Encrypts persisted LinuxDo refresh tokens (32 raw bytes or base64/base64url encoded 32-byte key). |
--linuxdo-oauth-user-sync-enabled / LINUXDO_OAUTH_USER_SYNC_ENABLED |
Enable the daily LinuxDo offline user sync scheduler (default true). |
--linuxdo-oauth-user-sync-at / LINUXDO_OAUTH_USER_SYNC_AT |
Daily LinuxDo offline sync time in server local time, format HH:mm (default 06:20). |
--linuxdo-credit-enabled / LINUXDO_CREDIT_ENABLED |
Enable the Linux.do Credit recharge payment flow (default false). |
--linuxdo-credit-client-id / LINUXDO_CREDIT_CLIENT_ID |
Linux.do Credit application client ID. |
--linuxdo-credit-client-secret / LINUXDO_CREDIT_CLIENT_SECRET |
Linux.do Credit application client secret. |
--linuxdo-credit-merchant-private-key / LINUXDO_CREDIT_MERCHANT_PRIVATE_KEY |
Ed25519 merchant private key for Linux.do Credit LDC signing. |
--linuxdo-credit-submit-url / LINUXDO_CREDIT_SUBMIT_URL |
Linux.do Credit LDC submit endpoint (default https://credit.linux.do/epay/pay/submit.php). |
--linuxdo-credit-notify-url / LINUXDO_CREDIT_NOTIFY_URL |
Optional order-level notify URL, usually https://<your-host>/api/linuxdo-credit/notify. |
--linuxdo-credit-return-url / LINUXDO_CREDIT_RETURN_URL |
Optional browser return URL after payment, usually https://<your-host>/console/dashboard. |
--linuxdo-credit-test-price-enabled / LINUXDO_CREDIT_TEST_PRICE_ENABLED |
Enable the test offer where 1 LDC buys 1 monthly credit (default false). |
--user-session-max-age-secs / USER_SESSION_MAX_AGE_SECS |
End-user login cookie max age in seconds (default 1209600, 14 days). |
--oauth-login-state-ttl-secs / OAUTH_LOGIN_STATE_TTL_SECS |
One-time OAuth state token TTL in seconds (default 600). |
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.
TAVILY_UPSTREAMis interpreted as the full MCP endpoint. If your reverse proxy keeps Tavily under a path prefix, include the final/mcppath in the configured URL.TAVILY_USAGE_BASEmay include a path prefix. Hikari appends/search,/extract,/crawl,/map,/research,/research/{id}, and/usageunder that prefix.
| Method | Path | Description | Auth |
|---|---|---|---|
GET |
/health |
Liveness plus xray readiness after startup grace. | 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.
- Base URL:
https://<your Hikari host>/api/tavily - API key: Hikari access token
th-<id>-<secret>created from the user dashboard
Cherry Studio setup:
- Create an access token (for example
th-xxxx-xxxxxxxxxxxx) from the Tavily Hikari user dashboard and copy it. - In Cherry Studio, open Settings → Web Search.
- Choose the provider Tavily (API key).
- Set API URL to
https://<your Hikari host>/api/tavily(for local dev it is usuallyhttp://127.0.0.1:58087/api/tavily). - Set API key to the Hikari access token from step 1 (the full
th-xxxx-xxxxxxxxxxxxvalue), not your Tavily official API key. - Optionally tune result count, answer/date options, etc.; Cherry Studio will pass these fields through to Tavily while Hikari rotates Tavily keys and enforces token quotas.
Do not put your Tavily API key directly into Cherry Studio. Always route traffic through Hikari by using its access token.
Install the GitHub Release-distributed wrapper with your Hikari origin and Hikari access token:
curl -fsSL "https://github.com/IvanLi-CN/tavily-hikari/releases/latest/download/install-tvly-hikari.sh" | bash -s -- \
--base-url "https://<your Hikari host>" \
--token "th-<id>-<secret>"Then run official Tavily CLI commands through Hikari:
tvly-hikari search "latest AI agent news" --json
tvly-hikari extract https://example.com --json
tvly-hikari crawl https://example.com/docs --json
tvly-hikari map https://example.com/docs --json
tvly-hikari research "compare MCP and CLI agent search" --jsonOptional Agent Skills install:
npx skills add https://github.com/IvanLi-CN/tavily-hikari --globaltvly-hikari stores the Hikari token in ~/.config/tavily-hikari-cli/config.json with 0600
permissions and injects TAVILY_API_BASE_URL=https://<your Hikari host>/api/tavily plus
TAVILY_API_KEY=th-<id>-<secret> for the official tvly command. The token is not a raw Tavily
API key.
For the full HTTP proxy design and acceptance criteria, see docs/tavily-http-api-proxy.md.
exhaustedstatus is triggered automatically when upstream returns 432; scheduler skips those keys until UTC month rollover or manual recovery.- Each access token maintains a soft affinity to a single API key for a short time window. Within that window, the proxy prefers the same key when it remains active; when affinity expires or the key becomes exhausted/disabled, the next key is chosen by a global least‑recently‑used scheduler to keep load balanced across healthy keys. If all are disabled, the proxy falls back to the oldest disabled entries.
request_logscaptures request metadata, upstream payloads, and dropped/forwarded header sets for postmortem analysis.- Runtime process logs are separate from
request_logs. By default Hikari emits JSON lines on stderr viatracing; useRUNTIME_LOG_FORMAT=text(or--log-format text) only when you explicitly need grep-friendly local fallback output. - Stable runtime event fields include
component,event, and per-path fields such asoperation,job_type,attempt,backoff_ms,path,method, anderr. Secrets, full tokens, cookies, and raw sensitive headers are intentionally excluded. RUST_LOGstill controls filtering. Typical operator flows aredocker logs ... | jq -cin JSON mode andRUNTIME_LOG_FORMAT=text RUST_LOG=info cargo run ... | rg "component=db|event=operation_"in fallback text mode.- High-anonymity behavior (header allowlist, origin rewrite, etc.) is detailed in
docs/high-anonymity-proxy.md.
For production deployments, prefer passkey admin login. It keeps the administrator trust boundary inside Hikari instead of trusting a user identity header forwarded by a reverse proxy:
export ADMIN_AUTH_PASSKEY_ENABLED=true
export NODE_ID=tavily-node-a
export NODE_PUBLIC_SCHEME=https
export NODE_PUBLIC_HOST=tavily-node-a.example.comAfter deployment, create a one-time enrollment URL on the server:
tavily-hikari admin passkey reset-url --base-url https://tavily-node-a.example.comOpen the printed URL once to register the first admin passkey.
In HA, Passkeys are node-local. Configure a distinct NODE_ID and NODE_PUBLIC_* origin on every
node, upgrade the current full_master first, then roll the release to standby/recovery nodes.
Run the reset command on each target node with that node's HTTPS origin and enroll separately.
ADMIN_PASSKEY_RP_ID and ADMIN_PASSKEY_RP_ORIGIN remain supported as explicit overrides; the
command rejects a --base-url whose origin does not exactly match the effective RP origin.
ForwardAuth support is retained for explicitly managed trusted networks, but it is disabled by default and should not be used as the only public admin trust boundary. If you enable it, 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- Existing deployments that already set both
FORWARD_AUTH_HEADERandFORWARD_AUTH_ADMIN_VALUEcontinue to enable ForwardAuth automatically for compatibility; new deployments should setADMIN_AUTH_FORWARD_ENABLED=trueexplicitly when using this mode. - Requests must include the header defined by
FORWARD_AUTH_HEADER. If its value equalsFORWARD_AUTH_ADMIN_VALUE, the caller is treated as an admin and can hit/api/keys/*privileged endpoints. - Do not expose Hikari directly to the public internet with ForwardAuth enabled unless the edge proxy strips any client-supplied identity headers before authentication.
FORWARD_AUTH_NICKNAME_HEADER(optional) is surfaced in the UI to show who is operating the console. When absent, the backend falls back toADMIN_MODE_NAME(if provided) or hides the nickname.- For purely local experiments you can set
DEV_OPEN_ADMIN=true, but never enable it in production.
Tavily Hikari can also 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: enable ForwardAuth only when the upstream proxy boundary is trusted.
# export ADMIN_AUTH_FORWARD_ENABLED=true- When built-in login is enabled and the browser is not signed in, the public homepage shows an Admin Login button.
- Successful login sets an HttpOnly cookie (
hikari_admin_session) and unlocks admin-only APIs +/admin. - For production, prefer passkey login. Built-in password login is intended as a break-glass path for small/self-hosted deployments.
- Avoid storing plaintext passwords in env vars. Prefer
ADMIN_AUTH_BUILTIN_PASSWORD_HASH(PHC string) and use a strong password. - Sessions are stored in-memory and expire server-side (aligned with cookie
Max-Age, default 14 days). Restarting the process logs users out. - The in-memory session store is bounded (evicts oldest sessions when the cap is exceeded) to avoid unbounded growth.
- If you terminate TLS at a reverse proxy, set
X-Forwarded-Proto: https(orForwarded: proto=https) so the backend can mark the session cookie asSecure.
- Avoid storing plaintext passwords in env vars. Prefer
Deployment example (Caddy as gateway): see examples/forwardauth-caddy/.
Tavily Hikari can expose Linux DO Connect OAuth2 login for regular users, independent from admin auth.
export LINUXDO_OAUTH_ENABLED=true
export LINUXDO_OAUTH_CLIENT_ID='<your-linuxdo-client-id>'
export LINUXDO_OAUTH_CLIENT_SECRET='<your-linuxdo-client-secret>'
export LINUXDO_OAUTH_REDIRECT_URL='https://tavily.ivanli.cc/console/oauth/linuxdo/callback'
export LINUXDO_OAUTH_REFRESH_TOKEN_CRYPT_KEY='<32-byte-secret-or-base64>'
export LINUXDO_OAUTH_USER_SYNC_ENABLED=true
export LINUXDO_OAUTH_USER_SYNC_AT='06:20'- Homepage behavior:
- When not logged in, area ① shows a Sign in with Linux DO button.
- After login, area ① is hidden and area ② auto-fills the user's bound
th-...token.
- Callback handoff behavior:
- LinuxDo should redirect the browser to
/console/oauth/linuxdo/callback, not the legacy backend callback path. - The callback page stays inside the
/consoleshell, shows a provider-specific "connecting" state, then postscode+statetoPOST /auth/linuxdo/finalize. - Successful finalize sets the user session cookie and automatically enters
/console. - Provider denial, invalid/expired state, timeout, and upstream failures stay on the callback page with fresh restart + home CTAs.
- When new-user registration is paused, finalize redirects to
/registration-pausedinstead of showing a generic failure card.
- LinuxDo should redirect the browser to
- Token policy:
- First Linux DO login automatically creates and binds one Hikari access token.
- Later logins reuse the same binding; no extra token is created.
- If the bound token is disabled/deleted,
/api/user/tokenreturns an error (404or409) and does not auto-regenerate.
- Quota policy:
- New user accounts no longer receive built-in base quota on first login.
- Effective quota for new accounts comes from system/user tags only.
- A newly created account without any quota-granting tags stays at
0/0/0/0until an admin assigns tags or appends a base quota ledger row.
- Offline profile sync:
- After a successful LinuxDo login, Hikari stores the latest non-empty
refresh_tokenin encrypted form. - The server runs a daily offline sync at
06:20in the server's local time by default; the scheduler refreshes each eligible LinuxDo profile and rebinds the matchinglinuxdo_l*system tag. LINUXDO_OAUTH_REFRESH_TOKEN_CRYPT_KEYaccepts either exactly 32 raw bytes or a base64/base64url string that decodes to 32 bytes.- If the crypt key is missing or invalid, login still works, but refresh-token persistence and the daily LinuxDo sync become no-op.
- Existing LinuxDo accounts that were created before refresh tokens started being stored are not picked up automatically; those users need to sign in once again to join the daily sync.
- Sync failures such as
invalid_grant, transport errors, or userinfo mismatches keep the previous trust level, existing user session, and currentlinuxdo_l*tag until the next successful refresh or a user re-login.
- After a successful LinuxDo login, Hikari stores the latest non-empty
- New endpoints:
GET /auth/linuxdoPOST /auth/linuxdo/finalizeGET /auth/linuxdo/callback(diagnostics only; no longer the official login completion path)GET /api/user/tokenPOST /api/user/logout
Tavily Hikari can let logged-in Linux DO users buy additional monthly quota through Linux.do Credit LDC payments. This requires Linux DO OAuth login to be enabled first, because recharge orders are attached to the logged-in user account.
export LINUXDO_CREDIT_ENABLED=true
export LINUXDO_CREDIT_CLIENT_ID='<your-linuxdo-credit-client-id>'
export LINUXDO_CREDIT_CLIENT_SECRET='<your-linuxdo-credit-client-secret>'
export LINUXDO_CREDIT_MERCHANT_PRIVATE_KEY='<ed25519-private-key>'
export LINUXDO_CREDIT_NOTIFY_URL='https://<your-hikari-host>/api/linuxdo-credit/notify'
export LINUXDO_CREDIT_RETURN_URL='https://<your-hikari-host>/console/dashboard'LINUXDO_CREDIT_MERCHANT_PRIVATE_KEYis used to sign official LDC order creation requests. The backend accepts Ed25519 private material as base64/base64url/hex seed or PKCS#8 DER/PEM.LINUXDO_CREDIT_NOTIFY_URLmust be publicly reachable by Linux.do Credit. Successful signed notifications mark pending orders as paid and apply quota entitlements idempotently.LINUXDO_CREDIT_RETURN_URLis the browser landing page after payment. The user console can refresh order state after returning.LINUXDO_CREDIT_SUBMIT_URLdefaults to the official Linux.do Credit LDC endpoint and usually does not need to be changed.LINUXDO_CREDIT_TEST_PRICE_ENABLED=trueexposes a test offer where1 LDCbuys1monthly credit. Keep it disabled for normal paid operation.
After the process starts with the payment credentials, open the admin system settings and enable Enable recharge. Keep Allow non-admin recharge disabled while testing with an admin session; turn it on only when regular users should see the recharge card and create payment orders. When Enable recharge is off, the user console hides the recharge entry and the backend rejects new order creation while still accepting already-paid callbacks.
- Built with React 18, TanStack Router, shadcn/ui (Radix), Tailwind, Iconify.
- Displays live key table, request log stream, and admin-only actions (copy real key, restore, delete).
- Admin routes are path-based (
/admin/dashboard,/admin/tokens/:id,/admin/keys/:id); legacy hash routes are removed. - Public and admin PWA caches are intentionally separated so ordinary users do not accumulate persistent admin shell caches or an admin install identity.
scripts/write-version.mjsstamps the build version into the UI during CI releases.bun run dev(forced through Bun runtime viaweb/bunfig.toml) proxies/api,/mcp, and/healthto 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:
- Codex CLI
- Claude Code CLI
- VS Code — Use MCP servers
- GitHub Copilot — GitHub MCP Server
- Claude Desktop
- Cursor
- Windsurf
- Any MCP client supporting HTTP + Bearer token auth
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 pinned to 1.91.0 via
rust-toolchain.toml. - Repo tooling (Bun, pinned via
.bun-version):bun install --frozen-lockfile,bun run hooks:install,bun run worktree:setup,bun run test:worktree-bootstrap. - Common commands:
cargo fmt,cargo clippy -- -D warnings,cargo test --locked --all-features,cargo run -- --help. - Frontend (Bun, pinned via
.bun-version):bun install --frozen-lockfile,bun run dev,bun run demo,bun run build(uses Bun-forcedtsc -b+vite build; seeweb/bunfig.toml). - Hooks:
bun install --frozen-lockfileorbun run hooks:installinstalls the sharedpost-checkouthook; if thelefthookbinary is available onPATH, it also refreshes automaticcargo fmt,cargo clippy,bunx --bun dprint fmt, andbunx --bun commitlint --editcommit hooks. - No-node proof: run
bun run validate:no-node-runtimeto verify the repo build/hook paths still pass when a failingnodeshim is prepended toPATH. - CI:
.github/workflows/ci.ymlruns the linked-worktree bootstrap smoke, lint/tests/build, and release prerequisites. - Release:
.github/workflows/release.ymlruns after main CI succeeds and publishes tags, GitHub Releases, Linux binary assets, and GHCR images. Release completion is reported by the workflow result and summary; it does not post back to the source PR.
Releases are label-driven:
- Every PR must have exactly one intent label:
type:patch,type:minor,type:major,type:docs, ortype:skip. - Every PR must have exactly one channel label:
channel:stableorchannel:rc. - When a PR is merged into
mainand CI passes, the release workflow computes the next stable semver (X.Y.Z) and publishes:- Git tag + GitHub Release
- GHCR image tags:
- stable (
channel:stable):latest,vX.Y.Z - prerelease (
channel:rc):vX.Y.Z-rc.<sha7>(nolatest)
- stable (
- Web assets are built once per release run and reused by both Docker and binary release jobs
- If the release fails on a first-attempt transient Docker Hub / BuildKit fetch outage, the repo-local notifier auto-reruns failed Docker jobs once and suppresses the first Telegram alert; if the rerun still fails, the later attempt alerts normally.
- If a commit cannot be mapped to exactly one PR, release is skipped (conservative default).
- Only expose
/mcp,/api/*, and static assets; everything else returns 404. - Protect admin APIs/UI with passkey login or another trusted admin boundary so regular users never see real keys.
- Follow the header sanitization guidance in
docs/high-anonymity-proxy.mdwhen operating in high-anonymity environments. - Persist
tavily_proxy.dbvia volumes or external storage and exportrequest_logsfor compliance if needed.
Distributed under the MIT License. Keep the license notice intact when copying or distributing the software.



