Skip to main content
One npm package, @lit-protocol/keychain, covers the SDK, a CLI and a local MCP server. Node 22+, one runtime dependency, Apache-2.0. The agent’s private key never leaves its machine, and the SDK attests the Lit endpoint before it sends an execution request. The package’s own README is the exhaustive reference and is published alongside the app so agents can fetch it. This page is the map.

Installation and identity

SDK

  • get on a connected service fails with Secret "X" was created with the <action> action; call use(). use on a stored secret is the mirror mistake.
  • Pass { usageApiKey } as the third constructor argument to override the config’s execution key, for example after the owner replaced it.
  • Import by package name so Node selects the TLS-aware entry point. dist/index.js is the browser build and cannot bind the live TLS certificate.
  • ACTIONS exports the catalog compiled into the client; describeCredential(value) classifies a value you are unsure about: an identity or config object, the raw JSON text of either file, a private key, or a usage key.

CLI

run is a handoff to a tool you trust, not a sandbox: the child inherits the environment and can still log or disclose the value. With --file, SIGKILL can leave the file behind and unlinking does not guarantee erasure; prefer a tmpfs path such as /dev/shm for anything long-lived. Set CHIPOTLE_USAGE_API_KEY to override the config’s execution key and KEYCHAIN_BASE_RPC_URL to pin your own Base RPC for the on-chain attestation step.

MCP server

Cursor, Windsurf and similar clients take the same command in their JSON config:
Pass one or more configs after the identity. Paths must be absolute and readable by the client’s user, and Node 22+ must be on that client’s PATH. Tools: agent_public_key (for the owner to approve), list_actions, list_secrets (names, permitted operation and input shape, no values), get_secret, and one tool per catalog action (stripe_balance, openai_chat, github_read_file, slack_post_message, supabase_tables), each taking name and, where the action declares one, input. The server is deliberately local rather than hosted. Decryption needs the agent’s private identity, and a remote endpoint would hand that key and every plaintext to whoever runs it, which the Keychain trust boundary forbids. Tool results enter the model context like any other tool output, so approve agents only for the secrets they need.

The three artifacts

A per-secret Agent config names one secret. Config · all secrets, next to an agent under Authorized agents, names every secret in the vault that agent is approved for, which is what keychain run --only A,B and a single get/use config expect. The MCP server additionally merges several config files from the same vault. usageApiKey is an opaque string minted by Chipotle (currently 44 characters of base64). It pays for execution and cannot read a secret without the agent identity and an owner grant. There are no setup tokens, management bearer tokens or server-minted grants in Keychain. Never ask an owner for a private key or Google token. The SDK and CLI reject an identity passed as a config, a config passed as an identity, and a private key passed as a usage key, each with a message naming the mistake.

When a request is refused

The enclave answers every failure with the same bare access_denied, so nothing about the policy or the upstream service leaks. Before spending an execution, the client checks the signed policy it already fetched and explains what it can see. Every such message starts with Access denied: and tells you who can fix it. Slack posts and Supabase inserts are not exactly-once. A timeout after an upstream write does not prove nothing was sent; inspect provider state before retrying.

Owner-side integration

Owner and browser integrations use OwnerClient, LitConnection and authorizationTypedData from the same package. The hosted web app’s identities.ts shows wallet, passkey and Google signers. The first sign-in for a vault provisions its Chipotle groups and execution key on-chain and takes roughly 30 seconds; later sign-ins take a few seconds.