npx skills add ...
npx skills add launchdarkly/experimental-agent-skills --skill onboardingv2
Scripted, branded onboarding for LaunchDarkly. Fixed sequence with LaunchDarkly voice and tone. Enforces step completion before advancing. Redirects drift. Use when the user wants to set up LaunchDarkly from scratch or asks to start onboarding.
npx skills add launchdarkly/experimental-agent-skills --skill onboardingv2
Write plainly. Say only what you did or are about to do. No flourishes, slogans, or metaphors.
The signup URL includes a source query parameter for attribution. Resolve it once at kickoff by scanning the user's original message. Store the resolved URL for the session. This marker is for the agent only. Never show it to the user.
| User's original prompt contains | Source value | Resulting URL |
|---|---|---|
source-launchdarkly | ldwebsite | https://app.launchdarkly.com/signup?source=ldwebsite |
| No marker | agent | https://app.launchdarkly.com/signup?source=agent |
source-launchdarkly. If found, use ldwebsite. Otherwise use agent.agent.Wherever these instructions say "offer the signup link," use the resolved URL. Never hardcode ?source=agent.
Keep user-facing messages rare and short. You are letting the user delegate and walk away.
Greet and present the first choice immediately. Do not make the user wait on a scan. Start the codebase scan in the background (a subagent if available) and use its results when they land. Never ask the user about the scan.
| Signal | Inference |
|---|---|
| LD SDK in dependencies | Knows LaunchDarkly |
variation(), useFlags(), or equivalent calls present | Has used flags before |
| MCP already configured | Familiar with the tooling |
| Well-structured codebase (CI, tests, linting) | Experienced developer |
| Empty workspace, no LD presence | Treat as first-time |
If experienced signals show, move faster: skip the orientation line, do each action and report it in one line, and jump to whichever step is incomplete. Either way the outcomes are the same: SDK installed, first flag evaluating, and MCP only if they ask for it.
If the user says "continue onboarding," they are returning to the flow. Do not ask what was happening. Detect live state in order: check for a LaunchDarkly SDK package and init code, then for variation() calls, then for the launchdarkly-onboarding branch. Resume at the first incomplete step and say where things stand in one sentence ("SDK is installed. Creating your first flag now."). Then continue without preamble.
When the user asks to set up LaunchDarkly:
"Let's get you set up with LaunchDarkly. Once integrated, we'll create a test flag in your app so you can see how it works. No code will be changed without your approval."
If this is a git repository, create and switch to a new branch named launchdarkly-onboarding before changing any files, so everything is isolated and reversible. If that branch already exists, append a short suffix. If this is not a git repo, skip silently.
Do not write an onboarding log or any summary file. Track state in memory for this session.
The scan runs in the background (see Experience Detection). Do not announce it beyond the one status line. Use its results when they land.
Classify the workspace before proceeding:
| State | Criteria | Action |
|---|---|---|
| Clear app | One language, a real entrypoint, one dependency manifest at the obvious location | Continue |
| Unclear | Minimal or conflicting signals, or a multi-package workspace (yarn/pnpm/npm workspaces, lerna, nx, turborepo, gradle, cargo, go) where more than one package could host LaunchDarkly | Ask (unclear form below) |
| No app found | No manifests, no entrypoints, empty workspace | Ask (no-app form below) |
A workspace with two or more candidate packages is always Unclear. Never guess which one to integrate.
Ask form, unclear workspace (one option per candidate package, with its path as the label):
Ask form, no app found:
On a demo choice, scaffold a minimal app in a new subfolder (e.g. launchdarkly-demo/).
Identify language, framework, and environment type from dependency files (package.json, go.mod, requirements.txt/pyproject.toml, pom.xml/build.gradle, Gemfile, *.csproj, Cargo.toml). Search for existing LaunchDarkly usage (launchdarkly, ldclient, LDClient, @launchdarkly). Determine server-side, client-side, or mobile, which drives SDK selection. If LD is already integrated, note the SDK version so install can be skipped.
Detect the coding agent for --agent flags: Cursor (.cursor/, .cursorrules), Claude Code (~/.claude/, CLAUDE.md), Windsurf (.windsurfrules), GitHub Copilot (.github/copilot/), Codex (~/.codex/, AGENTS.md). If ambiguous, ask.
Do not set up MCP on the way to the first flag, and do not ask about it during setup. Reach the first flag without it (Step 4 uses a dashboard link). Offer it only after the flag works, as one short choice:
"Want to manage flags from your editor next time? I can set that up. [Set it up] [Skip]"
If they choose Set it up: check for a local mcp-configure skill before installing. If not present, install it:
If that fails, check ~/.agents/skills/ and ~/.cursor/skills/ for a cached copy, or follow mcp-configure inline using MCP Config Templates. After it succeeds, call get-project once (projectKey: "default") and store projectKey and envKey (test).
Install the SDK and wire up initialization automatically. Do not ask how, and do not explain what the SDK is. Tell the user one line: "Scan complete. Installing SDK." Then proceed.
Hand off to sdk-install with the stack context from Step 1. It selects the package, installs it, and wires initialization to match the codebase.
When the app was scaffolded by the agent in Step 1, skip the nested skill and use the fast path directly (the stack is known; skip npm run build):
| Scaffold | Package | Install | Env var | Entrypoint | Init |
|---|---|---|---|---|---|
| React (Vite) | launchdarkly-react-client-sdk | npm install launchdarkly-react-client-sdk | VITE_LAUNCHDARKLY_CLIENT_SIDE_ID | src/main.jsx/.tsx | asyncWithLDProvider around the root render |
| Node.js | @launchdarkly/node-server-sdk | npm install @launchdarkly/node-server-sdk | LAUNCHDARKLY_SDK_KEY | src/index.js/server.js | init(sdkKey) then waitForInitialization() |
| Python | launchdarkly-server-sdk | pip install launchdarkly-server-sdk | LAUNCHDARKLY_SDK_KEY | app.py/main.py | ldclient.set_config(Config(sdk_key)) then ldclient.get() |
Rules: the SDK key lives in an environment variable, never hardcoded. One client instance, shared. Wait for initialization before evaluating flags.
The SDK needs a key. Default to fetching it for the user when MCP is connected; otherwise give them the direct link and let them paste it. Ask only if you cannot determine the path:
get-environments, write it to .env, and ensure .env is gitignored. Never print key values.https://app.launchdarkly.com/projects/{projectKey}/settings/environments/{envKey}/keysDo not proceed until initialization is verified.
Create the flag, wire it into the app, and let the user watch it turn on.
create-flag (on a duplicate-key conflict, call get-flag and adopt the existing flag; do not list-flags first). If MCP is not connected, give them a dashboard link that opens the create form with the key prefilled and have them create it: https://app.launchdarkly.com/projects/{projectKey}/flags/new?key={flagKey}lsof -ti :3000,4000,5173 first). Keep it running until the user has seen the flag turn on. Do not stop the server before then.https://app.launchdarkly.com/projects/{projectKey}/flags/{flagKey}/targeting?env={envKey}toggle-flag (MCP) or the REST API, whichever is configured. If neither is, fall back to the dashboard link.Do not print the page or the banner text in chat. Point the user to their browser: the banner at <url> flips live with the server still running. That is the flag working.
Keep it to a few lines:
https://app.launchdarkly.com/projects/{projectKey}/flags/{flagKey}/targeting?env={envKey}launchdarkly-onboarding branch, so you can review, keep, or drop them however you like.If the user asks to skip a step or jump ahead mid-flow, your first reply always does three things, in order, before writing code or skipping:
"I hear you, you want the flag code now. Without the SDK installed those calls won't run. Setup takes about two minutes. Want me to finish that first, or hand you the code to wire up after?"
Never silently dump code with no tradeoff, and never rigidly refuse. If they insist, respect it, note what was skipped, restate the risk in one sentence, and keep moving.
| Repo | Skills | Purpose |
|---|---|---|
launchdarkly/experimental-agent-skills | onboardingV2, sdk-install, mcp-configure | Setup |
launchdarkly/agent-skills | launchdarkly-flag-create and related | Flag management |
get-project to store keys and continue.mcp/launchdarkly server. Do not auto-migrate.