@apex-inc/mcp-server 0.27.5 → 0.28.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.27.5",
3
+ "version": "0.28.0",
4
4
  "description": "MCP server for Apex \u2014 currently in private beta.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,108 +1,130 @@
1
1
  ---
2
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.
3
+ description: Help users set up Apex Adoption — one Milestone per feature, one Adaptive Journey when they want letters (Nudge and/or Celebration), hours or days, unique Communications, and two stills. Use when they mention product adoption, activation letters, "people who haven't tried X", or feature adoption. A Milestone is NOT a Target.
4
4
  ---
5
5
 
6
6
  # Apex Adoption (MCP)
7
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.
8
+ Adoption tracks whether each person has finished a Milestone. If they want letters, Apex stamps **one Adaptive Journey**:
9
+
10
+ ```
11
+ Trigger: signed up (or the anchor)
12
+ Wait until they finish
13
+ on event → Celebration Send → Exit (or Exit if no letter)
14
+ on deadline → Nudge Send → Exit (or Exit if just-track)
15
+ ```
16
+
17
+ Just-track is a Milestone only. No Adaptive Journey. `scaffold: "none"`.
18
+
19
+ Do **not** clone two templates. Do **not** create a second live Adaptive Journey for the same Milestone.
20
+
21
+ ## Words
22
+
23
+ - **Milestone** — they finished one thing. Not a Target (that is an aggregate number by a date).
24
+ - **Nudge** — the letter when they have not finished yet.
25
+ - **Celebration** — the letter when they finish.
26
+ - **Adaptive Journey** — the graph those letters ride.
27
+ - **Communication** — the letter on a Send.
28
+ - **Segment** — a saved Customers rule, only if they check save.
29
+ - **Not yet / Done** — picture labels, not objects.
30
+
31
+ Do not say reminder, congratulations, clock, or watch list as names they see.
9
32
 
10
33
  ## Core idea
11
34
 
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 deterministic holdout is kept automatically (~5–10%); the report shows lift vs that holdout. Users in an active experiment are never nudged.
15
- - New milestones default to **future-only** (`enroll_mode: "future"`): only people who sign up after the milestone is created can enter the nudge. Pass `enroll_mode: "all"` to include the historical roster. Existing milestones without `enrollMode` stay "all" so live lists do not shrink.
16
- - `gap_hours` wins over `gap_days`. `0` hours or days means right away. Do not assume a 1-day floor.
17
- - A milestone has **two possible journeys**, and they are opposites:
18
- - **Nudge** (audience-entry): fires when a user *hasn't* adopted within the gap window. Drives them toward the feature.
19
- - **Celebration** (fires once on adoption): congratulates the user the moment they *do* reach the milestone, and tells them what's next. Scaffold both legs in one call with `compose_adoption_milestone` + `scaffold: "both"` (this mirrors the dashboard sentence on-ramp).
20
- - Milestones can be given a sequence **order** (which one accounts reach first). Ordering the full set unlocks the account-view "Path" funnel (a step-by-step drop-off chart). Unordered milestones are treated as independent (order-agnostic coverage).
35
+ - A Milestone is per person, per feature. Event (`report_run`) or trait (`plan = pro`).
36
+ - Hours or days from signup (or the anchor). `0` is right away. 1 hour is not right away.
37
+ - New Milestones default to **from now on** (`enroll_mode: "future"`). Do not publish a short clock on everyone already here (`enroll_mode: "all"`).
38
+ - Each Send gets its **own** Communication. Never reuse `comm-adoption-nudge` or `comm-adoption-celebration`.
39
+ - Extra Nudges are more hours or days on the deadline arm (duration Wait + Send). One lift for the protocol.
40
+ - Completing the Milestone stops leftover Nudges (exit rule on the done event).
41
+ - Celebration Send is holdout-exempt. Nudge honors holdout, opt-out, and the Nudge cap.
42
+ - Already finished when the Wait starts event arm. Do not sit to the deadline and Nudge.
21
43
 
22
- Name live hosts (`list_workspace_environments` / `set_workspace_environments` or Foundations) before you trust Production adoption numbers. Unmatched hosts stay Unclassified.
44
+ Name live hosts (`list_workspace_environments` / `set_workspace_environments` or Foundations) before you trust Production numbers. Unmatched hosts stay Unclassified.
23
45
 
24
46
  ## When to Activate
25
47
 
26
- - "Nudge users who signed up but never ran their first report."
27
- - "Which features are people not adopting?"
28
- - "Set up an activation program / onboarding nudges."
48
+ - "Nudge people who signed up but never ran their first report."
49
+ - "Which features are people not finishing?"
50
+ - "Set up activation letters."
29
51
 
30
52
  ## Tool Map
31
53
 
32
54
  | Tool | When to use |
33
55
  |---|---|
34
- | `list_adoption_milestones` | See the workspace's current milestones |
35
- | `get_adoption_milestone` | Inspect one milestone |
36
- | `create_adoption_milestone` | Define a new "adopted feature" milestone |
37
- | `compose_adoption_milestone` | Create a milestone AND scaffold its journey legs (`scaffold: "both" \| "celebration" \| "nudge" \| "none"`) in one call |
38
- | `update_adoption_milestone` | Change priority / order / gap window / turn on/off |
39
- | `reorder_adoption_milestones` | Set the sequence order of the whole set (unlocks the Path funnel) |
40
- | `delete_adoption_milestone` | Remove a milestone |
41
- | `get_adoption_metrics` | Per-milestone funnel + lift-vs-holdout + workspace health |
42
- | `list_adoption_features` / `create_adoption_feature` | Tenant-owned feature groupings (group your own events) |
43
- | `list_segments` / `get_segment` / `create_segment` | Saved groups of customers — same grammar as milestones |
44
- | `define_event` | Register an event's NAME before it fires (define ≠ fire) |
45
-
46
- Read-only summary resource: `apex://adoption`.
47
-
48
- ## One grammar: define → wire → verify
49
-
50
- Milestones and segments both describe "people who…" over the workspace's own
51
- events + traits. The methodology is the same everywhere (dashboard, SDK, MCP):
52
-
53
- 1. **Define** — name the signal. If the event doesn't exist yet, `define_event`
54
- registers it. Defining does NOT make it fire.
55
- 2. **Wire** — a developer calls `apex.track("your_event")` from the app (or
56
- sends the trait via `apex.identify`). Until then it shows a "not seen yet"
57
- dot.
58
- 3. **Verify**once real events arrive, milestone lift / segment counts fill in.
59
-
60
- ### Segments `create_segment`
61
-
62
- Author with the friendly `conditions` grammar (snake_case sub-keys), or pass a
63
- raw `predicate`:
64
-
65
- ```json
66
- {
67
- "name": "Power users who haven't upgraded",
68
- "conditions": {
69
- "match": "all",
70
- "groups": [
71
- { "match": "all", "conditions": [
72
- { "verb": "has", "event": "report_run", "window_days": 30 },
73
- { "attribute": "plan", "op": "is_not", "value": "pro" }
74
- ] }
75
- ]
76
- }
77
- }
78
- ```
56
+ | `list_adoption_milestones` | See the current Milestones |
57
+ | `get_adoption_milestone` | Inspect one |
58
+ | `create_adoption_milestone` | Define a Milestone (just-track unless they compose) |
59
+ | `compose_adoption_milestone` | Create a Milestone and stamp **one** Adaptive Journey |
60
+ | `update_adoption_milestone` | Change priority / order / hours or days / on-off |
61
+ | `reorder_adoption_milestones` | Sequence for the Path funnel |
62
+ | `delete_adoption_milestone` | Remove a Milestone |
63
+ | `get_adoption_metrics` | Funnel + one lift number |
64
+ | `attach_adoption_milestone_still` | Attach Not yet or Done |
65
+ | `list_adoption_milestone_stills` | List those two pictures |
66
+ | `recapture_adoption_milestone_stills` | Capture from public pages on a named host |
67
+ | `edit_communication` / `set_journey_send` | Write the letter on an existing Send |
68
+ | `publish_journey` | Go live after preview |
69
+ | `add_journey_step` | Hand-built Adaptive Journey only. Prefer compose. |
70
+
71
+ Read-only summary: `apex://adoption`.
72
+
73
+ ## Compose
74
+
75
+ `compose_adoption_milestone` with `scaffold`:
76
+
77
+ - `both` (default) Nudge + Celebration
78
+ - `nudge` deadline letter only
79
+ - `celebration` — finish letter only
80
+ - `none`just-track
81
+
82
+ Returns one `journey_id` (also `nudge_journey_id` for old callers) and each Send as `{ role, step_id, comm_id }`. `celebration_journey_id` is null on new rows.
83
+
84
+ Params: `action_label`, `gap_hours` or `gap_days`, `nudge_clocks` (each hours or days), `save_not_yet_segment`, `save_done_segment`, `enroll_mode`.
85
+
86
+ Preview each Communication, then `publish_journey`. Leave the Milestone off until they confirm.
87
+
88
+ Do not `add_journey_step` send on a compose-built path. Point the existing Send with `set_journey_send`.
89
+
90
+ ## Stills
91
+
92
+ Two pictures: **Not yet** (empty screen) and **Done** (finished). Shop or agent attaches. No Apex default stills.
93
+
94
+ - `attach_adoption_milestone_still` `image_base64` or a public image URL
95
+ - `recapture_adoption_milestone_stills` public https pages on a **named workspace host**. Not localhost. A login wall writes nothing.
96
+
97
+ ## Hand-built Adaptive Journey
98
+
99
+ Only when they are not using compose:
100
+
101
+ 1. `create_journey` → `set_journey_trigger`
102
+ 2. `add_journey_step` `kind=wait` `mode=until_event` `trigger_contract_id` `deadline_iso`
103
+ 3. `add_journey_step` `kind=send` `arm=event` or `arm=deadline`
104
+ 4. `set_journey_send` if the Send already exists
79
105
 
80
106
  ## Tool Invocation Order
81
107
 
82
- ### "Nudge users who haven't run their first report"
83
- 1. `list_adoption_milestones` → check it doesn't already exist.
84
- 2. `create_adoption_milestone` with `name: "Ran first report"`, `feature_key: "reporting"`, `adopted_when_kind: "event"`, `event_name: "report_run"`, `gap_days: 3` (or `gap_hours` for a same-day clock). Defaults to future-only. Leave `active` off first. Read the `warnings` in the response — a duplicate event or an event never seen on an identified person is a hard honesty problem.
85
- 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).
86
- 4. Later: `get_adoption_metrics` → report the lift-vs-holdout so they know whether it worked.
108
+ ### "Nudge people who haven't run their first report"
109
+ 1. `list_adoption_milestones`
110
+ 2. `compose_adoption_milestone` with `scaffold: "nudge"`, `enroll_mode: "future"`, hours or days. Leave `active` off.
111
+ 3. Preview the Communication. `publish_journey`. Then turn the Milestone on.
87
112
 
88
- ### "Congratulate users when they start their first experiment"
89
- 1. `compose_adoption_milestone` with `name: "Started first experiment"`, `featureKey: "experiments"`, `adoptedWhenKind: "event"`, `eventName: "experiment_started"`, `scaffold: "celebration"`. This creates the milestone AND a draft celebration journey wired to fire once, the moment the user reaches it.
90
- 2. Tell the user the celebration journey is a **draft**. Preview with `preview_communication`, then `publish_journey` (dry-run first).
91
- 3. Turning the milestone on is separate from publishing the journey; both must be live for the celebration to send.
113
+ ### "Celebrate when they start their first experiment"
114
+ 1. `compose_adoption_milestone` `scaffold: "celebration"` (or `both` if they also want a Nudge).
115
+ 2. Preview. Publish. Do not scaffold a Celebration on an event that already has a published operator letter pass `scaffold: "nudge"`.
92
116
 
93
- ### "Set up a full milestone nudge the ones who don't, celebrate the ones who do"
94
- 1. `compose_adoption_milestone` with `scaffold: "both"` (default). Example: `name: "Started first experiment"`, `feature_key: "experiments"`, `adopted_when_kind: "event"`, `event_name: "experiment_started"`, `gap_hours: 1` (or `gap_days: 7` in production). One call creates the milestone plus BOTH draft journeys.
95
- 2. The response carries `nudge_journey_id`, `celebration_journey_id`, and `warnings`. Preview the letter with `preview_communication`, then `publish_journey` (dry-run first). Do not activate until the letter is previewed and the journey is published.
96
- 3. Do not scaffold a celebration on an event that already has a published operator letter (experiment started, domain verified, etc.) — pass `scaffold: "nudge"`.
97
- 4. Turn the milestone on (`update_adoption_milestone` `active: true`) once its nudge is published, so it can measure lift vs the holdout.
117
+ ### "Just trackno letter"
118
+ 1. `compose_adoption_milestone` `scaffold: "none"`.
98
119
 
99
- ### "Put my milestones in the order accounts should hit them"
100
- 1. `list_adoption_milestones` get the ids.
101
- 2. `reorder_adoption_milestones` with `orderedIds` in the intended sequence (activation before depth).
102
- 3. Tell the user the account view's "Path" funnel is now unlocked — it shows drop-off between consecutive milestones. Without a full order it stays on the order-agnostic "Coverage" view.
120
+ ### "Save not-yet as a Segment"
121
+ Pass `save_not_yet_segment: true` (and/or `save_done_segment`) on compose. Names: `Not yet: {name}` / `Done: {name}`. Completing drops them from not-yet. The Adaptive Journey watch list stays private if they do not check this.
103
122
 
104
123
  ## Guardrails
105
124
 
106
- - Milestones start OFF. Only set `active: true` when the user confirms they want to start sending.
107
- - Never call it a "goal" in user-facing text.
108
- - The `eventName`/`traitPath` must be an event/trait the workspace actually sends — confirm with the user if unsure.
125
+ - Milestones start OFF.
126
+ - Never call a Milestone a Target or a goal.
127
+ - Unique Communications. Never reuse the shared catalog letter ids.
128
+ - Do not publish a short clock on everyone already here.
129
+ - Do not publish Website is talking / Send from your own domain / Started your first experiment / Connected your first integration unless they ask — those are Apex's own product drafts.
130
+ - Capture fail never writes a still.