@apex-inc/mcp-server 0.13.0 → 0.14.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/index.js +29 -2
- package/dist/index.js.map +1 -1
- package/dist/param-casing.d.ts +54 -0
- package/dist/param-casing.d.ts.map +1 -0
- package/dist/param-casing.js +101 -0
- package/dist/param-casing.js.map +1 -0
- package/dist/tools.d.ts +46 -90
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +27 -47
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/skills/apex-experimentation/SKILL.md +3 -1
- package/skills/apex-journeys/SKILL.md +8 -0
package/dist/tools.js
CHANGED
|
@@ -2919,12 +2919,12 @@ Events fired through this tool carry a stable synthetic visitorId (mcp-agent-*,
|
|
|
2919
2919
|
},
|
|
2920
2920
|
},
|
|
2921
2921
|
add_journey_branch: {
|
|
2922
|
-
description: `${APEX} — Insert a CONDITIONAL content branch before the exit: evaluate one condition and send a different communication to each side. Use this for true content branching (e.g. "cart value > $100 → VIP email, else standard email"). For the simpler "skip the next send if they already converted" case, use add_journey_exit instead. The condition is an attribute test (
|
|
2922
|
+
description: `${APEX} — Insert a CONDITIONAL content branch before the exit: evaluate one condition and send a different communication to each side. Use this for true content branching (e.g. "cart value > $100 → VIP email, else standard email"). For the simpler "skip the next send if they already converted" case, use add_journey_exit instead. The condition is an attribute test (field_path + operator + value) or an event test (event_fired / event_not_fired within a window).`,
|
|
2923
2923
|
schema: z.object({
|
|
2924
2924
|
journeyId: z.string(),
|
|
2925
2925
|
condition: z.object({
|
|
2926
2926
|
kind: z.enum(["attribute", "event_fired", "event_not_fired"]),
|
|
2927
|
-
|
|
2927
|
+
field_path: z.string().optional().describe("attribute only: dotted path, e.g. 'cart.valueCents' or 'plan'."),
|
|
2928
2928
|
operator: z
|
|
2929
2929
|
.enum(["equals", "not_equals", "greater_than", "less_than", "in", "exists", "not_exists"])
|
|
2930
2930
|
.optional()
|
|
@@ -2933,8 +2933,8 @@ Events fired through this tool carry a stable synthetic visitorId (mcp-agent-*,
|
|
|
2933
2933
|
.union([z.string(), z.number(), z.boolean(), z.array(z.union([z.string(), z.number(), z.boolean()]))])
|
|
2934
2934
|
.optional()
|
|
2935
2935
|
.describe("attribute only: the comparison value (omit for exists/not_exists)."),
|
|
2936
|
-
|
|
2937
|
-
|
|
2936
|
+
event_name: z.string().optional().describe("event only: the canonical event, e.g. 'purchase'."),
|
|
2937
|
+
window_days: z.number().optional().describe("event only: look-back window in days (omit = ever)."),
|
|
2938
2938
|
}),
|
|
2939
2939
|
whenTrueCommId: z.string().describe("Communication to send when the condition matches."),
|
|
2940
2940
|
whenFalseCommId: z.string().optional().describe("Communication to send when it doesn't match (omit to just continue to exit)."),
|
|
@@ -2946,24 +2946,24 @@ Events fired through this tool carry a stable synthetic visitorId (mcp-agent-*,
|
|
|
2946
2946
|
// Build the predicate leaf (AudiencePredicate is a bare leaf here).
|
|
2947
2947
|
let predicate;
|
|
2948
2948
|
if (c.kind === "attribute") {
|
|
2949
|
-
if (!c.
|
|
2950
|
-
return { content: [{ type: "text", text: `${APEX} An attribute condition needs
|
|
2949
|
+
if (!c.field_path || !c.operator) {
|
|
2950
|
+
return { content: [{ type: "text", text: `${APEX} An attribute condition needs field_path and operator.` }], isError: true };
|
|
2951
2951
|
}
|
|
2952
2952
|
predicate = {
|
|
2953
2953
|
kind: "attribute",
|
|
2954
|
-
fieldPath: c.
|
|
2954
|
+
fieldPath: c.field_path,
|
|
2955
2955
|
operator: c.operator,
|
|
2956
2956
|
...(c.value !== undefined ? { value: c.value } : {}),
|
|
2957
2957
|
};
|
|
2958
2958
|
}
|
|
2959
2959
|
else {
|
|
2960
|
-
if (!c.
|
|
2961
|
-
return { content: [{ type: "text", text: `${APEX} An event condition needs
|
|
2960
|
+
if (!c.event_name) {
|
|
2961
|
+
return { content: [{ type: "text", text: `${APEX} An event condition needs event_name.` }], isError: true };
|
|
2962
2962
|
}
|
|
2963
2963
|
predicate = {
|
|
2964
2964
|
kind: c.kind,
|
|
2965
|
-
eventName: c.
|
|
2966
|
-
window: c.
|
|
2965
|
+
eventName: c.event_name,
|
|
2966
|
+
window: c.window_days ? { type: "last_n_days", days: c.window_days } : { type: "ever" },
|
|
2967
2967
|
};
|
|
2968
2968
|
}
|
|
2969
2969
|
const j = await apiGet(`/api/journeys/${encodeURIComponent(args.journeyId)}`);
|
|
@@ -3081,15 +3081,10 @@ Events fired through this tool carry a stable synthetic visitorId (mcp-agent-*,
|
|
|
3081
3081
|
get_journey: {
|
|
3082
3082
|
description: `${APEX} — Read the full configuration for a single journey, including steps, goal event, attribution window, and exit rules. Use after list_journeys to inspect a journey's wiring before recommending edits.`,
|
|
3083
3083
|
schema: z.object({
|
|
3084
|
-
journeyId: z.string().
|
|
3085
|
-
journey_id: z.string().optional().describe("Deprecated alias for journeyId."),
|
|
3084
|
+
journeyId: z.string().describe("Journey id returned from list_journeys."),
|
|
3086
3085
|
}),
|
|
3087
|
-
handler: async ({ journeyId
|
|
3088
|
-
const
|
|
3089
|
-
if (!jid) {
|
|
3090
|
-
return { content: [{ type: "text", text: `${APEX} journeyId is required.` }], isError: true };
|
|
3091
|
-
}
|
|
3092
|
-
const journey = await apiGet(`/api/journeys/${encodeURIComponent(jid)}`);
|
|
3086
|
+
handler: async ({ journeyId }) => {
|
|
3087
|
+
const journey = await apiGet(`/api/journeys/${encodeURIComponent(journeyId)}`);
|
|
3093
3088
|
return {
|
|
3094
3089
|
content: [
|
|
3095
3090
|
{
|
|
@@ -3103,15 +3098,10 @@ Events fired through this tool carry a stable synthetic visitorId (mcp-agent-*,
|
|
|
3103
3098
|
list_journey_exits: {
|
|
3104
3099
|
description: `${APEX} — Just the exit-rules block of one journey. Cheaper than get_journey for audit loops that only need to know "does this journey suppress purchase / unsubscribe?".`,
|
|
3105
3100
|
schema: z.object({
|
|
3106
|
-
journeyId: z.string()
|
|
3107
|
-
journey_id: z.string().optional().describe("Deprecated alias for journeyId."),
|
|
3101
|
+
journeyId: z.string(),
|
|
3108
3102
|
}),
|
|
3109
|
-
handler: async ({ journeyId
|
|
3110
|
-
const
|
|
3111
|
-
if (!jid) {
|
|
3112
|
-
return { content: [{ type: "text", text: `${APEX} journeyId is required.` }], isError: true };
|
|
3113
|
-
}
|
|
3114
|
-
const body = await apiGet(`/api/journeys/${encodeURIComponent(jid)}/exit-rules`);
|
|
3103
|
+
handler: async ({ journeyId }) => {
|
|
3104
|
+
const body = await apiGet(`/api/journeys/${encodeURIComponent(journeyId)}/exit-rules`);
|
|
3115
3105
|
return {
|
|
3116
3106
|
content: [
|
|
3117
3107
|
{
|
|
@@ -3125,21 +3115,16 @@ Events fired through this tool carry a stable synthetic visitorId (mcp-agent-*,
|
|
|
3125
3115
|
add_journey_exit: {
|
|
3126
3116
|
description: `${APEX} — Append a new exit rule to a journey's draft. Rule fires when the chosen trigger contract's event lands on a contact with an in-flight execution — Apex stops the execution and skips any pending sends. Re-publish required for the rule to take effect on live runs.`,
|
|
3127
3117
|
schema: z.object({
|
|
3128
|
-
journeyId: z.string()
|
|
3129
|
-
|
|
3130
|
-
trigger_contract_id: z
|
|
3118
|
+
journeyId: z.string(),
|
|
3119
|
+
triggerContractId: z
|
|
3131
3120
|
.string()
|
|
3132
3121
|
.describe("Trigger-contract id, e.g. trig-in-app-purchase"),
|
|
3133
3122
|
label: z.string().optional(),
|
|
3134
3123
|
enabled: z.boolean().optional().default(true),
|
|
3135
3124
|
}),
|
|
3136
|
-
handler: async ({ journeyId,
|
|
3137
|
-
const
|
|
3138
|
-
|
|
3139
|
-
return { content: [{ type: "text", text: `${APEX} journeyId is required.` }], isError: true };
|
|
3140
|
-
}
|
|
3141
|
-
const body = await apiPost(`/api/journeys/${encodeURIComponent(jid)}/exit-rules`, {
|
|
3142
|
-
triggerContractId: trigger_contract_id,
|
|
3125
|
+
handler: async ({ journeyId, triggerContractId, label, enabled, }) => {
|
|
3126
|
+
const body = await apiPost(`/api/journeys/${encodeURIComponent(journeyId)}/exit-rules`, {
|
|
3127
|
+
triggerContractId,
|
|
3143
3128
|
...(label !== undefined && { label }),
|
|
3144
3129
|
enabled: enabled !== false,
|
|
3145
3130
|
});
|
|
@@ -3156,21 +3141,16 @@ Events fired through this tool carry a stable synthetic visitorId (mcp-agent-*,
|
|
|
3156
3141
|
remove_journey_exit: {
|
|
3157
3142
|
description: `${APEX} — Remove an exit rule from a journey's draft. Re-publish required for the change to apply to live runs.`,
|
|
3158
3143
|
schema: z.object({
|
|
3159
|
-
journeyId: z.string()
|
|
3160
|
-
|
|
3161
|
-
rule_id: z.string(),
|
|
3144
|
+
journeyId: z.string(),
|
|
3145
|
+
ruleId: z.string(),
|
|
3162
3146
|
}),
|
|
3163
|
-
handler: async ({ journeyId,
|
|
3164
|
-
|
|
3165
|
-
if (!jid) {
|
|
3166
|
-
return { content: [{ type: "text", text: `${APEX} journeyId is required.` }], isError: true };
|
|
3167
|
-
}
|
|
3168
|
-
await apiDelete(`/api/journeys/${encodeURIComponent(jid)}/exit-rules/${encodeURIComponent(rule_id)}`);
|
|
3147
|
+
handler: async ({ journeyId, ruleId, }) => {
|
|
3148
|
+
await apiDelete(`/api/journeys/${encodeURIComponent(journeyId)}/exit-rules/${encodeURIComponent(ruleId)}`);
|
|
3169
3149
|
return {
|
|
3170
3150
|
content: [
|
|
3171
3151
|
{
|
|
3172
3152
|
type: "text",
|
|
3173
|
-
text: `Removed exit rule ${
|
|
3153
|
+
text: `Removed exit rule ${ruleId} from journey ${journeyId}.`,
|
|
3174
3154
|
},
|
|
3175
3155
|
],
|
|
3176
3156
|
};
|