@apex-inc/mcp-server 0.27.3 → 0.27.4

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.3",
3
+ "version": "0.27.4",
4
4
  "description": "MCP server for Apex \u2014 currently in private beta.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,7 +11,9 @@ The Adoption Engine tracks whether each end-user has adopted each feature, nudge
11
11
 
12
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
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.
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.
15
17
  - A milestone has **two possible journeys**, and they are opposites:
16
18
  - **Nudge** (audience-entry): fires when a user *hasn't* adopted within the gap window. Drives them toward the feature.
17
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).
@@ -79,19 +81,20 @@ raw `predicate`:
79
81
 
80
82
  ### "Nudge users who haven't run their first report"
81
83
  1. `list_adoption_milestones` → check it doesn't already exist.
82
- 2. `create_adoption_milestone` with `name: "Ran first report"`, `featureKey: "reporting"`, `adoptedWhenKind: "event"`, `eventName: "report_run"`, `gapDays: 3`. Leave `active` off first.
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.
83
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).
84
86
  4. Later: `get_adoption_metrics` → report the lift-vs-holdout so they know whether it worked.
85
87
 
86
88
  ### "Congratulate users when they start their first experiment"
87
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.
88
- 2. Tell the user the celebration journey is a **draft** they edit the congratulatory message in the canvas (Communications composer), then publish it.
90
+ 2. Tell the user the celebration journey is a **draft**. Preview with `preview_communication`, then `publish_journey` (dry-run first).
89
91
  3. Turning the milestone on is separate from publishing the journey; both must be live for the celebration to send.
90
92
 
91
93
  ### "Set up a full milestone — nudge the ones who don't, celebrate the ones who do"
92
- 1. `compose_adoption_milestone` with `scaffold: "both"` (e.g. `name: "Started first experiment"`, `featureKey: "experiments"`, `adoptedWhenKind: "event"`, `eventName: "experiment_started"`, `gapDays: 7`). One call creates the milestone plus BOTH draft journeys: the nudge (for users who haven't started an experiment within 7 days) and the celebration (for the moment they do). This is exactly what the dashboard sentence on-ramp produces.
93
- 2. The response carries `nudgeJourneyId` and `celebrationJourneyId` both are **drafts**. Edit copy in the canvas and publish each.
94
- 3. Turn the milestone on (`update_adoption_milestone` `active: true`) once its nudge is published, so it can measure lift vs the holdout.
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.
95
98
 
96
99
  ### "Put my milestones in the order accounts should hit them"
97
100
  1. `list_adoption_milestones` → get the ids.