@loopops/mcp-server 2.6.0 → 2.8.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.
@@ -101,4 +101,66 @@ export function registerCompanyGraphTools(server, allowed) {
101
101
  .describe("If true, drain the queue via the matcher immediately after insert."),
102
102
  }, safeTool(async (input) => trpcMutation("mcp.importAccountsCsv", input)));
103
103
  }
104
+ if (allowed.has("show_cg_config")) {
105
+ server.tool("show_cg_config", [
106
+ "Read the current contents of a Company Graph YAML config from the repo.",
107
+ "Use this before update_cg_config to see the current state. Today only",
108
+ "`resolution_rules` exists; future entries (e.g. sfdc_field_map) join the enum.",
109
+ ].join(" "), {
110
+ file: z
111
+ .enum(["resolution_rules"])
112
+ .describe("Which file under config/cg/ to read. Today only resolution_rules."),
113
+ }, safeTool(async (input) => trpcQuery("mcp.showCgConfig", input)));
114
+ }
115
+ if (allowed.has("sync_cg_resolution_rules")) {
116
+ server.tool("sync_cg_resolution_rules", [
117
+ "Apply the committed config/cg/resolution_rules.yaml to the DB.",
118
+ "Server-side equivalent of `node scripts/cg-sync-resolution-rules.mjs --resolve`.",
119
+ "Idempotent — re-running with no YAML changes is a no-op. Pair with",
120
+ "update_cg_config to complete an edit→commit→apply cycle from one Claude",
121
+ "session, no local clone needed. Resolver backfills golden records by default.",
122
+ ].join(" "), {
123
+ branch: z
124
+ .string()
125
+ .optional()
126
+ .describe("Branch to read YAML from. Default: main. Useful for testing a feature branch's YAML before merging."),
127
+ resolve: z
128
+ .boolean()
129
+ .optional()
130
+ .describe("Re-run the resolver across affected accounts after applying rule changes so golden records update. Default: true."),
131
+ dryRun: z
132
+ .boolean()
133
+ .optional()
134
+ .describe("Read + validate + diff against DB without writing. Useful for previewing."),
135
+ }, safeTool(async (input) => trpcMutation("mcp.syncCgResolutionRules", input)));
136
+ }
137
+ if (allowed.has("update_cg_config")) {
138
+ server.tool("update_cg_config", [
139
+ "Edit a Company Graph YAML config by committing the new content to the repo",
140
+ "via the GitHub API (same pattern as update_config for per-loop configs).",
141
+ "Workflow: read the current file with show_cg_config, edit, send back via this tool.",
142
+ "Commit goes to the target branch (default `main`); Vercel auto-deploys.",
143
+ "After commit, run `node scripts/cg-sync-resolution-rules.mjs --resolve`",
144
+ "from a local clone to apply the change to the DB and backfill golden records.",
145
+ "There's no direct DB-write path — YAML is the single source of truth, drift is",
146
+ "structurally impossible.",
147
+ ].join(" "), {
148
+ file: z
149
+ .enum(["resolution_rules"])
150
+ .describe("Which file under config/cg/ to update. Today only resolution_rules."),
151
+ content: z
152
+ .string()
153
+ .min(1)
154
+ .describe("Full new YAML content (the tool replaces the file wholesale). Run show_cg_config first to read, then edit, then send back."),
155
+ message: z
156
+ .string()
157
+ .min(3)
158
+ .max(72)
159
+ .describe("Git commit message. Convention: `cg: <what changed and why>` (e.g. 'cg: drop annual_revenue min_confidence to 40 — pdl coverage sparse')."),
160
+ branch: z
161
+ .string()
162
+ .optional()
163
+ .describe("Target branch. Default: main. Pass a feature branch if you want review-before-merge."),
164
+ }, safeTool(async (input) => trpcMutation("mcp.updateCgConfig", input)));
165
+ }
104
166
  }
@@ -343,4 +343,59 @@ export function registerConfigTools(server, allowed) {
343
343
  branch: z.string().optional().describe("Branch to read YAML from. Default: main."),
344
344
  }, safeTool(async ({ mode, dryRun, useAgent, branch }) => trpcMutation("mcp.assignTerritories", { mode, dryRun, useAgent, branch })));
345
345
  }
346
+ if (allowed.has("show_govern_config")) {
347
+ server.tool("show_govern_config", [
348
+ "Read a YAML file under `config/govern/`. Most-common use: viewing",
349
+ "`schedules` to see what crons exist + their enabled/disabled state.",
350
+ "Other files: `actions`, `agent`, `audit_config`, `compliance_rules`,",
351
+ "`health_monitoring`.",
352
+ ].join(" "), {
353
+ file: z
354
+ .enum([
355
+ "schedules",
356
+ "actions",
357
+ "agent",
358
+ "audit_config",
359
+ "compliance_rules",
360
+ "health_monitoring",
361
+ ])
362
+ .describe("Which file under config/govern/ to read. `schedules` is the cron table."),
363
+ }, safeTool(async (input) => trpcQuery("mcp.showGovernConfig", input)));
364
+ }
365
+ if (allowed.has("update_govern_config")) {
366
+ server.tool("update_govern_config", [
367
+ "Edit a Company Operations governance YAML config (config/govern/*.yaml)",
368
+ "by committing the new content to the repo via the GitHub API.",
369
+ "Most-common use: flipping a cron entry's `enabled: true/false` in",
370
+ "`schedules.yaml`. Workflow: read with show_govern_config, edit, send",
371
+ "back. Commit goes to target branch (default `main`); Vercel auto-deploys.",
372
+ "Schedule changes take effect at the next scheduler tick. Adding or",
373
+ "removing a schedule (not just toggling) also requires a matching",
374
+ "vercel.json edit.",
375
+ ].join(" "), {
376
+ file: z
377
+ .enum([
378
+ "schedules",
379
+ "actions",
380
+ "agent",
381
+ "audit_config",
382
+ "compliance_rules",
383
+ "health_monitoring",
384
+ ])
385
+ .describe("Which file under config/govern/ to update. `schedules` is the cron table."),
386
+ content: z
387
+ .string()
388
+ .min(1)
389
+ .describe("Full new YAML content. The tool replaces the file wholesale — read with show_govern_config first, edit, send back. Don't drop unrelated entries."),
390
+ message: z
391
+ .string()
392
+ .min(3)
393
+ .max(72)
394
+ .describe("Git commit message. Convention: `govern: <what changed and why>` (e.g. 'govern: disable cg_sync_clickhouse cron temporarily')."),
395
+ branch: z
396
+ .string()
397
+ .optional()
398
+ .describe("Target branch. Default: main. Pass a feature branch for review-before-merge."),
399
+ }, safeTool(async (input) => trpcMutation("mcp.updateGovernConfig", input)));
400
+ }
346
401
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopops/mcp-server",
3
- "version": "2.6.0",
3
+ "version": "2.8.0",
4
4
  "description": "Loop Operations MCP Server — AI skills for RevOps",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",