Project Onboarding: redisctl init¶
redisctl init onboards the current project to Redis and makes its AI coding agents
(Claude Code, Cursor, VS Code, Codex) Redis-fluent - one command from an empty
directory to a validated database with the project wired.
What it does¶
- Detects the project: runtime (Node, Python, Go, Rust, Java), package manager, framework, and which agent tools are present.
- Provisions or discovers a database: on a terminal the wizard asks where it
comes from - Redis Cloud (the default; signs you in when needed), a local Redis
on
localhost:6379or a new Docker container, a pasted connection string, or "skip for now" (a.envplaceholder to fill in later). When.envalready holds aREDIS_URL, keeping it is the first option and the default, and "skip for now" is not offered. Without a terminal, or with--defaults, it keeps an existingREDIS_URLin.env, else reuses this project's container (restarted if stopped), else creates a local Docker container.--url(a pasted Redis Cloud connect command works verbatim) and--cloudanswer the question up front. - Wires the project:
REDIS_URLwritten to.env(an explicit database choice replaces an existing value), a committed.env.exampleplaceholder, a.gitignoreguard, the official Redis client for the detected runtime, and redis-cli when missing (on a terminal init asks first; otherwise it prints the install command unless--install-cliis passed). - Teaches the agents: the official redis/agent-skills
via the standard skills CLI, a generated
redis-project-setupskill carrying this project's specific facts, and a credential-freeredisMCP server registration per agent config. - Proves it works: a live PING and SET/GET round trip.
Re-running with the same choices preserves the existing setup. An explicit database
choice replaces REDIS_URL; other env values are kept, including placeholders
that need filling. A redis entry in an agent's MCP
config that differs from the generated launcher is replaced (reported updated);
other MCP servers in the file survive
untouched. The generated skill describes the whole project: a run that adds a
product keeps what the skill says about the database and about the products set
up before.
Options¶
| Flag | Meaning |
|---|---|
--url <redis-url> |
use an existing database instead of Docker (rediss:// supported; accepts a pasted redis-cli -u ... command) |
--cloud |
take the database from Redis Cloud: connect to an existing database by --name, pick one interactively, or create one on the free Essentials plan. An account that already has databases needs --name when nothing can prompt (piped or --defaults). Not signed in yet? On a terminal it opens the browser to sign in first |
--cloud-subscription <id> |
create in this Essentials subscription instead of the free plan (requires --cloud) |
--name <label> |
database name: with --cloud it is the reuse key and the name of a new database; a database outside Docker is named by it in the generated project skill |
--agent <name> |
configure specific agents (claude, cursor, vscode, codex, all; repeatable or comma-separated). Default: on a terminal the wizard asks; otherwise the detected tools, or all four when none is detected |
--no-install-cli |
skip installing redis-cli when it is missing |
--install-cli |
install a missing redis-cli without asking. On a terminal init asks before running the official installer from packages.redis.io; a run with nothing to ask (piped stdin, CI set, or --defaults) only prints the install command unless this flag is set |
--skills-repo <dir> |
copy skills from a local redis/agent-skills checkout (offline-safe); a same-named skill dir that init did not copy and the skills CLI does not track is kept as it is |
--skills-global |
install the official skills for your user instead of this project |
--no-skills |
skip the official skills; the generated redis-project-setup skill is still written. The wizard offers the same as "Skip" |
--defaults |
take the defaults instead of asking: with no database flag that is a local Docker container. With --cloud and no Cloud sign-in, a terminal still opens the browser to sign in; piped stdin never prompts |
--dry-run |
print the full plan, write nothing |
--no-telemetry |
do not send the anonymous usage event for this run |
--agent-memory <endpoint> |
wire Agent Memory (with --store <id>); without --api-key or an exported AGENT_MEMORY_API_KEY, the key stays a .env placeholder to paste by hand |
--langcache <endpoint> |
wire LangCache (with --cache <id>) |
--context-retriever <endpoint> |
wire Context Retriever and bridge its MCP tools into the project agents |
--api-key <key> |
key for the one product being wired. A real key already in .env wins over it, and so does the product's own env var when .env has none; a placeholder in .env gives way to the flag |
--complete |
validate a product setup already present in .env (after filling the placeholders) |
--no-example |
skip the per-product example module |
--iris |
discovery-only: teach the agent to recommend the smallest Iris setup; adds no runtime |
Credentials¶
.env is the only file that ever holds the connection string. The MCP configs and
the generated skill are credential-free and safe to commit: the MCP launcher reads
REDIS_URL from .env when the agent starts the server (without executing the
file) and hands the server the password through its environment, never on a command
line other users can see. The launcher runs through sh: on native Windows, use WSL or
put Git Bash's sh on PATH, and init notes when it finds no sh. Passwords are masked in all terminal output. A new .env is readable
only by you, .gitignore covers it before it is written, and a .env that git
already tracks is refused rather than handed a secret. So are a .env or .gitignore
that is a symlink, and a .env that is the same file as .env.example: each could
put the password in a committed file or leave .env unignored. In a git repository,
git decides whether .env is already ignored. A .env that sets one of
init's keys on more than one line is refused too: dotenv loaders read the last line,
and so does the MCP launcher. With --cloud, these checks and every other check on
the project's files run before Redis Cloud is asked for a database.
Pinned tools¶
The MCP configs launch exact releases: redis-mcp-server through uvx, the mcp/redis
image by digest when uvx is missing, and mcp-remote for Context Retriever. init itself
runs a pinned skills CLI, and tells the redis-cli installer which version to fetch (a
REDIS_CLI_VERSION you export wins). Only those packages are pinned: uvx and npx
resolve their dependencies the first time a machine runs them, while the Docker image
carries its own locked set. The versions are in the generated configs and can move with
a redisctl release: after upgrading, run redisctl init again to refresh them (add
--complete when Context Retriever is set up). The redis/agent-skills content itself
comes from that repository's default branch.
init fetches the redis-cli installer script over https only. The script's own downloads, and its checksum check against a file on the same server, are its own.
Exit codes¶
Built on the standard redisctl exit codes:
| Code | Meaning |
|---|---|
| 0 | success, including --dry-run and a run that ends with "Action required" |
| 1 | the run cannot finish: Docker unavailable or a docker command failed, no free port, a project file cannot be read or written, .env tracked by git while init would write a secret into it, a .env or .gitignore symlink, a product key rejected, --cloud with no sign-in and nothing to prompt on, the OS keyring cannot store a new sign-in, an account with databases and no --name when nothing can prompt, a new Cloud database that never gets an endpoint |
| 2 | usage: an unknown flag or argument, --cloud together with --url or a pasted URL, --cloud-subscription without --cloud |
| 3 | the redisctl configuration cannot be used, for example -p names a profile that is not a Redis Cloud one |
| 4 | Redis Cloud rejected the API keys |
| 5 | Redis Cloud has no such resource |
| 6 | invalid input: no redis:// URL in --url, a product flag missing its companion, --complete with nothing to complete, an invalid Cloud database name, a .env that sets one of init's keys on more than one line |
| 7 | Redis Cloud conflict: a paid redisctl-<name> subscription, the free plan already used up, a quota reached |
| 8 | any other Redis Cloud API or server error |
| 9 | Redis Cloud rate limit |
| 10 | the database cannot be reached (for a stale .env value, the message names it) |
| 12 | cancelled at a wizard question or the Cloud picker |
A failure inside the browser sign-in itself comes from redisctl cloud auth login
and keeps that command's exit codes.
Telemetry¶
When a telemetry key is configured, the first run on a machine prints a notice and
sends nothing. From the next run on, each run sends one anonymous usage event to
Amplitude: which paths get used (flags as booleans, outcome, duration) - never paths,
names, URLs, or credentials. The device id is a random UUID in
~/.cache/redisctl/id: it links the runs from one machine and nothing else, and a
machine that cannot save it sends nothing. Opt out with --no-telemetry,
REDISCTL_INIT_TELEMETRY=0, or DO_NOT_TRACK=1. The Amplitude key is read from
REDISCTL_INIT_AMPLITUDE_KEY at runtime, or from the build environment at compile
time; a build without one sends nothing. REDISCTL_INIT_TELEMETRY_DEBUG=1 prints the
event body and send outcome to stderr, or why nothing was shared.
Iris products¶
Product flags wire Redis Iris services into the project: env blocks in .env and
.env.example (never clobbering existing keys), the SDK for the detected runtime,
an example module nothing imports, product facts in the generated skill, and - for
Context Retriever - a project MCP bridge that reads the agent key from .env at
launch. The API key crosses the secret boundary by hand: without one the run ends
successfully with "Action required", you paste the key into .env yourself, and
redisctl init --complete validates the full setup live. --iris installs only
the recommendation guidance so an agent can propose the smallest setup, which you
approve before anything is added.