@apex-inc/mcp-server 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apex-inc/mcp-server",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "description": "MCP server for Apex — currently in private beta.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,82 @@
1
+ ---
2
+ name: apex-adoption
3
+ description: Help users set up and run Apex's Adoption Engine — per-feature adoption milestones defined over their own events/traits, automatic nudges to users who haven't adopted, and lift-vs-holdout measurement. Use whenever the user mentions product adoption, activation nudges, "users who haven't tried X", feature adoption, onboarding nudges, or wants to drive users to a feature. A milestone is NOT a goal.
4
+ ---
5
+
6
+ # Apex Adoption (MCP)
7
+
8
+ The Adoption Engine tracks whether each end-user has adopted each feature, nudges the ones who haven't (one next-best nudge per user), and measures the lift against a holdout.
9
+
10
+ ## Core idea
11
+
12
+ - A **milestone** = "has this end-user adopted feature X?" — defined by an event they fire (`report_run`) or a trait (`plan = pro`). It is per-user and per-feature. It is **not** a goal (goals are workspace/experiment/journey success).
13
+ - Apex ranks a user's unmet milestones by priority and sends the single top nudge per cadence — so nobody gets spammed.
14
+ - A ~10% deterministic holdout is kept automatically; the report shows lift vs that holdout, not last-touch attribution. Users in an active experiment are never nudged.
15
+
16
+ ## When to Activate
17
+
18
+ - "Nudge users who signed up but never ran their first report."
19
+ - "Which features are people not adopting?"
20
+ - "Set up an activation program / onboarding nudges."
21
+
22
+ ## Tool Map
23
+
24
+ | Tool | When to use |
25
+ |---|---|
26
+ | `list_adoption_milestones` | See the workspace's current milestones |
27
+ | `get_adoption_milestone` | Inspect one milestone |
28
+ | `create_adoption_milestone` | Define a new "adopted feature" milestone |
29
+ | `update_adoption_milestone` | Change priority / gap window / turn on/off |
30
+ | `delete_adoption_milestone` | Remove a milestone |
31
+ | `get_adoption_metrics` | Per-milestone funnel + lift-vs-holdout + workspace health |
32
+ | `list_adoption_features` / `create_adoption_feature` | Tenant-owned feature groupings (group your own events) |
33
+ | `list_segments` / `get_segment` / `create_segment` | Saved groups of customers — same grammar as milestones |
34
+ | `define_event` | Register an event's NAME before it fires (define ≠ fire) |
35
+
36
+ Read-only summary resource: `apex://adoption`.
37
+
38
+ ## One grammar: define → wire → verify
39
+
40
+ Milestones and segments both describe "people who…" over the workspace's own
41
+ events + traits. The methodology is the same everywhere (dashboard, SDK, MCP):
42
+
43
+ 1. **Define** — name the signal. If the event doesn't exist yet, `define_event`
44
+ registers it. Defining does NOT make it fire.
45
+ 2. **Wire** — a developer calls `apex.track("your_event")` from the app (or
46
+ sends the trait via `apex.identify`). Until then it shows a "not seen yet"
47
+ dot.
48
+ 3. **Verify** — once real events arrive, milestone lift / segment counts fill in.
49
+
50
+ ### Segments — `create_segment`
51
+
52
+ Author with the friendly `conditions` grammar (snake_case sub-keys), or pass a
53
+ raw `predicate`:
54
+
55
+ ```json
56
+ {
57
+ "name": "Power users who haven't upgraded",
58
+ "conditions": {
59
+ "match": "all",
60
+ "groups": [
61
+ { "match": "all", "conditions": [
62
+ { "verb": "has", "event": "report_run", "window_days": 30 },
63
+ { "attribute": "plan", "op": "is_not", "value": "pro" }
64
+ ] }
65
+ ]
66
+ }
67
+ }
68
+ ```
69
+
70
+ ## Tool Invocation Order
71
+
72
+ ### "Nudge users who haven't run their first report"
73
+ 1. `list_adoption_milestones` → check it doesn't already exist.
74
+ 2. `create_adoption_milestone` with `name: "Ran first report"`, `featureKey: "reporting"`, `adoptedWhenKind: "event"`, `eventName: "report_run"`, `gapDays: 3`. Leave `active` off first.
75
+ 3. Tell the user it's created as a draft, and that turning it on (`update_adoption_milestone` with `active: true`) starts nudging through their journeys (opt-out + caps respected).
76
+ 4. Later: `get_adoption_metrics` → report the lift-vs-holdout so they know whether it worked.
77
+
78
+ ## Guardrails
79
+
80
+ - Milestones start OFF. Only set `active: true` when the user confirms they want to start sending.
81
+ - Never call it a "goal" in user-facing text.
82
+ - The `eventName`/`traitPath` must be an event/trait the workspace actually sends — confirm with the user if unsure.
@@ -72,7 +72,7 @@ Interactive flows: MCP prompts `new-experiment` and `experiment-review` orchestr
72
72
  - **Screenshots are first-class.** For public web URLs, `create_experiment` auto-captures control + variant screenshots and shows them on the dashboard experiment card + detail gallery. For localhost / auth-gated / mobile screens, capture the image yourself and call `attach_experiment_asset({ experimentId, variantKey, imageBase64 })`.
73
73
  - **Mobile/Capacitor experiments capture on-device.** When the experiment runs on an authed in-app screen (servers can't reach it), tell the dev to call `Apex.captureVariantScreenshot({ experimentId, variantKey })` on the variant's screen, keyed to the resolved variant in a `useEffect`, in a debug build (`Apex.initialize({ ..., debug: true })`). It no-ops in production and lands the shot on the dashboard card + gallery like web/agent captures.
74
74
  - **Exposure auto-fires.** When a variant resolves via `useApexVariant` (web) or `Apex.getVariant()` (mobile), the SDK fires the canonical `experiment_exposure` event — the denominator for results. You don't fire it manually.
75
- - **Don't launch a dead experiment.** `activate_experiment` is gated on `verify_experiment_wiring`: both arms must be producing `experiment_exposure` events first, or it refuses (pass `force: true` to override). Run `verify_experiment_wiring({ experimentId })` after deploying the variant code to confirm both arms are live before launch.
75
+ - **Don't launch a dead experiment.** `activate_experiment` is gated on `verify_experiment_wiring`. Code-wired (SDK-hook) web experiments are safe to activate before their code ships: the server holds them in `pending_deployment` ("Waiting on deploy") and starts them automatically at the first `experiment_exposure`. Non-SDK experiments with unwired arms are refused (pass `force: true` to override). Run `verify_experiment_wiring({ experimentId })` after the deploy lands to confirm both arms are live.
76
76
 
77
77
  ### Journey-arm experiments (any surface)
78
78