@loopops/mcp-server 3.3.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.
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ import { registerEngTools } from "./tools/eng.js";
13
13
  import { registerCrmTools } from "./tools/crm.js";
14
14
  import { registerEngageTools } from "./tools/engage.js";
15
15
  import { registerAccountMasterTools } from "./tools/account-master.js";
16
+ import { registerTalTools } from "./tools/tal.js";
16
17
  // Read our own package.json at runtime so the version baked into MCP
17
18
  // initialize-handshake `serverInfo.version` matches the published npm
18
19
  // version. Was hardcoded "1.0.0" — confusing in Claude Desktop logs and
@@ -55,5 +56,6 @@ registerEngTools(server, allowedSkills);
55
56
  registerCrmTools(server, allowedSkills);
56
57
  registerEngageTools(server, allowedSkills);
57
58
  registerAccountMasterTools(server, allowedSkills);
59
+ registerTalTools(server, allowedSkills);
58
60
  const transport = new StdioServerTransport();
59
61
  await server.connect(transport);
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Target Account List (TAL) MCP tool wrappers.
3
+ *
4
+ * Phase 3.5.5 of docs/ACCOUNT-MASTER-PLAN.md.
5
+ *
6
+ * Tools (ops + eng):
7
+ * list_tals — catalog of every TAL with member counts
8
+ * show_tal_membership — paginated members of one TAL with key attributes
9
+ * evaluate_tal_now — manual trigger for the evaluator (one TAL)
10
+ * create_tal — define a new TAL with criteria + cadence
11
+ *
12
+ * tRPC procedures live in packages/api/src/routers/mcp.ts; input schemas
13
+ * in packages/api/src/routers/mcp-schemas.ts.
14
+ */
15
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
16
+ export declare function registerTalTools(server: McpServer, allowed: Set<string>): void;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Target Account List (TAL) MCP tool wrappers.
3
+ *
4
+ * Phase 3.5.5 of docs/ACCOUNT-MASTER-PLAN.md.
5
+ *
6
+ * Tools (ops + eng):
7
+ * list_tals — catalog of every TAL with member counts
8
+ * show_tal_membership — paginated members of one TAL with key attributes
9
+ * evaluate_tal_now — manual trigger for the evaluator (one TAL)
10
+ * create_tal — define a new TAL with criteria + cadence
11
+ *
12
+ * tRPC procedures live in packages/api/src/routers/mcp.ts; input schemas
13
+ * in packages/api/src/routers/mcp-schemas.ts.
14
+ */
15
+ import { z } from "zod";
16
+ import { trpcMutation, trpcQuery } from "../api-client.js";
17
+ import { safeTool } from "./_helpers.js";
18
+ const talIdentifierShape = {
19
+ talName: z
20
+ .string()
21
+ .min(1)
22
+ .optional()
23
+ .describe("Human-readable TAL name (e.g. 'signal_scanner_targets'). Easier to type than the UUID."),
24
+ talId: z
25
+ .string()
26
+ .uuid()
27
+ .optional()
28
+ .describe("TAL UUID. Use list_tals to discover it."),
29
+ };
30
+ export function registerTalTools(server, allowed) {
31
+ if (allowed.has("list_tals")) {
32
+ server.tool("list_tals", "Catalog every Target Account List (TAL): name, purpose, member count, cadence, active state, when last evaluated. TALs are named, criteria-based sets of accounts used by downstream consumers (signal scanner, ABM, outbound sequences, exclusion lists). Use this to discover what TALs exist before invoking show_tal_membership or evaluate_tal_now.", {
33
+ purpose: z
34
+ .string()
35
+ .min(1)
36
+ .optional()
37
+ .describe("Filter to a single purpose ('signal_scanner', 'outbound_sequence', 'abm_advertising', 'exclusion', etc.). Omit to see all."),
38
+ includeInactive: z
39
+ .boolean()
40
+ .optional()
41
+ .describe("Include TALs where is_active=false. Default: false."),
42
+ }, safeTool(async (input) => trpcQuery("mcp.listTals", input)));
43
+ }
44
+ if (allowed.has("show_tal_membership")) {
45
+ server.tool("show_tal_membership", "Show members of one Target Account List with their domain, segment, status, and when each was added. Includes the TAL's full membership criteria (DSL JSON) for context. Identify the TAL by tal_name (preferred) or tal_id. Capped at 100 members by default; pass `limit` for more.", {
46
+ ...talIdentifierShape,
47
+ limit: z
48
+ .number()
49
+ .int()
50
+ .positive()
51
+ .max(500)
52
+ .optional()
53
+ .describe("Max members to return (1–500). Default: 100."),
54
+ }, safeTool(async (input) => trpcQuery("mcp.showTalMembership", input)));
55
+ }
56
+ if (allowed.has("evaluate_tal_now")) {
57
+ server.tool("evaluate_tal_now", "Manually trigger the TAL evaluator for one TAL right now. Re-computes membership against the current resolved record and applies adds/removes (with audit-log events). Use after editing a TAL's criteria, after a bulk enrichment run that may have changed which accounts qualify, or to skip waiting for the next scheduled evaluator pass. Pass `dryRun: true` to preview the changes without writing.", {
58
+ ...talIdentifierShape,
59
+ dryRun: z
60
+ .boolean()
61
+ .optional()
62
+ .describe("If true, classify changes but skip writes. Useful for previewing the impact of a criteria edit. Default: false."),
63
+ }, safeTool(async (input) => trpcMutation("mcp.evaluateTalNow", input)));
64
+ }
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.",
70
+ "",
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)",
75
+ "",
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.",
82
+ ].join("\n"), {
83
+ branch: z
84
+ .string()
85
+ .optional()
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()
89
+ .optional()
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()
93
+ .optional()
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)));
96
+ }
97
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopops/mcp-server",
3
- "version": "3.3.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",