
Launchdarkly Flag Create
- 537 installs
- 23 repo stars
- Updated August 5, 2026
- launchdarkly/ai-tooling
This is a copy of launchdarkly-flag-create by launchdarkly - installs and ranking accrue to the original listing.
Create new LaunchDarkly feature flags with correct keys, variations, and environments when introducing gated functionality in application code.
About
Walks agents through creating LaunchDarkly feature flags with correct keys, variation types, and environment mappings, ensuring new gated functionality in application code is backed by properly configured toggles across development, staging, and production projects.
- Creates LaunchDarkly flags with proper keys
- Defines boolean or multivariate variations
- Maps flags across dev and prod environments
- Aligns SDK usage with console setup
- Supports incremental feature delivery
Launchdarkly Flag Create by the numbers
- 537 all-time installs (skills.sh)
- +53 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/launchdarkly/ai-tooling --skill launchdarkly-flag-createAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 537 |
|---|---|
| repo stars | ★ 23 |
| Last updated | August 5, 2026 |
| Repository | launchdarkly/ai-tooling ↗ |
What it does
Create new LaunchDarkly feature flags with correct keys, variations, and environments when introducing gated functionality in application code.
Files
LaunchDarkly Flag Create & Configure
You're using a skill that will guide you through introducing a new feature flag into a codebase. Your job is to explore how flags are already used in this codebase, create the flag in LaunchDarkly in a way that fits, add the evaluation code matching existing patterns, and verify everything is wired up correctly.
Prerequisites
This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.
Required MCP tools:
create-flag: create a new feature flag in a projectget-flag: verify the flag was created correctly
Optional MCP tools (enhance workflow):
list-flags: browse existing flags to understand naming conventions and tagsupdate-flag-settings: update flag metadata (name, description, tags, temporary/permanent status)
Workflow
Step 1: Explore the Codebase
Before creating anything, understand how this codebase uses feature flags.
1. Find the SDK. Search for LaunchDarkly SDK imports or initialization:
- Look for
launchdarkly,ldclient,ld-client,LDClientin imports - Check
package.json,requirements.txt,go.mod,Gemfile, or equivalent for the SDK dependency - Identify which SDK is in use (server-side Node, React, Python, Go, Java, etc.)
2. Find existing flag evaluations. Search for variation calls to understand the patterns this codebase uses:
- Direct SDK calls:
variation(),boolVariation(),useFlags(), etc. - Wrapper patterns: Does this codebase abstract flags behind a service or utility?
- Constant definitions: Are flag keys defined as constants somewhere?
- See SDK Evaluation Patterns for patterns by language
3. Understand conventions. Look at existing flags to learn:
- Naming convention: Are keys
kebab-case,snake_case,camelCase? - Organization: Are flag keys co-located with features, or centralized in a constants file?
- Default values: What defaults do existing evaluations use?
- Context/user construction: How does this codebase build the user/context object passed to the SDK?
4. Check LaunchDarkly project conventions. Optionally use list-flags to see existing flags:
- What tags are commonly used?
- Are flags marked as temporary or permanent?
- What naming patterns exist in the project?
Step 2: Determine the Right Flag Type
Based on what the user needs, choose the appropriate flag configuration. See Flag Types and Patterns for the full guide.
Quick decision:
| User intent | Flag kind | Variations |
|---|---|---|
| "Toggle a feature on/off" | boolean | true / false |
| "Gradually roll out a feature" | boolean | true / false |
| "A/B test between options" | multivariate (string) | User-defined values |
| "Configure a numeric threshold" | multivariate (number) | User-defined values |
| "Serve different config objects" | multivariate (JSON) | User-defined values |
Defaults to apply:
- Set
temporary: trueunless the user explicitly says this is a permanent/long-lived flag. Most flags are release flags that should eventually be cleaned up. - Generate a
keyfrom the name if not provided (e.g., "New Checkout Flow" ->new-checkout-flow), but match the codebase's naming convention if one exists. - Suggest relevant tags based on the feature area, team, or context the user mentions.
Step 3: Create the Flag in LaunchDarkly
Use create-flag with the configuration determined in Step 2.
After creation:
- The flag is created with targeting OFF in all environments.
- The flag serves the
offVariationto everyone until targeting is turned on. - Remind the user they'll need to use the flag targeting skill to toggle it on and optionally set up rollout rules.
Step 4: Add Flag Evaluation to Code
Now add the code to evaluate the flag, matching the patterns you found in Step 1.
1. Use the same SDK patterns the codebase already uses. If there's a wrapper, use the wrapper. If there are constants, add the new key to the constants file. 2. Use an appropriate default value. The default (fallback) value in code should be the "safe" behavior: typically the existing behavior before the flag. This ensures the feature stays off if the SDK can't reach LaunchDarkly. 3. Add the conditional logic. Wrap the new behavior in a flag check. 4. Handle both branches. Make sure the code path for each variation is clear and complete.
See SDK Evaluation Patterns for implementation examples by language and framework.
Step 5: Verify
Confirm the flag is properly set up:
1. Code compiles/passes linting. Run the project's build or lint step. 2. Flag exists in LaunchDarkly. Use get-flag to confirm it was created with the right configuration. 3. Both code paths work. The flag-off path preserves existing behavior; the flag-on path enables the new feature. 4. Default value is safe. If LaunchDarkly is unreachable, the code falls back to the default: make sure that's the existing/safe behavior.
Updating Flag Settings
If the user wants to change flag metadata (not targeting), use update-flag-settings. Supported changes:
| Change | Instruction |
|---|---|
| Rename | {kind: "updateName", value: "New Name"} |
| Update description | {kind: "updateDescription", value: "New description"} |
| Add tags | {kind: "addTags", values: ["tag1", "tag2"]} |
| Remove tags | {kind: "removeTags", values: ["old-tag"]} |
| Mark as temporary | {kind: "markTemporary"} |
| Mark as permanent | {kind: "markPermanent"} |
Multiple instructions can be batched in a single call. These changes are project-wide, not environment-specific.
Important: Metadata updates (above) are separate from targeting changes (toggle, rollout, rules). If the user wants to change who sees what, direct them to the flag targeting skill.
Important Context
- Flag keys are immutable. Once created, a flag's key cannot be changed. Choose carefully.
- Flags start OFF. Creation never enables a flag. This is a safety feature.
- The default value in code is your safety net. It's what gets served when the SDK can't connect to LaunchDarkly. Always use the "safe" / existing behavior as the default.
- Follow existing codebase conventions. The most common mistake is introducing a flag pattern that doesn't match what the team already does. Step 1 exists to prevent this.
References
- Flag Types and Patterns: Boolean vs multivariate, naming conventions, configuration best practices
- SDK Evaluation Patterns: How to evaluate flags in each SDK, including common wrapper patterns
{
"name": "launchdarkly-flag-create",
"description": "Create and configure LaunchDarkly feature flags in a way that fits the existing codebase",
"version": "1.0.0-experimental",
"author": "LaunchDarkly",
"repository": "https://github.com/launchdarkly/ai-tooling",
"skills": ["./"],
"tags": [
"launchdarkly",
"feature-flags",
"feature-management",
"flag-creation",
"feature-toggle",
"sdk",
"devops",
"mcp"
],
"requirements": {
"mcp-servers": ["@launchdarkly/mcp-server"]
}
}
LaunchDarkly Flag Create Skill
An Agent Skill for introducing new feature flags into a codebase, matching existing patterns and conventions.
Overview
This skill teaches agents how to:
- Explore a codebase to understand existing flag patterns and SDK usage
- Choose the right flag type and configuration
- Create the flag in LaunchDarkly
- Add flag evaluation code that matches codebase conventions
- Verify the flag is wired up correctly
Installation (Local)
For now, install by placing this skill directory where your agent client loads skills.
Examples:
- Generic: copy
skills/feature-flags/launchdarkly-flag-create/into your client's skills path
Prerequisites
This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment. The remote server provides higher-level, agent-optimized tools that orchestrate multiple API calls and return pruned, actionable responses.
Usage
Once installed, the skill activates automatically when you ask about creating flags:
Create a feature flag for the new checkout flowWrap the dark mode feature in a LaunchDarkly flagAdd a feature toggle for the new pricing pageStructure
launchdarkly-flag-create/
├── SKILL.md
├── marketplace.json
├── README.md
└── references/
├── flag-types.md
└── sdk-evaluation-patterns.mdRelated
- LaunchDarkly Flag Targeting: Control targeting after creating a flag
- LaunchDarkly Flag Cleanup: Remove flags when they're no longer needed
- LaunchDarkly MCP Server
- LaunchDarkly Docs
License
Apache-2.0
Flag Types and Patterns
A reference for choosing the right flag type and configuring it properly.
Flag Kinds
Boolean Flags
The most common type. Two variations: true and false.
When to use:
- Feature toggles (show/hide a feature)
- Kill switches (disable a feature in emergencies)
- Gradual rollouts (serve
trueto a percentage of traffic) - Simple A/B tests (control vs treatment)
Configuration:
{
"kind": "boolean",
"variations": [
{"value": true},
{"value": false}
]
}Convention: Variation 0 is true (the new/enabled behavior), variation 1 is false (the old/disabled behavior). The offVariation should point to false.
Multivariate Flags (String)
Multiple string values. Use for text variants, feature versions, or named configurations.
When to use:
- A/B/C tests with different copy or UI variants
- Feature version selection ("v1", "v2", "v3")
- Named configuration modes ("basic", "advanced", "enterprise")
Configuration:
{
"kind": "multivariate",
"variations": [
{"value": "control", "name": "Control"},
{"value": "variant-a", "name": "Variant A"},
{"value": "variant-b", "name": "Variant B"}
]
}Multivariate Flags (Number)
Numeric values. Use for thresholds, limits, or quantities.
When to use:
- Rate limits
- Timeout durations
- Feature limits (max items, max size)
- Numeric configuration that varies by audience
Configuration:
{
"kind": "multivariate",
"variations": [
{"value": 10, "name": "Default"},
{"value": 50, "name": "Increased"},
{"value": 100, "name": "Maximum"}
]
}Multivariate Flags (JSON)
Complex objects. Use for structured configuration.
When to use:
- Configuration objects with multiple fields
- UI layout configurations
- Feature bundles (multiple settings in one flag)
Configuration:
{
"kind": "multivariate",
"variations": [
{"value": {"theme": "light", "density": "comfortable"}, "name": "Default"},
{"value": {"theme": "dark", "density": "compact"}, "name": "Dark Compact"}
]
}Naming Conventions
Flag Keys
Flag keys are immutable identifiers. Choose carefully.
Common conventions:
| Convention | Example | When used |
|---|---|---|
kebab-case | new-checkout-flow | Most common, LaunchDarkly default |
snake_case | new_checkout_flow | Common in Python/Ruby codebases |
camelCase | newCheckoutFlow | Sometimes in JS/TS codebases |
dot.notation | checkout.new-flow | Hierarchical organization |
Always check the existing codebase for which convention is in use before creating a new flag.
Good key practices:
- Descriptive but concise:
new-checkout-flownotthe-new-checkout-flow-feature - Feature-oriented:
dark-modenotjira-1234 - Avoid dates:
new-pricingnotnew-pricing-2025
Flag Names
The human-readable display name in the LaunchDarkly UI. Can be changed later (unlike keys).
Good name practices:
- Use title case: "New Checkout Flow"
- Be descriptive: "Dark Mode Toggle" not "DM"
- Include context: "Checkout V2 (Q1 Experiment)" can be helpful
Temporary vs Permanent
Temporary Flags (default)
- Expected to be removed after the feature is fully rolled out
- LaunchDarkly tracks these for cleanup reminders
- Most feature toggles and release flags are temporary
Permanent Flags
- Long-lived configuration that should NOT be cleaned up
- Kill switches, ops toggles, plan-based feature gating
- Only mark as permanent when the user explicitly says the flag is long-lived
Tags
Tags help organize flags in LaunchDarkly. Suggest tags based on:
| Category | Example tags |
|---|---|
| Team | team-checkout, team-platform |
| Feature area | payments, onboarding, search |
| Flag purpose | experiment, release, ops |
| Lifecycle | q1-2025, migration |
Best Practices for Variations
Boolean Flags
- Name variations:
true-> "Enabled" / "New behavior",false-> "Disabled" / "Old behavior" - Set
offVariationtofalse(index 1)
Multivariate Flags
- Always include a "control" or "default" variation
- Give every variation a descriptive
name - Consider what the
offVariationshould be: typically the control/default - Order variations with the default/control first
Default Values in Code
- The default value (fallback) in your code should ALWAYS be the safe/existing behavior
- For boolean flags: default to
false(feature off) unless the feature is already live - For multivariate: default to the control/existing variation
- This ensures graceful degradation if LaunchDarkly is unreachable
SDK Evaluation Patterns
How to evaluate feature flags in each LaunchDarkly SDK. Use this reference to match the patterns already in use in the codebase.
JavaScript/TypeScript (Node.js Server SDK)
// Standard boolean evaluation
const enabled = await ldClient.boolVariation('flag-key', context, false);
// Standard string evaluation
const variant = await ldClient.stringVariation('flag-key', context, 'default');
// Standard number evaluation
const limit = await ldClient.numberVariation('flag-key', context, 10);
// JSON evaluation
const config = await ldClient.jsonVariation('flag-key', context, {});
// Generic evaluation (returns any type)
const value = await ldClient.variation('flag-key', context, defaultValue);
// With evaluation details (includes reason for the variation served)
const detail = await ldClient.boolVariationDetail('flag-key', context, false);
// detail.value, detail.variationIndex, detail.reason
// All flags at once
const allFlags = await ldClient.allFlagsState(context);JavaScript/TypeScript (React SDK)
// Hook-based (most common in React)
import { useFlags, useLDClient } from 'launchdarkly-react-client-sdk';
function MyComponent() {
const { flagKey } = useFlags(); // camelCase access
const flags = useFlags();
const value = flags['flag-key']; // bracket access for kebab-case keys
// Direct client access when needed
const ldClient = useLDClient();
const variant = ldClient?.variation('flag-key', 'default');
}
// HOC pattern (older codebases)
import { withLDConsumer } from 'launchdarkly-react-client-sdk';
class MyComponent extends React.Component {
render() {
const enabled = this.props.flags['flag-key'];
return enabled ? <NewFeature /> : <OldFeature />;
}
}
export default withLDConsumer()(MyComponent);Python
# Standard evaluation
enabled = ld_client.variation('flag-key', context, False)
# Typed evaluations
enabled = ld_client.bool_variation('flag-key', context, False)
variant = ld_client.string_variation('flag-key', context, 'default')
limit = ld_client.int_variation('flag-key', context, 10)
ratio = ld_client.float_variation('flag-key', context, 0.0)
config = ld_client.json_variation('flag-key', context, {})
# With details
detail = ld_client.variation_detail('flag-key', context, False)
# detail.value, detail.variation_index, detail.reason
# All flags
all_flags = ld_client.all_flags_state(context)Go
// Typed evaluations
enabled, err := ldClient.BoolVariation("flag-key", context, false)
variant, err := ldClient.StringVariation("flag-key", context, "default")
limit, err := ldClient.IntVariation("flag-key", context, 10)
ratio, err := ldClient.Float64Variation("flag-key", context, 0.0)
config, err := ldClient.JSONVariation("flag-key", context, ldvalue.Null())
// With details
detail, err := ldClient.BoolVariationDetail("flag-key", context, false)
// detail.Value, detail.VariationIndex, detail.Reason
// All flags
allFlags := ldClient.AllFlagsState(context)Java/Kotlin
// Typed evaluations
boolean enabled = ldClient.boolVariation("flag-key", context, false);
String variant = ldClient.stringVariation("flag-key", context, "default");
int limit = ldClient.intVariation("flag-key", context, 10);
double ratio = ldClient.doubleVariation("flag-key", context, 0.0);
LDValue config = ldClient.jsonValueVariation("flag-key", context, LDValue.ofNull());
// With details
EvaluationDetail<Boolean> detail = ldClient.boolVariationDetail("flag-key", context, false);
// detail.getValue(), detail.getVariationIndex(), detail.getReason()
// All flags
FeatureFlagsState allFlags = ldClient.allFlagsState(context);Ruby
# Standard evaluation
enabled = ld_client.variation('flag-key', context, false)
# Typed evaluations
enabled = ld_client.bool_variation('flag-key', context, false)
variant = ld_client.string_variation('flag-key', context, 'default')
limit = ld_client.number_variation('flag-key', context, 10)
config = ld_client.json_variation('flag-key', context, {})
# With details
detail = ld_client.variation_detail('flag-key', context, false)
# detail.value, detail.variation_index, detail.reason
# All flags
all_flags = ld_client.all_flags_state(context).NET (C#)
// Typed evaluations
bool enabled = ldClient.BoolVariation("flag-key", context, false);
string variant = ldClient.StringVariation("flag-key", context, "default");
int limit = ldClient.IntVariation("flag-key", context, 10);
float ratio = ldClient.FloatVariation("flag-key", context, 0.0f);
double precise = ldClient.DoubleVariation("flag-key", context, 0.0);
LdValue config = ldClient.JsonVariation("flag-key", context, LdValue.Null);
// With details
EvaluationDetail<bool> detail = ldClient.BoolVariationDetail("flag-key", context, false);
// detail.Value, detail.VariationIndex, detail.Reason
// All flags
FeatureFlagsState allFlags = ldClient.AllFlagsState(context);Common Wrapper Patterns
Many teams build abstraction layers over the SDK. Search for these in addition to direct SDK calls:
// Service/utility wrappers
featureFlagService.isEnabled('flag-key');
featureFlagService.getValue('flag-key');
FeatureFlags.isEnabled('flag-key');
flagsClient.check('flag-key');
// Constants/enums for flag keys
FLAGS.NEW_CHECKOUT_FLOW
FeatureFlag.NEW_CHECKOUT_FLOW
FEATURE_FLAGS['flag-key']
const FLAG_KEY = 'flag-key';
// Decorator patterns (Python/Java)
@feature_flag('flag-key')
@FeatureFlag("flag-key")
// React context/provider patterns
<FeatureFlagProvider flags={['flag-key']}>
<ConditionalFeature flag="flag-key">
<NewFeature />
</ConditionalFeature>
</FeatureFlagProvider>
// Configuration files (YAML, JSON)
feature_flags:
flag-key: trueAdding a New Flag Evaluation
When adding flag evaluation code, follow this pattern:
1. Import/access the client the same way existing code does 2. Define the flag key following the project's convention (constants file, inline, etc.) 3. Choose the right evaluation method based on the flag type 4. Set a safe default value: the behavior when LaunchDarkly is unreachable 5. Add the conditional logic for each variation
Example: Adding a boolean flag (Node.js)
// If the codebase uses constants:
// In flags.ts / constants.ts
export const NEW_CHECKOUT_FLOW = 'new-checkout-flow';
// In the feature code:
import { NEW_CHECKOUT_FLOW } from '../flags';
const showNewCheckout = await ldClient.boolVariation(
NEW_CHECKOUT_FLOW,
context,
false // default: keep old behavior if LD is unreachable
);
if (showNewCheckout) {
return renderNewCheckout();
} else {
return renderOldCheckout();
}Example: Adding a boolean flag (React)
import { useFlags } from 'launchdarkly-react-client-sdk';
function CheckoutPage() {
const { newCheckoutFlow } = useFlags();
if (newCheckoutFlow) {
return <NewCheckout />;
}
return <OldCheckout />;
}