LaunchDarkly Projects for AI Configs
Create and manage projects to organize your AI Configs. Projects are the top-level containers in LaunchDarkly.
Prerequisites
- LaunchDarkly API access token with
projects:writepermission - Python 3.8+
API Key Detection
Before prompting the user for an API key, try to detect it automatically:
- Check Claude MCP config - Read
~/.claude/config.jsonand look formcpServers.launchdarkly.env.LAUNCHDARKLY_API_KEY - Check environment variables - Look for
LAUNCHDARKLY_API_KEY,LAUNCHDARKLY_API_TOKEN, orLD_API_KEY - Prompt user - Only if detection fails, ask the user for their API key
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
What Are Projects?
Projects are containers that hold:
- All your AI Configs
- Feature flags and segments
- Multiple environments (Production and Test are created by default)
Think of projects as separate applications or services that need their own set of AI Configs.
Quick Start
import requests
import os
API_TOKEN = os.environ.get("LAUNCHDARKLY_API_TOKEN")
BASE_URL = "https://app.launchdarkly.com/api/v2"
def create_project(name: str, key: str):
"""
Create a new LaunchDarkly project for your AI Configs.
Args:
name: Human-readable project name (e.g., "Customer Support AI")
key: Unique identifier, lowercase with hyphens (e.g., "support-ai")
Returns:
Created project with SDK keys, or existing project if already exists
"""
url = f"{BASE_URL}/projects"
headers = {
"Authorization": API_TOKEN,
"Content-Type": "application/json"
}
payload = {
"name": name,
"key": key,
"tags": ["ai-configs"]
}
response = requests.post(url, headers=headers, json=payload)
if response.status_code == 201:
project = response.json()
print(f"[OK] Project '{name}' created successfully!")
_print_sdk_keys(project)
return project
elif response.status_code == 409:
print(f"[INFO] Project '{key}' already exists")
return get_project(key)
else:
print(f"[ERROR] Failed to create project: {response.text}")
return None
def get_project(project_key: str):
"""Get an existing project with its SDK keys."""
url = f"{BASE_URL}/projects/{project_key}"
headers = {"Authorization": API_TOKEN}
params = {"expand": "environments"}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
project = response.json()
print(f"[PROJECT] {project['name']} ({project['key']})")
_print_sdk_keys(project)
return project
else:
print(f"[ERROR] Project not found")
return None
def _get_environments(project: dict) -> list:
"""Extract environments list from project (handles both API formats)."""
envs = project.get("environments", {})
if isinstance(envs, dict):
return envs.get("items", [])
return envs
def _print_sdk_keys(project: dict):
"""Print SDK keys for all environments."""
for env in _get_environments(project):
print(f"\n{env['name']} Environment:")
print(f" SDK Key: {env['apiKey']}")
def get_sdk_key(project_key: str, environment: str = "production") -> str:
"""
Get the SDK key for a specific environment.
Args:
project_key: The project key
environment: Environment name (default: "production")
Returns:
The SDK key string, or None if not found
"""
url = f"{BASE_URL}/projects/{project_key}"
headers = {"Authorization": API_TOKEN}
params = {"expand": "environments"}
response = requests.get(url, headers=headers, params=params)
if response.status_code != 200:
print(f"[ERROR] Project not found")
return None
project = response.json()
for env in _get_environments(project):
if env["key"] == environment:
return env["apiKey"]
print(f"[ERROR] Environment '{environment}' not found")
return None
def list_projects():
"""List all projects in your organization."""
url = f"{BASE_URL}/projects"
headers = {"Authorization": API_TOKEN}
response = requests.get(url, headers=headers)
if response.status_code == 200:
projects = response.json().get("items", [])
print(f"[PROJECTS] Found {len(projects)} projects:\n")
for project in projects:
print(f" - {project['name']} ({project['key']})")
tags = ', '.join(project.get('tags', [])) or 'none'
print(f" Tags: {tags}")
return projects
else:
print(f"[ERROR] Failed to list projects")
return []
def delete_project(project_key: str):
"""
Delete a project. Warning: This deletes all configs, flags, and segments in the project.
Args:
project_key: The project key to delete
Returns:
True if deleted, False otherwise
"""
url = f"{BASE_URL}/projects/{project_key}"
headers = {"Authorization": API_TOKEN}
response = requests.delete(url, headers=headers)
if response.status_code == 204:
print(f"[OK] Deleted project: {project_key}")
return True
elif response.status_code == 404:
print(f"[INFO] Project '{project_key}' does not exist")
return False
else:
print(f"[ERROR] Failed to delete project: {response.text}")
return False
# Example usage
project = create_project(
name="Customer Support AI",
key="support-ai"
)
# Get SDK key for your application
sdk_key = get_sdk_key("support-ai", "production")
print(f"\n[SDK] Use this SDK key in your application: {sdk_key}")
Save SDK Key to .env File
Automatically save your SDK key to a .env file for use in your application:
def save_sdk_key_to_env(
project_key: str,
environment: str = "production",
env_file: str = ".env",
var_name: str = "LAUNCHDARKLY_SDK_KEY"
):
"""
Extract SDK key from project and save to .env file.
Args:
project_key: The project key
environment: Environment to get key for (default: "production")
env_file: Path to .env file (default: ".env")
var_name: Environment variable name (default: "LAUNCHDARKLY_SDK_KEY")
"""
sdk_key = get_sdk_key(project_key, environment)
if not sdk_key:
print(f"[ERROR] Could not get SDK key for {project_key}/{environment}")
return False
# Read existing .env content
env_content = {}
try:
with open(env_file, "r") as f:
for line in f:
line = line.strip()
if line and not line.startswith("#") and "=" in line:
key, value = line.split("=", 1)
env_content[key] = value
except FileNotFoundError:
pass # File doesn't exist yet
# Update or add the SDK key
env_content[var_name] = sdk_key
# Write back to .env
with open(env_file, "w") as f:
for key, value in env_content.items():
f.write(f"{key}={value}\n")
print(f"[OK] Saved SDK key to {env_file}")
print(f" {var_name}={sdk_key[:10]}...{sdk_key[-4:]}")
return True
# Example: Save production SDK key
save_sdk_key_to_env("support-ai", "production")
# Example: Save test environment key with custom variable name
save_sdk_key_to_env("support-ai", "test", var_name="LAUNCHDARKLY_SDK_KEY_TEST")
Clone a Project
When you need to create a similar project (e.g., for a different region or team):
def clone_project(source_key: str, new_name: str, new_key: str):
"""
Clone an existing project's structure to create a new one.
Args:
source_key: The project to copy from
new_name: Name for the new project
new_key: Unique key for the new project
Returns:
The newly created project
"""
headers = {
"Authorization": API_TOKEN,
"Content-Type": "application/json"
}
# Get the source project
source_resp = requests.get(f"{BASE_URL}/projects/{source_key}", headers=headers)
if source_resp.status_code != 200:
print(f"[ERROR] Source project '{source_key}' not found")
return None
source = source_resp.json()
# Create new project with same settings
payload = {
"name": new_name,
"key": new_key,
"tags": source.get("tags", []) + ["cloned"],
"includeInSnippetByDefault": source.get("includeInSnippetByDefault", True)
}
response = requests.post(f"{BASE_URL}/projects", headers=headers, json=payload)
if response.status_code == 201:
project = response.json()
print(f"[OK] Cloned '{source_key}' -> '{new_key}'")
_print_sdk_keys(project)
return project
else:
print(f"[ERROR] Failed to clone: {response.text}")
return None
# Example: Create a regional variant
# clone_project(
# source_key="support-ai",
# new_name="Customer Support AI - Europe",
# new_key="support-ai-eu"
# )
Project Keys Best Practice
Project keys must be:
- Lowercase letters, numbers, and hyphens only
- Start with a letter
- Unique across your organization
# Good examples:
"support-ai"
"chat-bot-v2"
"internal-tools"
# Bad examples:
"Support_AI" # No uppercase or underscores
"123-project" # Must start with letter
"my.project" # No dots allowed
Common Patterns
Projects by Team
create_project("Platform AI", "platform-ai")
create_project("Customer AI", "customer-ai")
create_project("Internal Tools AI", "internal-ai")
Projects by Application
create_project("Mobile App AI", "mobile-ai")
create_project("Web App AI", "web-ai")
create_project("API Services AI", "api-ai")
Projects by Region
create_project("AI Services - US", "ai-us")
clone_project("ai-us", "AI Services - EU", "ai-eu")
clone_project("ai-us", "AI Services - APAC", "ai-apac")
Next Steps
After creating a project:
- Save your SDK keys - You'll need them to connect your application
- Create AI Configs - Use the
aiconfig-createskill - Set up targeting - Use the
aiconfig-targetingskill
Related Skills
aiconfig-create- Create AI Configs in projectsaiconfig-api- API patterns and authenticationaiconfig-sdk- Use project configs in codeaiconfig-variations- Manage config variationsaiconfig-segments- Create user segments