@loopops/mcp-server 3.4.0 → 3.5.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.
Files changed (2) hide show
  1. package/dist/tools/tal.js +24 -70
  2. package/package.json +1 -1
package/dist/tools/tal.js CHANGED
@@ -15,25 +15,6 @@
15
15
  import { z } from "zod";
16
16
  import { trpcMutation, trpcQuery } from "../api-client.js";
17
17
  import { safeTool } from "./_helpers.js";
18
- // Local replicas of the criteria DSL types — kept narrow so the MCP
19
- // tool description doesn't have to ship the full zod schema. The
20
- // authoritative validator lives in mcp-schemas.ts; this is just for
21
- // tool-input typing on the client side.
22
- const conditionSchema = z.lazy(() => z.union([
23
- z.object({
24
- operator: z.enum(["AND", "OR", "NOT"]),
25
- conditions: z.array(conditionSchema),
26
- }),
27
- z.object({
28
- type: z.enum([
29
- "attribute",
30
- "score",
31
- "lifecycle_state",
32
- "member_of",
33
- "exclusion",
34
- ]),
35
- }).passthrough(),
36
- ]));
37
18
  const talIdentifierShape = {
38
19
  talName: z
39
20
  .string()
@@ -81,63 +62,36 @@ export function registerTalTools(server, allowed) {
81
62
  .describe("If true, classify changes but skip writes. Useful for previewing the impact of a criteria edit. Default: false."),
82
63
  }, safeTool(async (input) => trpcMutation("mcp.evaluateTalNow", input)));
83
64
  }
84
- if (allowed.has("create_tal")) {
85
- server.tool("create_tal", [
86
- "Create a new Target Account List with a name, purpose, criteria DSL, and refresh cadence.",
87
- "The TAL starts active but empty call evaluate_tal_now to populate it.",
65
+ if (allowed.has("sync_account_master_tals")) {
66
+ server.tool("sync_account_master_tals", [
67
+ "Apply config/account_master/tals.yaml to the DB. Reads the YAML from GitHub, validates,",
68
+ "upserts target_account_list rows by tal_name, and (by default) re-evaluates each affected",
69
+ "TAL so membership reflects criteria changes immediately.",
88
70
  "",
89
- "Criteria is a tree of conditions evaluated against an account's resolved attributes,",
90
- "score, lifecycle states, and existing TAL memberships. Operators: AND, OR, NOT. Condition",
91
- "types: attribute (with operators =, !=, >, >=, <, <=, in, not_in, exists, matches), score",
92
- "(model + band), lifecycle_state (lifecycle_type + state), member_of (tal_name), exclusion",
93
- "(tal_name — sugar for NOT member_of).",
71
+ "This is the WRITE path for TAL definitions. To create or edit a TAL:",
72
+ " 1. update_account_master_config file=tals (commits new YAML to main)",
73
+ " 2. sync_account_master_tals (apply YAML DB; this tool)",
74
+ " 3. evaluate_tal_now (optional) (run sooner than the cron's next fire)",
94
75
  "",
95
- "Example criteria for 'enterprise US accounts that are enriched and not in the do-not-contact list':",
96
- "{",
97
- ' "operator": "AND",',
98
- ' "conditions": [',
99
- ' {"type": "attribute", "attribute": "employee_count", "operator": ">=", "value": 500},',
100
- ' {"type": "attribute", "attribute": "hq_country", "operator": "=", "value": "US"},',
101
- ' {"type": "lifecycle_state", "lifecycle_type": "enrichment", "state": "enriched"},',
102
- ' {"type": "exclusion", "tal_name": "do_not_contact"}',
103
- " ]",
104
- "}",
76
+ "TALs in DB but absent from YAML are LEFT UNTOUCHED to remove a TAL, set is_active: false",
77
+ "in YAML. Permanent deletion requires explicit DB action so an accidental YAML edit",
78
+ "doesn't orphan target_account_list_membership rows.",
79
+ "",
80
+ "Idempotent. Safe to call after every update_account_master_config. Pass dryRun: true to",
81
+ "preview before applying.",
105
82
  ].join("\n"), {
106
- talName: z
107
- .string()
108
- .min(1)
109
- .max(200)
110
- .regex(/^[a-z0-9_]+$/, "tal_name must be snake_case")
111
- .describe("Snake-case identifier (e.g. 'enterprise_expansion_targets'). Must be unique."),
112
- description: z
113
- .string()
114
- .min(1)
115
- .describe("One-sentence description of what this list is for and who consumes it."),
116
- purpose: z
117
- .enum([
118
- "signal_scanner",
119
- "abm_advertising",
120
- "outbound_sequence",
121
- "csm_book",
122
- "event_invite",
123
- "exclusion",
124
- ])
125
- .describe("What the TAL is for. Drives which consumers read it."),
126
- consumerSystem: z
83
+ branch: z
127
84
  .string()
128
85
  .optional()
129
- .describe("Free-text identifier for the system that reads this TAL (e.g. 'signal_scanner', 'gong_engage'). Defaults to the purpose string."),
130
- criteria: conditionSchema.describe("DSL tree of membership conditions. See tool description for grammar + example."),
131
- refreshCadence: z
132
- .enum(["frozen", "weekly", "daily", "hourly"])
86
+ .describe("Branch to read YAML from. Default: main. Use a feature branch if you committed via update_account_master_config to a feature branch and want to test before merging."),
87
+ evaluate: z
88
+ .boolean()
133
89
  .optional()
134
- .describe("How often the evaluator should re-compute membership. 'frozen' = never recomputed. Default: weekly."),
135
- maxSize: z
136
- .number()
137
- .int()
138
- .positive()
90
+ .describe("After applying TAL changes, re-evaluate every affected TAL (criteria/is_active/max_size diffs) so membership picks up the new definition immediately. Default: true."),
91
+ dryRun: z
92
+ .boolean()
139
93
  .optional()
140
- .describe("Hard cap on TAL size. Matches above the cap are deterministically truncated. Omit for no cap."),
141
- }, safeTool(async (input) => trpcMutation("mcp.createTal", input)));
94
+ .describe("Read + validate + diff against DB without writing. Useful for previewing a TAL edit before applying."),
95
+ }, safeTool(async (input) => trpcMutation("mcp.syncAccountMasterTals", input)));
142
96
  }
143
97
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopops/mcp-server",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "Loop Operations MCP Server — AI skills for RevOps",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",