$npx -y skills add launchdarkly/ai-tooling --skill first-flagCreate a boolean first flag, add evaluation, toggle on/off for end-to-end proof. Parent onboarding Step 6; uses MCP, API, or ldcli; optional flag-create skill.
| 1 | # Create first feature flag |
| 2 | |
| 3 | The SDK is connected. Now help the user create their first feature flag and see it work end-to-end. |
| 4 | |
| 5 | This skill is nested under [LaunchDarkly onboarding](../SKILL.md); the parent **Step 6** is **first flag**. **Prior:** [Apply code changes](../sdk-install/apply/SKILL.md). |
| 6 | |
| 7 | **Optional -- Flag Create skill already installed:** If the **`launchdarkly-flag-create`** skill from [github.com/launchdarkly/ai-tooling](https://github.com/launchdarkly/ai-tooling) is available in the session (install with `npx skills add launchdarkly/ai-tooling --skill launchdarkly-flag-create -y --agent <agent>`), you may use it for **creating the flag** and **choosing evaluation code** that matches the repo. You must still complete **default off -> verify OFF -> toggle on -> verify ON** (Steps 3-5 below). **Do not** require that skill: this page stays the full fallback when it is missing or MCP-only flows conflict with the user's setup. |
| 8 | |
| 9 | ## Security: Credential handling |
| 10 | |
| 11 | **Never substitute literal token values into commands.** Use environment variable references instead: |
| 12 | |
| 13 | - Shell commands: `$LAUNCHDARKLY_ACCESS_TOKEN` (expanded by the shell, not visible in `ps` output) |
| 14 | - Set the variable in your session: `export LAUNCHDARKLY_ACCESS_TOKEN=<your-token>` |
| 15 | |
| 16 | This prevents tokens from appearing in process lists, shell history, and screen recordings. |
| 17 | |
| 18 | ## Step 0: Consult SDK flag-key guidance |
| 19 | |
| 20 | Before creating the flag or wiring evaluation code, check the [Flag key behavior by SDK](#flag-key-behavior-by-sdk) table below. Some SDKs transform flag keys before exposing them in application code (e.g. the React SDK camelCases kebab-case keys). The flag key you create in LaunchDarkly, the SDK/framework configuration, and the key you reference in code must all align. |
| 21 | |
| 22 | - **If the SDK transforms keys** (e.g. React `useFlags()` camelCases `my-first-flag` → `myFirstFlag`): generate evaluation code using the **transformed** key. The flag key in LaunchDarkly stays as-is (kebab-case is conventional). |
| 23 | - **If the SDK preserves keys as-is** (most server-side SDKs): use the exact LaunchDarkly flag key string in code. |
| 24 | - **If the SDK supports both modes** (e.g. React allows disabling camelCase via provider options): decide which mode the project uses (check existing code or provider config), then generate code that matches. |
| 25 | |
| 26 | ### Flag key behavior by SDK |
| 27 | |
| 28 | | SDK | Key transformation | Code key for `my-first-flag` | Notes | |
| 29 | |-----|--------------------|------------------------------|-------| |
| 30 | | React Web (`useFlags()`) | camelCase by default | `myFirstFlag` | `reactOptions: { useCamelCaseFlagKeys: false }` on the provider disables this | |
| 31 | | React Native (`useFlags()`) | camelCase by default | `myFirstFlag` | Same `reactOptions` override available | |
| 32 | | Vue (`useLDFlag()`) | None (pass original key) | `'my-first-flag'` | | |
| 33 | | JavaScript Browser | None | `'my-first-flag'` | | |
| 34 | | Node.js Server | None | `'my-first-flag'` | | |
| 35 | | Python Server | None | `'my-first-flag'` | | |
| 36 | | Go Server | None | `"my-first-flag"` | | |
| 37 | | Java Server | None | `"my-first-flag"` | | |
| 38 | | .NET Server | None | `"my-first-flag"` | | |
| 39 | | Ruby Server | None | `'my-first-flag'` | | |
| 40 | | Swift/iOS | None | `"my-first-flag"` | | |
| 41 | | Android | None | `"my-first-flag"` | | |
| 42 | | Flutter | None | `'my-first-flag'` | | |
| 43 | |
| 44 | When wiring the evaluation code in Step 2 below, use the **Code key** column value, not the raw LaunchDarkly key, whenever the SDK applies a transformation. |
| 45 | |
| 46 | ## Step 1: Create the flag |
| 47 | |
| 48 | **REST / curl auth:** Use `$LAUNCHDARKLY_ACCESS_TOKEN` as the `Authorization` header value (LaunchDarkly uses the raw token, no `Bearer` prefix). The shell expands the variable but doesn't log it. |
| 49 | |
| 50 | ### Via MCP (preferred) |
| 51 | |
| 52 | If the LaunchDarkly MCP server is available, use `create-feature-flag` (or the equivalent flag-creation tool your server exposes): |
| 53 | |
| 54 | - **Key**: `my-first-flag` (or a name relevant to the user's project) |
| 55 | - **Name**: "My First Flag" |
| 56 | - **Kind**: `boolean` |
| 57 | - **Variations**: `true` / `false` |
| 58 | - **Temporary**: `true` |
| 59 | |
| 60 | ### Via LaunchDarkly API |
| 61 | |
| 62 | ```bash |
| 63 | curl -s -X POST \ |
| 64 | "https://app.launchdarkly.com/api/v2/flags/PROJECT_KEY" \ |
| 65 | -H "Authorization: $LAUNCHDARKLY_ACCESS_TOKEN" \ |
| 66 | -H "Content-Type: application/json" \ |
| 67 | -d '{ |
| 68 | "name": "My First Flag", |
| 69 | "key": "my-first-flag", |
| 70 | "kind": "boolean", |
| 71 | "variations": [ |
| 72 | {"value": true}, |
| 73 | {"value": false} |
| 74 | ], |
| 75 | "temporary": true |
| 76 | }' |
| 77 | ``` |
| 78 | |
| 79 | ### Via ldcli |
| 80 | |
| 81 | ```bash |
| 82 | ldcli flags create \ |
| 83 | --access-token "$LAUNCHDARKLY_ACCESS_TOKEN" \ |
| 84 | --project PROJECT_KEY \ |
| 85 | --data '{"name": "My First Flag", "key": "my-first-flag", "kind": "boolean", "temporary": true}' |
| 86 | ``` |
| 87 | |
| 88 | After creatio |