@loopops/mcp-server 3.0.0 → 3.2.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/tools/account-master.js +121 -1
- package/package.json +1 -1
|
@@ -101,6 +101,120 @@ export function registerAccountMasterTools(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("override_account_attribute")) {
|
|
105
|
+
server.tool("override_account_attribute", [
|
|
106
|
+
"Manually correct one resolved attribute on one account by writing a high-confidence",
|
|
107
|
+
"`manual` provider observation. Because every resolution rule has `manual` first in",
|
|
108
|
+
"`providers_in_order`, the next resolver run picks the manual value over any other",
|
|
109
|
+
"provider's, and the golden record updates immediately (with `resolveAfter:true`, the",
|
|
110
|
+
"default).",
|
|
111
|
+
"",
|
|
112
|
+
"Identify the account by ANY ONE of: accountId (UUID), domain, sfAccountId, or accountName.",
|
|
113
|
+
"Use accountId or domain for unambiguous matching — accountName is normalized but may",
|
|
114
|
+
"resolve to multiple accounts (the call fails with the candidate list if so).",
|
|
115
|
+
"",
|
|
116
|
+
"The `reason` field is required and stored on the row's audit payload — every manual",
|
|
117
|
+
"override is traceable to who set it, when, and why. Append-only: re-running enrichment",
|
|
118
|
+
"from PDL/D&B/etc. cannot dislodge a manual row. To revert, write a new override with",
|
|
119
|
+
"the corrected value (the resolver always picks the most recent qualifying manual row).",
|
|
120
|
+
].join(" "), {
|
|
121
|
+
accountId: z
|
|
122
|
+
.string()
|
|
123
|
+
.uuid()
|
|
124
|
+
.optional()
|
|
125
|
+
.describe("Account Master account_id (UUID). Most precise key."),
|
|
126
|
+
domain: z
|
|
127
|
+
.string()
|
|
128
|
+
.min(1)
|
|
129
|
+
.optional()
|
|
130
|
+
.describe("Domain (e.g. 'snowflake.com'). Unambiguous in practice."),
|
|
131
|
+
sfAccountId: z
|
|
132
|
+
.string()
|
|
133
|
+
.min(3)
|
|
134
|
+
.optional()
|
|
135
|
+
.describe("Salesforce Account ID (15- or 18-char SF id)."),
|
|
136
|
+
accountName: z
|
|
137
|
+
.string()
|
|
138
|
+
.min(1)
|
|
139
|
+
.optional()
|
|
140
|
+
.describe("Company name. Matched after normalization. Use accountId or domain when possible — accountName can be ambiguous."),
|
|
141
|
+
attribute: z
|
|
142
|
+
.string()
|
|
143
|
+
.min(1)
|
|
144
|
+
.max(64)
|
|
145
|
+
.regex(/^[a-z0-9_]+$/)
|
|
146
|
+
.describe("Attribute name in snake_case (e.g. 'hq_state', 'industry_naics', 'employee_count'). Must match the `attribute_name` used in resolution rules."),
|
|
147
|
+
value: z
|
|
148
|
+
.string()
|
|
149
|
+
.min(1)
|
|
150
|
+
.max(2048)
|
|
151
|
+
.describe("The corrected value as text. Numeric attributes auto-parse into `attribute_value_numeric` for range queries."),
|
|
152
|
+
reason: z
|
|
153
|
+
.string()
|
|
154
|
+
.min(3)
|
|
155
|
+
.max(512)
|
|
156
|
+
.describe("Why this override is warranted. Stored in the row's audit payload and surfaces in account_show provenance. Required."),
|
|
157
|
+
resolveAfter: z
|
|
158
|
+
.boolean()
|
|
159
|
+
.optional()
|
|
160
|
+
.describe("Re-run the resolver for this (account, attribute) immediately so the golden record updates now. Default: true."),
|
|
161
|
+
}, safeTool(async (input) => trpcMutation("mcp.overrideAccountAttribute", input)));
|
|
162
|
+
}
|
|
163
|
+
if (allowed.has("deactivate_account_attribute_override")) {
|
|
164
|
+
server.tool("deactivate_account_attribute_override", [
|
|
165
|
+
"Soft-toggle off a manual override on one (account, attribute). Writes a new manual",
|
|
166
|
+
"`provider_attribute_value` row with `confidence_score=0` and `attribute_value=NULL`.",
|
|
167
|
+
"The resolver's latest-period semantic (PR #148) makes the manual provider drop out,",
|
|
168
|
+
"so other providers (D&B, PDL, ZoomInfo, etc.) take over for this attribute.",
|
|
169
|
+
"",
|
|
170
|
+
"Append-only: the original override row stays in place historically. To re-enable, call",
|
|
171
|
+
"`override_account_attribute` again with a fresh value — the new manual row supersedes",
|
|
172
|
+
"this deactivation because the resolver picks the most-recent manual row.",
|
|
173
|
+
"",
|
|
174
|
+
"Identify the account by ANY ONE of: accountId / domain / sfAccountId / accountName.",
|
|
175
|
+
"Refuses to write if no prior manual override exists for the (account, attribute).",
|
|
176
|
+
"",
|
|
177
|
+
"Common workflow: PDL data was stale → manual override applied →",
|
|
178
|
+
"PDL/D&B refreshes with correct data → deactivate the manual override so the new",
|
|
179
|
+
"provider data takes over without manual maintenance.",
|
|
180
|
+
].join(" "), {
|
|
181
|
+
accountId: z
|
|
182
|
+
.string()
|
|
183
|
+
.uuid()
|
|
184
|
+
.optional()
|
|
185
|
+
.describe("Account Master account_id (UUID)."),
|
|
186
|
+
domain: z
|
|
187
|
+
.string()
|
|
188
|
+
.min(1)
|
|
189
|
+
.optional()
|
|
190
|
+
.describe("Domain (e.g. 'snowflake.com')."),
|
|
191
|
+
sfAccountId: z
|
|
192
|
+
.string()
|
|
193
|
+
.min(3)
|
|
194
|
+
.optional()
|
|
195
|
+
.describe("Salesforce Account ID."),
|
|
196
|
+
accountName: z
|
|
197
|
+
.string()
|
|
198
|
+
.min(1)
|
|
199
|
+
.optional()
|
|
200
|
+
.describe("Company name. Use accountId or domain when possible — accountName can be ambiguous."),
|
|
201
|
+
attribute: z
|
|
202
|
+
.string()
|
|
203
|
+
.min(1)
|
|
204
|
+
.max(64)
|
|
205
|
+
.regex(/^[a-z0-9_]+$/)
|
|
206
|
+
.describe("Attribute name (e.g. 'hq_state'). Must match a prior manual override row."),
|
|
207
|
+
reason: z
|
|
208
|
+
.string()
|
|
209
|
+
.min(3)
|
|
210
|
+
.max(512)
|
|
211
|
+
.describe("Why is this override no longer warranted? Stored in audit payload."),
|
|
212
|
+
resolveAfter: z
|
|
213
|
+
.boolean()
|
|
214
|
+
.optional()
|
|
215
|
+
.describe("Re-run the resolver immediately so the golden record updates. Default: true."),
|
|
216
|
+
}, safeTool(async (input) => trpcMutation("mcp.deactivateAccountAttributeOverride", input)));
|
|
217
|
+
}
|
|
104
218
|
if (allowed.has("show_account_master_config")) {
|
|
105
219
|
server.tool("show_account_master_config", [
|
|
106
220
|
"Read the current contents of a Account Master YAML config from the repo.",
|
|
@@ -136,7 +250,7 @@ export function registerAccountMasterTools(server, allowed) {
|
|
|
136
250
|
}
|
|
137
251
|
if (allowed.has("update_account_master_config")) {
|
|
138
252
|
server.tool("update_account_master_config", [
|
|
139
|
-
"Edit
|
|
253
|
+
"Edit an Account Master YAML config by committing the new content to the repo",
|
|
140
254
|
"via the GitHub API (same pattern as update_config for per-loop configs).",
|
|
141
255
|
"Workflow: read the current file with show_account_master_config, edit, send back via this tool.",
|
|
142
256
|
"Commit goes to the target branch (default `main`); Vercel auto-deploys.",
|
|
@@ -144,6 +258,12 @@ export function registerAccountMasterTools(server, allowed) {
|
|
|
144
258
|
"from a local clone to apply the change to the DB and backfill golden records.",
|
|
145
259
|
"There's no direct DB-write path — YAML is the single source of truth, drift is",
|
|
146
260
|
"structurally impossible.",
|
|
261
|
+
"Resolution rules support optional per-provider overrides under",
|
|
262
|
+
"`rule_config.provider_overrides`: a map keyed on provider name with optional",
|
|
263
|
+
"`min_confidence` and `max_age_days` (where `null` means 'no age cap for this",
|
|
264
|
+
"provider'). Useful when one provider's confidence scale differs from another,",
|
|
265
|
+
"or when one provider refreshes on a different cadence. Override keys must appear",
|
|
266
|
+
"in `providers_in_order` / `eligible_providers` (sync validates this).",
|
|
147
267
|
].join(" "), {
|
|
148
268
|
file: z
|
|
149
269
|
.enum(["resolution_rules"])
|