Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
launchdarkly avatar

Configs Targeting

  • 1.6k installs
  • 23 repo stars
  • Updated August 5, 2026
  • launchdarkly/agent-skills

configs-targeting is a LaunchDarkly agent skill that lets coding agents dynamically read, create, and update LaunchDarkly feature flag configurations and targeting rules from natural language inside the chat interface.

About

configs-targeting is a LaunchDarkly agent-skills package entry with 681 installs on skills.sh that enables coding agents to manage feature flag targeting configurations through conversational prompts. It covers reading existing flag targeting rules, creating new audience segments, and updating rollout conditions without switching to the LaunchDarkly dashboard. Developers reach for configs-targeting when rolling out features to percentage rollouts, user segments, or environment-specific audiences and want the agent to apply LaunchDarkly API changes directly. The skill fits teams using LaunchDarkly for progressive delivery who want flag targeting edits co-located with code changes in Claude Code, Cursor, or similar agent environments.

  • Directly reads and writes LaunchDarkly configs and targeting rules from within Claude or Cursor
  • Enables agents to implement runtime feature toggles and audience segmentation
  • Supports conditional logic for user cohorts and percentage rollouts
  • Reduces context switching between code and LaunchDarkly dashboard
  • Maintains flag state as code-adjacent artifacts

Configs Targeting by the numbers

  • 1,595 all-time installs (skills.sh)
  • +9 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #771 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/launchdarkly/agent-skills --skill configs-targeting

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1.6k
repo stars23
Last updatedAugust 5, 2026
Repositorylaunchdarkly/agent-skills

How do you manage LaunchDarkly flag targeting from an agent?

Let their coding agent dynamically read, create, and update LaunchDarkly feature flag configurations and targeting rules without leaving the chat interface.

Who is it for?

Developers using LaunchDarkly who want agents to configure flag targeting without leaving the IDE chat.

Skip if: Teams without LaunchDarkly or projects managing feature flags only through dashboard clicks with no agent integration.

When should I use this skill?

A feature flag needs new audience targeting, segment rules, or rollout percentage changes in LaunchDarkly.

What you get

Updated LaunchDarkly flag targeting rules, segment definitions, and rollout conditions applied via API.

  • Updated flag targeting rules
  • Audience segment configurations

By the numbers

  • 681 installs on skills.sh
  • Rank 7459 on skills.sh catalog

Files

SKILL.mdMarkdownGitHub ↗

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)

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.
# 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:

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:

curl -X PATCH "..." \
  -d '{
    "environmentKey": "production",
    "instructions": [{
      "kind": "addRule",
      "clauses": [{
        "contextKind": "user",
        "attribute": "tier",
        "op": "in",
        "values": ["premium"],
        "negate": false
      }],
      "percentageRolloutConfig": {
        "contextKind": "user",
        "bucketBy": "key",
        "variations": [
          {"variation": 0, "weight": 60000},
          {"variation": 1, "weight": 40000}
        ]
      }
    }]
  }'

Set fallthrough (default rule):

curl -X PATCH "..." \
  -d '{
    "environmentKey": "production",
    "instructions": [{
      "kind": "updateFallthroughVariationOrRollout",
      "variationId": "fallback-variation-uuid"
    }]
  }'

Python Implementation

import requests
import os
from typing import Dict, List, Optional

class AIConfigTargeting:
    """Manager for config targeting rules"""

    def __init__(self, api_token: str, project_key: str):
        self.api_token = api_token
        self.project_key = project_key
        self.base_url = "https://app.launchdarkly.com/api/v2"

    def get_targeting(self, config_key: str) -> Optional[Dict]:
        """Get current targeting with variation IDs."""
        url = f"{self.base_url}/projects/{self.project_key}/ai-configs/{config_key}/targeting"

        response = requests.get(url, headers={
            "Authorization": self.api_token,
            "LD-API-Version": "beta"
        })

        if response.status_code == 200:
            return response.json()
        print(f"[ERROR] {response.status_code}: {response.text}")
        return None

    def get_variation_id(self, config_key: str, variation_key: str) -> Optional[str]:
        """Look up variation UUID from key or name."""
        targeting = self.get_targeting(config_key)
        if targeting:
            for var in targeting.get("variations", []):
                if var.get("key") == variation_key or var.get("name") == variation_key:
                    return var.get("_id")
        return None

    def update_targeting(self, config_key: str, environment: str,
                         instructions: List[Dict], comment: str = "") -> Optional[Dict]:
        """Send semantic patch instructions."""
        url = f"{self.base_url}/projects/{self.project_key}/ai-configs/{config_key}/targeting"

        payload = {"environmentKey": environment, "instructions": instructions}
        if comment:
            payload["comment"] = comment

        response = requests.patch(url, headers={
            "Authorization": self.api_token,
            "Content-Type": "application/json; domain-model=launchdarkly.semanticpatch",
            "LD-API-Version": "beta"
        }, json=payload)

        if response.status_code == 200:
            return response.json()
        print(f"[ERROR] {response.status_code}: {response.text}")
        return None

    def enable_config(self, config_key: str, environment: str,
                      variation_key: str = "default") -> bool:
        """
        Enable a config by setting fallthrough to an enabled variation.

        Note: turnTargetingOn doesn't work for configs. Instead, set the
        fallthrough from the disabled variation (index 0) to an enabled one.
        """
        variation_id = self.get_variation_id(config_key, variation_key)
        if not variation_id:
            print(f"[ERROR] Variation '{variation_key}' not found")
            return False
        return self.set_fallthrough(config_key, environment, variation_id)

    def add_rule(self, config_key: str, environment: str,
                 clauses: List[Dict], variation: int,
                 description: str = "") -> bool:
        """Add targeting rule serving a specific variation index."""
        instruction = {
            "kind": "addRule",
            "clauses": clauses,
            "variation": variation
        }
        if description:
            instruction["description"] = description

        result = self.update_targeting(config_key, environment,
            [instruction], f"Add rule: {description}")
        if result:
            print(f"[OK] Rule added")
            return True
        return False

    def add_rollout_rule(self, config_key: str, environment: str,
                         clauses: List[Dict],
                         weights: List[Dict],
                         bucket_by: str = "key") -> bool:
        """
        Add percentage rollout rule.

        weights: [{"variation": 0, "weight": 50000}, {"variation": 1, "weight": 50000}]
        """
        result = self.update_targeting(config_key, environment, [{
            "kind": "addRule",
            "clauses": clauses,
            "percentageRolloutConfig": {
                "contextKind": "user",
                "bucketBy": bucket_by,
                "variations": weights
            }
        }], "Add percentage rollout")
        if result:
            print(f"[OK] Rollout rule added")
            return True
        return False

    def set_fallthrough(self, config_key: str, environment: str,
                        variation_id: str) -> bool:
        """Set default (fallthrough) variation by UUID."""
        result = self.update_targeting(config_key, environment, [{
            "kind": "updateFallthroughVariationOrRollout",
            "variationId": variation_id
        }], "Set fallthrough")
        if result:
            print(f"[OK] Fallthrough set")
            return True
        return False

    def target_individuals(self, config_key: str, environment: str,
                          context_keys: List[str], variation: int,
                          context_kind: str = "user") -> bool:
        """Target specific context keys."""
        result = self.update_targeting(config_key, environment, [{
            "kind": "addTargets",
            "variation": variation,
            "contextKind": context_kind,
            "values": context_keys
        }], f"Target {len(context_keys)} individuals")
        if result:
            print(f"[OK] Individual targets added")
            return True
        return False

    def target_segment(self, config_key: str, environment: str,
                      segment_keys: List[str], variation: int) -> bool:
        """Target a segment."""
        result = self.update_targeting(config_key, environment, [{
            "kind": "addRule",
            "clauses": [{
                "attribute": "segmentMatch",
                "contextKind": "",  # Leave blank for segments
                "op": "segmentMatch",
                "values": segment_keys,
                "negate": False
            }],
            "variation": variation
        }], f"Target segments: {segment_keys}")
        if result:
            print(f"[OK] Segment targeting added")
            return True
        return False

    def clear_rules(self, config_key: str, environment: str) -> bool:
        """Remove all targeting rules."""
        result = self.update_targeting(config_key, environment,
            [{"kind": "replaceRules", "rules": []}], "Clear all rules")
        if result:
            print(f"[OK] All rules cleared")
            return True
        return False

Instruction Reference

Note: turnTargetingOn and turnTargetingOff do not work for configs. Configs have targeting enabled by default. To "enable" a config, set the fallthrough to an enabled variation using updateFallthroughVariationOrRollout.

Rules

KindDescription
addRuleAdd rule with clauses and variation/rollout
removeRuleRemove by ruleId
replaceRulesReplace all rules
reorderRulesChange evaluation order
updateRuleVariationOrRolloutUpdate what a rule serves

Fallthrough

KindDescription
updateFallthroughVariationOrRolloutSet default variation or rollout

Individual Targets

KindDescription
addTargetsTarget specific context keys
removeTargetsRemove specific targets
replaceTargetsReplace all targets

Operators Reference

OperatorDescriptionExample
inValue in list["premium", "enterprise"]
containsString contains["sonnet"]
startsWithString prefix["user-"]
endsWithString suffix[".edu"]
matchesRegex match["^user-\\d+$"]
greaterThan / lessThanNumeric comparison[100]
before / afterDate comparison["2024-12-31T00:00:00Z"]
semVerEqual / semVerGreaterThanVersion comparison["2.0.0"]
segmentMatchSegment membership["beta-testers"]

Clause Structure

{
  "contextKind": "user",
  "attribute": "email",
  "op": "endsWith",
  "values": [".edu"],
  "negate": false
}
  • Multiple clauses = AND (all must match)
  • Multiple values = OR (any can match)
  • negate: true inverts the operator

Rollout Types

Manual Percentage Rollout

{
  "percentageRolloutConfig": {
    "contextKind": "user",
    "bucketBy": "key",
    "variations": [
      {"variation": 0, "weight": 50000},
      {"variation": 1, "weight": 50000}
    ]
  }
}

Progressive Rollout

{
  "progressiveRolloutConfig": {
    "contextKind": "user",
    "controlVariation": 1,
    "endVariation": 0,
    "steps": [
      {"rolloutWeight": 1000, "duration": {"quantity": 4, "unit": "hour"}},
      {"rolloutWeight": 5000, "duration": {"quantity": 4, "unit": "hour"}},
      {"rolloutWeight": 10000, "duration": {"quantity": 4, "unit": "hour"}}
    ]
  }
}

Guarded Rollout

{
  "guardedRolloutConfig": {
    "randomizationUnit": "user",
    "stages": [
      {"rolloutWeight": 1000, "monitoringWindowMilliseconds": 17280000},
      {"rolloutWeight": 5000, "monitoringWindowMilliseconds": 17280000}
    ],
    "metrics": [{
      "metricKey": "error-rate",
      "onRegression": {"rollback": true},
      "regressionThreshold": 0.01
    }]
  }
}

Common Patterns

Model Routing by Attribute

# Route based on selectedModel context attribute
targeting.add_rule(
    config_key="model-selector",
    environment="production",
    clauses=[{
        "contextKind": "user",
        "attribute": "selectedModel",
        "op": "contains",
        "values": ["sonnet"],
        "negate": False
    }],
    variation=0,  # Sonnet variation index
    description="Route sonnet requests"
)

Tier-Based Variation

targeting.add_rule(
    config_key="chat-assistant",
    environment="production",
    clauses=[{
        "contextKind": "user",
        "attribute": "tier",
        "op": "in",
        "values": ["premium", "enterprise"],
        "negate": False
    }],
    variation=0  # Premium model variation
)

Segment Targeting

targeting.target_segment(
    config_key="chat-assistant",
    environment="production",
    segment_keys=["beta-testers"],
    variation=1  # Experimental variation
)

Error Handling

StatusCauseSolution
400Invalid semantic patchCheck instruction format, ops must be lowercase
403Insufficient permissionsCheck API token
404Config not foundVerify projectKey and configKey
422Invalid variationUse index (0, 1, 2...) or UUID from targeting response

Next Steps

After configuring targeting: 1. Provide config URL:

   https://app.launchdarkly.com/projects/{projectKey}/ai-configs/{configKey}

2. Monitor performance with built-in-metrics 3. Attach judges with online-evals 4. Set up guarded rollouts for automatic regression detection

Related Skills

  • configs-create - Create configs with variations
  • configs-variations - Manage variations
  • online-evals - Attach judges
  • segments - Create segments for targeting

References

Related skills

How it compares

Pick configs-targeting over configs-variations when the task is audience segments and rollout rules rather than flag value variations.

FAQ

What can configs-targeting do in LaunchDarkly?

configs-targeting lets coding agents read, create, and update LaunchDarkly feature flag targeting rules and audience segments from natural language prompts, avoiding context switches to the LaunchDarkly dashboard.

How popular is the configs-targeting skill?

configs-targeting from launchdarkly/agent-skills has 681 installs on skills.sh, ranking it among actively used LaunchDarkly agent integration skills for flag targeting management.

AI & Agent Buildingagentsautomation

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.