Skip to content
Documentation

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
$ pnpm add -g @i4ctime/q-ring
npm
$ npm install -g @i4ctime/q-ring
yarn
$ yarn global add @i4ctime/q-ring
bun
$ bun add -g @i4ctime/q-ring
brew
$ 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):

~ / terminal
# 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 for q-ring to 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 or secret-tool search can 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.

machine-readable
qring health --json
qring doctor --json

Shell 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.

bash
# 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 present

2Store 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.

bash
# 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-existing

3Inject 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.

bash
# 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.js

Destructive 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.

bash
qring setup cursor     # .cursor/mcp.json
qring setup kiro       # .kiro/settings/mcp.json
qring setup claude     # .mcp.json
qring setup cursor --dry-run

Per-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 with QRING_BACKEND=file and QRING_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 from command -v qring-mcp in the MCP config.
  • The agent gets Policy Denied or an approval error. The key is denied in .q-ring.json or stored with --requires-approval. Grant a window with qring approve KEY --for 3600 --reason "...". The CLI itself is never gated, only agent reads.
  • qring get says not found but qring list shows the key. Scope mismatch. Project scope is keyed by the absolute project path; pass --project from the same directory or --project-path explicitly.
  • 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?