LaunchDarkly Feature Flags
Sanctiv uses LaunchDarkly for feature flag management. This provides:- Instant toggling - Enable/disable features without deployment
- Gradual rollouts - Release to percentage of users
- User targeting - Target by org, user, or custom attributes
- A/B testing - Test different feature variants
Architecture
MCP Server Setup (For AI Agents)
CRITICAL: This section is for AI agents (Cursor, Claude Code) to manage flags programmatically.
Credential Types (Don’t Confuse These!)
| Credential | Prefix | Purpose | Where to Find |
|---|---|---|---|
| API Access Token | api-xxx | MCP Server, REST API | Account Settings → Authorization |
| Mobile Key | mob-xxx | Client SDK initialization | Project Settings |
| SDK Key | sdk-xxx | Server SDK initialization | Project Settings |
1. Get API Access Token
- Go to LaunchDarkly Dashboard
- Navigate to Account Settings (gear icon, top right)
- Go to Authorization → Access Tokens
- Click Create Token
- Name:
cursor-mcp(or similar) - Role: Writer (to create/update flags)
- Copy the token (starts with
api-)
2. Configure MCP Server
Add to~/.cursor/mcp.json:
3. Verify Connectivity
After reloading Cursor, test with MCP tools:4. Common MCP Errors
| Error | Cause | Solution |
|---|---|---|
| ”fetch failed” | Network/auth issue | Check API token is valid |
| ”Invalid account ID header” | Wrong credential type | Use API Access Token, not account ID |
| ”Tool not found” | MCP not loaded | Reload Cursor, check mcp.json syntax |
| Rate limit exceeded | Too many API calls | Wait 60 seconds, retry |
5. MCP Tools Available
| Tool | Purpose |
|---|---|
list-feature-flags | List all flags in project |
get-feature-flag | Get flag details |
create-feature-flag | Create new flag |
update-feature-flag | Update flag config/targeting |
delete-feature-flag | Remove flag |
get-environments | List environments |
SDK Setup (For App Development)
1. Environment Variables
Add to.env:
2. Get Your Mobile Key
- Go to LaunchDarkly Dashboard
- Navigate to Account Settings → Projects
- Select your project
- Copy the Mobile Key (NOT the SDK key)
Usage
FeatureGate Component (Recommended)
TheFeatureGate component provides declarative feature flag gating with a “Coming Soon” placeholder:
Basic Boolean Flag
Multivariate Flag (A/B Testing UI Variations)
Multivariate flags return string values, enabling A/B testing of different UI approaches.Example: Journal Prompt Style Experiment
We have ajournal-prompt-style flag with three variations:
traditional: “What are you grateful for today?”conversational: “Hey! What’s been on your heart lately?”scripture-led: “Reflect on Philippians 4:8…”
Measuring Experiment Success
Track completion rates for each variant:Available Multivariate Flags
| Flag Key | Variations | Purpose |
|---|---|---|
journal-prompt-style | traditional, conversational, scripture-led | Test prompt effectiveness |
Outside React Components
Event Tracking Strategy
LaunchDarkly event tracking enables analytics, experimentation, and conversion tracking.Standard Events
Use theLD_EVENTS constants for consistent event naming:
Available Event Constants
| Category | Events |
|---|---|
| Journal | JOURNAL_STARTED, JOURNAL_COMPLETED, JOURNAL_ABANDONED, JOURNAL_EDITED, JOURNAL_SEARCHED |
| Voice | VOICE_RECORDING_STARTED, VOICE_RECORDING_COMPLETED, VOICE_TRANSCRIPTION_COMPLETED, LOCAL_TRANSCRIPTION_USED |
| AI | AI_SUMMARY_GENERATED, AI_GENERATION_TIME, AI_IMAGE_GENERATED, FOLLOWUP_PROMPT_SHOWN |
| Library | TRUTH_SAVED, TRUTH_VIEWED, TRUTH_SHARED, TRUTH_REMINDER_SET |
| Habits | HABIT_CREATED, HABIT_COMPLETED, HABIT_SKIPPED, HABIT_STREAK_ACHIEVED |
| Companion | COMPANION_INVITED, COMPANION_CONNECTED, COMPANION_CHAT_SENT |
| Conversion | ONBOARDING_COMPLETED, FIRST_JOURNAL_COMPLETED, WEEKLY_ACTIVE |
When to Track Events
- Feature Usage: Track when users interact with flagged features
- A/B Test Metrics: Track outcomes to measure experiment success (Pro plan)
- Conversion Funnel: Track key milestones for product analytics
- Error Monitoring: Track feature failures for reliability insights
Event Tracking Best Practices
Available Flags
Complete Reference: See FEATURE_FLAGS.md for comprehensive feature flag documentation including taxonomy, user flows, and best practices.
Core Tab Flags
| Flag Key | Type | Description |
|---|---|---|
insights-enabled | Boolean | Insights tab with analytics |
habits-enabled | Boolean | Habit tracking feature |
truth-library-enabled | Boolean | Scripture & devotional content |
companion-sharing-enabled | Boolean | Companion connections |
Journaling Flags
| Flag Key | Type | Description |
|---|---|---|
voice-journaling-enabled | Boolean | Voice-to-text journaling |
local-transcription-enabled | Boolean | On-device Whisper transcription |
journal-editing-enabled | Boolean | Edit existing journal entries |
journal-search-enabled | Boolean | Search journal entries |
followup-prompts | Boolean | AI-generated follow-up questions |
AI Flags
| Flag Key | Type | Description |
|---|---|---|
ai-summary-enabled | Boolean | AI summary generation |
ai-summary-v2 | Boolean | New AI summary model (experiment) |
ai-image-generation | Boolean | Grok-powered image generation |
ai-scripture-suggestions-enabled | Boolean | AI scripture suggestions |
emotion-detection-enabled | Boolean | AI emotion detection |
truth-generation-enabled | Boolean | AI truth generation from journals |
Notification Flags
| Flag Key | Type | Description |
|---|---|---|
push-notifications | Boolean | Push notification delivery |
followup-notifications-enabled | Boolean | Follow-up notification scheduling |
truth-reminders-enabled | Boolean | Daily truth reminders |
habit-reminders-enabled | Boolean | Habit reminder notifications |
Social Flags
| Flag Key | Type | Description |
|---|---|---|
companion-chat | Boolean | Real-time chat between companions |
Admin Flags
| Flag Key | Type | Description |
|---|---|---|
admin-panel-enabled | Boolean | Admin panel access |
impersonation-enabled | Boolean | User impersonation |
debug-mode | Boolean | Debug panel visibility |
beta-features-enabled | Boolean | Opt-in beta features |
Analytics Flags
| Flag Key | Type | Description |
|---|---|---|
mood-trends-enabled | Boolean | Mood trends visualization |
journal-streaks-enabled | Boolean | Journal streak tracking |
habit-streaks-enabled | Boolean | Habit streak tracking |
User Targeting
LaunchDarkly identifies users for sophisticated targeting. The more attributes you provide, the more powerful your targeting becomes.Basic Identification (On Login)
Rich Identification (Elite Targeting)
Reset on Logout
Segments (Reusable User Groups)
LaunchDarkly Segments are reusable user groups that can be targeted across multiple flags. Instead of duplicating rules on every flag, create segments once and reference them.Recommended Segments
Create these segments in LaunchDarkly Dashboard → Segments:| Segment Key | Name | Rule | Purpose |
|---|---|---|---|
beta-testers | Beta Testers | is_beta_tester = true | Users in beta program |
pilot-churches | Pilot Churches | org_id in [uuid1, uuid2, ...] | Initial pilot partners |
internal-team | Internal Team | email ends with @sanctiv.ai | Team members |
Creating a Segment
- Go to Segments → Create Segment
- Configure:
- Name:
Beta Testers - Key:
beta-testers - Description:
Users who have opted into the beta program
- Name:
- Add Rule:
- Attribute:
is_beta_tester - Operator:
is one of - Values:
true
- Attribute:
- Click Save Segment
Using Segments in Flag Targeting
In Dashboard:- Open any feature flag
- Add targeting rule: “User is in segment”
- Select
beta-testers - Set variation:
true
beta-testers segment, they automatically get access to ALL flags that target that segment.
Segment vs Direct Attribute Targeting
| Approach | Pros | Cons |
|---|---|---|
| Segment | Reusable, centralized management | Requires dashboard setup |
| Direct Attribute | Quick, no setup needed | Duplicated rules across flags |
Elite Targeting Patterns
1. Church-by-Church Pilot Rollout
Roll out Voice Journaling to pilot churches one at a time: LaunchDarkly Dashboard Setup:- Open flag
voice-journaling-enabled - Add targeting rule:
- If
org_idis one of["church-a-uuid", "church-b-uuid"]→ true - Default → false
- If
2. Percentage-Based Gradual Rollout
Release AI Summary V2 to 10% of users, then gradually increase: LaunchDarkly Dashboard Setup:- Open flag
ai-summary-v2 - Set fallthrough to percentage rollout:
- Day 1: 10%
- Day 3: 25%
- Day 7: 50%
- Day 14: 100%
3. Beta Tester Program
Let specific users opt-in to beta features: LaunchDarkly Dashboard Setup:- Open flag
beta-features-enabled - Add targeting rule:
- If
is_beta_tester= true → true - Default → false
- If
4. Role-Based Feature Access
Enable Admin Panel only for admins and pastors: LaunchDarkly Dashboard Setup:- Open flag
admin-panel-enabled - Add targeting rules:
- If
role= admin → true - If
is_pastor= true → true - Default → false
- If
5. Device-Specific Rollouts
Roll out to iOS first, then Android: LaunchDarkly Dashboard Setup:- Open flag
voice-journaling-enabled - Add targeting rules:
- If
platform= ios → true - If
platform= android → false (then enable later)
- If
6. Emergency Kill Switch
Instantly disable AI features if costs spike: LaunchDarkly Dashboard:- Toggle
ai-summary-enabledto OFF - All AI summaries stop immediately across all users
Creating New Flags
1. Add to FEATURE_FLAGS Constant
2. Create in LaunchDarkly
Option A: Via MCP (Agents)- Go to Feature Flags → Create Flag
- Name:
my-new-feature - Kind: Boolean (or Multivariate)
- Default: Off
- Save
3. Enable the Flag
Option A: Via MCP (Agents)- Open flag
- Toggle ON for desired environments
- Save
4. Wire Up in Code
Best Practices
1. Define Flags in FEATURE_FLAGS Constant
2. Use FeatureGate for Screens
3. Track Events for Observability
4. Handle Loading States
Troubleshooting
Flags Return Default Values Initially (UI Flash)
Symptom: Components briefly render with default flag values before switching to actual values, causing a “Coming Soon” flash. Cause: LaunchDarkly SDK initializes asynchronously. Until initialization completes, flags return default values. Solutions:- Use
FeatureGatecomponent for screens - It automatically shows a loading state:
- Check
isReadyfromuseFeatureFlags()hook before rendering:
- For small UI elements, consider deferring render until ready:
Flags Always Return Default
- Check
EXPO_PUBLIC_LAUNCHDARKLY_MOBILE_KEYis set - Verify it’s a Mobile Key (starts with
mob-) - Check LaunchDarkly dashboard for flag status
- Verify flag is enabled in the correct environment
- Check console for dev warning:
[FeatureFlags] Flag "xxx" returned default value
Flag Changes Not Reflected
- LaunchDarkly streams updates in real-time
- Kill and restart the app if using dev client
- Check network connectivity
- Clear Metro cache:
npx expo start --clear
User Targeting Not Working
- Verify
identifyLDUser()is called after login - Check user attributes match targeting rules
- Verify flag is enabled in dashboard
MCP Not Working (Agents)
- Verify API Access Token (not mobile key or account ID)
- Token should start with
api- - Reload Cursor after changing mcp.json
- Check mcp.json syntax is valid JSON
- Try running MCP server manually to see errors
Related Documentation
- Intercom Setup - Analytics and support
- Feature Inventory - All features and flags
- CI/CD Architecture - Deployment pipeline