@apex-inc/mcp-server 0.50.0 → 0.52.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/dist/setup-catchup-tools.d.ts +84 -5
- package/dist/setup-catchup-tools.d.ts.map +1 -1
- package/dist/setup-catchup-tools.js +33 -3
- package/dist/setup-catchup-tools.js.map +1 -1
- package/dist/tool-groups.d.ts.map +1 -1
- package/dist/tool-groups.js +3 -0
- package/dist/tool-groups.js.map +1 -1
- package/dist/tools/ad-platforms.d.ts +3 -3
- package/dist/tools/ad-platforms.js +2 -2
- package/dist/tools/ad-platforms.js.map +1 -1
- package/dist/tools/apex-campaigns.d.ts +133 -0
- package/dist/tools/apex-campaigns.d.ts.map +1 -0
- package/dist/tools/apex-campaigns.js +156 -0
- package/dist/tools/apex-campaigns.js.map +1 -0
- package/dist/tools/experiments.d.ts +8 -5
- package/dist/tools/experiments.d.ts.map +1 -1
- package/dist/tools/experiments.js +64 -41
- package/dist/tools/experiments.js.map +1 -1
- package/dist/tools/letters.d.ts +22 -12
- package/dist/tools/letters.d.ts.map +1 -1
- package/dist/tools/letters.js +23 -44
- package/dist/tools/letters.js.map +1 -1
- package/dist/tools.d.ts +240 -25
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +2 -0
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/skills/apex-experimentation/SKILL.md +6 -2
- package/skills/apex-growth-intelligence/SKILL.md +17 -0
- package/skills/apex-growth-tracking/SKILL.md +1 -0
- package/skills/apex-integration-cookbook/SKILL.md +10 -0
- package/skills/apex-journeys/SKILL.md +17 -0
|
@@ -38,6 +38,7 @@ When a user was anonymous and then becomes known (signup, login, checkout email)
|
|
|
38
38
|
|
|
39
39
|
- Call **`identify`** with a stable `userId` and pass **`traits.email`** when applicable.
|
|
40
40
|
- **Server-side** `identify` (webhooks, API routes): pass **`traits.visitorId`** = value of the browser **`apex_vid`** cookie so the stitch links to the real marketing session. Without it, Apex may create a synthetic visitor disconnected from prior events.
|
|
41
|
+
- **Declined cookies, then sent a form**: the snippet (and the SDK's `trackForm` under `requireConsent`) still makes them a person with the form's answers. No browsing is joined, no ad click id is kept, and advertising is recorded as denied, so no ad platform hears about them. Do not build a workaround to "recover" those visits. See `/docs/concepts/consent`.
|
|
41
42
|
- **Sign-out**: call **`reset()`** from `@apex-inc/sdk` (or `window.apex.reset()` on snippet-only sites) in every logout handler. It starts the browser as a fresh anonymous visitor, so a shared computer does not credit the next person's visits to the last one. Without it, Apex still never merges two signed-in people; anonymous visits go to whoever signed in on that browser most recently.
|
|
42
43
|
|
|
43
44
|
## B2B accounts + groups (model the company, not just the seat)
|
|
@@ -343,6 +343,16 @@ If get_setup_state shows first-run incomplete, name the merchant before inventin
|
|
|
343
343
|
|
|
344
344
|
After ads are connected, make a paid Apex Link before inventing UTMs. Do not stamp conversion ack. `create_apex_link` writes the paid medium by default; pass `placement: "social-post"` (or `social-bio`, `other`) for a free post so it never lands in paid reporting. `other` needs `source` naming the site, show, or community (e.g. `indie-hackers`) so signups credit it by name. A link shows its landing page's card when pasted into Slack, iMessage, LinkedIn, or X; pass `preview_title`, `preview_description`, or `preview_image_url` only when that link should look different. `set_ad_measurement_events` chooses which sales to forward and returns a URL if the legal sentence is still open. `set_conversion_source_of_truth` records whether another tool already sends the sale; Apex holds everything for Meta and Google until it is answered. The rail finishes when those things exist — there is no mark-complete tool.
|
|
345
345
|
|
|
346
|
+
## Recipe: one launch across several ad platforms (Apex Campaigns)
|
|
347
|
+
|
|
348
|
+
When the same launch runs on Meta, Google, LinkedIn and TikTok, each platform has its own campaign with its own id. An **Apex Campaign** puts them under one name so spend, clicks and results read side by side under Attribution → Campaigns.
|
|
349
|
+
|
|
350
|
+
1. `create_apex_link` for each ad version and platform, all with the same `campaign_name`.
|
|
351
|
+
2. `create_apex_campaign({ name })` with that same name. Pass `members: [{ platform, platform_campaign_id }]` if the ads already exist.
|
|
352
|
+
3. Once the ads are live and synced, `list_apex_campaigns` shows `unlinked_platform_campaigns`; link them with `add_apex_campaign_member({ campaign_id, members })`.
|
|
353
|
+
|
|
354
|
+
Each platform keeps its own attribution, so the columns are not added into one cost per result unless the owner turns that on in the dashboard. Do not make a second Apex Campaign with the same name; `create_apex_campaign` refuses it.
|
|
355
|
+
|
|
346
356
|
## Recipe: Apex Links for app installs (Mobile Measurement)
|
|
347
357
|
|
|
348
358
|
An Apex Link is a short URL that routes to the App Store / Play Store when the app is not installed and carries the click through to the first open (deferred deep link). Apex credits the install to the link's campaign and sends it back to the ad network the click came from.
|
|
@@ -26,6 +26,7 @@ The single hardest thing about journeys is **knowing when to stop**. The vast ma
|
|
|
26
26
|
| `list_journey_exits` | Read only the exit rules for one journey. Use when the user asks "what triggers an exit for this?" |
|
|
27
27
|
| `add_journey_exit` | Add an exit rule to a journey draft. Use when the user (or you proactively) decides a journey needs a new exit trigger. |
|
|
28
28
|
| `remove_journey_exit` | Remove an exit rule from a journey draft. |
|
|
29
|
+
| `add_journey_branch` | Split the flow on one condition and send a different letter to each side. The condition is an attribute, an event (fired / not fired in a window), or how they responded to the letter the journey just sent (`letter_opened` / `letter_clicked`, waiting `wait_days`, default 3). |
|
|
29
30
|
| `audit_journey_exits` | Sweep across all published marketing journeys and find ones missing purchase exits. Run this proactively when a user mentions journeys, cart recovery, or marketing programs. |
|
|
30
31
|
| `get_contact_cart` | Inspect a contact's current cart state to debug cart-recovery journeys or branch.condition evaluations. |
|
|
31
32
|
|
|
@@ -61,6 +62,22 @@ When teaching users, this is the mental model:
|
|
|
61
62
|
|
|
62
63
|
> "A journey starts because something happened. An exit fires when the reason for the journey no longer exists."
|
|
63
64
|
|
|
65
|
+
### Branching on how they responded to a letter
|
|
66
|
+
|
|
67
|
+
"If they clicked the welcome letter, send the next step; if not, send a reminder" is one call:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
add_journey_branch({ journey_id, after_step_id: "<the welcome send>",
|
|
71
|
+
condition: { kind: "letter_clicked", wait_days: 2 },
|
|
72
|
+
when_true_comm_id: "<next step letter>", when_false_comm_id: "<reminder>" })
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- It goes right after the send it is about. Without `after_step_id` it goes after the step that leads into the exit, which has to be that send.
|
|
76
|
+
- The journey waits up to `wait_days` for the click, then takes the other side. Both sides then continue where the flow went before.
|
|
77
|
+
- Prefer `letter_clicked`. Mail apps preload images, so opens overcount and someone who never read it can take the "opened" side.
|
|
78
|
+
- Push reports opens and dismissals, not clicks, so `letter_clicked` after a push is refused.
|
|
79
|
+
- A branch on whether they did something on the site (booked, paid) is `event_fired` / `event_not_fired`, not a letter branch. If doing it should end the journey, that's an exit rule instead.
|
|
80
|
+
|
|
64
81
|
### Send-time gate is authoritative
|
|
65
82
|
|
|
66
83
|
Even if the stream-based exit matcher misses an event (race conditions are rare but possible), every `send_*` step re-checks exit rules immediately before firing. This is the guarantee Apex makes to its users: **if an exit event has fired by the moment we send, we will not send**.
|