@loopops/mcp-server 3.12.0 → 3.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 CHANGED
@@ -9,6 +9,7 @@ import { trpcQuery } from "./api-client.js";
9
9
  import { registerIdentityTools } from "./tools/identity.js";
10
10
  import { registerReportingTools } from "./tools/reporting.js";
11
11
  import { registerConfigTools } from "./tools/config.js";
12
+ import { registerDeployTools } from "./tools/deploy.js";
12
13
  import { registerEngTools } from "./tools/eng.js";
13
14
  import { registerCrmTools } from "./tools/crm.js";
14
15
  import { registerEngageTools } from "./tools/engage.js";
@@ -60,6 +61,7 @@ registerCrmTools(server, allowedSkills);
60
61
  registerEngageTools(server, allowedSkills);
61
62
  registerAccountMasterTools(server, allowedSkills);
62
63
  registerPeopleMasterTools(server, allowedSkills);
64
+ registerDeployTools(server, allowedSkills);
63
65
  registerTalTools(server, allowedSkills);
64
66
  registerScoringTools(server, allowedSkills);
65
67
  registerSfdcSyncTools(server, allowedSkills);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Deploy — placement-pipeline MCP tools (ops+).
3
+ *
4
+ * Phase 1.2 (this file) ships the first user-placement tool:
5
+ * propose_user_assignments — run the Python placement model on Modal,
6
+ * persist proposals against an open
7
+ * planning_cycle. See docs/DEPLOY-PLAN.md.
8
+ *
9
+ * The review/edit/approve/commit triplet (Phase 1.3–1.5) lands here too
10
+ * as it ships. Quota + account placement (Phases 2–3) get separate
11
+ * groups on top.
12
+ *
13
+ * tRPC procedures live in packages/api/src/routers/mcp.ts; input schemas
14
+ * in packages/api/src/routers/mcp-schemas.ts.
15
+ */
16
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
17
+ export declare function registerDeployTools(server: McpServer, allowed: Set<string>): void;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Deploy — placement-pipeline MCP tools (ops+).
3
+ *
4
+ * Phase 1.2 (this file) ships the first user-placement tool:
5
+ * propose_user_assignments — run the Python placement model on Modal,
6
+ * persist proposals against an open
7
+ * planning_cycle. See docs/DEPLOY-PLAN.md.
8
+ *
9
+ * The review/edit/approve/commit triplet (Phase 1.3–1.5) lands here too
10
+ * as it ships. Quota + account placement (Phases 2–3) get separate
11
+ * groups on top.
12
+ *
13
+ * tRPC procedures live in packages/api/src/routers/mcp.ts; input schemas
14
+ * in packages/api/src/routers/mcp-schemas.ts.
15
+ */
16
+ import { z } from "zod";
17
+ import { trpcMutation } from "../api-client.js";
18
+ import { safeTool } from "./_helpers.js";
19
+ export function registerDeployTools(server, allowed) {
20
+ if (allowed.has("propose_user_assignments")) {
21
+ server.tool("propose_user_assignments", [
22
+ "Run the user-placement model for an open planning cycle. The",
23
+ "model walks the active scenario's roster + the current",
24
+ "config/deploy/assignments.yaml and emits one proposal row per AE",
25
+ "across three kinds: 'assign' (planned hire onto a new territory),",
26
+ "'ratify' (existing AE staying put), 'depart' (AE in",
27
+ "assignments.yaml but not in the roster — will be removed at",
28
+ "commit). Patches in hierarchy.yaml not covered by any",
29
+ "assign/ratify proposal surface as 'uncovered territories'",
30
+ "warnings. Re-running on the same cycle supersedes the prior set",
31
+ "of proposals — the partial unique index keeps only one active",
32
+ "proposal per (cycle, user). Pass dryRun:true to preview the",
33
+ "model output without writing to the proposal table.",
34
+ ].join(" "), {
35
+ planningCycleId: z
36
+ .string()
37
+ .uuid()
38
+ .optional()
39
+ .describe("Planning cycle to write proposals against. Defaults to the org's currently-open cycle if exactly one exists; if multiple open or none, the call returns an error listing the cycles found."),
40
+ scenarioId: z
41
+ .string()
42
+ .optional()
43
+ .describe("Override which scenario to load (e.g. 'stretch'). Default: 'base'. Must exist in config/design/scenarios/."),
44
+ dryRun: z
45
+ .boolean()
46
+ .optional()
47
+ .describe("Run the model and return proposals without persisting. Useful for previewing what the model would emit before committing to a cycle. Default: false."),
48
+ branch: z
49
+ .string()
50
+ .optional()
51
+ .describe("Git branch to read configs from. Default: main."),
52
+ }, safeTool(async (input) => trpcMutation("mcp.proposeUserAssignments", input)));
53
+ }
54
+ }
@@ -142,6 +142,33 @@ export function registerPeopleMasterTools(server, allowed) {
142
142
  return trpcMutation("mcp.importPeopleCsv", { csv, ...rest });
143
143
  }));
144
144
  }
145
+ if (allowed.has("notify_activity_capture")) {
146
+ server.tool("notify_activity_capture", [
147
+ "Send the one-time privacy notification email to cro_org members whose meeting",
148
+ "metadata is being captured. Defaults to dryRun: true so the operator previews the",
149
+ "recipient list before committing. Idempotent — re-running drains only un-notified",
150
+ "persons. Required step before flipping the activity-capture cron from disabled to",
151
+ "enabled in config/govern/schedules.yaml.",
152
+ ].join(" "), {
153
+ walkId: z
154
+ .string()
155
+ .optional()
156
+ .describe("Walk id from config/people_master/hierarchy_walks.yaml. Default: 'cro_org'."),
157
+ dryRun: z
158
+ .boolean()
159
+ .optional()
160
+ .describe("When true (default), returns the would-be recipients without sending. Pass false to actually send."),
161
+ personIds: z
162
+ .array(z.string().uuid())
163
+ .optional()
164
+ .describe("Restrict to a specific subset of person ids (e.g. for a test send before broadcast). Empty = full walk."),
165
+ privacyDocUrl: z
166
+ .string()
167
+ .url()
168
+ .optional()
169
+ .describe("Optional 'Learn more' URL surfaced as a button in the email body. Omit to hide."),
170
+ }, safeTool(async (input) => trpcMutation("mcp.notifyActivityCapture", input)));
171
+ }
145
172
  if (allowed.has("sync_people_master_resolution_rules")) {
146
173
  server.tool("sync_people_master_resolution_rules", [
147
174
  "Apply the committed config/people_master/resolution_rules.yaml to the DB.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopops/mcp-server",
3
- "version": "3.12.0",
3
+ "version": "3.14.0",
4
4
  "description": "Loop Operations MCP Server — AI skills for RevOps",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",