| name | aiconfig-projects |
| description | Create LaunchDarkly projects to organize your AI Configs. Projects are containers that hold AI Configs, feature flags, and segments. |
| compatibility | Requires LaunchDarkly API access token with projects:write permission. |
| metadata | {"author":"launchdarkly","version":"0.3.0"} |
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:write permission
- 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.json and look for mcpServers.launchdarkly.env.LAUNCHDARKLY_API_KEY
- Check environment variables - Look for
LAUNCHDARKLY_API_KEY, LAUNCHDARKLY_API_TOKEN, or LD_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."""
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
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
project = create_project(
name="Customer Support AI",
key="support-ai"
)
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
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
env_content[var_name] = sdk_key
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
save_sdk_key_to_env("support-ai", "production")
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"
}
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()
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
Project Keys Best Practice
Project keys must be:
- Lowercase letters, numbers, and hyphens only
- Start with a letter
- Unique across your organization
"support-ai"
"chat-bot-v2"
"internal-tools"
"Support_AI"
"123-project"
"my.project"
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-create skill
- Set up targeting - Use the
aiconfig-targeting skill
Related Skills
aiconfig-create - Create AI Configs in projects
aiconfig-api - API patterns and authentication
aiconfig-sdk - Use project configs in code
aiconfig-variations - Manage config variations
aiconfig-segments - Create user segments
References