Getting Started
Two steps to quantum-secured secrets: install and store. Then wire up your editor in MCP Setup and dive into the 63-command CLI Reference.
Step 1 → 2
Quick start
From npm install to your first stored secret in under a minute.
1Install q-ring
Pick your package manager and install globally:
$ pnpm add -g @i4ctime/q-ring
$ npm install -g @i4ctime/q-ring
$ yarn global add @i4ctime/q-ring
$ bun add -g @i4ctime/q-ring
$ brew install i4ctime/tap/qring
2Store your first secret
Secrets are stored in your OS-native keyring (macOS Keychain, Windows Credential Vault, or Linux Secret Service):
# Store a secret $ qring set OPENAI_API_KEY sk-proj-abc123... # Retrieve it $ qring get OPENAI_API_KEY --raw sk-proj-abc123... # List all stored keys $ qring list OPENAI_API_KEY [dev] healthy 0 reads # Run a health check $ qring health
Next step: connect your AI editor — configure the MCP server for Cursor, Kiro, Claude Code, or VS Code.
Under the hood
What just happened
The value went into the operating system's credential store, not into a file q-ring owns. Here is where it lives on each platform and what the two check commands verify.
1Where the secret went
qring set wraps the value in a small JSON envelope (the value, optional per-environment states, TTL, tags, access count) and writes it through @napi-rs/keyring as one keychain item. The service name encodes the scope: q-ring:global by default, q-ring:project:<hash> when you pass --project. The account is the key name.
- macOS: a generic password in the login keychain (
~/Library/Keychains/login.keychain-db). Open Keychain Access and search forq-ringto see it. - Windows: a generic credential in Credential Manager, encrypted with DPAPI under your account. Control Panel, Credential Manager, Windows Credentials lists it.
- Linux: an item in your Secret Service collection (GNOME Keyring, ksecretservice or KeePassXC), usually stored under
~/.local/share/keyrings/. Seahorse orsecret-tool searchcan show it.
The files q-ring keeps under ~/.config/q-ring/ hold the audit log and the entanglement, approval and hook registries, created 0600. Secret values are never written there.
2What qring health and qring doctor check
qring health is about the secrets. It walks every key in scope and sorts them by TTL into healthy, stale (75 percent or more of the lifetime used), expired, and no decay set, then scans the audit log for access anomalies such as bursts or unusual hours. It does not test the keychain itself.
qring doctor is about the installation. It writes, reads and deletes a throwaway probe entry to prove the keychain backend works, confirms the audit directory is writable, looks for a .q-ring.json manifest and policy, flags approvals that predate project binding, and checks that qring-mcp is on PATH. Run it first when anything fails.
qring health --json
qring doctor --jsonShell and scripts
Use it from a shell or script
The CLI is built to be piped. These are the patterns that keep a value out of your history, your logs and your terminal scrollback.
1Read a value into a script
--raw prints the bare value with no trailing newline, which is what command substitution wants. Without it, qring get prints a JSON object with key and value; --json wraps that in the { ok, data } shape every read command shares.
# Bare value, no trailing newline
OPENAI_API_KEY="$(qring get OPENAI_API_KEY --raw)"
# Structured output for tooling
qring get OPENAI_API_KEY --json
qring list --json
# Exit-code check, decay-aware (expired counts as absent)
qring has OPENAI_API_KEY --quiet && echo present2Store without echoing
Omit the value and qring set prompts for it on stderr without echoing. When stdin is not a terminal it reads the value to EOF instead, so a pipe works in scripts. Existing .env files can be imported in bulk; --dry-run shows what would be written.
# Interactive prompt, nothing in shell history
qring set STRIPE_KEY
# Non-interactive: value arrives on stdin
printf '%s' "$VALUE" | qring set STRIPE_KEY
# Migrate a dotenv file, then delete it
qring import .env --skip-existing --dry-run
qring import .env --skip-existing3Inject instead of print
Most scripts do not need the value in the shell at all; they need it in a child process. qring exec injects secrets into the environment of the command after -- and replaces any known secret value in the captured stdout and stderr before it reaches you. qring run is the narrower form: only keys declared in .q-ring.json or referenced as qring:// pointers in a .env file are injected.
# Every secret in scope, output redacted
qring exec -- pnpm test
# Only the keys you name
qring exec --keys DATABASE_URL,REDIS_URL -- pnpm run db:migrate
# Only what the project manifest declares
qring run -- node server.js
qring run --dry-run -- node server.jsDestructive commands such as qring delete ask for confirmation on a terminal and fail on non-interactive stdin; pass --yes in scripts.
MCP
Connect an agent
The same install ships qring-mcp, a stdio MCP server that gives Cursor, Kiro, Claude Code and VS Code tools instead of file access.
One command writes the MCP entry into the editor config without touching other servers already listed there. The agent then gets has_secret and inspect_secret for metadata, exec_with_secrets to run a command with secrets injected and the output redacted, and get_secret for reads you allow through policy. Keys stored with --requires-approval stay closed to the agent until you grant a time-boxed approval from the CLI. Every agent read, write and delete lands in the same audit log the CLI writes, tagged with the client name, so qring audit:sessions shows what each agent touched.
qring setup cursor # .cursor/mcp.json
qring setup kiro # .kiro/settings/mcp.json
qring setup claude # .mcp.json
qring setup cursor --dry-runPer-editor configuration, the plugins, and the prompt cookbook are on the MCP Setup page.
Troubleshooting
Common problems
Start with qring doctor. Set QRING_DEBUG=1 to get a full stack trace from any CLI error.
- Keyring error on a headless Linux box, over SSH or in CI. There is no running Secret Service. Start one around the command with
dbus-run-session -- sh -c 'echo "" | gnome-keyring-daemon --unlock; exec qring list', or opt into the encrypted file backend withQRING_BACKEND=fileandQRING_FILE_PASSPHRASE. It never activates on its own and fails closed without the passphrase. - The editor does not list any q-ring tools. GUI editors often start without your shell's
PATH. Put the absolute path fromcommand -v qring-mcpin the MCP config. - The agent gets Policy Denied or an approval error. The key is denied in
.q-ring.jsonor stored with--requires-approval. Grant a window withqring approve KEY --for 3600 --reason "...". The CLI itself is never gated, only agent reads. qring getsays not found butqring listshows the key. Scope mismatch. Project scope is keyed by the absolute project path; pass--projectfrom the same directory or--project-pathexplicitly.- A script hangs or errors on
qring delete. It is waiting for confirmation that a non-interactive stdin cannot give. Add--yes.
Ready to explore more features?