klavy-local-bridge
v0.2.13
Published
Klavy Remote Local Bridge agent for Claude Code, Codex CLI, Gemini CLI, and Kimi CLI.
Readme
klavy-local-bridge
Node CLI agent for the Klavy Remote Local Bridge. It connects to the Klavy
ActionCable WebSocket with a bearer token, reports local Claude/Codex/Gemini/Kimi
health for text/coding jobs, receives invoke jobs, runs local provider CLIs,
and sends job lifecycle messages back over the cable. Klavy image generation is
not routed through the local bridge; image models use the configured API/shared
credential path.
Install
npx klavy-local-bridge install-service --server https://klavy.app --token <token> --profile <profile-id>Or install the command globally:
npm install -g klavy-local-bridgeFor local development in this repository:
cd packages/local-bridge-agent
npm install
npm testCommands
npx klavy-local-bridge install-service --server https://klavy.app --token <token> --profile <profile-id>
npx klavy-local-bridge connect --server https://klavy.app --token <token>
klavy-local-bridge connect --server https://klavy.app --token <token>
klavy-local-bridge gemini-image-mcp
klavy-local-bridge gemini-image-mcp-settings
klavy-local-bridge status
klavy-local-bridge service-status
klavy-local-bridge disconnect
klavy-local-bridge uninstall-serviceinstall-service is the recommended macOS setup. It upserts the token into
~/.config/klavy-local-bridge/config.json with 0600 permissions and installs
a single LaunchAgent at ~/Library/LaunchAgents/app.klavy.local-bridge.plist.
The plist runs the bridge with --config and does not contain tokens.
Config version 2 supports multiple account profiles in one local service:
{
"version": 2,
"defaults": {
"channel": "LocalBridgeChannel"
},
"profiles": [
{
"id": "prod-admin-1",
"name": "Production Admin",
"token": "klb_...",
"enabled": true,
"url": "wss://klavy.app/cable",
"origin": "https://klavy.app"
},
{
"id": "local-user-6",
"name": "Local User",
"token": "klb_...",
"enabled": true,
"url": "ws://localhost:7700/cable",
"origin": "http://localhost:7700"
}
]
}Legacy flat configs with a single token still work and are migrated to the
multi-profile shape the next time install-service runs.
Older v2 configs with defaults.url and token-only profiles also keep working;
newly installed profiles store their own url and origin so production and
localhost profiles can run side by side without retargeting each other.
connect also reads these environment variables:
| Variable | Purpose |
| --- | --- |
| KLAVY_CABLE_URL | Full ActionCable WebSocket URL. |
| KLAVY_CABLE_ORIGIN | WebSocket Origin header; inferred from the cable URL by default. |
| KLAVY_URL | Base app URL; /cable is inferred. |
| KLAVY_BRIDGE_TOKEN | Bearer token sent as Authorization: Bearer .... |
| KLAVY_LOCAL_BRIDGE_CHANNEL | ActionCable channel, default LocalBridgeChannel. |
| KLAVY_CLAUDE_BIN | Claude Code binary, default claude. |
| KLAVY_CODEX_BIN | Codex CLI binary, default codex. |
| KLAVY_GEMINI_BIN | Gemini CLI binary, default gemini. |
| KLAVY_GEMINI_CWD | Gemini CLI working directory, default KLAVY_LOCAL_BRIDGE_CWD / current directory. |
| KLAVY_GEMINI_CONFIG_DIR | Gemini CLI config directory, default ~/.gemini. |
| KLAVY_GEMINI_SETTINGS_PATH | Explicit Gemini settings JSON path for diagnostics. |
| KLAVY_GEMINI_IMAGE_GENERATION_ENABLED | Deprecated compatibility flag. Image generation uses API models, not local bridge. |
| KLAVY_GEMINI_IMAGE_MCP_ENGINE | Engine for gemini-image-mcp: none, google_api, or klavy_direct_api. Default: none. |
| KLAVY_GEMINI_IMAGE_MCP_MODEL | Default Google image model for gemini-image-mcp. Default: gemini-2.5-flash-image. |
| KLAVY_GEMINI_IMAGE_MCP_KLAVY_ENDPOINT | Bearer-auth image endpoint for klavy_direct_api. |
| KLAVY_GEMINI_IMAGE_MCP_KLAVY_URL | Klavy app URL fallback for klavy_direct_api experiments. |
| KLAVY_GEMINI_IMAGE_MCP_KLAVY_TOKEN | Klavy bearer token for klavy_direct_api. |
| KLAVY_GEMINI_IMAGE_MCP_TIMEOUT_MS | Timeout for gemini-image-mcp engine calls. Default: 180000. |
| KLAVY_GEMINI_TRUST_WORKSPACE | Whether the agent sets GEMINI_CLI_TRUST_WORKSPACE=true, default true. |
| KLAVY_KIMI_BIN | Kimi CLI binary, default kimi. |
| KLAVY_KIMI_CWD | Kimi CLI working directory, default KLAVY_LOCAL_BRIDGE_CWD / current directory. |
| KLAVY_KIMI_MODEL | Optional Kimi CLI config model alias. If unset, the Kimi CLI default model is used. |
| KLAVY_CODEX_MODEL | Default Codex model, default gpt-5.4. |
Use --url wss://.../cable only when you need to pass a full ActionCable URL
directly.
Wire Protocol
The agent subscribes to LocalBridgeChannel by default. Server frames with
message.type, message.event, or message.action equal to invoke are
treated as jobs.
An invoke job should include:
{
"type": "invoke",
"job": {
"id": "job_123",
"provider": "claude",
"request": {
"system": "You are helpful.",
"messages": [{ "role": "user", "content": "Hello" }],
"model": "gpt-5.4"
}
}
}The agent performs channel actions named:
heartbeatacceptedchunkcompletedfailed
The bridge supports claude, openai, gemini, and kimi. codex is accepted as an
alias for openai; moonshot is accepted as an alias for kimi. Gemini CLI jobs run with GEMINI_CLI_TRUST_WORKSPACE=true
by default so LaunchAgent/headless execution does not get stuck on trusted
folder prompts. Gemini jobs may include request.model; when present, the
agent forwards it to the Gemini CLI as --model <model>. Omit it to use the
Gemini CLI default model.
Kimi jobs use the local Kimi CLI in non-interactive mode. Jobs may include
request.model; when present, the agent forwards it as --model <model>.
Gemini Image MCP (experimental diagnostics only)
gemini-image-mcp is a stdio MCP server that can be attached to Gemini CLI. It
exposes a generate_image tool with this input shape. This command remains for
diagnostics and experiments only. Klavy does not use it to show the L badge,
does not advertise image_generation in local bridge heartbeat, and does not
route image model execution through local bridge.
{
"prompt": "Hero image for a home service intro",
"model": "gemini-2.5-flash-image",
"aspect_ratio": "16:9",
"category": "hero",
"alt_text": "Service hero image"
}Print a copyable Gemini settings.json snippet with:
npx klavy-local-bridge gemini-image-mcp-settingsDefault snippet:
{
"mcpServers": {
"klavy-image": {
"command": "npx",
"args": ["--yes", "klavy-local-bridge@latest", "gemini-image-mcp"],
"trust": true,
"includeTools": ["generate_image"]
}
}
}The default engine is none. In that mode the MCP tool is visible for setup
diagnostics, but it reports image_engine_configured: false in tools/list,
and tools/call fails with image_engine_not_configured.
To use a Google API based image engine, configure the MCP server environment explicitly. This can incur separate Google API or Vertex billing:
{
"mcpServers": {
"klavy-image": {
"command": "npx",
"args": ["--yes", "klavy-local-bridge@latest", "gemini-image-mcp"],
"env": {
"KLAVY_GEMINI_IMAGE_MCP_ENGINE": "google_api",
"GEMINI_API_KEY": "your-api-key"
},
"trust": true,
"includeTools": ["generate_image"]
}
}
}klavy_direct_api is also explicit and calls Klavy/Rails image generation with
a bearer token. It is useful for diagnostics or controlled internal setups, but
it still uses Klavy's configured upstream image provider and can incur that
provider's cost:
{
"mcpServers": {
"klavy-image": {
"command": "npx",
"args": ["--yes", "klavy-local-bridge@latest", "gemini-image-mcp"],
"env": {
"KLAVY_GEMINI_IMAGE_MCP_ENGINE": "klavy_direct_api",
"KLAVY_GEMINI_IMAGE_MCP_KLAVY_ENDPOINT": "https://klavy.app/internal/image-generation",
"KLAVY_GEMINI_IMAGE_MCP_KLAVY_TOKEN": "your-bearer-token"
},
"trust": true,
"includeTools": ["generate_image"]
}
}
}For Klavy UI/UX design image slots, the server should use the shared/API image
credential path. If an image_generation invoke reaches the local bridge, the
agent rejects it with unsupported_task and a message telling the caller to use
an image API model instead. OpenAI/Codex/Gemini image generation is unsupported
through the local bridge.
