$npx -y skills add launchdarkly/ai-tooling --skill launchdarkly-metric-instrumentInstrument 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.
| 1 | # LaunchDarkly Metric Instrument |
| 2 | |
| 3 | 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. |
| 4 | |
| 5 | ## Prerequisites |
| 6 | |
| 7 | This skill requires the remotely hosted LaunchDarkly MCP server to be configured in your environment. |
| 8 | |
| 9 | **Required MCP tools:** |
| 10 | - `list-metric-events` — verify events are flowing after instrumentation |
| 11 | |
| 12 | **Optional MCP tools (enhance workflow):** |
| 13 | - `get-project` — retrieve the SDK key for the right environment when SDK initialization is needed |
| 14 | |
| 15 | ## Workflow |
| 16 | |
| 17 | ### Step 1: Detect the SDK |
| 18 | |
| 19 | Before writing any code, understand the LaunchDarkly setup already in this codebase. |
| 20 | |
| 21 | 1. **Search for existing `track()` calls.** This is the fastest signal: |
| 22 | - Look for `ldClient.track(`, `.track(`, `ld.track(` |
| 23 | - If any exist, they tell you the SDK type, call signature, and context pattern in one shot — mirror those exactly. |
| 24 | |
| 25 | 2. **Search for SDK imports and initialization** if no `track()` calls exist: |
| 26 | - Check `package.json`, `requirements.txt`, `go.mod`, `Gemfile`, `*.csproj` for an LD SDK dependency |
| 27 | - Look for `LDClient`, `ldclient`, `launchdarkly-server-sdk`, `launchdarkly-node-server-sdk`, `launchdarkly-react-client-sdk`, etc. |
| 28 | - Find the initialization block to understand how the client is accessed across the codebase |
| 29 | |
| 30 | 3. **Determine client-side or server-side.** This is the most critical distinction — it determines the `track()` signature: |
| 31 | |
| 32 | | SDK type | `track()` signature | Notes | |
| 33 | |----------|---------------------|-------| |
| 34 | | Server-side (Node, Python, Go, Java, Ruby, .NET) | `ldClient.track(eventKey, context, data?, metricValue?)` | Context required per call | |
| 35 | | Client-side (React, browser JS) | `ldClient.track(eventKey, data?, metricValue?)` | Context set at init, not per call | |
| 36 | |
| 37 | See [SDK Track Patterns](references/sdk-track-patterns.md) for full examples by language. |
| 38 | |
| 39 | ### Step 2: Install & Initialize (if SDK not present) |
| 40 | |
| 41 | Skip this step if the SDK is already in the codebase. |
| 42 | |
| 43 | 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. |
| 44 | |
| 45 | 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. |
| 46 | |
| 47 | 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). |
| 48 | |
| 49 | 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. |
| 50 | |
| 51 | ### Step 3: Find the Right Placement |
| 52 | |
| 53 | Locate where in the code the user action or event occurs. |
| 54 | |
| 55 | 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. |
| 56 | |
| 57 | 2. **Look for signals of the right location:** |
| 58 | - Form submissions, button click handlers, API route completions, mutation hooks |
| 59 | - Existing analytics calls (`segment.track()`, `mixpanel.track()`, `gtag()`) — these are often co-located with where LD track calls should go |
| 60 | - Comments like `// TODO: track this` |
| 61 | |
| 62 | 3. **Show the candidate location** to the user before writing anything: |
| 63 | ``` |
| 64 | I'll add the track() call here, in the checkout submit handler (src/checkout/CheckoutForm.tsx, line 47). |
| 65 | Does that look right? |
| 66 | ``` |
| 67 | |
| 68 | 4. **Proceed once confirmed** (or if you're confident enough from codebase signals). |
| 69 | |
| 70 | ### Step 4: Write the `track()` Call |
| 71 | |
| 72 | Write the call following the patterns found in Step 1. |
| 73 | |
| 74 | **Server-side SDKs** — context is required: |
| 75 | ```typescript |
| 76 | ldClient.track('checkout-completed', context); |
| 77 | ``` |
| 78 | |
| 79 | **Client-side SDKs** — context is implicit: |
| 80 | ```typescript |
| 81 | ldClient.track('checkout-completed'); |
| 82 | ``` |
| 83 | |
| 84 | **For `value` metrics** — include `metricValue` with the numeric measurement: |
| 85 | ```typescript |
| 86 | // Server-side: latency metric (ms) |
| 87 | ldClient.track('api-response-time', context, null, responseTimeMs); |
| 88 | |
| 89 | // Client-side: revenue metric |
| 90 | ldClient.track('purchase-completed', { orderId }, purchaseAmountUSD); |
| 91 | ``` |
| 92 | |
| 93 | **Key rules:** |
| 94 | - **Match the existing conte |