Install
openclaw skills install @askegor/space-duck-kimi-relayOptional add-on for Space Duck — local "Sign in with Kimi" device flow so a Remote-Hosted (Lane A / BYOB) duck can run Kimi models on the owner's flat-rate Kimi membership. Token is stored on the owner's own box and never sent to Spaceduckling. Hosted (Lane B) ducks do NOT need this skill — they use the "Sign in with Kimi" card in Mission Control instead. Triggers on phrases like "sign in with kimi", "kimi membership login", "clawhub space-duck kimi", "kimi relay login".
openclaw skills install @askegor/space-duck-kimi-relayLets a duck that runs on your own infrastructure use your Kimi membership (flat-rate subscription quota) for inference instead of pay-per-token API keys.
~/.kimi-code/credentials/kimi.json (0600), on
your machine only.auth.kimi.com and
api.kimi.com). Spaceduckling never sees or holds the token.kimi_login.py login # interactive device sign-in
kimi_login.py token # print fresh access token (auto-refresh, file-locked)
kimi_login.py probe # inference smoke on membership quota
kimi_login.py serve [port] # local proxy for your runtime (default 8471)
kimi_login.py install-service [port] # run proxy as a service (systemd user / launchd)
kimi_login.py uninstall-service # remove the service
kimi_login.py status [port] # creds + proxy + fallback-meter health check
kimi_login.py logout # delete local credentials
login shows a kimi.com URL + user code; approve it in your browser and
the script stores the tokens. token transparently refreshes — Kimi
access tokens live ~15 minutes and refresh tokens rotate on every
grant, so always let this script (not ad-hoc curl) do the refreshing;
a stale refresh token is dead after one rotation.
Kimi access tokens live ~15 minutes, so a static key in your runtime's config will not survive. Run the local proxy instead:
kimi_login.py serve # http://127.0.0.1:8471/v1/chat/completions
Point your runtime's OpenAI-compatible provider at
http://127.0.0.1:8471/v1 with any placeholder api key. The proxy
injects a fresh membership token per request (refreshes under a file
lock — safe when several ducks on one box share the login).
k3 (full), kimi-for-coding (budget)reasoning_content and spends completion budget on it —
give it roomy max_tokens (512+) or replies can arrive empty.Streaming ("stream": true) is passed through as SSE, so chat UIs get
token-by-token output on the membership lane.
Automatic fallback: export OPENROUTER_API_KEY before serve and
any failed membership call (quota/auth/outage) is retried once on
OpenRouter's kimi lane (moonshotai/*, pay-per-token) — same
degradation the hosted lane performs. Fallback is metered: capped at
KIMI_RELAY_FALLBACK_DAILY_CAP calls/day (default 200) so a broken
membership can't silently run up a pay-per-token bill; past the cap the
proxy returns 429. If the client asked for stream: true, the fallback
reply is wrapped as a single SSE chunk + [DONE] so streaming clients
still get valid SSE. Without the env var, failures return the error so
your runtime's own ladder takes over.
For a proxy that survives reboots, install-service writes a systemd
user unit (Linux — enable lingering with
loginctl enable-linger $USER so it runs while logged out) or a
launchd agent (macOS). Any OPENROUTER_API_KEY / KIMI_* env vars set
when you run install-service are captured into the unit (0600), so
the fallback survives reboots too. status shows creds, proxy health,
and the fallback meter.
Env overrides: KIMI_CLIENT_ID (if Moonshot rotates the public
client), KIMI_AUTH_HOST, KIMI_CODING_BASE,
KIMI_RELAY_FALLBACK_DAILY_CAP.
Kimi inference is processed by Moonshot AI on infrastructure in China. Don't route conversations through this lane if you require Western data residency.
| Script | Purpose |
|---|---|
scripts/kimi_login.py | Device sign-in, token refresh, probe, logout |
space-duck skill works without it.