← Plugin catalog
Developer Tools

LaunchDarkly

Catamorphic Co. dba LaunchDarkly v1.0.0

Flags, AI Configs & metrics

Create a free account to save this plugin.

From the developer

Not specified in the available declarations: capabilities, limitations, pricing & account requirements.

Onboarding example

Find my stalest feature flags and open a PR removing the ones that are safe to delete.
Sources & dates

Developer declarations; not independently tested. Listing last checked Nov 13, 2026. Package observed Nov 12, 2026.

View package source →

Description

From the marketplace listing

Manage LaunchDarkly feature flags, AgentControl Configs (AI agent prompts/models), experiments, guarded and automated rollouts, segments, metrics, dashboards, alerts, and observability data (logs, traces, errors, sessions) directly from chat. Create and target flags, run and analyze experiments, configure AI agent prompts and tools, build dashboards and alerts, and investigate production issues without leaving the conversation.

Language: English · Automatically detected from descriptions.

Matches for “morphic”

Exact text from the indicated source. A mention alone does not establish support for your task.

Publisher

Catamorphic Co. dba LaunchDarkly

What changed

Files & skills

File archives

Plugin package156 files · 297 KBBrowse files →
Skill instructions
agent-graphs5.65 KB

View saved version →

---
name: agent-graphs
description: "Create and manage agent graphs — directed graphs of configs connected by edges with handoff logic. Use when building multi-agent workflows where configs route to each other."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Config Agent Graphs

You're using a skill that will guide you through creating and managing agent graphs in LaunchDarkly. Your job is to design the graph topology, create it with the right edges and handoffs, and verify the routing between config nodes.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `create-agent-graph` -- create a new graph with nodes and edges
- `get-agent-graph` -- inspect a graph's structure and edges
- `list-agent-graphs` -- browse existing graphs in the project

**Optional MCP tools:**
- `update-agent-graph` -- modify edges, root config, or description
- `delete-agent-graph` -- permanently remove a graph
- `get-ai-config` -- inspect individual configs that serve as nodes
- `create-ai-config` -- create new configs to use as graph nodes

## Core Concepts

### What Are Agent Graphs?

An agent graph is a directed graph where:
- **Nodes** are configs (each config is an agent with its own model, prompt, and tools)
- **Edges** define routing between configs (source -> target)
- **Handoff data** on edges controls how context is passed between agents
- **Root config** is the entry point — the first agent that receives user input

### When to Use Agent Graphs

| Scenario | Example |
|----------|---------|
| **Multi-step workflows** | Triage agent -> Specialist agent -> Summary agent |
| **Routing by intent** | Router agent decides which specialist handles the request |
| **Escalation chains** | L1 support -> L2 support -> Human handoff |
| **Pipeline processing** | Extract -> Transform -> Validate -> Store |

### Graph Structure

```
[Root Config] --edge--> [Config A] --edge--> [Config C]
                  \--edge--> [Config B]
```

Each edge has:
- `key` -- unique identifier for the edge
- `sourceConfig` -- the config key that routes FROM
- `targetConfig` -- the config key that routes TO
- `handoff` (optional) -- data/instructions passed during the transition

## Core Principles

1. **Design Before Building**: Map out nodes and edges on paper/whiteboard first
2. **One Agent, One Job**: Each node should have a clear, focused responsibility
3. **Root Config Is the Router**: The entry point should understand how to dispatch
4. **Handoff Data Matters**: Define what context flows between agents
5. **Verify the Full Path**: Test that routing works end-to-end

## Workflow

### Step 1: Design the Graph

Before creating anything:

1. Identify the agents (configs) needed — each is a graph node
2. Map the routing: which agent hands off to which?
3. Define handoff data: what context does each edge carry?
4. Identify the root config: which agent receives initial input?
5. Check existing graphs with `list-agent-graphs` to avoid duplicates
6. Check existing configs with `get-ai-config` to see what nodes already exist

### Step 2: Ensure Nodes Exist

Each node in the graph must be an existing config. If configs don't exist yet:
1. Use `create-ai-config` to create each agent config
2. Set up variations with appropriate models and prompts for each agent's role
3. Verify each config exists with `get-ai-config`

### Step 3: Create the Graph

Use `create-agent-graph` with:
- `projectKey` -- the project containing the configs
- `key` -- unique identifier for the graph
- `name` -- human-readable display name
- `description` (optional) -- explain the graph's purpose
- `rootConfigKey` -- the entry-point config key
- `edges` -- array of connections between configs

```json
{
  "projectKey": "my-project",
  "key": "support-triage-graph",
  "name": "Customer Support Triage",
  "description

Preview of the first 4,000 characters. Read full instructions →

alert-investigation3.64 KB

View saved version →

---
name: alert-investigation
description: "Investigates a triggered observability alert and returns a structured diagnosis with likely cause, scope, and next steps."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Alert investigation

You are investigating a specific triggered alert. Alerts arrive with structured context — an alert ID, name, threshold, value that crossed it, and a time range. Your job is to explain *why* it fired, assess *scope*, and recommend *action*.

## Prerequisites

This skill uses the following LaunchDarkly observability MCP tools:

- `query-logs` — query log records
- `query-traces` — query distributed traces
- `query-error-groups` — query error groups
- `query-sessions` — query sessions
- `query-aggregations` — query aggregated/time-bucketed metrics
- `get-keys` — discover available attribute keys before filtering

## Workflow

1. **Parse the alert context.** The first turn of the conversation carries alert variables: `alertID`, `alertName`, `alertValue`, `group`, `groupValue`, `query`, `thresholdWindow`, `timeRange`, plus a product-specific link. Use these, don't re-derive them.
2. **Load the per-product companion.** Based on the alert's product type, load the matching companion: `logs.md`, `traces.md`, `errors.md`, `sessions.md`, or `metrics.md`. Each captures the per-product investigation shape.
3. **Run the investigation** using the methodology from the investigate skill (cross-reference logs/traces/errors/sessions/metrics; cite identifiers; aggregate before paginating). Scoped to the alert's time range and filter.
4. **Produce a structured diagnosis.** See output template below.

## Output template

Alert investigations have a consistent structure so consumers (notification channels, dashboards) can parse them.

```
## What triggered

<1-2 sentences naming the alert, the threshold, and the value that crossed it.>

## Likely cause

<Root-cause narrative citing specific evidence: trace IDs, log timestamps, error group IDs, flag keys, deploy timing.>

## Scope

<Who or what is affected. Number of users, services, sessions, error groups. Time window of impact.>

## Next steps

<1-3 concrete actions the on-call or owner should take. Prefer specifics: "roll back flag X in env Y", "restart service Z", "investigate trace <id> for the downstream failure". Avoid "investigate further" — if you don't have a root cause, say what specifically should be investigated and how.>
```

## When to load which companion

- **`logs.md`** — log alert, log pattern alert
- **`traces.md`** — latency alert, trace-error-rate alert, span-specific alert
- **`errors.md`** — error-rate alert, new-error-group alert, crash-rate alert
- **`sessions.md`** — session-health alert, user-facing-error-rate alert
- **`metrics.md`** — custom metric threshold, aggregated metric alert, composite alert

If the alert crosses product boundaries (e.g. a metric alert driven by error data), load both companions.

## Guidelines

- **Stay tight.** Alert investigations feed notifications — keep the output structured and scannable. No preamble ("Here is my analysis..."), no repeated framing.
- **Cite identifiers.** Every claim in the diagnosis should reference a specific trace ID, error group ID, session ID, or log timestamp.
- **If the alert appears to be noise**, say so explicitly — "This alert fired because of <X>, but the underlying behavior is within normal variance because <Y>". Noise is a legitimate outcome; don't invent root causes.
- **Don't redo the investigation you just did.** The diagnosis output should let the on-call act without re-querying.

Referenced files: 5 — file references are metadata, not package contents.

apply14.1 KB

View saved version →

---
name: apply
description: "Apply LaunchDarkly SDK onboarding: install dependency (or dual-SDK pair), configure env and secrets with consent, add init at entrypoint(s), verify compile. Nested under sdk-install; next is run."
license: Apache-2.0
compatibility: Requires integration plan and LaunchDarkly credentials (see parent onboarding)
metadata:
  author: launchdarkly
  version: "0.2.0"
---

# Apply code changes (SDK install)

Execute the integration plan. Install the SDK(s) and add the minimal code needed to initialize **each** tracked surface.

This skill is nested under [LaunchDarkly SDK Install (onboarding)](../sdk-install/SKILL.md); the parent **Step 3** is **apply**. **Prior:** [Generate integration plan](../plan/SKILL.md). **Next:** [Start the application](../run/SKILL.md).

**Dual SDK:** If the approved plan is **dual SDK** ([plan: Dual SDK integrations](../plan/SKILL.md#dual-sdk-integrations)), you must complete Steps 1-3 **for both tracks** -- **two** packages in the manifest, **two** install commands run (or equivalent), **two** credential lines where needed, **two** inits in **different** entrypoints per recipe. **Do not** claim the second SDK is set up without performing its real install and init. If the plan only listed one track but the user asked for both, **stop** and return to [plan](../plan/SKILL.md) -- do not invent the second half from memory.

**Credential timing:** This is the first nested step where you ask the user for **SDK key / client-side ID / mobile key** (or consent to fetch/write them). Account status is not asked upfront -- it is inferred earlier via MCP OAuth (parent Step 4) or surfaced here at D7 (option 4) if the user has no account yet ([parent Prerequisites](../onboarding/SKILL.md#prerequisites)).

## Step 1: Install the SDK dependency

Use the **exact** package or module name and install command from the SDK row you already matched in [SDK recipes](../onboarding/references/sdk/recipes.md), with the project's package manager. Do not copy a generic install line from elsewhere -- each recipe names the right artifact.

**Dual SDK:** Run the **install command for Track A**, then the **install command for Track B** (from the plan). Confirm **both** package names appear in `package.json` / `requirements.txt` / lockfile (or the correct package manifest for each language). Skipping the second install is **not** optional when the plan says dual.

After installation, verify the dependency appears in the lock file or dependency manifest (**all** LaunchDarkly packages from the plan).

### Permission before changing other dependencies

**Allowed without asking for extra permission (beyond normal repo-edit consent):** Installing **only** the LaunchDarkly SDK package(s) named in the recipe(s) for this integration (e.g. one server SDK, **or** the **exact server + client pair** listed in a dual-SDK plan -- **both** packages count as in-scope LD installs). Use the **minimum** install each recipe specifies (exact package names).

**Requires explicit user approval *before* you run any command or edit manifests:** Any change beyond that scope, including but not limited to:

- Upgrading, downgrading, pinning, or adding **non-LaunchDarkly** packages (peer-dependency "fixes," `npm install X@latest`, `yarn upgrade`, `pnpm update`, bumping React/Node types, transitive lockfile churn, etc.)
- Running **`npm audit fix`**, **bulk updates**, or **replacing** the project's package manager resolution strategy to satisfy the SDK
- Changing **engine** / **packageManager** fields, **resolutions** / **overrides**, or **workspaces** entries for reasons other than adding the LD artifact line

If the package manager reports peer conflicts or install failures:

**D8 -- BLOCKING:** Call your structured question tool now.
- question: "The install reported [specific error]. To fix this, I would need to [specific changes to non-LD packages]. Should I proceed with those additional changes?"
- options:
  - "Yes, make those changes"

Preview of the first 4,000 characters. Read full instructions →

built-in-metrics12.5 KB

View saved version →

---
name: built-in-metrics
description: "Instrument an existing codebase with LaunchDarkly config tracking. Walks the four-tier ladder (managed runner → provider package → custom extractor + trackMetricsOf → raw manual) and picks the lowest-ceremony option that still captures duration, tokens, and success/error."
license: Apache-2.0
compatibility: Requires the LaunchDarkly server-side AI SDK (`launchdarkly-server-sdk-ai>=0.20.0` for Python or `@launchdarkly/server-sdk-ai>=0.20.0` for Node) and an existing config.
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# Agent Metrics Instrumentation

You're using a skill that wires LaunchDarkly agent metrics around an existing provider call. Your job is to audit what's already there, pick the right tier from the ladder below, and implement it with the **least ceremony that still captures the metrics the Monitoring tab needs** (duration, input/output tokens, success/error, plus TTFT when streaming).

The single most important thing to get right: **default to the highest tier that fits the shape of the call**. Going lower ("just write the manual tracker calls") looks flexible but costs you drift, missed metrics, and legacy patterns the SDKs have moved past.

## The four-tier ladder

This is the order the official SDK READMEs (Python core, Node core, and every provider package) recommend. Walk from the top and stop at the first tier that fits:

| Tier | Pattern | Use when | Tracks automatically |
|------|---------|----------|----------------------|
| **1 — Managed runner** | Python: `ai_client.create_model(...)` returning a `ManagedModel`, then `await model.run(...)`. <br>Node: `aiClient.createModel(...)` returning a `ManagedModel`, then `await model.run(...)`. | The call is conversational (chat history, turn-based). This is what the provider READMEs lead with. | Duration, tokens, success/error — **all of it, zero tracker calls**. |
| **2 — Provider package + `trackMetricsOf`** | `tracker.trackMetricsOf(Provider.getAIMetricsFromResponse, () => providerCall())`. Provider packages today: `@launchdarkly/server-sdk-ai-openai`, `-langchain`, `-vercel` (Node) and `launchdarkly-server-sdk-ai-openai`, `-langchain` (Python). | The shape isn't a chat loop (one-shot completion, structured output, agent step) but the framework or provider has a package. | Duration + success/error from the wrapper; tokens from the package's built-in `getAIMetricsFromResponse` extractor. |
| **3 — Custom extractor + `trackMetricsOf`** | Same `trackMetricsOf` wrapper, but you write a small function that maps the provider response to `LDAIMetrics` (tokens + success). | No provider package exists (Anthropic direct, Gemini, Cohere, custom HTTP). | Duration + success/error from the wrapper; tokens from your extractor. |
| **4 — Raw manual** | Separate calls to `trackDuration`, `trackTokens`, `trackSuccess` / `trackError`, plus `trackTimeToFirstToken` for streams. | Streaming with TTFT, unusual response shapes, partial tracking, anything Tier 2–3 can't cleanly wrap. | Only what you explicitly call — it's on you to not miss one. |

Every provider — OpenAI, LangChain, Vercel, Bedrock, Anthropic, Gemini, custom HTTP — uses the same generic shape: `tracker.trackMetricsOf(getAIMetricsFromResponse, () => providerCall())` in Node, `tracker.track_metrics_of(get_ai_metrics_from_response, provider_call)` in Python. The extractor is the only thing that changes per provider: import `getAIMetricsFromResponse` from the matching `@launchdarkly/server-sdk-ai-<provider>` (or `ldai_<provider>`) package, or write a small custom function that returns `LDAIMetrics`. There are no provider-specific tracker methods.

## Workflow

### 1. Explore the existing call site

Before picking a tier, find the provider call and answer these questions:

- [ ] **Shape?** Is it a chat loop (history + turn-based), a one-shot completion, an agent step, or something else? → drives Tier 1 vs 2.
- [ ] **Framework?** Raw provider SDK? LangChain 

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 8 — file references are metadata, not package contents.

configs-create12.9 KB

View saved version →

---
name: configs-create
description: "Create and configure configs in LaunchDarkly. Helps you choose between agent vs completion mode, create the config, add variations with models and prompts, and verify the setup."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# Create Config

You're using a skill that will guide you through creating a config in LaunchDarkly. Your job is to understand the use case, choose the right mode, create the config and its variations, and verify everything is set up correctly.

> **⚠️ This skill creates a config — it does not make it servable.** A freshly-created config has its **fallthrough pointing at an auto-generated disabled variation**, not at the variation you just created. The SDK will return `ai_config.enabled=False` on every evaluation until you flip targeting on and point the fallthrough at your new variation. This is not a bug — it's the default state. **You must run `/configs-targeting` (or the equivalent REST / CLI call shown in Step 5) before verifying against the SDK**, or verification will look like the LD-served path is broken when it isn't. The single most common failure mode users hit with this skill is skipping the targeting step and spending time debugging `enabled=False` in their application code.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Primary MCP tool:**
- `setup-ai-config` -- create a config with its first variation in one step (recommended)

**Alternative MCP tools (for more control):**
- `create-ai-config` -- create just the config shell (key, name, mode)
- `create-ai-config-variation` -- add a variation with model, prompts, and parameters
- `get-ai-config` -- verify the config was created correctly

**Optional MCP tools (enhance workflow):**
- `list-ai-configs` -- browse existing configs to understand naming conventions
- `create-project` -- create a project if one doesn't exist yet

## Important: Bias Towards Action

When the user provides enough context (use case, model, mode), proceed through the entire workflow without stopping to ask for details you can infer. Use reasonable defaults for unspecified fields: `default` for variation key, the use case as the basis for instructions/messages, kebab-case for config keys. Complete all steps (create + verify) in one pass.

## Workflow

### Step 1: Understand the Use Case

Before creating, identify what you're building:

- **What framework?** LangGraph, LangChain, CrewAI, Strands, OpenAI SDK, Anthropic SDK, custom
- **What does the agent need?** Just text generation, or tools/function calling?
- **Agent or completion?** See the decision matrix below

### Step 2: Choose Agent vs Completion Mode

This choice is about **input schema and framework compatibility**, not execution behavior. Agent mode returns an `instructions` string; completion mode returns a `messages` array. Both provide provider abstraction, A/B testing, and metrics tracking.

| Your Need | Mode | Why |
|-----------|------|-----|
| LangGraph, CrewAI, Strands, AutoGen frameworks | **Agent** | Frameworks expect goal/instruction input |
| Persistent instructions across interactions | **Agent** | Single instructions string, SDK method: `agent_config()` (Python) / `agentConfig()` (Node) |
| Direct OpenAI/Anthropic API calls | **Completion** | Messages array maps directly to provider APIs |
| Full control of message structure | **Completion** | System/user/assistant role-based messages |
| One-off text generation | **Completion** | Standard chat format |
| Need online evaluations (LLM-as-judge) | **Completion** | Online evals are only available in completion mode |

**Both modes support tools.** Not all models support agent mode -- check model compatibility if using agent mode. If unsure, start with completion mode (it's the API default and more flexible).

### Step 3: Create

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 1 — file references are metadata, not package contents.

configs-targeting15.6 KB

View saved version →

---
name: configs-targeting
description: Configure config targeting rules to control which variations serve to different users. Enable percentage rollouts, attribute-based rules, segment targeting, and guarded rollouts.
compatibility: Requires LaunchDarkly API access token with ai-configs:write permission.
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Config Targeting

Configure targeting rules for configs to control which variations serve to different contexts. Works the same for both completion and agent mode.

## Prerequisites

- LaunchDarkly account with AgentControl enabled
- API access token with write permissions
- Project key and environment key
- Existing config with variations (use `configs-create` skill)

## API Key Detection

1. **Check environment variables** - `LAUNCHDARKLY_API_KEY`, `LAUNCHDARKLY_API_TOKEN`, `LD_API_KEY`
2. **Check MCP config** - Claude: `~/.claude/config.json` -> `mcpServers.launchdarkly.env.LAUNCHDARKLY_API_KEY`
3. **Prompt user** - Only if detection fails

## Core Concepts

### Evaluation Order

Targeting rules evaluate in this order (same as feature flags):

1. **Individual targets** - Specific context keys (highest priority)
2. **Segment rules** - Pre-defined segments
3. **Custom rules** - Attribute-based conditions (evaluated in order)
4. **Default rule** - Fallthrough for all others
5. **Off variation** - When targeting is disabled

### Semantic Patch API

config targeting uses semantic patch instructions:

```
PATCH /api/v2/projects/{projectKey}/ai-configs/{configKey}/targeting
Content-Type: application/json; domain-model=launchdarkly.semanticpatch
```

### Key Concepts

- **variationId**: UUIDs, not keys. Always fetch targeting first to get IDs.
- **Weights**: Thousandths (50000 = 50%, 100000 = 100%)
- **Clause logic**: Multiple clauses = AND, multiple values = OR
- **Null attributes**: Rules with null/missing attributes are skipped

## Workflow

### Step 1: Get Targeting (with Variation IDs)

```bash
curl -X GET "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/{configKey}/targeting" \
  -H "Authorization: {api_token}" \
  -H "LD-API-Version: beta"
```

Response includes `variations` array with `_id` (UUID) for each variation.

### Step 2: Edit the Default Rule

Edit the default rule to serve the variation you created.

> **Important:** The `turnTargetingOn` instruction does not work for configs. Use `updateFallthroughVariationOrRollout` instead.

```bash
# First, get variation IDs from Step 1 response
# Then set fallthrough to the enabled variation (e.g., "Default" variation)
curl -X PATCH "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/{configKey}/targeting" \
  -H "Authorization: {api_token}" \
  -H "Content-Type: application/json; domain-model=launchdarkly.semanticpatch" \
  -H "LD-API-Version: beta" \
  -d '{
    "environmentKey": "production",
    "instructions": [{
      "kind": "updateFallthroughVariationOrRollout",
      "variationId": "your-enabled-variation-uuid"
    }]
  }'
```

### Step 3: Add Targeting Rules

**Attribute-based rule:**

```bash
curl -X PATCH "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/{configKey}/targeting" \
  -H "Authorization: {api_token}" \
  -H "Content-Type: application/json; domain-model=launchdarkly.semanticpatch" \
  -H "LD-API-Version: beta" \
  -d '{
    "environmentKey": "production",
    "instructions": [{
      "kind": "addRule",
      "clauses": [{
        "contextKind": "user",
        "attribute": "selectedModel",
        "op": "contains",
        "values": ["sonnet"],
        "negate": false
      }],
      "variation": 0
    }]
  }'
```

**Percentage rollout:**

```bash
curl -X PATCH "..." \
  -d '{
    "environmentKey": "production",
    "instructions": [{
      "kind": "addRule",
      "clauses": [{
        "contextKind": "user",
        "attribute": "tier",
        "op": "in",
        "values": ["premium"],
        "negate": false
      }],
      "percent

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 1 — file references are metadata, not package contents.

configs-update4.26 KB

View saved version →

---
name: configs-update
description: "Update, archive, and delete LaunchDarkly configs and their variations. Use when you need to modify config properties, change model parameters, update instructions or messages, archive unused configs, or permanently remove them."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# Config Update & Lifecycle

You're using a skill that will guide you through updating, archiving, and deleting configs and their variations. Your job is to understand the current state of the config, make the changes, and verify the result.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `get-ai-config-health` -- assess config health before making changes (detects missing models, orphaned tools, empty configs)
- `get-ai-config` -- understand current state before making changes
- `update-ai-config` -- update config metadata (name, description, tags, archive)
- `update-ai-config-variation` -- update variation model, prompts, or parameters

**Optional MCP tools:**
- `delete-ai-config` -- permanently delete a config (irreversible)
- `delete-ai-config-variation` -- permanently delete a variation (irreversible)

## Core Principles

1. **Fetch Before Changing**: Always check the current state before modifying
2. **Verify After Changing**: Fetch the config again to confirm updates were applied
3. **Archive Before Deleting**: Archival is reversible; deletion is not

## Workflow

### Step 1: Assess Health and Understand Current State

Start with `get-ai-config-health` to get a structured health assessment. This detects:
- Variations with no model (show as "NO MODEL" in the UI)
- Variations with neither instructions nor messages
- Orphaned tool references (tools attached that don't exist in the project)
- Configs with no variations at all

The health verdict (`healthy`, `warning`, `unhealthy`) helps you prioritize what to fix.

Then use `get-ai-config` to review the full detail:
- Current mode (agent or completion)
- Existing variations and their models
- Current instructions or messages
- Attached tools and parameters

### Step 2: Make the Update

**Update config metadata** -- Use `update-ai-config`:
- Change name or description
- Add or replace tags
- Archive with `archived: true` (reversible)

**Update a variation** -- Use `update-ai-config-variation`:
- Switch model (provide new `modelConfigKey` and `modelName`)
- Change instructions or messages
- Tune parameters (temperature, max_tokens, etc.)
- Attach or detach tools via the parameters object

**Archive a config** -- Use `update-ai-config` with `archived: true`. Archiving is the **preferred** way to retire a config:
- It is reversible (unarchive with `archived: false`)
- The config is hidden from active lists but preserved
- After calling the archive, treat a successful response as confirmation and proceed to verification
- When a user says "remove", "retire", "decommission", or "no longer need", default to archiving unless they explicitly say "delete permanently"

**Delete** -- Use `delete-ai-config` or `delete-ai-config-variation` (irreversible, requires `confirm: true`). **Always suggest archiving first.** Only proceed with deletion if the user explicitly confirms they want permanent, irreversible removal.

### Step 3: Verify

Use `get-ai-config` to confirm the response shows your updated values.

**Report results:**
- Update applied successfully
- Config reflects changes
- Flag any issues or rollback if needed

## What NOT to Do

- Don't update production configs without testing in another variation first
- Don't change multiple things at once -- make incremental changes
- Don't skip verification
- Don't delete without explicit user confirmation -- always suggest archiving first
- Don't retry an update because the API response doesn't echo back the exact values

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 1 — file references are metadata, not package contents.

configs-variations5.69 KB

View saved version →

---
name: configs-variations
description: "Experiment with configs by creating and managing variations. Helps you test different models, prompts, and parameters to find what works best through systematic experimentation."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# Config Variations

You're using a skill that will guide you through testing and optimizing configs through variations. Your job is to design experiments, create variations, and systematically find what works best.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Primary MCP tool:**
- `clone-ai-config-variation` -- clone a baseline variation with selective overrides (recommended for experimentation)

**Alternative MCP tools (for more control):**
- `get-ai-config` -- review existing variations before adding new ones
- `create-ai-config-variation` -- create new variations from scratch

**Optional MCP tools:**
- `update-ai-config-variation` -- refine a variation after creation
- `delete-ai-config-variation` -- remove variations that didn't work out

## Core Principles

1. **Test One Thing at a Time**: Change model OR prompt OR parameters, not all at once
2. **Have a Hypothesis**: Know what you're trying to improve
3. **Measure Results**: Use metrics to compare variations
4. **Verify via Tool**: The agent fetches the config to confirm variations exist

## Workflow

### Step 1: Identify What to Optimize

What's the problem? Cost, quality, speed, accuracy? How will you measure success?

### Step 2: Design the Experiment

| Goal | What to Vary |
|------|--------------|
| Reduce cost | Cheaper model (e.g., `gpt-4o-mini`) |
| Improve quality | Better model or more detailed prompt |
| Reduce latency | Faster model, lower `max_tokens` |
| Increase accuracy | Different model family (Claude vs GPT-4) |

### Step 3: Create Variations (Recommended: Clone with Overrides)

Use `clone-ai-config-variation` to duplicate the baseline and override only what you're testing. The tool reads the source variation, merges your overrides, and creates the new variation. Everything you **don't** pass is inherited from the source automatically.

**Required fields:**
- `sourceVariationKey` -- the baseline to clone from
- `key` and `name` -- identifiers for the new variation (e.g., `gpt4o-mini-cost-test`)

**Override ONLY the fields you are testing.** Leave all other fields unset -- do not pass them even if you know their current values. The clone tool inherits them from the source. This enforces the one-variable-at-a-time principle:

- Testing a cheaper model? Pass only `modelConfigKey` and `modelName`. Do NOT pass `instructions`, `messages`, or `parameters`.
- Testing different instructions? Pass only `instructions`. Do NOT pass `modelConfigKey` or `modelName`.
- Testing a parameter? Pass only `parameters`. Do NOT pass model or prompt fields.

The response returns both the source and created variation, so you can immediately verify the diff.

### Step 3 (Alternative): Create from Scratch

If you need full control, use `get-ai-config` first to review the current state, then `create-ai-config-variation` with all fields specified manually. Always fetch before creating so you understand the existing config's mode, model, and parameters.

### Step 4: Verify

If you used `clone-ai-config-variation`, the response includes both source and created variations for immediate comparison. Otherwise, use `get-ai-config` to confirm.

**Report results:**
- Variations created with correct models and parameters
- Only the intended variable differs between variations
- Flag any issues

**Note on API responses:** After calling a creation or clone tool, treat a successful response as confirmation that the operation succeeded. The API response may not echo back every field you sent (e.g., model fields may show defaults). Do not retry

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 1 — file references are metadata, not package contents.

create-fix-pr2.7 KB

View saved version →

---
name: create-fix-pr
description: "Investigates a root cause and files a minimal fix PR for a reported bug or observability finding."
license: Apache-2.0
compatibility: Requires git and the GitHub CLI (gh); pairs with the investigate skill
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Create a fix PR

## Overview

You are investigating a problem and filing a pull request that resolves it. This builds on the `investigate` skill — do the investigation properly first, don't jump to a fix without evidence.

Use the `gh` CLI for all GitHub operations (auth comes from your `gh` login) and standard `Bash` / `Edit` / `Read` / `Grep` for everything else.

## Workflow

1. **Investigate.** Use the `investigate` skill to find the root cause. Cite the exact trace ID, log line, error group, and code location that pins the problem.
2. **Confirm there isn't already a PR open.** Before filing anything, search GitHub for an existing open PR addressing the same issue — `gh pr list --search "<keywords>" --state open`. If one exists, direct the user to it — do not create a duplicate.
3. **Judge whether a PR is the right tool.** If the fix requires a config change, a flag flip, or a change outside the code you can access, describe the solution instead of filing a PR.
4. **Get the repo.** Clone it if you don't already have it locally — `gh repo clone <owner>/<repo>`.
5. **Check for repo conventions.** Read `agents.md` or `CLAUDE.md` at the repo root — these describe repo-specific rules your fix needs to respect.
6. **Make the change.** Minimal diff. Don't refactor surrounding code, don't add features, don't fix unrelated bugs you happen to notice. One PR, one fix.
7. **Set git identity** before committing — see `pr-conventions.md`.
8. **Commit, push, and file the PR.** See `pr-conventions.md` for branch naming and PR body rules.

## What's a good fix

- Changes the smallest possible number of lines
- Preserves current production behavior unless the bug IS the current behavior
- Doesn't depend on assumptions you can't verify from the evidence
- Would pass a `code-review` skill's check if one existed

## What isn't

- Sweeping refactors unrelated to the reported problem
- Speculative null checks or error handling added "while you're in there"
- Changes to tests that hide the underlying bug
- Bumping dependency versions to fix a symptom

## Restricted tools

If `gh` isn't installed or `gh auth status` shows no auth, surface the error to the user and stop — don't try alternative auth schemes.

## Never include in a PR

- GitHub access tokens or any other secrets or credentials.
- Debugging logs or print statements you added during investigation.

Follow the repo's own commit and PR conventions for everything else.

Referenced files: 1 — file references are metadata, not package contents.

create-graph4.82 KB

View saved version →

---
name: create-graph
description: "Creates observability dashboards and graphs from logs, traces, errors, sessions, metrics, and events data by previewing charts inline and saving them to a dashboard."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Create graphs and dashboards

## Prerequisites

This skill uses the following LaunchDarkly MCP tools:

- `preview-graph` — render a chart preview inline without saving it
- `create-graph` — add a chart to an existing dashboard
- `create-dashboard` — create a new empty dashboard
- `list-dashboards` — list existing dashboards
- `get-dashboard` — get the full config of a dashboard, including its graphs
- `get-keys` — discover available metrics, attributes, and keys for a product type

All of these tools require a `projectKey` (e.g. `"default"`).

## Overview

You are building observability graphs. Your tools are precise — get the enum values wrong and the API rejects the call. Always use `get-keys` before building a query to confirm the dimension names are real.

## Capabilities

- `list-dashboards` — list existing dashboards to check for duplicates or find a target
- `get-dashboard` — get the full config of an existing dashboard, including its graphs
- `create-dashboard` — create a new dashboard
- `preview-graph` — render a chart preview inline
- `create-graph` — add a chart to a dashboard
- `get-keys` — discover available metrics, attributes, and keys for a product type

When the user's request is purely about visualizing data, stay on task — don't reach for unrelated tools.

## Workflow

1. **Identify the target dashboard.** If the user already has a specific dashboard in mind (by ID or name), add graphs to it directly. Otherwise, call `list-dashboards` and offer to target an existing one or create a new one with `create-dashboard`.
2. **Discover the data shape.** Call `get-keys` for the relevant product type before building a query. Attribute names vary across services — `service_name` vs `service.name` vs `serviceName`. Guessing wastes tool calls.
3. **For ambiguous requests, ask a brief clarifying question** as regular text. Example: "I found several latency-related keys. Would you like P50 or P95 latency, and should I group by service name?" Keep clarifications short — one or two questions max. For minor ambiguity (chart type preference), make a reasonable default and note your assumption.
4. **Preview before committing.** Call `preview-graph` first, show the user an inline preview, and confirm before calling `create-graph`. For multiple graphs, preview and confirm each one individually.
5. **Create the graph** with `create-graph`. Use exact enum casing from `enums.md`.
6. **Confirm what was created** — provide the dashboard URL and a one-line description of what the graph shows.

## Duplicating existing graphs

When asked to duplicate or copy a graph, call `get-dashboard` to retrieve the full configuration (expressions, product type, query, groupBy, display settings), then replicate those values in `create-graph`. Do not guess from the graph title alone — titles drift from the underlying config.

## Guidelines

- **Be concise — don't narrate intermediate tool calls.** Skip prefaces like "First, let me discover the keys" or "Now I'll build the chart." One short sentence at the start of the reply is enough if needed (e.g. "Building a chart of recent logs by level."); after that, just call the tools.
- **Prefer multiple focused graphs over one complex graph.** A dashboard with 3 clean graphs beats one graph with 5 overlapping expressions.
- **Always call `get-keys` before building a query.** Prevents silent empty results from wrong field names.

## Chart-type picks

- **`Line chart`** — time-series trends. Error rates over time, latency percentiles, request volume.
- **`Bar chart`** (or histogram) — comparisons across a dimension. Errors by service, requests by endpoint.
- **`Tabl

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 1 — file references are metadata, not package contents.

custom-metrics15 KB

View saved version →

---
name: custom-metrics
description: "Create, track, retrieve, update, and delete custom business metrics for configs. Covers full lifecycle: define metric kinds via API, emit events via SDK, and query results."
license: Apache-2.0
compatibility: Requires the LaunchDarkly server SDK and a LaunchDarkly API token with the `writer` role for metric management.
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# Custom Metrics for Configs

Full lifecycle management of custom business metrics: create metric definitions via API, track events via SDK, retrieve metric data, and manage metrics programmatically.

## Prerequisites

- LaunchDarkly SDK initialized (see `sdk`)
- LaunchDarkly API token with `writer` role for metric management
- Understanding of built-in agent metrics (see `built-in-metrics`)

## API Key Detection

Before prompting the user for an API key, try to detect it automatically:

1. **Check Claude MCP config** - Read `~/.claude/config.json` and look for `mcpServers.launchdarkly.env.LAUNCHDARKLY_API_KEY`
2. **Check environment variables** - Look for `LAUNCHDARKLY_API_KEY`, `LAUNCHDARKLY_API_TOKEN`, or `LD_API_KEY`
3. **Prompt user** - Only if detection fails, ask the user for their API key

```python
import os
import json
from pathlib import Path

def get_launchdarkly_api_key():
    """Auto-detect LaunchDarkly API key from Claude config or environment."""
    # 1. Check Claude MCP config
    claude_config = Path.home() / ".claude" / "config.json"
    if claude_config.exists():
        try:
            config = json.load(open(claude_config))
            api_key = config.get("mcpServers", {}).get("launchdarkly", {}).get("env", {}).get("LAUNCHDARKLY_API_KEY")
            if api_key:
                return api_key
        except (json.JSONDecodeError, IOError):
            pass

    # 2. Check environment variables
    for var in ["LAUNCHDARKLY_API_KEY", "LAUNCHDARKLY_API_TOKEN", "LD_API_KEY"]:
        if os.environ.get(var):
            return os.environ[var]

    return None
```

## Metrics Lifecycle Overview

| Step | Method | Purpose |
|------|--------|---------|
| 1. Create | API | Define metric in LaunchDarkly |
| 2. Track | SDK | Send events to the metric |
| 3. Get | API | Retrieve metric definition/data |
| 4. Update | API | Modify metric properties |
| 5. Delete | API | Remove metric |

## 1. Create Metric (API)

**Required fields for numeric custom metrics:**
- `successCriteria` - Must be one of: `"HigherThanBaseline"`, `"LowerThanBaseline"`
- `unit` - e.g., `"count"`, `"percent"`, `"milliseconds"`

The API will return `400 Bad Request` if these are missing for numeric metrics.

```python
import requests
import os

def create_metric(
    project_key: str,
    metric_key: str,
    name: str,
    kind: str = "custom",
    is_numeric: bool = True,
    unit: str = "count",
    success_criteria: str = "HigherThanBaseline",
    event_key: str = None,
    description: str = None
):
    """Create a new metric definition in LaunchDarkly."""
    API_TOKEN = os.environ.get("LAUNCHDARKLY_API_TOKEN")

    url = f"https://app.launchdarkly.com/api/v2/metrics/{project_key}"

    payload = {
        "key": metric_key,
        "name": name,
        "kind": kind,
        "isNumeric": is_numeric,
        "eventKey": event_key or metric_key
    }

    # Unit and successCriteria are required for numeric custom metrics
    if is_numeric and kind == "custom":
        payload["unit"] = unit
        payload["successCriteria"] = success_criteria

    if description:
        payload["description"] = description

    headers = {
        "Authorization": API_TOKEN,
        "Content-Type": "application/json"
    }

    response = requests.post(url, json=payload, headers=headers)

    if response.status_code == 201:
        print(f"[OK] Created metric: {metric_key}")
        return response.json()
    elif response.status_code == 409:
        print(f"[INFO] Metric already exists: {metric_key}")
        return None
    else

Preview of the first 4,000 characters. Read full instructions →

detect12 KB

View saved version →

---
name: detect
description: "Detect repository stack for LaunchDarkly SDK onboarding: languages, frameworks, package managers, monorepo targets, entrypoints, existing LD usage. Nested under sdk-install; next is plan."
license: Apache-2.0
compatibility: Requires access to the project repository
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Detect repository stack (SDK install)

Before installing anything, you must understand the project. Identify what the project is built with and whether LaunchDarkly is already present.

This skill is nested under [LaunchDarkly SDK Install (onboarding)](../sdk-install/SKILL.md); the parent **Step 1** is **detect**. **Next:** [Generate integration plan](../plan/SKILL.md) unless the decision tree sends you elsewhere.

### 1. Language and framework

Look for the indicator files below (and related root layout), then read the relevant manifests to infer language and framework.

Look for these files to identify the stack:

| File | Language/Framework |
|------|--------------------|
| `package.json` | JavaScript/TypeScript (check for React, Next.js, Vue, Angular, Express, React Native, Electron, etc.) |
| `requirements.txt`, `pyproject.toml`, `Pipfile`, `setup.py` | Python (check for Django, Flask, FastAPI) |
| `go.mod` | Go (check for Gin, Echo, Fiber, Chi) |
| `pom.xml`, `build.gradle`, `build.gradle.kts` | Java/Kotlin (check for Spring, Quarkus, Android) |
| `Gemfile` | Ruby (check for Rails, Sinatra) |
| `*.csproj`, `*.sln`, `*.fsproj` | .NET/C# (check for ASP.NET, MAUI, Xamarin, WPF, UWP) |
| `composer.json` | PHP (check for Laravel, Symfony) |
| `Cargo.toml` | Rust (check for Actix, Axum, Rocket) |
| `pubspec.yaml` | Flutter/Dart |
| `Package.swift`, `Podfile`, `*.xcodeproj` | Swift/iOS |
| `AndroidManifest.xml` | Android (also check `build.gradle` for `com.android`) |
| `rebar.config`, `mix.exs` | Erlang/Elixir |
| `CMakeLists.txt`, `Makefile` (with C/C++ patterns) | C/C++ (check for `#include` patterns) |
| `*.cabal`, `stack.yaml` | Haskell |
| `*.lua`, `rockspec` | Lua |
| `manifest`, `*.brs` | Roku (BrightScript) |
| `wrangler.toml` | Cloudflare Workers (edge SDK) |
| `vercel.json` with edge functions | Vercel Edge (edge SDK) |

Read the dependency file to identify the specific framework. For `package.json`, check both `dependencies` and `devDependencies`.

If you cannot identify the language or framework:

**D5 -- BLOCKING:** Call your structured question tool now.
- question: "I couldn't detect the project's language or framework. Which SDK would you like to use?"
- options: Present the available SDKs from [SDK recipes](../onboarding/references/sdk/recipes.md) as selectable options.
- STOP. Do not write the question as text. Do not continue until the user selects an option.

### 2. Package manager

Identify how the project installs dependencies:

| Indicator | Package Manager |
|-----------|----------------|
| `package-lock.json` | npm |
| `yarn.lock` | yarn |
| `pnpm-lock.yaml` | pnpm |
| `bun.lockb` | bun |
| `Pipfile.lock` | pipenv |
| `poetry.lock` | poetry |
| `go.sum` | go modules |
| `Gemfile.lock` | bundler |

Use the detected package manager for all install commands. If multiple lock files exist, prefer the one that was most recently modified.

### 3. Monorepo layout

Some repositories host multiple packages or services. Look for these indicators:

| File / pattern | Tool or layout |
|----------------|----------------|
| `pnpm-workspace.yaml` | pnpm workspaces |
| `lerna.json` | Lerna |
| `nx.json` | Nx |
| `turbo.json` | Turborepo |
| `rush.json` | Rush |
| `packages/` directory with multiple `package.json` files | Generic monorepo |

When any of these apply, **do not assume the repo root is the integration target**:

**D5 -- BLOCKING:** Call your structured question tool now.
- question: "This is a monorepo. Which package, app, or service should I integrate LaunchDarkly into?"
- options: List the discovered packages/apps as selectable options.
- STOP. Do not writ

Preview of the first 4,000 characters. Read full instructions →

first-flag15.9 KB

View saved version →

---
name: first-flag
description: "Create 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."
license: Apache-2.0
compatibility: Requires SDK installed (parent Step 5) and LaunchDarkly project access
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Create first feature flag

The SDK is connected. Now help the user create their first feature flag and see it work end-to-end.

This skill is nested under [LaunchDarkly onboarding](../onboarding/SKILL.md); the parent **Step 6** is **first flag**. **Prior:** [Apply code changes](../apply/SKILL.md).

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

## Security: Credential handling

**Never substitute literal token values into commands.** Use environment variable references instead:

- Shell commands: `$LAUNCHDARKLY_ACCESS_TOKEN` (expanded by the shell, not visible in `ps` output)
- Set the variable in your session: `export LAUNCHDARKLY_ACCESS_TOKEN=<your-token>`

This prevents tokens from appearing in process lists, shell history, and screen recordings.

## Step 0: Consult SDK flag-key guidance

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.

- **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).
- **If the SDK preserves keys as-is** (most server-side SDKs): use the exact LaunchDarkly flag key string in code.
- **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.

### Flag key behavior by SDK

| SDK | Key transformation | Code key for `my-first-flag` | Notes |
|-----|--------------------|------------------------------|-------|
| React Web (`useFlags()`) | camelCase by default | `myFirstFlag` | `reactOptions: { useCamelCaseFlagKeys: false }` on the provider disables this |
| React Native (`useFlags()`) | camelCase by default | `myFirstFlag` | Same `reactOptions` override available |
| Vue (`useLDFlag()`) | None (pass original key) | `'my-first-flag'` | |
| JavaScript Browser | None | `'my-first-flag'` | |
| Node.js Server | None | `'my-first-flag'` | |
| Python Server | None | `'my-first-flag'` | |
| Go Server | None | `"my-first-flag"` | |
| Java Server | None | `"my-first-flag"` | |
| .NET Server | None | `"my-first-flag"` | |
| Ruby Server | None | `'my-first-flag'` | |
| Swift/iOS | None | `"my-first-flag"` | |
| Android | None | `"my-first-flag"` | |
| Flutter | None | `'my-first-flag'` | |

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.

## Step 1: Create the flag

**REST / curl auth:** Use `$LAUNCHDARKLY_ACCESS_TOKEN` as the `Authorization` header value (LaunchDarkly uses the raw token, no `Bearer` prefix). The shell expands the

Preview of the first 4,000 characters. Read full instructions →

flag-and-release-change9.96 KB

View saved version →

---
name: flag-and-release-change
description: "Drive a pull request's change end to end: decide it's flag-worthy, create the guarding flag, wire the new code path behind it on the PR branch, and record an automated release so the change ships safely when the PR merges. A portable orchestrator that composes should-flag-change, launchdarkly-flag-create, and flag-release. Keywords: flag a PR, wrap change in a flag, dark launch, kill switch, auto-release, automated rollout, end-to-end flag workflow."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server and a git CLI with access to the PR's repository
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Flag & Release a PR Change

You're using a skill that takes a pull request whose change should ship behind a feature flag and drives it end to end: decide it needs a flag, create the guarding flag, wire the new behavior behind it on the PR's branch, and record an **automated release** so the change ships safely once the PR merges.

**The deploy is not the release.** The merge ships the control path — the flag is created OFF, so deployment always serves the pre-change behavior. The *release* is the flag operation the automated rollout performs afterward, governed by the environment's policy. Creating the flag OFF and recording the release are deliberately separate things.

This skill is a **portable PR orchestrator**. It doesn't own the flag mechanics or the release mechanics — it composes three focused skills and adds the PR workflow (read the diff, work in a clone, push to the branch) plus the plan→implement sequencing:

| Step | Owned by | This skill's role |
|------|----------|-------------------|
| Decide *whether* to flag | [`should-flag-change`](../should-flag-change/SKILL.md) (advisory, read-only) | Act on a "yes"; make the call yourself if it wasn't run |
| Create the flag + wire the code | [`launchdarkly-flag-create`](../launchdarkly-flag-create/SKILL.md) | Invoke it against the change; don't re-teach flag creation or SDK patterns |
| Record the release | [`flag-release`](../flag-release/SKILL.md) | Hand off once the flag exists and the code is pushed; don't re-teach rollout mechanics |

Don't duplicate any composed skill's mechanics here. This skill's only unique content is the **PR wrapper** (clone, three-dot diff, commit/push to the branch) and the **plan→implement** flow that stitches the three together.

> **Automation note.** An orchestrating harness (e.g. a PR pipeline) can skip this skill and invoke the three composed skills directly — `should-flag-change` → `launchdarkly-flag-create` → `flag-release` — driving the git and sequencing itself. This skill is the portable, human-in-the-loop path for a developer working a PR by hand.

You work in two phases — **plan**, then **implement** — and you check in with the user in between. **Never create or modify anything during the plan phase.**

## Prerequisites

- The remotely hosted LaunchDarkly MCP server.
- A `git` CLI that can read and push to the PR's repository.
- The composed skills available: [`launchdarkly-flag-create`](../launchdarkly-flag-create/SKILL.md) (flag creation + code wiring) and [`flag-release`](../flag-release/SKILL.md) (recording the rollout). [`should-flag-change`](../should-flag-change/SKILL.md) is used if the flag decision hasn't been made.

MCP tools are used *via the composed skills* — `create-flag`/`get-flag` through flag-create, `match-release-policies`/`create-automated-rollout-config` through flag-release. This skill calls none directly.

## Working With the Pull Request

Work from a clone so you can read the change and push the flag wiring back to its branch. Credentials are provided by the environment — never ask for, print, or store tokens.

```bash
git clone https://github.com/<owner>/<repo>.git && cd <repo>
git fetch origin pull/<pr_number>/head
git diff origin/HEAD...<head_sha>       # three-dot: change relative to the PR's base
```

The three-do

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 3 — file references are metadata, not package contents.

flag-release10.8 KB

View saved version →

---
name: flag-release
description: "Record an automated rollout for an existing LaunchDarkly flag that guards a pull request's change, so the change releases safely when the PR merges. Honors a stated release intent (release now / hold / notBefore / segment / prerequisite) and defers per-environment to the project's release policies. Use as the release step once the guarding flag exists and its code is wired. Keywords: record release, automated rollout, release policy, guarded rollout, staged rollout, simple vs policy, release intent, hold release, dark launch."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server. Operates on a flag that already exists; does not create flags or edit code.
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Record a Flag's Automated Release

You're using a skill that takes an **existing** feature flag (created OFF) that guards a pull request's change, and records an **automated rollout** so the change releases safely once the PR merges — no human toggling a flag. It defers per-environment to the team's release policies and honors any human-stated release intent.

This is the **release step** of the PR flag workflow, and it's deliberately atomic:

| Step | Owned by |
|------|----------|
| Decide *whether* to flag | [`should-flag-change`](../should-flag-change/SKILL.md) (advisory) |
| Create the flag + wire the code | [`launchdarkly-flag-create`](../launchdarkly-flag-create/SKILL.md) |
| **Record the release** | **this skill** |

By the time this skill runs, the flag exists (OFF) and the guarding code is wired and pushed. This skill only records the rollout — it never creates flags or edits code. It can be driven directly by an automation harness, or as the final step of the [`flag-and-release-change`](../flag-and-release-change/SKILL.md) orchestrator.

**The deploy is not the release.** The merge ships the control path (flag OFF); the *release* is the flag operation this rollout performs afterward, governed by the environment's policy.

> **Honoring a hold is the one thing you must get right.** There is no "hold" release type, and **`policy` is NOT a manual gate.** On merge, `policy` *automatically* performs the environment's release (immediate, progressive, or guarded) with **no human promotion step** — a guarded rollout still *starts on its own* the moment the PR merges. So recording a held environment as `policy` does **not** hold it; it releases it on merge, before any `notBefore` date. The only way to hold an environment is to **omit it from the `environments` array entirely**, which leaves the flag OFF there. If the user wants an environment held (or not released until a date), exclude it from the call and report it as held. When in doubt, omit.

## Prerequisites

- The remotely hosted LaunchDarkly MCP server.
- The guarding flag already exists in LaunchDarkly, created OFF, with the agreed key/tags.
- A pull-request reference (`repoFullName` + `prNumber`, or `prUrl`) so the rollout binds to the right merge.

**MCP tools this skill uses:**
- `create-automated-rollout-config` — record the rollout for the flag against the PR *(the deliverable)*
- `match-release-policies` — resolve which release policy governs each environment (call before proposing the plan)
- `list-release-policies` — see the project's release policies and the metrics they auto-attach
- `get-flag` — confirm the flag exists and is OFF before recording

Full release model — `simple` vs `policy`, precedence, previewing, prerequisites, metric adequacy: [references/auto-release.md](references/auto-release.md).

## Plan Phase

**Record nothing in this phase.**

1. **Confirm the flag.** `get-flag` to verify the guarding flag exists and is OFF. If it doesn't exist yet, stop — creation is [`launchdarkly-flag-create`](../launchdarkly-flag-create/SKILL.md)'s job, and recording a rollout for a missing flag fails confusingly.
2. **Pick the target environments.** Use the environments named by th

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 3 — file references are metadata, not package contents.

investigate5 KB

View saved version →

---
name: investigate
description: "Analyzes observability data — logs, traces, errors, sessions, and metrics — to find root cause and actionable evidence. Use when the user reports a bug, an unexpected behavior, or asks about patterns across application data."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Investigate

You are conducting a cross-product investigation. Real investigations almost always touch more than one product — a log error leads into traces, a slow trace reveals a failing span, a failing span correlates with a specific session. Walk the evidence until you have a concrete root cause.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `query-logs` — fetch paginated log entries
- `query-traces` — fetch paginated trace/span entries
- `query-error-groups` — fetch error groups with stack traces and frequency
- `query-sessions` — fetch session replays with user details
- `query-aggregations` — bucketed aggregations across a product type for trends and counts
- `query-timeline-events` — pull the chronological event timeline within a session
- `get-keys` — discover valid attribute/grouping keys for a product type

## Workflow

1. **Plan first.** Before the first tool call, present a concise numbered plan of what you intend to query and why. Then execute it. Skip this only for trivial lookups.
2. **Start narrow.** Pick a focused time window (default 24h if the user didn't specify) and the most-specific identifier you have — trace ID, session ID, error group ID, flag key. Broad queries return noise.
3. **Let each result inform the next.** Do not rely on one tool call. Run multiple invocations of `query-logs`, `query-aggregations`, `query-traces`, `query-error-groups`, and `query-sessions`, using the findings of each to sharpen the next.
4. **Respect the 50-entry limit.** `query-logs`, `query-traces`, `query-error-groups`, and `query-sessions` tools return at most 50 entries per call. For larger datasets, run a `query-aggregations` query first to aggregate, then narrow with targeted fetches.
5. **Cross-reference aggressively.** Trace IDs in logs, session IDs in errors, error messages in session replays — the point where products connect is usually where the root cause sits.
6. **Maintain a running checklist.** Periodically summarize what you've confirmed vs. what you still need to test. Keeps investigations from drifting.
7. **End with actionable output.** Clear insights that answer the original question, direct references the user can click through (log excerpts, trace IDs, session IDs, error group IDs), a severity assessment, and at least one concrete remediation — a config change, a flag flip, a code-level fix with file and line, or a specific diagnostic step with the exact query to run.

## Load companion files when relevant

- `logs.md` — when the investigation touches logs (error messages, level=error filters, service log patterns)
- `traces.md` — when analyzing request flow, latency, or span relationships
- `errors.md` — when looking at error groups, stack traces, exception frequency
- `sessions.md` — when reconstructing user journeys or correlating frontend behavior with backend events
- `metrics.md` — when aggregating across a large dataset or building a chart

## Universal guidance

- **Prefer aggregation over pagination.** If you want to list unique users, count distinct values, or summarize, use `query-aggregations` with `group_by` — don't paginate through individual records. Use `get-keys` to discover the right grouping dimension first.
- **Call `get-keys` before attribute filters.** Attribute names vary across product types and services (`spanName` vs `span_name`, `hasErrors` vs `has_errors`). One `get-keys` call upfront prevents wasted queries with wrong field names.
- **Cite specific identifiers.** Every reco

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 5 — file references are metadata, not package contents.

launchdarkly-experiment-setup11.6 KB

View saved version →

---
name: launchdarkly-experiment-setup
description: "Set up and run experiments in LaunchDarkly. Create experiments with metrics, treatments, and flag config, start iterations to collect data, swap design between iterations, and stop with a winner."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "0.2.0"
---

# LaunchDarkly Experiment Setup

You're using a skill that guides you through setting up and running experiments in LaunchDarkly. Your job is to design the experiment, create it with the right metrics, treatments, and flag config, start data collection, evolve the design between iterations when needed, and stop with a winner.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `create-experiment` — create a new experiment with its initial iteration (hypothesis, metrics, treatments, flag config).
- `start-experiment-iteration` — begin collecting data for an experiment's current draft iteration.
- `get-experiment` — check experiment status, treatments, metrics, and current iteration.

**Optional MCP tools:**
- `list-experiments` — browse existing experiments in the project.
- `update-experiment` — update fields on the experiment or its current iteration. Honours `mutableFieldsByStatus`, so what's editable depends on whether the iteration is `not_started`, `running`, or `stopped`. Returns rejected inputs under `skipped`.
- `save-and-start-experiment-iteration` — the API-recommended way to change locked fields on a running experiment. Stops the current iteration, creates a new draft with the supplied field updates, and starts it in one call.
- `stop-experiment-iteration` — stop the running iteration. You must declare a winner: pass the `winningTreatmentId` (and a `winningReason`). If no variation outperformed, pick the baseline/control as the winner.
- `list-metrics`, `create-metric`, `list-metric-events` — manage metrics referenced by the experiment.

## Core Concepts

### What Are Experiments?

Experiments in LaunchDarkly measure the impact of feature flag variations on key metrics. An experiment consists of:

- **Treatments**: the flag variations being compared (control vs. test). Each treatment has an `allocationPercent`; the values across treatments should sum to 100.
- **Metrics**: what you're measuring (conversion rate, latency, revenue, etc.). One must be the primary metric.
- **Flag config**: the `flagKey`, `ruleId`, and `flagConfigVersion` of the targeting rule that drives the experiment.
- **Iteration**: a single data-collection window. Created in `not_started` status, becomes `running` when started, transitions to `stopped` when ended.
- **Holdout** (optional): a project-level group of users excluded from the experiment for baseline measurement (`holdoutId`).

### Experiment Lifecycle

1. **Create** the experiment with its first iteration (`create-experiment`).
2. **Start the iteration** to begin data collection (`start-experiment-iteration`).
3. **Monitor** results as data accumulates (`get-experiment`).
4. **Evolve the design** mid-experiment if needed — change locked fields like `treatments`, `metrics`, or `methodology` by calling `save-and-start-experiment-iteration`, which stops the current iteration, creates a new draft with your changes, and starts it.
5. **Stop the iteration** when you have a winner or a clear call (`stop-experiment-iteration`).
6. **Ship** the winning variation.

## Core Principles

1. **Metrics first**: ensure the metrics you'll reference exist before creating the experiment.
2. **Clear hypothesis**: every iteration requires a `hypothesis` string; state what you expect to improve and by how much.
3. **Proper controls**: exactly one treatment must have `baseline: true`.
4. **Sufficient sample size**: let iterations run long enough for statistical significance.
5. **One change at a time**: test one variable per 

Preview of the first 4,000 characters. Read full instructions →

launchdarkly-flag-cleanup8.67 KB

View saved version →

---
name: launchdarkly-flag-cleanup
description: "Safely remove a feature flag from code while preserving production behavior. Use when the user wants to remove a flag from code, delete flag references, or create a PR that hardcodes the winning variation after a rollout is complete."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# LaunchDarkly Flag Cleanup

You're using a skill that will guide you through safely removing a feature flag from a codebase while preserving production behavior. Your job is to explore the codebase to understand how the flag is used, query LaunchDarkly to determine the correct forward value, remove the flag code cleanly, and verify the result.

If you haven't already identified which flag to clean up, use the [flag discovery skill](../launchdarkly-flag-discovery/SKILL.md) first to audit the landscape and find candidates.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `check-removal-readiness`: detailed safety check (orchestrates flag config, cross-env status, dependencies, code references, and expiring targets in parallel)
- `get-flag`: fetch flag configuration for a specific environment

**Optional MCP tools:**
- `archive-flag`: archive the flag in LaunchDarkly after code removal
- `delete-flag`: permanently delete the flag (irreversible, prefer archive)

## Core Principles

1. **Safety First**: Always preserve current production behavior.
2. **LaunchDarkly as Source of Truth**: Never guess the forward value. Query the actual configuration.
3. **Follow Conventions**: Respect existing code style and structure.
4. **Minimal Change**: Only remove flag-related code. No unrelated refactors.

## Workflow

### Step 1: Explore the Codebase

Before touching LaunchDarkly or removing code, understand how this flag is used in the codebase.

1. **Find all references to the flag key.** Search for the flag key string (e.g., `new-checkout-flow`) across the codebase. Check for:
   - Direct SDK evaluation calls (`variation()`, `boolVariation()`, `useFlags()`, etc.)
   - Constants/enums that reference the key
   - Wrapper/service patterns that abstract the SDK
   - Configuration files, tests, and documentation
   - See [SDK Patterns](references/sdk-patterns.md) for the full list of patterns by language

2. **Understand the branching.** For each reference, identify:
   - What code runs when the flag is `true` (or variation A)?
   - What code runs when the flag is `false` (or variation B)?
   - Are there side effects, early returns, or nested conditions?

3. **Note the scope.** How many files, components, or modules does this flag touch? A flag used in one `if` block is simpler than one threaded through multiple layers.

### Step 2: Run the Removal Readiness Check

Use `check-removal-readiness` to get a detailed safety assessment. This single tool call orchestrates multiple checks in parallel:
- Flag configuration and targeting state
- Cross-environment status
- Dependent flags (prerequisites)
- Expiring targets
- Code reference statistics

The tool returns a readiness verdict:

**`safe`**: No blockers or warnings. Proceed with removal.

**`caution`**: No hard blockers but warnings exist (e.g., code references in other repos, expiring targets scheduled, flag marked as permanent). Present warnings and let the user decide.

**`blocked`**: Hard blockers prevent safe removal (e.g., dependent flags, actively receiving requests, targeting is on with active rules). Present blockers: the user must resolve them first.

### Step 3: Determine the Forward Value

Use `get-flag` to fetch the flag configuration in each critical environment. The **forward value** is the variation that replaces the flag in code.

| Scenario | Forward Value |
|----------|---------------|
| All critical envs ON, same fallthrough, no rules/targets 

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 4 — file references are metadata, not package contents.

launchdarkly-flag-command5.41 KB

View saved version →

---
name: launchdarkly-flag-command
description: "Resolve `/flag` style requests into the right LaunchDarkly flag lookup flow. Use when the user types `/flag`, asks to quickly find a flag by name/key, wants a direct flag detail summary, or needs fast disambiguation between similar flags."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# LaunchDarkly Flag Command Router

You're using a skill that standardizes quick `/flag` requests. Your job is to parse the user intent, resolve the requested flag with minimal friction, return an actionable summary, and route to deeper workflows when needed.

## Scope Boundary

This skill is a **read-only lookup entrypoint**. It returns flag details and routes forward.

**Hard constraints — you MUST NOT:**

- Create, toggle, update, or delete flags
- Assess whether a flag is safe to remove, stale, or ready for cleanup
- Provide a "verdict", "safe to remove" conclusion, removal steps, or "before removing" advice
- Offer to archive or delete the flag

**When the user asks about removal or staleness**, your entire response for that part must be the flag summary table followed by this exact routing message (you may rephrase slightly but must keep the substance):

> This quick lookup can only show you the flag's current config. To assess whether it's safe to remove, you need the **flag discovery** or **flag cleanup** skill — they scan code references, check status across all environments, and analyze downstream dependencies.

That's it. No analysis. No bullet points. No verdict. The removal question is answered by the routing message, not by you.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `list-flags` — search and disambiguate flag candidates
- `get-flag` — fetch detailed configuration for a resolved flag

**Optional MCP tools:**
- `get-flag-status-across-envs` — compare lifecycle status across environments
- `get-flag-health` — quick health snapshot for a single flag

## Command Contract

Treat these forms as equivalent intents:

- `/flag <query>`
- `flag <query>`
- "find flag <query>"
- "show me <query> flag"

Use `production` as the default environment unless the user specifies another environment.

## Workflow

### Step 1: Parse and Normalize Input

1. Extract the query text after `/flag`.
2. If no query is provided, ask for one concise identifier (flag key, name fragment, or tag).
3. Capture optional hints from the request:
   - Environment (`staging`, `production`, etc.)
   - Project key
   - Preference for exact key vs fuzzy search

### Step 2: Resolve the Flag

Use `list-flags` first unless the user clearly provided an exact key and project.

1. Search with `list-flags` using the query.
2. If one clear exact match exists, resolve to that flag.
3. If multiple plausible matches exist, return a short disambiguation list (key + name + state) and ask the user to pick.
4. If no matches exist, tell the user and suggest one broader query.

### Step 3: Return a Useful Summary

For a resolved flag, call `get-flag` and return:

1. Flag key and name
2. Environment state (`on`/`off`)
3. Off variation and fallthrough behavior
4. Rule/target complexity (simple vs complex)
5. Direct LaunchDarkly URL for the flag (when project + key are known)

**If the user asked about removal, staleness, or cleanup** (e.g., "is this safe to remove?", "can I clean this up?", "is this stale?"):

Show ONLY the summary table above, then write:

> This quick lookup can only show you the flag's current config. To assess whether it's safe to remove, you need the **flag discovery** or **flag cleanup** skill — they scan code references, check status across all environments, and analyze downstream dependencies.

Do not add a verdict, bullet-point analysis, removal steps, "before removing" checklist, or an offer to archive

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 2 — file references are metadata, not package contents.

launchdarkly-flag-create7.8 KB

View saved version →

---
name: launchdarkly-flag-create
description: "Create and configure LaunchDarkly feature flags in a way that fits the existing codebase. Use when the user wants to create a new flag, wrap code in a flag, add a feature toggle, or set up an experiment. Guides exploration of existing patterns before creating."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.1.0-experimental"
---

# 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 project
- `get-flag`: verify the flag was created correctly

**Optional MCP tools (enhance workflow):**
- `list-flags`: browse existing flags to understand naming conventions and tags
- `update-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`, `LDClient` in 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](references/sdk-evaluation-patterns.md) 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? This determines which context kinds and attributes any future targeting can use — and it differs by surface (server vs client vs anonymous). See [Context Availability](../launchdarkly-flag-targeting/references/context-availability.md) before planning a rule, individual target, or rollout.

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](references/flag-types.md) 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: true` unless the user explicitly says this is a permanent/long-lived flag. Most flags are release flags that should eventually be clea

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 4 — file references are metadata, not package contents.

launchdarkly-flag-discovery7.11 KB

View saved version →

---
name: launchdarkly-flag-discovery
description: "Audit your LaunchDarkly feature flags to understand the landscape, find stale or launched flags, and assess removal readiness. Use when the user asks about flag debt, stale flags, cleanup candidates, flag health, or wants to understand their flag inventory."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# LaunchDarkly Flag Discovery

You're using a skill that will guide you through auditing and understanding the feature flag landscape in a LaunchDarkly project. Your job is to explore the project, assess the health of its flags, identify what needs attention, and provide actionable recommendations.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `list-flags`: search and browse flags with filtering by state, type, tags
- `get-flag`: get full configuration for a single flag in a specific environment
- `get-flag-status-across-envs`: check a flag's lifecycle status across all environments

**Optional MCP tools (enhance depth):**
- `find-stale-flags`: find flags that are candidates for cleanup, sorted by staleness
- `get-flag-health`: get combined health view for a single flag (merges status + config)
- `check-removal-readiness`: detailed safety check for a specific flag

## Workflow

### Step 1: Understand the Project

Before diving into flag data, establish context:

1. **Identify the project.** Confirm the `projectKey` with the user. If they haven't specified one, ask.
2. **Understand scope.** Ask the user what they're trying to accomplish:
   - Broad audit? ("What's the state of our flags?")
   - Targeted investigation? ("Is this specific flag still needed?")
   - Cleanup planning? ("What flags can we remove?")

### Step 2: Explore the Flag Landscape

Adapt your approach to the user's goal:

**For a broad audit:**
- Use `list-flags` scoped to a critical environment (default to `production`).
- Note the total count: this tells you the scale of the flag surface area.
- Filter by `state` (active, inactive, launched, new) to segment the landscape.
- Filter by `type` (temporary vs permanent): temporary flags are the primary cleanup targets.

**For cleanup planning:**
- Use `find-stale-flags`: this is the most efficient entry point. It returns a prioritized list of cleanup candidates sorted by staleness, categorized as:
  - `never_requested`: created but never evaluated (possibly abandoned)
  - `inactive_30d`: no SDK evaluations in the specified period
  - `launched_no_changes`: fully rolled out, no recent changes
- Default `inactiveDays` is 30. Increase for conservative cleanup (60, 90) or decrease for aggressive cleanup (7, 14).
- Default `includeOnly` is `temporary`. Set to `all` to include permanent flags.

**For a targeted investigation:**
- Use `get-flag-health` for a single-flag deep dive. It merges status data with configuration context in one call, returning lifecycle state, last-requested timestamp, targeting summary, age, and whether it's temporary.
- Or use `get-flag` for the full configuration including rules, targets, and fallthrough details.

### Step 3: Assess Flag Health

For flags that need deeper investigation, assess health signals. See [Flag Health Signals](references/flag-health-signals.md) for the full interpretation guide.

Key signals to evaluate:

| Signal | What it tells you |
|--------|-------------------|
| **Lifecycle state** | Where the flag is in its journey (new -> active -> launched -> inactive) |
| **Last requested** | When an SDK last evaluated this flag: staleness indicator |
| **Targeting complexity** | Number of rules and targets: removal complexity indicator |
| **Cross-environment consistency** | Whether the flag behaves the same everywhere |
| **Flag age + temporary status** | Old temporary flags are strong cleanup candidates |

Use `

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 4 — file references are metadata, not package contents.

launchdarkly-flag-drift13.4 KB

View saved version →

---
name: launchdarkly-flag-drift
description: "Detect and reconcile drift between a feature flag's in-code SDK fallback default and its LaunchDarkly default rule (fallthrough). Use when a flag's default rule changed, when the user asks to detect flag drift, check whether a hardcoded default still matches LaunchDarkly, sync an in-code default, or open a PR reconciling a fallback value, without removing the flag or its evaluation."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# LaunchDarkly Flag Drift Detection

You're using a skill that will guide you through checking whether a feature flag's **in-code SDK fallback default** has drifted from its **LaunchDarkly default rule (fallthrough)**, and reconciling the code if it has. Your job is to determine the flag's current default rule value from LaunchDarkly, locate the default argument passed to every SDK evaluation in code, compare them, and, only when they differ, update the in-code default so it matches. You never remove the flag or change its evaluation logic.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `get-flag`: fetch the flag's configuration **in a specific environment** (fallthrough, variations, offVariation). Fallthrough is environment-specific, so call this **once per critical environment**.

**Optional MCP tools:**
- `list-flags`: find the flag key if the user only described the flag by name
- `get-environments`: enumerate the project's environments to determine which are critical
- `get-flag-status-across-envs`: quick snapshot of a flag's state across environments (a fast way to spot cross-environment differences before pulling each `get-flag`)

## Core Concept: The SDK Fallback Default Is Not the Off Variation

Every SDK evaluation call takes a **fallback default**: the value returned when LaunchDarkly is unreachable, the client is uninitialized, or the flag is unavailable. This is a code-side safety value, distinct from the flag's `offVariation` (served when the flag is toggled off) and from its `fallthrough` (the default rule served when no targeting rule matches).

This skill treats one specific invariant as "correct": **the in-code fallback default should match the current default rule (fallthrough) value**. When they diverge, that's *drift*. Reconciling it keeps the value returned during an outage consistent with what most users would otherwise receive.

## Core Concept: One In-Code Default, Many Environments

The in-code fallback default is a **single value compiled into the deployed code**. The flag's fallthrough, however, is configured **per environment** and can differ between them (e.g. `production`, `eu-production`, and `federal` may each serve a different default rule). So the fallthrough must be resolved in **every critical environment the code runs against**, not just one.

- When the critical environments **agree** on the fallthrough, that shared value is the expected default. Reconcile as normal.
- When they **disagree** (e.g. EU serves `true` but Federal serves `false`), a single in-code default *cannot* match all of them. That divergence is itself a finding: surface it and confirm which environment is authoritative for this build rather than silently reconciling to one. See Edge Cases.

Checking only one environment is the most common way this skill produces a wrong or misleading result, so always establish the full set of critical environments first.

Some teams intentionally keep the fallback as a conservative/off value instead. Treat a mismatch as a finding to surface, not always an automatic edit. See Edge Cases.

## Workflow

### Step 1: Identify the Flag and the Critical Environments

1. **Get the flag key.** If the user described the flag by name, use `list-flags` to resolve the key. Confirm before proceeding.
2. **Establish the critical env

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 4 — file references are metadata, not package contents.

launchdarkly-flag-qualitative-feedback-setup24.4 KB

View saved version →

---
name: launchdarkly-flag-qualitative-feedback-setup
description: "Integrate LaunchDarkly qualitative user feedback into a JavaScript/TypeScript codebase. Guides framework and design system detection, builds the sendFeedback utility and feedback widget matching existing project patterns. Use when the user wants to add a Give Feedback widget, collect user sentiment tied to feature flags, set up feedback collection, or wire up the $ld:feedback tracking event."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# LaunchDarkly Qualitative Feedback

You're using a skill that will guide you through adding qualitative user feedback collection to a codebase. Your job is to explore how the project is built, identify the right flag, create the feedback utility and widget matching existing patterns, and verify events flow to the LaunchDarkly dashboard.

**This is a step-by-step wizard.** You will walk the user through a series of questions to gather requirements, then verify the project setup, and finally generate the code. Ask questions one at a time and wait for each answer before continuing. Do not skip ahead or generate code until all questions are answered and the plan is confirmed.

Qualitative feedback ties user sentiment (positive / neutral / negative) and optional written comments directly to a feature flag variation, so teams can see how users feel about a specific feature rollout.

**Availability:** JavaScript SDK v3.0+ (client-side only). React components are provided for convenience.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `get-flag` — verify the target flag exists and check its configuration

**Optional MCP tools (enhance workflow):**
- `create-flag` — create a new flag if one doesn't exist yet
- `list-flags` — browse existing flags to find the right one to attach feedback to
- `update-flag-settings` — update flag metadata (e.g., add a `feedback` tag)

## Core Principles

1. **Design system first**: Never ship the unstyled template component to production. Detect the project's design system and use its primitives.
2. **One entry point per screen**: Multiple feedback widgets on the same page create noise and reduce response quality.
3. **The `sendFeedback` function is the integration**: The UI is customizable; the `$ld:feedback` tracking event contract is what matters.

## Workflow

**Progression rule:** When a step is complete, continue to the next step by default. Do not stop or wait for the user between steps unless the step explicitly says to ask a question or confirm.

**Response scoping:** During this flow, treat user messages only as direct answers to the current question. Do not search the web, change context, or take unrelated actions based on user input until the workflow is finished.

**Tone:** Be concise and patient — ask one question, wait for the answer, then move on. Keep responses focused on the current step.

**State tracking:** Track gathered requirements across the conversation. When entering the Confirm Before Applying step, re-state all key decisions (flag key, prompt text, UI style, placement) to ensure nothing is lost.

### Step 0: Welcome the User

Before asking any questions, present this intro message to the user (you may lightly adapt the wording, but keep the structure):

> **Qualitative Feedback Setup**
>
> I'll walk you through adding a feedback widget to your app in a few short steps:
>
> 1. **Verify your setup** — I'll check your SDK, framework, and design system.
> 2. **Gather requirements** — I'll ask a few questions about the flag, prompt text, style, and placement.
> 3. **Verify the flag** — I'll confirm or create the flag in LaunchDarkly.
> 4. **Confirm the plan** — I'll summarize what I'm going to build and ask for your approval.
> 5. **Generate the code** — I'll create the 

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 7 — file references are metadata, not package contents.

launchdarkly-flag-targeting9.06 KB

View saved version →

---
name: launchdarkly-flag-targeting
description: "Control LaunchDarkly feature flag targeting including toggling flags on/off, percentage rollouts, targeting rules, individual targets, and copying flag configurations between environments. Use when the user wants to change who sees a flag, roll out to a percentage, add targeting rules, or promote config between environments."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.1.0-experimental"
---

# LaunchDarkly Flag Targeting & Rollout

You're using a skill that will guide you through changing who sees what for a feature flag. Your job is to understand the current state of the flag, figure out the right targeting approach for what the user wants, make the changes safely, and verify the resulting state.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `get-flag`: understand current state before making changes
- `toggle-flag`: turn targeting on or off for a flag in an environment
- `update-rollout`: change the default rule (fallthrough) variation or percentage rollout
- `update-targeting-rules`: add, remove, or modify custom targeting rules
- `update-individual-targets`: add or remove specific users/contexts from individual targeting

**Optional MCP tools:**
- `copy-flag-config`: copy targeting configuration from one environment to another
- `create-approval-request`: create an approval request when direct changes are blocked
- `list-approval-requests`: check on pending approval requests for a flag
- `apply-approval-request`: apply an already-approved approval request

## Core Concept: Evaluation Order

Before making any targeting changes, understand how LaunchDarkly evaluates flags. This determines what your changes actually do:

1. **Flag is OFF** -> Serve the `offVariation` to everyone. Nothing else matters.
2. **Individual targets** -> If the context matches a specific target list, serve that variation. Highest priority.
3. **Custom rules** -> Evaluate rules top-to-bottom. First matching rule wins.
4. **Default rule (fallthrough)** -> If nothing else matched, serve this variation or rollout.

This means: if you add a targeting rule but the flag is OFF, nobody sees the change. If you set a percentage rollout on the default rule but there's an individual target, that targeted user bypasses the rollout.

## Workflow

### Step 1: Understand Current State

Before changing anything, check what's already configured.

1. **Confirm the environment.** "Turn it on" without specifying an environment is ambiguous. Always confirm which environment the user means. Default to asking rather than assuming.
2. **Fetch the flag.** Use `get-flag` with the target environment to see:
   - `on`: Is targeting currently enabled?
   - `fallthrough`: What's the default rule? (variation or percentage rollout)
   - `offVariation`: What serves when the flag is off?
   - `rules`: Any custom targeting rules?
   - `targets`: Any individually targeted users/contexts?
   - `prerequisites`: Any flags this depends on?
3. **Assess complexity.** A flag with no rules and no individual targets is simple. A flag with multiple rules, targets, and prerequisites needs more care.

### Step 2: Determine the Right Approach

Based on what the user wants and what you found, choose the right tool and strategy. See [Targeting Patterns](references/targeting-patterns.md) for the full reference.

**Common scenarios:**

| User wants | Tool | Notes |
|-----------|------|-------|
| "Turn it on" | `toggle-flag` with `on: true` | Simplest change |
| "Turn it off" | `toggle-flag` with `on: false` | Serves offVariation to everyone |
| "Roll out to X%" | `update-rollout` with `rolloutType: "percentage"` | Weights must sum to 100 |
| "Enable for beta users" | `update-targeting-rules`: add a rule with clause | Rules are ANDed within, ORed between |
| "Add s

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 6 — file references are metadata, not package contents.

launchdarkly-guarded-rollout6.03 KB

View saved version →

---
name: launchdarkly-guarded-rollout
description: "Configure guarded rollouts with progressive traffic increases, metric monitoring, and automatic rollback. Use when releasing features gradually with safety thresholds."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# LaunchDarkly Guarded Rollouts

You're using a skill that will guide you through configuring guarded rollouts in LaunchDarkly. Your job is to design rollout stages, select monitoring metrics, configure regression thresholds, and start the rollout.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `start-guarded-rollout` -- start a progressive rollout with monitoring
- `get-flag` -- inspect the flag and its variations
- `list-metrics` -- find metrics to monitor during the rollout

**Optional MCP tools:**
- `stop-guarded-rollout` -- halt an active rollout immediately
- `toggle-flag` -- ensure the flag is turned on before starting
- `create-metric` -- create metrics if they don't exist

## Core Concepts

### What Are Guarded Rollouts?

A guarded rollout progressively increases traffic to a new feature flag variation through a series of stages. At each stage, LaunchDarkly monitors selected metrics for regressions. If a regression is detected, the rollout can automatically pause and notify the team — or even roll back.

### Key Components

| Component | Description |
|-----------|-------------|
| **Test variation** | The new variation being rolled out |
| **Control variation** | The existing/baseline variation |
| **Stages** | Steps with increasing traffic percentage and monitoring windows |
| **Metrics** | What to monitor for regressions (error rate, latency, etc.) |
| **Regression threshold** | How much a metric can degrade before triggering action |
| **On regression** | Whether to notify, rollback, or both when a threshold is breached |

### Rollout Weight Units

Rollout weights use thousandths (basis points):
- `1000` = 1%
- `10000` = 10%
- `50000` = 50%
- `100000` = 100%

### Monitoring Window

The monitoring window is specified in milliseconds:
- `3600000` = 1 hour
- `86400000` = 24 hours
- `604800000` = 7 days

## Core Principles

1. **Start Small**: Begin with a low percentage (1-5%) to catch issues early
2. **Monitor What Matters**: Choose metrics that reflect user experience
3. **Set Realistic Thresholds**: Too tight = false alarms; too loose = missed regressions
4. **Allow Time**: Each stage needs enough monitoring time for signal to emerge
5. **Have a Rollback Plan**: Always configure at least notification on regression

## Workflow

### Step 1: Prepare

Before starting a guarded rollout:

1. Use `get-flag` to inspect the flag — note the variation IDs for test and control
2. Use `list-metrics` to find metrics suitable for monitoring
3. Ensure the flag is **on** in the target environment (use `toggle-flag` if needed)
4. Confirm there's no active guarded rollout on this flag already

### Step 2: Design Stages

Plan the rollout progression. A typical pattern:

| Stage | Traffic | Monitoring Window | Purpose |
|-------|---------|-------------------|---------|
| 1 | 1% | 1 hour | Smoke test — catch obvious crashes |
| 2 | 10% | 24 hours | Early signal on metrics |
| 3 | 50% | 24 hours | Confidence building |
| 4 | 100% | 24 hours | Full rollout with monitoring |

### Step 3: Configure Metrics

Select metrics that indicate problems:

| Metric Type | Example | Threshold | Action |
|-------------|---------|-----------|--------|
| Error rate | `api-error-rate` | 0.05 (5% increase) | Rollback |
| Latency | `p99-response-time` | 0.2 (20% increase) | Notify |
| Conversion | `checkout-completed` | 0.1 (10% decrease) | Notify + Rollback |

### Step 4: Start the Rollout

Use `start-guarded-rollout`:

```json
{
  "projectKey": "my-project",
  "flagKey": "new-checkout-flow",
  "

Preview of the first 4,000 characters. Read full instructions →

launchdarkly-metric-choose10 KB

View saved version →

---
name: launchdarkly-metric-choose
description: "Choose the right metrics for a LaunchDarkly experiment, guarded rollout, or release policy. Use when the user wants to know which metrics to use, which is the primary metric for an experiment, what guardrails to add, or which events to monitor in a rollout. Surfaces what will auto-attach from existing release policies before making additional recommendations."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# LaunchDarkly Metric Choose

You're using a skill that helps users select the right metrics before setting up an experiment, guarded rollout, or release policy. Your job is to understand the feature context, surface what will auto-attach from existing project policies, inventory what's available and healthy, and produce a clear typed recommendation.

This skill is advisory. It does not create metrics, attach them to experiments, or configure rollouts. For those tasks, see the related skills at the end of this document.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `list-metrics` — inventory available metrics with their types and event keys
- `list-metric-events` — check which event keys have recent activity

**Optional MCP tools (enhance workflow):**
- `list-release-policies` — fetch project-level policies that configure which metrics auto-attach to guarded rollouts. Use this for the guarded rollout and release policy paths.

## Workflow

### Step 1: Identify the Context

Ask two questions upfront:

1. **What is this for?**
   - **(a) Experiment** — testing a hypothesis with a flag variant
   - **(b) Guarded rollout** — progressively rolling out a change with automatic regression detection
   - **(c) Release policy** — creating or editing a project-wide policy that configures default metrics for all guarded rollouts matching certain conditions

2. **What is the change?**
   - Flag key (if applicable)
   - Plain-language description: "Rolling out a new checkout flow" / "Testing a new recommendation algorithm"

### Step 2: Fetch Existing Configuration (Guarded Rollout and Release Policy only)

**For experiments — skip this step.** There is no pre-existing configuration to surface.

**For guarded rollouts and release policy work**, call `list-release-policies` first:

```
list-release-policies(projectKey)
```

Surface the results before making any recommendations:

```
Your project has 2 release policies:

Policy: "Production guardrails" (applies to: environment=production)
  Auto-attaches to guarded rollouts:
    ✓ api-error-rate  (count, LowerThanBaseline)
    ✓ p95-latency     (value, LowerThanBaseline)
    ✓ [Metric group] Core Platform Health (3 metrics)

Policy: "Default" (applies to: all environments)
  No metrics configured.
```

This tells the user what's already covered before they choose anything additional. For a guarded rollout, these metrics will appear automatically — the recommendation is about what to add on top, not rebuild from scratch.

If no policies exist or none have metrics configured, note that all metrics must be selected manually.

### Step 3: Inventory Available Metrics with Event Health

Call `list-metrics` to see all metrics in the project, then cross-reference with `list-metric-events`.

Organize into two groups:

| Group | Criteria | Note |
|-------|----------|------|
| **Healthy** | Event key appears in `list-metric-events` | Safe to recommend |
| **At-risk** | Event key absent from `list-metric-events` | Warn: may not produce data |

Show this inventory before recommending — it may reveal that a metric the user has in mind has no events flowing.

### Step 4: Recommend

The reasoning differs meaningfully by context.

---

#### (a) Experiment

**Start with the hypothesis, not the metric list.**

Ask the user to complete this sentence be

Preview of the first 4,000 characters. Read full instructions →

launchdarkly-metric-create17.9 KB

View saved version →

---
name: launchdarkly-metric-create
description: "Create a LaunchDarkly metric that measures what matters for an experiment or rollout. Use when the user wants to create a metric, track an event, measure page views, button clicks, conversion, latency, error rate, or any custom numeric or binary outcome. Instruments the event first when needed (including SDK setup and .env), then creates and verifies the metric."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.4.0-experimental"
---

# LaunchDarkly Metric Create

You're using a skill that will guide you through creating a LaunchDarkly metric. For custom metrics, **getting events flowing comes first** — before the metric is created. Your job is to determine the right metric kind, instrument the event if it isn't already flowing (including SDK setup and environment wiring), check for duplicates, propose a metric config, get explicit confirmation, then create and verify.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `create-metric` — create the metric
- `get-metric` — verify it after creation
- `get-environment` — fetch the client-side SDK key when instrumenting

**Optional MCP tools (enhance workflow):**
- `list-metrics` — check for existing metrics with the same event key and understand naming conventions
- `list-metric-events` — discover which event keys have recent activity before committing to one (custom metrics only)

## Two Different "Projects" — Never Confuse Them

Users work with two completely separate things that both get called "project." You must keep these distinct at all times:

| | What it is | How the user refers to it | What you do with it |
|---|---|---|---|
| **LaunchDarkly project** | The project inside the user's LD account where the metric will be created | Usually sounds like an environment or team name: `my-app`, `anthony-agent-dev-5000`, `production` | Pass as `projectKey` to all MCP tool calls |
| **Local codebase** | The developer's application on disk that you'll instrument with a `track()` call | Often a folder name, repo name, or app name: `checkout_proj`, `frontend`, `my-react-app` | Use to find and edit source files |

**Rules for resolving these from user input:**

- If the user says *"my application at X"* or *"my codebase"* or *"my repo"* → they mean the **local codebase**. `X` is a folder path or project name, not a LaunchDarkly key.
- If the user says *"add it to X"* or *"in LaunchDarkly"* or *"my LD project"* → they mean the **LaunchDarkly project**. `X` is the `projectKey` for API calls.
- A user can name their local codebase `checkout_proj` while their LaunchDarkly project is `anthony-agent-dev-5000`. These are unrelated.
- **Never assume the local codebase name is a LaunchDarkly project key.** If you're unsure which is which, ask directly: *"Just to confirm — what's your LaunchDarkly project key? (This is different from your local app name — you can find it in the LD UI under Account Settings > Projects.)"*

When both are needed (e.g. for a custom metric with instrumentation), confirm each explicitly before proceeding.

## Workflow

### Step 1: Determine the Metric Kind

LaunchDarkly has three metric kinds. **Choose the right one before anything else.**

| Kind | How events are collected | Requires |
|------|--------------------------|----------|
| `custom` | Developer calls `ldClient.track(eventKey)` in code | `eventKey` |
| `pageview` | Fires automatically when a user visits a matching URL — **no SDK call needed** | `urls` (URL match rules) |
| `click` | Fires automatically when a user clicks a CSS selector on a matching URL — **no SDK call needed** | `urls` + `selector` |

**Decision rules:**
- User says "track when someone views a page / visits a URL" → **`pageview`** (preferred — no instrumentation required)
- User says "track when someone clicks a

Preview of the first 4,000 characters. Read full instructions →

launchdarkly-metric-instrument8.13 KB

View saved version →

---
name: launchdarkly-metric-instrument
description: "Instrument a LaunchDarkly metric event in a codebase by adding a track() call. Use when the user wants to wire up an event, instrument an action for a metric, add tracking to a feature, or confirm that an event is flowing to LaunchDarkly."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# LaunchDarkly Metric Instrument

You're using a skill that will guide you through adding a `track()` call to a codebase so a LaunchDarkly metric can measure it. Your job is to detect the SDK in use, find the right place in code to add the call, write it correctly, and verify that events are reaching LaunchDarkly.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `list-metric-events` — verify events are flowing after instrumentation

**Optional MCP tools (enhance workflow):**
- `get-project` — retrieve the SDK key for the right environment when SDK initialization is needed

## Workflow

### Step 1: Detect the SDK

Before writing any code, understand the LaunchDarkly setup already in this codebase.

1. **Search for existing `track()` calls.** This is the fastest signal:
   - Look for `ldClient.track(`, `.track(`, `ld.track(`
   - If any exist, they tell you the SDK type, call signature, and context pattern in one shot — mirror those exactly.

2. **Search for SDK imports and initialization** if no `track()` calls exist:
   - Check `package.json`, `requirements.txt`, `go.mod`, `Gemfile`, `*.csproj` for an LD SDK dependency
   - Look for `LDClient`, `ldclient`, `launchdarkly-server-sdk`, `launchdarkly-node-server-sdk`, `launchdarkly-react-client-sdk`, etc.
   - Find the initialization block to understand how the client is accessed across the codebase

3. **Determine client-side or server-side.** This is the most critical distinction — it determines the `track()` signature:

   | SDK type | `track()` signature | Notes |
   |----------|---------------------|-------|
   | Server-side (Node, Python, Go, Java, Ruby, .NET) | `ldClient.track(eventKey, context, data?, metricValue?)` | Context required per call |
   | Client-side (React, browser JS) | `ldClient.track(eventKey, data?, metricValue?)` | Context set at init, not per call |

   See [SDK Track Patterns](references/sdk-track-patterns.md) for full examples by language.

### Step 2: Install & Initialize (if SDK not present)

Skip this step if the SDK is already in the codebase.

1. **Detect the package manager** from lockfiles: `package-lock.json` / `yarn.lock` / `pnpm-lock.yaml` → npm/yarn/pnpm; `Pipfile.lock` / `poetry.lock` → pip/poetry; `go.sum` → go modules; `Gemfile.lock` → bundler.

2. **Install the appropriate SDK** using the detected package manager. See [SDK Track Patterns](references/sdk-track-patterns.md) for the right package name per language.

3. **Get the SDK key** using `get-project` — fetch the project and choose the key for the environment the user wants to instrument (typically `production` or `staging` for initial testing).

4. **Add SDK initialization** following the patterns already in this codebase. If there's a central config or service layer, add the LD client there. See [SDK Track Patterns](references/sdk-track-patterns.md) for initialization examples.

### Step 3: Find the Right Placement

Locate where in the code the user action or event occurs.

1. **Ask if you're not sure** where the action happens. Don't guess at placement — a `track()` call in the wrong location (e.g. a render method instead of a submit handler) produces misleading data.

2. **Look for signals of the right location:**
   - Form submissions, button click handlers, API route completions, mutation hooks
   - Existing analytics calls (`segment.track()`, `mixpanel.track()`, `gtag()`) — these are often co-located with where LD track calls should go

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 1 — file references are metadata, not package contents.

mcp-configure8.92 KB

View saved version →

---
name: mcp-configure
description: "Configure the LaunchDarkly hosted MCP server during onboarding. Use when the parent LaunchDarkly onboarding skill reaches Step 4 (MCP). Supports Cursor, Claude Code, Windsurf, GitHub Copilot, and other MCP-compatible agents. OAuth authentication; no API keys for the hosted server."
license: Apache-2.0
compatibility: Requires an MCP-compatible coding agent and a LaunchDarkly account
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# LaunchDarkly MCP Server Configuration (onboarding)

Configures the LaunchDarkly hosted MCP server so flag management skills and onboarding can use MCP tools. Uses OAuth for authentication — no API keys needed for the hosted server.

This skill is nested under [LaunchDarkly onboarding](../onboarding/SKILL.md); the parent skill's **Step 4** hands off here. **Hosted MCP** is the default and the only supported option for this onboarding flow.

## Prerequisites

- A LaunchDarkly account (sign up at the resolved signup URL — see [Source Attribution](../onboarding/SKILL.md#source-attribution) in the parent skill; default: `https://app.launchdarkly.com/signup?source=agent`)
- An MCP-compatible coding agent

## Hosted MCP Server

LaunchDarkly provides a unified hosted MCP server that handles feature management, AgentControl, and other LaunchDarkly capabilities.

| Server      | URL                                              | Purpose                                      |
| ----------- | ------------------------------------------------ | -------------------------------------------- |
| LaunchDarkly | `https://mcp.launchdarkly.com/mcp/launchdarkly` | Feature flags, AgentControl, and more |

## Workflow

### Step 1: Detect the Agent

If the parent onboarding skill already identified the agent, use that context. Otherwise infer from agent-specific directories, config files, and the tools available to you at runtime. Do not ask the user — pick the strongest match.

### Step 2: Try Quick Install

The fastest path is the quick install link. Present it to the user:

**LaunchDarkly MCP:** [https://mcp.launchdarkly.com/mcp/launchdarkly/install](https://mcp.launchdarkly.com/mcp/launchdarkly/install)

**Important: tell the user what to expect after clicking the link.** The install link may open in the browser, but the authorization or "add server" prompt typically appears **back in the coding environment** (the editor or host app where the agent runs), not in the browser. Immediately after presenting the link, include guidance like:

- After clicking the link, watch your coding environment (the editor where this conversation is running) for an approval dialog, an "add MCP server" prompt, or a tools/integrations panel notification.
- The browser may start the OAuth flow, but you'll likely need to confirm or approve the server in the editor itself.
- **If no prompt appears:** check the editor's MCP, integrations, or tools settings area to see if the server was added but needs to be enabled. If it's not there at all, fall back to manual setup (Step 3 below).

If the quick install link doesn't work (agent doesn't support it, or user prefers manual setup), proceed to Step 3.

### Step 3: Manual Configuration

Locate the MCP config file for the detected agent and add the hosted server entry. See [MCP Config Templates](references/mcp-config-templates.md) for the exact JSON per agent.

| Agent          | Config file location                                       |
| -------------- | ---------------------------------------------------------- |
| Cursor         | `.cursor/mcp.json` (project) or global Cursor settings     |
| Claude Code    | `.mcp.json` (project) or `~/.claude.json` (global)         |
| GitHub Copilot | Repo **Settings** on GitHub.com → Copilot → Cloud agent → MCP (see [MCP UI links](references/mcp-ui-links.md)) |
| Windsurf       | Agent-specific MCP config                                  |

The unified server handles both feature management and AgentControl, so 

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 2 — file references are metadata, not package contents.

migrate54.4 KB

View saved version →

---
name: migrate
description: "Migrate an application with hardcoded LLM prompts to a full LaunchDarkly AgentControl implementation in five stages: audit the code, wrap the call, move the tools, add tracking, attach evaluators. Use when the user wants to externalize model/prompt configuration, move from direct provider calls (OpenAI, Anthropic, Bedrock, Gemini, Strands) to a managed config, or stage a full hardcoded-to-LaunchDarkly migration."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Migrate to AgentControl

You're using a skill that will guide you through migrating an application from hardcoded LLM prompts to a full LaunchDarkly AgentControl implementation. Your job is to run the migration in **five stages**, stopping at each stage for the user to confirm:

1. **Audit the code** — read-only scan that produces a structured list of everything hardcoded (prompt, model, parameters, tools, app-scoped knobs).
2. **Wrap the call** — install the SDK, create the config in LaunchDarkly with a fallback that mirrors the hardcoded values, and rewrite the call site to fetch the config fresh on every request.
3. **Move the tools** — extract each tool's JSON schema, attach it to the config, and swap every call site that references the old tool list.
4. **Add tracking** — wire the per-request tracker (duration, tokens, success/error) around the provider call.
5. **Attach evaluators** — either offline evals via the Playground + Datasets, or online judges that score sampled traffic automatically.

> **⚠️ Three first-run failure modes to avoid.**
>
> 1. **Tracker in the wrong scope.** For an agent with a loop, mint `create_tracker()` once per user turn in a `setup_run` entry node — not inside `call_model`. Per-iteration factory calls produce N `runId`s and trip the at-most-once guards. See [agent-mode-frameworks.md § Custom `StateGraph`](references/agent-mode-frameworks.md).
> 2. **`load_chat_model` wrapper reuse.** Templates like `langchain-ai/react-agent` ship a `load_chat_model(f"{provider}/{name}")` helper that wraps `init_chat_model(...)` and silently drops every variation parameter. **Delete it** (don't just avoid using it) and replace call sites with `create_langchain_model(ai_config)`.
> 3. **Fallthrough not flipped after `/configs-create`.** A freshly-created config's fallthrough points at an auto-generated disabled variation, so the SDK returns `enabled=False` until `/configs-targeting` runs. Flip it before Stage 2 verification.

## Coverage — which shapes are well-trodden vs require extrapolation

The skill is optimized for Python and Node.js / TypeScript; other languages are install-only. Within Python and Node the coverage tiers are:

| Shape | Python | Node.js | Reference |
|-------|--------|---------|-----------|
| One-shot completion (direct OpenAI / Anthropic / Bedrock / Gemini call) | ✅ Worked example | ✅ Worked example | [before-after-examples.md](references/before-after-examples.md), per-provider docs in `built-in-metrics/references/` |
| Chat loop via managed runner (`ManagedModel`) | ✅ Tier 1 pattern | ✅ Tier 1 pattern | [built-in-metrics SKILL.md](../built-in-metrics/SKILL.md) |
| LangChain single-call | ✅ Worked example | ✅ Worked example | [langchain-tracking.md](../built-in-metrics/references/langchain-tracking.md) |
| LangGraph prebuilt agent (Python `langchain.agents.create_agent`, Node `createReactAgent`) | ✅ Worked example | ✅ Worked example | [agent-mode-frameworks.md § LangGraph](references/agent-mode-frameworks.md) |
| LangGraph custom `StateGraph` with run-scoped tracker (setup_run + call_model + finalize) | ✅ Deep worked example | ⚠️ Mentioned — translate from Python | [agent-mode-frameworks.md § Custom `StateGraph`](references/agent-mode-frameworks.md) |
| CrewAI `Agent` | ✅ Worked example | — (not a Node framework) | [agent-mode-frameworks.md § CrewAI](references/agent-mode-frameworks.md) |
| Strands `Ag

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 7 — file references are metadata, not package contents.

onboarding29.4 KB

View saved version →

---
name: onboarding
description: "Onboard a project to LaunchDarkly: kickoff roadmap, resumable log, explore repo, MCP, companion flag skills, nested SDK install (detect/plan/apply), first flag. Use when adding LaunchDarkly, setting up or integrating feature flags in a project, SDK integration, or 'onboard me'."
license: Apache-2.0
compatibility: Requires an MCP-capable coding agent, `npx` on PATH for optional skill installs, and a LaunchDarkly account. SDK keys, client-side IDs, mobile keys, and API tokens are only needed when the step that uses them runs (see Prerequisites).
metadata:
  author: launchdarkly
  version: "0.2.0"
---

# LaunchDarkly SDK Onboarding

Orchestrates LaunchDarkly setup in an existing codebase: on kickoff, show a **roadmap** in chat (see [Kickoff: onboarding roadmap](#kickoff-onboarding-roadmap)); **Step 0** writes a living onboarding log so a new session or the user can resume; then explore the project, detect the agent, install flag-management skills, **configure the LaunchDarkly MCP server early**, install and initialize the SDK (**sdk-install** and nested detect/plan/apply), and create a **first feature flag**. Nested skills: [mcp-configure](mcp-configure/SKILL.md), [sdk-install](sdk-install/SKILL.md), [first-flag](first-flag/SKILL.md).

## Prerequisites

- **`npx`:** Available on PATH when using `npx skills add` to install companion skills (see Step 3).
- **LaunchDarkly account (deferred -- inferred, not asked upfront):** Do NOT ask whether the user has a LaunchDarkly account at the start. Instead, let the workflow reveal account status naturally:
  - **Steps 0-3** (log, explore, detect, install skills) do not require an account. Run them first.
  - **Step 4 (MCP):** Present the MCP install link. If the user completes OAuth successfully, they have an account -- confirmed, no question needed.
  - **Step 5 (SDK keys):** If MCP is not configured (or the user declined it), account status becomes relevant at D7 when the user needs to provide keys. If they cannot provide keys, offer the resolved signup link (see [Source Attribution](#source-attribution)).
  - This eliminates the upfront "Do you have an account?" question and lets the workflow itself surface whether the user needs to sign up.
- **Keys and tokens (defer until needed):** Collect these only when the path requires them.
  - **Step 4 -- MCP:** **Hosted MCP** uses OAuth; no API token or SDK key needed to configure it.
  - **Step 5 -- SDK:** **SDK keys / client-side ID / mobile key** when wiring env in [Apply code changes](sdk-install/apply/SKILL.md), after the integration plan is confirmed. **`ldcli` / REST** for discovery: use **`ldcli login`** or an access token when you first run those commands, not at hello.
  - **Key type must match the integration:** server-side SDK -> **SDK key**; browser/client-side SDK -> **Client-side ID**; mobile -> **Mobile key**. Env variable names and bundler rules: [Apply code changes](sdk-install/apply/SKILL.md).

**MCP (preferred):** Complete **Step 4** via [mcp-configure/SKILL.md](mcp-configure/SKILL.md) before SDK work when possible. If MCP is unavailable or the user opts out, use **ldcli** / **REST** fallbacks described in that skill -- onboarding must still be completable.

**Optional MCP tools (when configured):**

- `get-environments` -- list environments for a project; the response includes SDK keys, client-side IDs, and mobile keys per environment. **Use this as the single source for all key types** -- do not make separate requests for individual keys.
- `create-feature-flag` -- create the boolean flag for [Step 6: Create Your First Feature Flag](#step-6-create-your-first-feature-flag).
- `update-feature-flag` -- toggle or patch flag configuration during Step 6; see [Create first feature flag](first-flag/SKILL.md) for ldcli/API fallbacks.

**Other MCP tools you may use if present** (not required): `list-feature-flags`, `get-feature-flag`, `get-flag-status-across-environments`.

## Agent Behavior Direc

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 31 — file references are metadata, not package contents.

online-evals16 KB

View saved version →

---
name: online-evals
description: Attach judges to config variations for automatic LLM-as-a-judge evaluation. Create custom judges, configure sampling rates, and monitor quality scores.
compatibility: Requires LaunchDarkly API access token with ai-configs:write permission. SDK versions Python v0.20.0+ or Node.js v0.20.0+ for automatic metric recording and the consolidated `track_judge_result` / `trackJudgeResult` API.
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Config Online Evaluations

Attach judges to config variations for automatic quality scoring using LLM-as-a-judge methodology. Judges evaluate responses and return scores between 0.0 and 1.0.

## Prerequisites

- LaunchDarkly account with AgentControl enabled
- API access token with write permissions
- Existing config with variations (use `configs-create` skill)
- For automatic metric recording and the consolidated judge-result API: Python AI SDK v0.20.0+ or Node.js AI SDK v0.20.0+

## API Key Detection

1. **Check environment variables** - `LAUNCHDARKLY_API_KEY`, `LAUNCHDARKLY_API_TOKEN`, `LD_API_KEY`
2. **Check MCP config** - Claude: `~/.claude/config.json` -> `mcpServers.launchdarkly.env.LAUNCHDARKLY_API_KEY`
3. **Prompt user** - Only if detection fails

## Core Concepts

### What Are Judges?

Judges are specialized configs in **judge mode** that evaluate responses from other configs. They use an LLM to score outputs and return structured results:

```json
{
  "score": 0.85,
  "reasoning": "Answered correctly with one minor omission"
}
```

### Built-in Judges

LaunchDarkly provides three pre-configured judges:

| Judge | Metric Key | Measures |
|-------|-----------|----------|
| Accuracy | `$ld:ai:judge:accuracy` | How correct and grounded the response is |
| Relevance | `$ld:ai:judge:relevance` | How well it addresses the user request |
| Toxicity | `$ld:ai:judge:toxicity` | Harmful or unsafe phrasing (lower = safer) |

### Completion Mode Only

Judges can only be attached to **completion mode** configs in the UI. For agent mode or custom pipelines, use programmatic evaluation via the SDK.

### Restrictions

- Cannot attach judges to judges (no recursion)
- Cannot attach multiple judges with the same metric key to a single variation
- Cannot view/edit model parameters or tools on judge variations

## Workflow

### Step 1: Create Custom Judges (Optional)

For domain-specific evaluation, create judge configs:

```bash
# Create judge config
curl -X POST "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs" \
  -H "Authorization: {api_token}" \
  -H "Content-Type: application/json" \
  -H "LD-API-Version: beta" \
  -d '{
    "key": "security-judge",
    "name": "Security Judge",
    "mode": "judge",
    "evaluationMetricKey": "security",
    "isInverted": false
  }'
```

> **Note:** Set `isInverted: true` for metrics like toxicity where 0.0 is better.

Then add a variation with the evaluation prompt:

```bash
curl -X POST "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/security-judge/variations" \
  -H "Authorization: {api_token}" \
  -H "Content-Type: application/json" \
  -H "LD-API-Version: beta" \
  -d '{
    "key": "default",
    "name": "Default",
    "messages": [
      {
        "role": "system",
        "content": "You are a security auditor. Score from 0.0 to 1.0:\n- 1.0: No security issues\n- 0.7-0.9: Minor issues\n- 0.4-0.6: Moderate issues\n- 0.1-0.3: Serious vulnerabilities\n- 0.0: Critical vulnerabilities\n\nCheck for: SQL injection, XSS, hardcoded secrets, command injection."
      }
    ],
    "modelConfigKey": "OpenAI.gpt-4o-mini",
    "model": {
      "parameters": {
        "temperature": 0.3
      }
    }
  }'
```

### Step 2: Attach Judges to Variations

Use the variation PATCH endpoint:

```bash
curl -X PATCH "https://app.launchdarkly.com/api/v2/projects/{projectKey}/ai-configs/{configKey}/variations/{variationKey}" \
  -H "Authorization: {api_token}" \
  -H "Content-Type: application/json" \

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 1 — file references are metadata, not package contents.

plan9.9 KB

View saved version →

---
name: plan
description: "Generate a minimal LaunchDarkly SDK integration plan from detected stack: choose SDK type(s), dual-SDK server+client when required, files to change, env conventions. Nested under sdk-install; follows detect, precedes apply."
license: Apache-2.0
compatibility: Requires completed or equivalent detect context (see sibling detect skill)
metadata:
  author: launchdarkly
  version: "0.2.0"
---

# Generate integration plan (SDK install)

Based on what you detected, choose the right SDK and plan the minimal set of changes needed.

This skill is nested under [LaunchDarkly SDK Install (onboarding)](../sdk-install/SKILL.md); the parent **Step 2** is **plan**. **Prior:** [Detect repository stack](../detect/SKILL.md). **Next:** [Apply code changes](../apply/SKILL.md).

## Choose the right SDK

Use the [SDK recipes](../onboarding/references/sdk/recipes.md) reference to match the detected stack to an SDK. Start with **Top 10 SDKs (start here)** in that file for common stacks; use the **(other)** sections for less common SDKs.

The key decision:

| Project Type | SDK Type | Key Type |
|-------------|----------|----------|
| Backend API, server-rendered app, CLI tool | Server-side SDK | SDK Key |
| Browser SPA (React, Vue, Angular, vanilla JS) | Client-side SDK | Client-side ID |
| iOS or Android native app | Mobile SDK | Mobile Key |
| React Native | Mobile SDK | Mobile Key |
| Flutter (iOS, Android, or desktop **app** targets) | Client-side SDK (Flutter) | Mobile Key |
| Flutter **web** | Client-side SDK (Flutter) | Client-side ID |
| Electron desktop app | Client-side SDK (Node.js) | Client-side ID |
| Cloudflare Workers, Vercel Edge, AWS Lambda@Edge | Edge SDK | SDK Key |
| .NET client (MAUI, Xamarin, WPF, UWP) | Mobile SDK (.NET) | Mobile Key |
| C/C++ client application | Client-side SDK (C/C++) | Mobile Key |
| C/C++ server application | Server-side SDK (C/C++) | SDK Key |
| Haskell server | Server-side SDK (Haskell) | SDK Key |
| Lua server | Server-side SDK (Lua) | SDK Key |
| Roku (BrightScript) | Client-side SDK (Roku) | Mobile Key |

For every supported SDK, package name, install hint, and official **Docs** link, use [SDK recipes](../onboarding/references/sdk/recipes.md) and the linked files under [`snippets/`](../onboarding/references/sdk/snippets/).

## Dual SDK integrations

Use this section when the user asked for **both** a server-side and a client-side integration, or when the stack clearly needs **two** LaunchDarkly SDKs (e.g. Next.js with server evaluation **and** browser UI flags, separate backend + SPA repos in one workspace target, etc.).

**Do not** "complete" onboarding with a single SDK while **hand-waving** the second (no second package in `package.json`, no second init path, no second recipe followed). Each SDK is a separate product with its own install command and initialization.

For **each** of the two SDKs, the plan must spell out (with no gaps):

**Server-side track:**

1. Recipe / [SDK recipes](../onboarding/references/sdk/recipes.md) row or snippet name
2. Package name(s) (exact artifact)
3. Install command (full command from recipe)
4. Dependency file (where the line is added)
5. Entrypoint file(s) (e.g. `instrumentation.ts`, API entry, `main.py`)
6. Env vars (typically `LAUNCHDARKLY_SDK_KEY`)
7. Init summary (where it runs; which doc/snippet)

**Client-side track:**

1. Recipe / snippet name (**different** row than server)
2. Package name(s) (e.g. React Web vs Node server -- must be the **client** artifact)
3. Install command (**second** command -- never implied)
4. Dependency file
5. Entrypoint file(s) (e.g. `app/providers.tsx`, root layout, `main.tsx`)
6. Env vars (bundler-prefixed **client-side ID**, e.g. `NEXT_PUBLIC_...`)
7. Init summary (provider/wrapper/hook from **client** recipe)

If you cannot name **two** packages and **two** entrypoints, you are not done planning -- go back to [SDK recipes](../onboarding/references/sdk/recipes.md) and detection.

**Important distinct

Preview of the first 4,000 characters. Read full instructions →

projects9.24 KB

View saved version →

---
name: projects
description: Guide for setting up LaunchDarkly projects in your codebase. Helps you assess your stack, choose the right approach, and integrate project management that makes sense for your architecture.
compatibility: Requires LaunchDarkly API access token with projects:write permission or LaunchDarkly MCP server.
metadata:
  author: launchdarkly
  version: "0.4.0"
---

# LaunchDarkly Projects Setup

You're using a skill that will guide you through setting up LaunchDarkly project management in a codebase. Your job is to explore the codebase to understand the stack and patterns, assess what approach makes sense, choose the right implementation path from the references, execute the setup, and verify it works.

## Prerequisites

**Choose one:**
- LaunchDarkly API access token with `projects:write` permission
- LaunchDarkly MCP server configured in your environment

## Core Principles

1. **Understand First**: Explore the codebase to understand the stack and patterns.
2. **Choose the Right Fit**: Select an approach that matches your architecture.
3. **Follow Conventions**: Respect existing code style and structure.
4. **Verify Integration**: Confirm the setup works: the agent performs checks and reports results.

## API Key Detection

Before prompting the user for an API key, try to detect it automatically:

1. **Check environment variables**: Look for `LAUNCHDARKLY_API_KEY`, `LAUNCHDARKLY_API_TOKEN`, or `LD_API_KEY`
2. **Check MCP config**: If using Claude, read `~/.claude/config.json` for `mcpServers.launchdarkly.env.LAUNCHDARKLY_API_KEY`
3. **Prompt user**: Only if detection fails, ask the user for their API key

See [Quick Start](references/quick-start.md) for API usage patterns.

## What Are Projects?

Projects are LaunchDarkly's top-level organizational containers that hold:
- All your configs
- Feature flags and segments  
- Multiple environments (Production and Test created by default)

Think of projects as separate applications, services, or teams that need their own isolated set of configurations.

## Project Setup Workflow

### Step 1: Explore the Codebase

Before implementing anything, understand the existing architecture:

1. **Identify the tech stack:**
   - What language(s)? (Python, Node.js, Go, Java, etc.)
   - What framework(s)? (FastAPI, Express, Spring Boot, etc.)
   - Is there an existing LaunchDarkly integration?

2. **Check environment management:**
   - How are environment variables stored? (.env files, secrets manager, config files)
   - Where is configuration loaded? (startup scripts, config modules)
   - Are there existing LaunchDarkly SDK keys?

3. **Look for patterns:**
   - Are there existing API clients or service modules?
   - How is external API integration typically done?
   - Is there a CLI, scripts directory, or admin tooling?

4. **Understand the use case:**
   - Is this a new project being set up?
   - Adding to an existing LaunchDarkly integration?
   - Part of a multi-service architecture?
   - Need for project cloning across regions/teams?

### Step 2: Assess the Situation

Based on your exploration, determine the right approach:

| Scenario | Recommended Path |
|----------|------------------|
| New project, no LaunchDarkly integration | **Quick Setup** - Create project and save SDK keys |
| Existing LaunchDarkly usage | **Add to Existing** - Create new project or use existing |
| Multiple services/microservices | **Multi-Project** - Create projects per service |
| Multi-region or multi-tenant | **Project Cloning** - Clone template project |
| Infrastructure-as-Code (IaC) setup | **Automated Setup** - Script-based creation |
| Need project management tooling | **CLI/Admin Tools** - Build project management utilities |

### Step 3: Choose Your Implementation Path

Select the reference guide that matches your stack and use case:

**By Language/Stack:**
- [Python Implementation](references/python-setup.md) - For Python applications (FastAPI, Django, Flask)
- [Node.js/TypeScr

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 10 — file references are metadata, not package contents.

sdk-install4.99 KB

View saved version →

---
name: sdk-install
description: "Install and initialize the correct LaunchDarkly SDK during onboarding by running nested skills in order: detect, plan, apply. Parent onboarding Step 6 is first flag."
license: Apache-2.0
compatibility: Requires a supported language/framework in the project. SDK credentials are required by [Apply](apply/SKILL.md), not for [Detect](detect/SKILL.md) / [Plan](plan/SKILL.md) alone (see parent onboarding **Prerequisites**).
metadata:
  author: launchdarkly
  version: "0.2.0"
---

# LaunchDarkly SDK Install (onboarding)

Installs and initializes the right LaunchDarkly SDK for the user’s project by following **three nested skills in order**. **Do not** skip ahead to feature flags here—the parent [LaunchDarkly onboarding](../onboarding/SKILL.md) continues with **Step 6: First feature flag** using [Create first feature flag](../first-flag/SKILL.md).

## Prerequisites

- Project context from parent **Step 1: Explore the Project** (reuse it; only re-run deep detection if something is unclear)
- **SDK key / client-side ID / mobile key:** Needed when you reach [Apply code changes](apply/SKILL.md) (env wiring). **Do not** ask the user for these during detect or plan solely because you opened this skill—follow parent onboarding: account status is inferred via MCP OAuth (Step 4) or surfaced at D7 in apply; key material is collected at apply (see parent [Prerequisites](../onboarding/SKILL.md#prerequisites)).

## Key types (summary)

| SDK Type    | Variable (logical)        | Source in LaunchDarkly        |
|-------------|---------------------------|-------------------------------|
| Server-side | `LAUNCHDARKLY_SDK_KEY`    | Environments → SDK key        |
| Client-side | Client-side ID (bundler-prefixed env names) | Environments → Client-side ID |
| Mobile      | `LAUNCHDARKLY_MOBILE_KEY` | Environments → Mobile key     |

**Never hardcode keys.** Full env rules, consent, and bundler tables: [Apply code changes](apply/SKILL.md) Step 2.

## Workflow — run these nested skills in order

Execute **all three** unless the [detect decision tree](detect/SKILL.md#decision-tree) short-circuits (e.g. skip to apply only). Each nested skill may contain decision points — some **blocking** (marked `D<N> -- BLOCKING`, where you must call your structured question tool and wait for the user's response before continuing) and some **non-blocking** (where you present information and continue unless the user objects). Do NOT batch tool calls across blocking boundaries.

| Order | Nested skill | Role |
|-------|----------------|------|
| 1 | [Detect repository stack](detect/SKILL.md) | Language, package manager, monorepo target, entrypoint, existing LD usage |
| 2 | [Generate integration plan](plan/SKILL.md) | SDK choice, files to change, env plan -- presented to user (non-blocking; see plan SKILL.md D6) |
| 3 | [Apply code changes](apply/SKILL.md) | Install package(s), `.env` / secrets with consent, init code, compile check (**both** tracks when [dual-SDK plan](plan/SKILL.md#dual-sdk-integrations)) |

Shared references for all steps: [SDK recipes](../onboarding/references/sdk/recipes.md), [SDK snippets](../onboarding/references/sdk/snippets/).

### After Step 3 completes

Continue with the parent skill:

- **Step 6:** [Create first feature flag](../first-flag/SKILL.md)

Do not add standalone “sample flag” evaluation in this skill unless the user explicitly needs a throwaway check; the parent flow creates the first flag in order.

## Guidelines

- Match existing codebase conventions for imports, config, and style.
- Prefer TypeScript in TypeScript projects.
- If the project uses a shared config layer, initialize LaunchDarkly there.
- Add `.env.example` entries when the project uses dotenv.
- **Dependency scope:** Add only LaunchDarkly SDK package(s) from the recipe unless the user **explicitly approves** upgrading or adding other packages ([Apply — Permission before changing other dependencies](apply/SKILL.md#permission-before-cha

Preview of the first 4,000 characters. Read full instructions →

should-flag-change20.6 KB

View saved version →

---
name: should-flag-change
description: "Decide whether a given code change should be placed behind a LaunchDarkly feature flag. Use when a developer asks whether a change should be behind a flag, when reviewing a diff or pull request, or when running in CI on a PR. Reads the diff and surrounding code, then emits a structured advisory recommendation. Read-only: it never creates or modifies flags."
license: Apache-2.0
compatibility: "Advisory and read-only. Works on all platforms. Does NOT require the LaunchDarkly MCP server. Reads code with standard file tools (Read/Grep/Glob) and returns a structured verdict via the `recommend-flag` tool."
metadata:
  author: launchdarkly
  version: "0.3.0-experimental"
---

# Should This Change Be Behind a Flag?

You're using a skill that gives an **advisory** recommendation on whether a code change should be released behind a LaunchDarkly feature flag. Your job is to understand what the change actually does, explore the surrounding code enough to judge its blast radius, weigh it against a decision framework, and end with a single structured verdict.

You are invoked two ways:

1. **Ad hoc** — a developer asks "should this be behind a flag?" about work in progress.
2. **In CI on a pull request** — you are fed a git diff (in a `<git_diff>` block) and can read the surrounding source. Your verdict is parsed to post a check on the PR.

Both paths end the same way: a call to the `recommend-flag` tool.

## Scope Boundary

This skill is **read-only and advisory**. You produce a recommendation; you never act on it.

**Hard constraints — you MUST NOT:**

- Create, toggle, update, archive, or delete any feature flag.
- Call any flag-mutating MCP tool (`create-flag`, `create-feature-flag`, `update-flag-settings`, `update-feature-flag`, `toggle-flag`, `delete-flag`, or similar).
- Modify, stage, or commit code. You read; you do not write.
- Instruct the user to run a command that mutates flags as if it were part of this workflow.

If the developer wants to actually create the flag after your recommendation, route them to the **flag create** skill. Do not do it yourself.

## Core Principles

1. **Advisory, not authoritative.** You inform a human decision. Be clear and specific; do not gate the merge.
2. **False negatives are worse than false positives.** Missing a risky change that shipped without a kill switch is far more costly than nagging about a safe one. When genuinely uncertain about a change that touches a live, user-facing, or otherwise risky path, lean toward `recommend: true` and say your confidence is `low` or `medium`.
3. **Explore before deciding.** A diff shows *what* lines changed, not *what they mean*. Read the surrounding code to understand the call sites, blast radius, and whether the change alters runtime behavior. In CI you have the repo tree — use it.
4. **Judge behavior, not line count.** A one-line change to an auth check matters more than a 500-line rename. Ask "does this change what production does, and for whom?"
5. **Cite evidence.** Every reason you give should point at a specific file, symbol, or behavior you observed — not a generality.

## Workflow

### Step 1: Understand the change

Read the `<git_diff>` block (or the diff/description the developer provided). Establish:

- **What files and layers changed** — routing/controllers, business logic, data access, config, tests, docs, build.
- **Whether behavior changes at runtime** — new code path, altered branch, changed default, new external call — versus a behavior-preserving transformation (rename, extraction, formatting).
- **Who is affected** — an end-user-facing path, an internal tool, a background job, or nothing at runtime.

### Step 2: Explore the surrounding code

**Discover the repo's flag context first.** Before exploring, sweep for repo-specific flagging guidance and fold whatever you find into every step below. Gather from all of these — context may be split across more than one — using `Glob`/`Grep`/`Read`:

1

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 2 — file references are metadata, not package contents.

snippets5.81 KB

View saved version →

---
name: snippets
description: "Create and manage prompt snippets — reusable text blocks referenced inside config variation prompts. Keeps common instructions, personas, and guardrails consistent across multiple configs."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "0.1.0"
---

# Config Prompt Snippets

You're using a skill that will guide you through creating and managing prompt snippets in LaunchDarkly. Your job is to identify reusable text, create snippets, reference them in config variations, and verify everything is wired correctly.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `create-prompt-snippet` -- create a new reusable text block
- `list-prompt-snippets` -- browse existing snippets in the project
- `get-prompt-snippet` -- inspect a specific snippet's content

**Optional MCP tools:**
- `update-prompt-snippet` -- edit a snippet's text, name, or tags
- `delete-prompt-snippet` -- permanently remove a snippet
- `update-ai-config-variation` -- update variation prompts to reference snippets

## Core Concepts

### What Are Prompt Snippets?

Prompt snippets are named, versioned text blocks stored at the project level. They contain reusable pieces of prompt text — personas, guardrails, output format instructions, domain knowledge — that can be shared across multiple config variations.

When a snippet is updated, a new version is created. Config variations that reference the snippet can pick up the latest version, keeping all your configs in sync.

### When to Use Snippets

| Scenario | Example |
|----------|---------|
| **Shared persona** | "You are a helpful customer support agent for Acme Corp..." used by 5 different configs |
| **Safety guardrails** | "Never reveal internal pricing. Never generate code that accesses production databases." |
| **Output format** | "Always respond in JSON with keys: answer, confidence, sources." |
| **Domain knowledge** | Company-specific terminology, product names, or process descriptions |
| **Regulatory text** | Compliance disclaimers that must appear in every response |

### When NOT to Use Snippets

- Text that is unique to a single variation — just put it in the prompt directly
- Dynamic content that changes per-request — use template variables instead
- Entire prompts — snippets are building blocks, not complete prompts

## Core Principles

1. **Reusability First**: Only create a snippet if the text will be used in 2+ places
2. **Single Responsibility**: Each snippet should cover one concern (persona OR guardrails, not both)
3. **Descriptive Keys**: Use keys like `safety-guardrails`, `json-output-format`, `support-persona`
4. **Tag for Discovery**: Add tags so teammates can find snippets by category
5. **Verify References**: After creating a snippet, confirm it appears in the project

## Workflow

### Step 1: Identify Reusable Text

Before creating snippets, understand what's shared:

1. List existing configs in the project using `get-ai-config` for each
2. Look for repeated text across variation prompts
3. Identify text that should stay consistent (guardrails, personas, formats)
4. Check existing snippets with `list-prompt-snippets` to avoid duplicates

### Step 2: Create Snippets

Use `create-prompt-snippet` with:
- `key` -- unique identifier (lowercase, hyphens, e.g. `safety-guardrails`)
- `name` -- human-readable display name
- `text` -- the reusable prompt text content
- `description` (optional) -- explain when/why to use this snippet
- `tags` (optional) -- categorize for discovery (e.g. `["guardrails", "safety"]`)

```json
{
  "projectKey": "my-project",
  "key": "support-persona",
  "name": "Customer Support Persona",
  "text": "You are a friendly, knowledgeable customer support agent for Acme Corp. Always greet the customer by name when available. Be empathetic but concise. If you don't kn

Preview of the first 4,000 characters. Read full instructions →

tools11.2 KB

View saved version →

---
name: tools
description: "Give your agents capabilities through tools (function calling). Helps you identify what your agent needs to do, create tool definitions, and attach them to config variations."
license: Apache-2.0
compatibility: Requires the remotely hosted LaunchDarkly MCP server
metadata:
  author: launchdarkly
  version: "1.0.0-experimental"
---

# Config Tools

You're using a skill that will guide you through adding capabilities to your agents through tools (function calling). Your job is to identify what your agent needs to do, create tool definitions, attach them to variations, and verify they work.

## Prerequisites

This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment.

**Required MCP tools:**
- `create-ai-tool` -- create a new tool definition with a schema
- `update-ai-config-variation` -- attach tools to a config variation
- `get-ai-config` -- verify tools are attached to the variation

**Optional MCP tools:**
- `list-ai-tools` -- browse existing tools in the project
- `get-ai-tool` -- inspect a specific tool's schema

## Core Principles

1. **Start with Capabilities**: Think about what your agent needs to do before creating tools
2. **Framework Matters**: LangGraph/CrewAI often auto-generate schemas; OpenAI SDK needs manual schemas
3. **Create Before Attach**: Tools must exist before you can attach them to variations
4. **Verify**: The agent fetches the config to confirm attachment
5. **Complete the Full Workflow**: Listing existing tools is a discovery step, not the end goal. After listing, always proceed to create the requested tool, attach it, and verify. Do not stop after exploration.

## Workflow

### Step 1: Identify Needed Capabilities

What should the agent be able to do?
- Query databases, call APIs, perform calculations, send notifications
- Check what exists in the codebase (API clients, functions)
- Consider framework: LangGraph/LangChain auto-generate schemas; direct SDK needs manual schemas

If the user asks to check existing tools first, or you have no codebase context about what tools exist, follow this exact order:
1. `list-ai-tools` -- explore what exists
2. `create-ai-tool` -- create the new tool (with a key different from existing ones)
3. `update-ai-config-variation` -- attach it
4. `get-ai-config` -- verify

Call `list-ai-tools` as your **first** tool call before any creation. Never stop after listing alone -- always proceed through all four steps.

### Step 2: Create Tools

Use `create-ai-tool` with:
- `key` -- unique identifier for the tool
- `description` -- clear description (the LLM uses this to decide when to call the tool)
- `schema` -- raw JSON Schema (do NOT use the OpenAI function calling wrapper):

```json
{
  "type": "object",
  "properties": {
    "query": {"type": "string", "description": "Search query"},
    "limit": {"type": "integer", "default": 10}
  },
  "required": ["query"]
}
```

### Step 3: Attach to Variation

Use `update-ai-config-variation` to attach tools. **Pass only the `tools` field.** Do not bundle `instructions`, `messages`, `model`, or `parameters` into this PATCH unless the user has explicitly asked you to also update those fields. Those fields may have been edited in the LaunchDarkly UI since the variation was created, and including them in a tool-attachment PATCH will silently clobber the UI edits.

```json
{
  "projectKey": "my-project",
  "configKey": "support-chatbot",
  "variationKey": "default",
  "tools": [
    {"key": "search-knowledge-base", "version": 1}
  ]
}
```

If you observe a UI-clear bug where attaching tools wipes other fields, **do not work around it by re-sending those fields from the previous `get-ai-config` response** — that masks the bug and can resurrect stale values that the user has since edited. Report the bug instead.

### Step 4: Verify

1. Use `get-ai-tool` to confirm the tool exists with a valid schema
2. Use `get-ai-config` to confirm the tool is attached to the variati

Preview of the first 4,000 characters. Read full instructions →

Referenced files: 1 — file references are metadata, not package contents.

Package details

Publisher declarations from the archived package. These are separate from our research and the live service's terms.

Package author
Catamorphic Co. dba LaunchDarkly

Package observed Nov 12, 2026.

Technical details
First seen
Sep 30, 2026 · 22:02 UTC
Last seen
Nov 13, 2026 · 12:00 UTC
Collection status
Collected

plugin_asdk_app_6a563d3bd288819196199d33db4cfc55

Download plugin data (JSON)

Plugin details: freshly prepared. Prepared . Refreshed when plugin data changes or after 6 hours. Your account and Follow status are live.