@sodiumhq/mcp-pm 0.1.0-beta.4489 → 0.1.0-beta.4707
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/README.md +1 -0
- package/dist/http.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-Ik7PFVX1.mjs → src-DNCbW1Ge.mjs} +170 -44
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -153,6 +153,7 @@ Only enable write mode with an AI client you trust — it hands the client the a
|
|
|
153
153
|
- **`update_task`** — change a task's status, dates, assignment, or details. Only the fields you mention change; everything else is preserved. "Mark TSK-123 complete", "push the deadline to Friday", "reassign it to Jane."
|
|
154
154
|
- **`update_workflow_step`** — complete, skip, block, or reassign a single workflow step on a task. "Mark the review step as done", "skip the client-approval step — they confirmed by phone."
|
|
155
155
|
- **`add_client_service`** — put a client on a catalogue service with frequency, pricing, and start date. "Put ACME on monthly bookkeeping."
|
|
156
|
+
- **`apply_service_package`** — put a client on one of the practice's bundled packages in a single call; contents and pricing follow the package definition. "Put ACME on the Growth package from 1 April."
|
|
156
157
|
- **`update_client_service_stage`** — move a client's service across the kanban board. "Move ACME's VAT return to Records In."
|
|
157
158
|
- **`create_document_request`** — draft (never send) a document request for a client. Sending stays in the Sodium UI.
|
|
158
159
|
- **`send_data_form`** — send a questionnaire to a client. Sends immediately, so your assistant confirms with you first.
|
package/dist/http.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as buildServer } from "./src-
|
|
2
|
+
import { t as buildServer } from "./src-DNCbW1Ge.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { createHash, randomUUID } from "node:crypto";
|
|
5
5
|
import { createServer } from "node:http";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as buildServer } from "./src-
|
|
2
|
+
import { t as buildServer } from "./src-DNCbW1Ge.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
import { parseArgs } from "node:util";
|
|
@@ -1719,6 +1719,26 @@ const listServicePackages = (options) => (options.client ?? client).get({
|
|
|
1719
1719
|
...options
|
|
1720
1720
|
});
|
|
1721
1721
|
/**
|
|
1722
|
+
* Apply Service Package to Client
|
|
1723
|
+
*
|
|
1724
|
+
* Applies a service package to a client, creating ClientBillableService records for each item in the package.
|
|
1725
|
+
*/
|
|
1726
|
+
const applyServicePackageToClient = (options) => (options.client ?? client).post({
|
|
1727
|
+
security: [{
|
|
1728
|
+
name: "x-api-key",
|
|
1729
|
+
type: "apiKey"
|
|
1730
|
+
}, {
|
|
1731
|
+
scheme: "bearer",
|
|
1732
|
+
type: "http"
|
|
1733
|
+
}],
|
|
1734
|
+
url: "/tenants/{tenant}/clients/{clientCode}/apply-service-package/{packageCode}",
|
|
1735
|
+
...options,
|
|
1736
|
+
headers: {
|
|
1737
|
+
"Content-Type": "application/json",
|
|
1738
|
+
...options.headers
|
|
1739
|
+
}
|
|
1740
|
+
});
|
|
1741
|
+
/**
|
|
1722
1742
|
* List BillableServices
|
|
1723
1743
|
*
|
|
1724
1744
|
* Lists all BillableServices for the given tenant.
|
|
@@ -3403,6 +3423,21 @@ var SodiumApiClient = class {
|
|
|
3403
3423
|
if (error !== void 0 || !data) throw this.toError(response, error, correlationId, `assign service to client ${clientCode}`);
|
|
3404
3424
|
return data;
|
|
3405
3425
|
}
|
|
3426
|
+
async applyServicePackageToClient(clientCode, packageCode, body) {
|
|
3427
|
+
const correlationId = randomUUID();
|
|
3428
|
+
const { data, error, response } = await applyServicePackageToClient({
|
|
3429
|
+
path: {
|
|
3430
|
+
tenant: this.tenant,
|
|
3431
|
+
clientCode,
|
|
3432
|
+
packageCode
|
|
3433
|
+
},
|
|
3434
|
+
body,
|
|
3435
|
+
headers: { "X-Correlation-Id": correlationId },
|
|
3436
|
+
client: this.http
|
|
3437
|
+
});
|
|
3438
|
+
if (error !== void 0 || !data) throw this.toError(response, error, correlationId, `apply package ${packageCode} to client ${clientCode}`);
|
|
3439
|
+
return data;
|
|
3440
|
+
}
|
|
3406
3441
|
async updateClientServiceStage(clientCode, clientServiceCode, body) {
|
|
3407
3442
|
const correlationId = randomUUID();
|
|
3408
3443
|
const { error, response } = await updateClientBillableServiceStage({
|
|
@@ -3542,7 +3577,7 @@ var SodiumApiClient = class {
|
|
|
3542
3577
|
//#endregion
|
|
3543
3578
|
//#region ../mcp-core/src/context/instructions.ts
|
|
3544
3579
|
const ROSTER_CAP = 20;
|
|
3545
|
-
async function buildInstructions(api,
|
|
3580
|
+
async function buildInstructions(api, ctx, selection) {
|
|
3546
3581
|
const [user, tenant, practice, team] = await Promise.allSettled([
|
|
3547
3582
|
api.getCurrentUser(),
|
|
3548
3583
|
api.getTenantDetails(),
|
|
@@ -3592,7 +3627,8 @@ async function buildInstructions(api, writesEnabled, selection) {
|
|
|
3592
3627
|
} else lines.push("Call list_practices to see the available practices.");
|
|
3593
3628
|
} else if (selection.kind === "none") lines.push("", "This user does not belong to any usable practice. Tell them their Sodium account has no active practice and there is nothing to show.");
|
|
3594
3629
|
else if (selection.kind === "auto") lines.push("", `Working in ${selection.practice.name} (${selection.practice.code}) — the only practice this user belongs to. It is selected automatically; no 'practice' argument is needed.`);
|
|
3595
|
-
|
|
3630
|
+
const isStdio = Boolean(ctx.apiKey) && !ctx.bearerToken;
|
|
3631
|
+
lines.push("", ctx.writesEnabled ? "Write mode: ENABLED. Create and update tools are available; delete and bulk operations are not exposed." : isStdio ? "Write mode: DISABLED. Read-only — tell the user to restart the server with --enable-writes (or SODIUM_ENABLE_WRITES=true) if they want changes made." : "Write mode: DISABLED. Read-only — this connection was authorised for read access only. Tell the user to reconnect the Sodium connector and approve write access if they want changes made.");
|
|
3596
3632
|
if (team.status === "fulfilled") {
|
|
3597
3633
|
const members = team.value.data ?? [];
|
|
3598
3634
|
const total = team.value.totalCount ?? members.length;
|
|
@@ -3738,7 +3774,7 @@ async function handleGetPracticeDetails(api) {
|
|
|
3738
3774
|
}
|
|
3739
3775
|
//#endregion
|
|
3740
3776
|
//#region ../mcp-core/src/tools/list-clients.ts
|
|
3741
|
-
const statusEnum$
|
|
3777
|
+
const statusEnum$15 = z.enum([
|
|
3742
3778
|
"Active",
|
|
3743
3779
|
"Inactive",
|
|
3744
3780
|
"Prospect",
|
|
@@ -3757,7 +3793,7 @@ const typeEnum$1 = z.enum([
|
|
|
3757
3793
|
const sortByEnum$19 = z.enum(["Name", "InternalReference"]);
|
|
3758
3794
|
const ListClientsInputSchema = {
|
|
3759
3795
|
search: z.string().min(3, "Search must be at least 3 characters when provided").optional().describe("Free-text search across client code, name, and internal reference. Minimum 3 characters. Omit to browse by filter only."),
|
|
3760
|
-
status: z.array(statusEnum$
|
|
3796
|
+
status: z.array(statusEnum$15).optional().describe("Filter by client status. Defaults to all statuses if omitted. Example: ['Active'] for active clients only."),
|
|
3761
3797
|
type: z.array(typeEnum$1).optional().describe("Filter by organisation type. Use ['PrivateLimitedCompany', 'PublicLimitedCompany'] for 'limited companies'. Use ['LimitedLiabilityPartnership'] for LLPs. Defaults to all types if omitted."),
|
|
3762
3798
|
managerCode: z.array(z.string()).optional().describe("Filter by assigned manager user codes."),
|
|
3763
3799
|
partnerCode: z.array(z.string()).optional().describe("Filter by assigned partner user codes."),
|
|
@@ -4544,7 +4580,7 @@ function describeFilters$3(args) {
|
|
|
4544
4580
|
}
|
|
4545
4581
|
//#endregion
|
|
4546
4582
|
//#region ../mcp-core/src/tools/list-tasks.ts
|
|
4547
|
-
const statusEnum$
|
|
4583
|
+
const statusEnum$14 = z.enum([
|
|
4548
4584
|
"NotStarted",
|
|
4549
4585
|
"InProgress",
|
|
4550
4586
|
"Blocked",
|
|
@@ -4587,7 +4623,7 @@ const sortByEnum$17 = z.enum([
|
|
|
4587
4623
|
const ListTasksInputSchema = {
|
|
4588
4624
|
user: z.array(z.string()).optional().describe("Filter by assigned user codes. For 'my tasks' use the current user's code from the startup context. For another team member's tasks, pass their code. Omit to see tasks across all users (useful for practice managers)."),
|
|
4589
4625
|
client: z.array(z.string()).optional().describe("Filter by client codes — tasks belonging to these specific clients only."),
|
|
4590
|
-
status: z.array(statusEnum$
|
|
4626
|
+
status: z.array(statusEnum$14).optional().describe("Filter by task status. Typical: ['NotStarted', 'InProgress'] to exclude completed/skipped. Leave empty for all statuses. IMPORTANT: if the query includes NotStarted (the default for new tasks), you must ALSO provide one of: dateRange, isOverdue=true, or restrict status to non-NotStarted values only — otherwise the API rejects the call to prevent unbounded queries."),
|
|
4591
4627
|
isOverdue: z.boolean().optional().describe("Set true to return only overdue tasks (DueDate before today, not completed/skipped). When true, no date range is required. Useful for sidestepping the NotStarted + date-range requirement."),
|
|
4592
4628
|
dateRange: dateRangeEnum$2.optional().describe("Preset date range. Use 'Today' for today's tasks, 'Next7Days' for 'due this week', 'Last30Days' for recent activity. If 'CustomDateRange', also provide startDate and/or endDate. REQUIRED when querying NotStarted tasks unless you pass isOverdue=true."),
|
|
4593
4629
|
startDate: z.string().optional().describe("Start of custom date range (YYYY-MM-DD). Used when dateRange='CustomDateRange'. Prefer specifying both startDate and endDate with a narrow window for performance — broad ranges strain the API. If startDate > endDate the API swaps them silently. Maximum allowed total range is 2 years."),
|
|
@@ -4665,7 +4701,7 @@ function describeFilters$2(args) {
|
|
|
4665
4701
|
}
|
|
4666
4702
|
//#endregion
|
|
4667
4703
|
//#region ../mcp-core/src/tools/list-users.ts
|
|
4668
|
-
const statusEnum$
|
|
4704
|
+
const statusEnum$13 = z.enum([
|
|
4669
4705
|
"Created",
|
|
4670
4706
|
"Invited",
|
|
4671
4707
|
"Active",
|
|
@@ -4685,7 +4721,7 @@ const sortByEnum$16 = z.enum([
|
|
|
4685
4721
|
]);
|
|
4686
4722
|
const ListUsersInputSchema = {
|
|
4687
4723
|
search: z.string().min(3, "Search must be at least 3 characters when provided").optional().describe("Free-text search across user code, first name, last name, and email. Minimum 3 characters. Use for 'find Jane' when the name isn't in the startup roster (large teams, non-active users)."),
|
|
4688
|
-
status: statusEnum$
|
|
4724
|
+
status: statusEnum$13.optional().describe("Filter by a single user status. Use 'Active' for currently-working members, 'Invited' for pending invitations, 'Disabled' for offboarded users, 'Deleted' for removed users. Note: this is a single value, not an array."),
|
|
4689
4725
|
systemRole: systemRoleEnum.optional().describe("Filter by system role. Admin = full access, StandardUser = normal access, Viewer = read-only. Single value."),
|
|
4690
4726
|
isClientManager: z.boolean().optional().describe("Set true to return only users flagged as client managers; false to exclude them."),
|
|
4691
4727
|
isPartner: z.boolean().optional().describe("Set true to return only users flagged as partners; false to exclude them. Use for 'list partners' queries."),
|
|
@@ -6199,7 +6235,7 @@ async function handleGetCompaniesHouseProfile(api, args) {
|
|
|
6199
6235
|
}
|
|
6200
6236
|
//#endregion
|
|
6201
6237
|
//#region ../mcp-core/src/tools/list-document-requests.ts
|
|
6202
|
-
const statusEnum$
|
|
6238
|
+
const statusEnum$12 = z.enum([
|
|
6203
6239
|
"Draft",
|
|
6204
6240
|
"Open",
|
|
6205
6241
|
"Submitted",
|
|
@@ -6213,7 +6249,7 @@ const sortByEnum$11 = z.enum([
|
|
|
6213
6249
|
"Deadline"
|
|
6214
6250
|
]);
|
|
6215
6251
|
const ListDocumentRequestsInputSchema = {
|
|
6216
|
-
status: statusEnum$
|
|
6252
|
+
status: statusEnum$12.optional().describe("Filter by request status. 'Open' = sent and waiting on the client (use for 'what are we waiting on from clients?'). 'Submitted' = client responded, awaiting practice review (use for 'what needs reviewing?'). 'Draft' = not yet sent. 'Accepted'/'Rejected' = reviewed. Single value — call per status for multiple."),
|
|
6217
6253
|
clientCode: z.string().optional().describe("Filter to one client's document requests. Get the code from list_clients."),
|
|
6218
6254
|
managerCode: z.string().optional().describe("Filter by the client manager's user code — 'what are MY clients waiting to send us?' for a manager."),
|
|
6219
6255
|
partnerCode: z.string().optional().describe("Filter by the client partner's user code."),
|
|
@@ -6279,10 +6315,10 @@ async function handleListDocumentRequests(api, args) {
|
|
|
6279
6315
|
}
|
|
6280
6316
|
//#endregion
|
|
6281
6317
|
//#region ../mcp-core/src/tools/list-data-form-requests.ts
|
|
6282
|
-
const statusEnum$
|
|
6318
|
+
const statusEnum$11 = z.enum(["PendingResponse", "ResponseReceived"]);
|
|
6283
6319
|
const sortByEnum$10 = z.enum(["CreatedDate", "Status"]);
|
|
6284
6320
|
const ListDataFormRequestsInputSchema = {
|
|
6285
|
-
status: statusEnum$
|
|
6321
|
+
status: statusEnum$11.optional().describe("Filter by request status. 'PendingResponse' = sent, waiting on the client to fill the form in (use for 'which questionnaires are clients sitting on?'). 'ResponseReceived' = the client submitted — answers may still need review (see pendingReviewCount in the output)."),
|
|
6286
6322
|
clientCode: z.string().optional().describe("Filter to one client's form requests. Get the code from list_clients."),
|
|
6287
6323
|
formCode: z.string().optional().describe("Filter by the data-form template code — 'who still hasn't returned the SA questionnaire?'."),
|
|
6288
6324
|
categoryCode: z.string().optional().describe("Filter by the form's category code."),
|
|
@@ -6667,6 +6703,7 @@ const TOPICS = {
|
|
|
6667
6703
|
- "Set the 'Referral source' custom field on ACME to 'Google'"
|
|
6668
6704
|
- "Mark the review step on the Greggs year-end task as complete" / "Skip the client-approval step — they confirmed by phone"
|
|
6669
6705
|
- "Put ACME on monthly bookkeeping at £350 from the 1st" / "Move their VAT return to 'Records In' on the board"
|
|
6706
|
+
- "Put Bristol Roofing on the Growth package from 1 April" — the whole bundle in one step
|
|
6670
6707
|
- "Draft a document request to ACME for their year-end records" (drafted — you press send)
|
|
6671
6708
|
- "Send the SA questionnaire to Greggs" (sends immediately — the assistant confirms first)
|
|
6672
6709
|
- "Draft a proposal for Bristol Roofing covering bookkeeping and VAT" (drafted Unsent — you review and send)
|
|
@@ -6698,7 +6735,7 @@ async function handleGetUsageExamples(args) {
|
|
|
6698
6735
|
}
|
|
6699
6736
|
//#endregion
|
|
6700
6737
|
//#region ../mcp-core/src/tools/create-task.ts
|
|
6701
|
-
const statusEnum$
|
|
6738
|
+
const statusEnum$10 = z.enum([
|
|
6702
6739
|
"NotStarted",
|
|
6703
6740
|
"InProgress",
|
|
6704
6741
|
"Blocked",
|
|
@@ -6708,7 +6745,7 @@ const statusEnum$9 = z.enum([
|
|
|
6708
6745
|
const CreateTaskInputSchema = {
|
|
6709
6746
|
name: z.string().min(1).describe("The task name — short and action-oriented, e.g. 'Chase rental schedule for year-end'."),
|
|
6710
6747
|
description: z.string().optional().describe("Longer description of what needs doing. Optional."),
|
|
6711
|
-
status: statusEnum$
|
|
6748
|
+
status: statusEnum$10.optional().describe("Initial status. Defaults to NotStarted — only override when the work is already underway (InProgress)."),
|
|
6712
6749
|
startDate: z.string().describe("When work should start (YYYY-MM-DD). For ad-hoc tasks, today is usually right — get today's date from the startup context."),
|
|
6713
6750
|
dueDate: z.string().describe("When the task is due (YYYY-MM-DD). Must be on or after startDate."),
|
|
6714
6751
|
statutoryDueDate: z.string().optional().describe("The statutory deadline (YYYY-MM-DD), for compliance tasks with a legal filing date distinct from the internal due date."),
|
|
@@ -6768,7 +6805,7 @@ async function handleCreateTask(api, args) {
|
|
|
6768
6805
|
}
|
|
6769
6806
|
//#endregion
|
|
6770
6807
|
//#region ../mcp-core/src/tools/update-task.ts
|
|
6771
|
-
const statusEnum$
|
|
6808
|
+
const statusEnum$9 = z.enum([
|
|
6772
6809
|
"NotStarted",
|
|
6773
6810
|
"InProgress",
|
|
6774
6811
|
"Blocked",
|
|
@@ -6777,7 +6814,7 @@ const statusEnum$8 = z.enum([
|
|
|
6777
6814
|
]);
|
|
6778
6815
|
const UpdateTaskInputSchema = {
|
|
6779
6816
|
taskCode: z.string().min(1).describe("The code of the task to update. Get it from list_tasks or get_task_context."),
|
|
6780
|
-
status: statusEnum$
|
|
6817
|
+
status: statusEnum$9.optional().describe("New status. 'Completed' for 'mark it done', 'InProgress' for 'I've started it', 'Blocked' when waiting on something. Note: completing a task does NOT complete its workflow steps — mention open steps to the user if get_task_context showed any."),
|
|
6781
6818
|
name: z.string().min(1).optional().describe("New task name. Omit to keep the current name."),
|
|
6782
6819
|
description: z.string().nullable().optional().describe("New description. Pass null to clear it. Omit to keep the current one."),
|
|
6783
6820
|
startDate: z.string().optional().describe("New start date (YYYY-MM-DD)."),
|
|
@@ -6893,7 +6930,7 @@ async function handleLogTimeEntry(api, args) {
|
|
|
6893
6930
|
}
|
|
6894
6931
|
//#endregion
|
|
6895
6932
|
//#region ../mcp-core/src/tools/list-sent-emails.ts
|
|
6896
|
-
const statusEnum$
|
|
6933
|
+
const statusEnum$8 = z.enum([
|
|
6897
6934
|
"Queued",
|
|
6898
6935
|
"Processing",
|
|
6899
6936
|
"Sent",
|
|
@@ -6906,7 +6943,7 @@ const sortByEnum$7 = z.enum([
|
|
|
6906
6943
|
"Status"
|
|
6907
6944
|
]);
|
|
6908
6945
|
const ListSentEmailsInputSchema = {
|
|
6909
|
-
status: statusEnum$
|
|
6946
|
+
status: statusEnum$8.optional().describe("Filter by delivery status. 'Failed' answers 'which emails didn't get through?' — the most actionable query. 'Queued'/'Processing' show what's still going out."),
|
|
6910
6947
|
search: z.string().optional().describe("Search in email subject and recipient email address — 'emails to john@acme.co.uk', 'the proposal email'."),
|
|
6911
6948
|
fromDate: z.string().optional().describe("Only emails created on or after this date (YYYY-MM-DD). Prefer setting a window — unbounded queries scan all history."),
|
|
6912
6949
|
toDate: z.string().optional().describe("Only emails created on or before this date (YYYY-MM-DD)."),
|
|
@@ -7037,8 +7074,9 @@ function formatThread(t) {
|
|
|
7037
7074
|
const from = t.latestFromName ?? t.latestFromEmail ?? "?";
|
|
7038
7075
|
const counts = `${t.messageCount ?? 0} message${t.messageCount === 1 ? "" : "s"}${t.unreadCount ? `, ${t.unreadCount} unread` : ""}`;
|
|
7039
7076
|
const attach = t.hasAttachments ? " · has attachments" : "";
|
|
7077
|
+
const ids = `\n configCode: ${t.configCode ?? "?"} · conversationId: ${t.conversationId ?? "?"}`;
|
|
7040
7078
|
const snippet = t.snippet ? `\n ${t.snippet.length > 160 ? `${t.snippet.slice(0, 160)}…` : t.snippet}` : "";
|
|
7041
|
-
return `- ${when} · "${t.subject ?? "(no subject)"}" · latest from ${from} · ${counts}${attach}${snippet}`;
|
|
7079
|
+
return `- ${when} · "${t.subject ?? "(no subject)"}" · latest from ${from} · ${counts}${attach}${ids}${snippet}`;
|
|
7042
7080
|
}
|
|
7043
7081
|
async function handleListClientEmails(api, args) {
|
|
7044
7082
|
try {
|
|
@@ -7060,6 +7098,7 @@ async function handleListClientEmails(api, args) {
|
|
|
7060
7098
|
...items.map(formatThread)
|
|
7061
7099
|
];
|
|
7062
7100
|
if (result.hasMore) lines.push("", `More results available — call again with offset: ${(args.offset ?? 0) + items.length}.`);
|
|
7101
|
+
lines.push("", "Use get_client_email_thread with a thread's configCode + conversationId to read the whole conversation.");
|
|
7063
7102
|
return { content: [{
|
|
7064
7103
|
type: "text",
|
|
7065
7104
|
text: lines.join("\n")
|
|
@@ -7075,6 +7114,12 @@ async function handleListClientEmails(api, args) {
|
|
|
7075
7114
|
}
|
|
7076
7115
|
}
|
|
7077
7116
|
//#endregion
|
|
7117
|
+
//#region ../mcp-core/src/tools/aml-common.ts
|
|
7118
|
+
function isAmlNotConfigured(error) {
|
|
7119
|
+
return error instanceof SodiumApiError && error.statusCode === 400 && /aml connection/i.test(error.message);
|
|
7120
|
+
}
|
|
7121
|
+
const AML_NOT_CONFIGURED = "This practice has no AML provider connected in Sodium, so there are no AML/KYC records to show. Records appear here once an AML connection is set up in Sodium.";
|
|
7122
|
+
//#endregion
|
|
7078
7123
|
//#region ../mcp-core/src/tools/list-aml-clients.ts
|
|
7079
7124
|
const ListAmlClientsInputSchema = {
|
|
7080
7125
|
search: z.string().min(3, "Search must be at least 3 characters when provided").optional().describe("Search across AML client name, reference, or contact details. Minimum 3 characters. Use the PM client's name to find its AML record."),
|
|
@@ -7120,6 +7165,10 @@ async function handleListAmlClients(api, args) {
|
|
|
7120
7165
|
text: lines.join("\n")
|
|
7121
7166
|
}] };
|
|
7122
7167
|
} catch (error) {
|
|
7168
|
+
if (isAmlNotConfigured(error)) return { content: [{
|
|
7169
|
+
type: "text",
|
|
7170
|
+
text: AML_NOT_CONFIGURED
|
|
7171
|
+
}] };
|
|
7123
7172
|
return {
|
|
7124
7173
|
content: [{
|
|
7125
7174
|
type: "text",
|
|
@@ -7178,6 +7227,10 @@ async function handleGetAmlClient(api, args) {
|
|
|
7178
7227
|
text: lines.join("\n")
|
|
7179
7228
|
}] };
|
|
7180
7229
|
} catch (error) {
|
|
7230
|
+
if (isAmlNotConfigured(error)) return { content: [{
|
|
7231
|
+
type: "text",
|
|
7232
|
+
text: AML_NOT_CONFIGURED
|
|
7233
|
+
}] };
|
|
7181
7234
|
return {
|
|
7182
7235
|
content: [{
|
|
7183
7236
|
type: "text",
|
|
@@ -7189,7 +7242,7 @@ async function handleGetAmlClient(api, args) {
|
|
|
7189
7242
|
}
|
|
7190
7243
|
//#endregion
|
|
7191
7244
|
//#region ../mcp-core/src/tools/list-billing-line-items.ts
|
|
7192
|
-
const statusEnum$
|
|
7245
|
+
const statusEnum$7 = z.enum([
|
|
7193
7246
|
"Pending",
|
|
7194
7247
|
"Approved",
|
|
7195
7248
|
"Invoiced",
|
|
@@ -7202,7 +7255,7 @@ const sortByEnum$5 = z.enum([
|
|
|
7202
7255
|
"UnitPrice"
|
|
7203
7256
|
]);
|
|
7204
7257
|
const ListBillingLineItemsInputSchema = {
|
|
7205
|
-
status: statusEnum$
|
|
7258
|
+
status: statusEnum$7.optional().describe("Filter by line-item status. 'Pending' = generated, awaiting approval (the 'what's waiting to be billed?' question). 'Approved' = ready for invoicing. 'Invoiced' = sent to the accounting system. Single value — call per status for multiple."),
|
|
7206
7259
|
clientCode: z.string().optional().describe("Filter to one client's billing lines — 'what are we about to bill ACME?'."),
|
|
7207
7260
|
billableServiceCode: z.string().optional().describe("Filter by the billable service — 'what bookkeeping revenue is queued?'. Get codes from list_services."),
|
|
7208
7261
|
clientBillableServiceCode: z.string().optional().describe("Filter by one client's specific service subscription (the code from get_client_summary's services section). Narrower than billableServiceCode."),
|
|
@@ -7265,7 +7318,7 @@ async function handleListBillingLineItems(api, args) {
|
|
|
7265
7318
|
}
|
|
7266
7319
|
//#endregion
|
|
7267
7320
|
//#region ../mcp-core/src/tools/update-workflow-step.ts
|
|
7268
|
-
const statusEnum$
|
|
7321
|
+
const statusEnum$6 = z.enum([
|
|
7269
7322
|
"NotStarted",
|
|
7270
7323
|
"InProgress",
|
|
7271
7324
|
"Blocked",
|
|
@@ -7276,7 +7329,7 @@ const UpdateWorkflowStepInputSchema = {
|
|
|
7276
7329
|
taskCode: z.string().min(1).describe("The task whose workflow step to update. Get it from list_tasks or get_task_context."),
|
|
7277
7330
|
groupNumber: z.number().int().min(1).describe("The workflow group number, exactly as shown in get_task_context's workflow section."),
|
|
7278
7331
|
stepNumber: z.number().int().min(1).describe("The step number within the group, exactly as shown in get_task_context."),
|
|
7279
|
-
status: statusEnum$
|
|
7332
|
+
status: statusEnum$6.optional().describe("New step status. 'Completed' for 'mark the review step done', 'Skipped' when the step doesn't apply, 'InProgress' when starting it, 'Blocked' with blockedReason when stuck. Steps may have dependencies — if the API rejects the change, report why rather than retrying."),
|
|
7280
7333
|
blockedReason: z.string().optional().describe("Why the step is blocked. Only meaningful with status='Blocked'."),
|
|
7281
7334
|
assignedUserCode: z.string().nullable().optional().describe("Reassign the step to this user code (resolve names via the roster or list_users). Pass null to unassign."),
|
|
7282
7335
|
assignedTeamCode: z.string().nullable().optional().describe("Assign the step to this team code (from list_teams), independent of the user assignment. Pass null to clear.")
|
|
@@ -7408,13 +7461,14 @@ async function handleGetClientAgentAuthorisations(api, args) {
|
|
|
7408
7461
|
type: "text",
|
|
7409
7462
|
text: `No agent authorisation records for client ${args.clientCode}. (Authorisations appear once the client has services that require them.)`
|
|
7410
7463
|
}] };
|
|
7411
|
-
const
|
|
7464
|
+
const required = auths.filter((a) => a.isRequired);
|
|
7465
|
+
const missing = required.filter((a) => a.status !== "Granted");
|
|
7412
7466
|
const lines = [
|
|
7413
7467
|
`HMRC agent authorisations for ${args.clientCode}:`,
|
|
7414
7468
|
"",
|
|
7415
7469
|
...auths.map(formatAuth)
|
|
7416
7470
|
];
|
|
7417
|
-
lines.push("", missing.length === 0 ? "All required authorisations are granted." : `⚠ ${missing.length} required authorisation${missing.length === 1 ? " is" : "s are"} not yet granted: ${missing.map((a) => a.authorisationType).join(", ")}. Requesting them is done from the client's page in Sodium.`);
|
|
7471
|
+
lines.push("", required.length === 0 ? "None of this client's current services require an HMRC agent authorisation." : missing.length === 0 ? "All required authorisations are granted." : `⚠ ${missing.length} required authorisation${missing.length === 1 ? " is" : "s are"} not yet granted: ${missing.map((a) => a.authorisationType).join(", ")}. Requesting them is done from the client's page in Sodium.`);
|
|
7418
7472
|
return { content: [{
|
|
7419
7473
|
type: "text",
|
|
7420
7474
|
text: lines.join("\n")
|
|
@@ -7631,7 +7685,7 @@ async function handleListClientDocuments(api, args) {
|
|
|
7631
7685
|
}
|
|
7632
7686
|
//#endregion
|
|
7633
7687
|
//#region ../mcp-core/src/tools/list-data-forms.ts
|
|
7634
|
-
const statusEnum$
|
|
7688
|
+
const statusEnum$5 = z.enum([
|
|
7635
7689
|
"Draft",
|
|
7636
7690
|
"Published",
|
|
7637
7691
|
"Archived"
|
|
@@ -7639,7 +7693,7 @@ const statusEnum$4 = z.enum([
|
|
|
7639
7693
|
const sortByEnum$2 = z.enum(["Name", "Status"]);
|
|
7640
7694
|
const ListDataFormsInputSchema = {
|
|
7641
7695
|
search: z.string().optional().describe("Search over form name — 'the SA questionnaire', 'onboarding form'."),
|
|
7642
|
-
status: statusEnum$
|
|
7696
|
+
status: statusEnum$5.optional().describe("Filter by form status. 'Published' = sendable to clients (the usual filter); 'Draft' = still being built; 'Archived' = retired."),
|
|
7643
7697
|
sortBy: sortByEnum$2.optional().describe("Field to sort by. Defaults to Name."),
|
|
7644
7698
|
sortDesc: z.boolean().optional().describe("Sort in descending order. Defaults to ascending."),
|
|
7645
7699
|
limit: z.number().int().min(0).max(50).optional().describe("Maximum forms per page. Default 10, max 50. Pass 0 for count-only."),
|
|
@@ -7749,7 +7803,7 @@ async function handleGetTaskHistory(api, args) {
|
|
|
7749
7803
|
}
|
|
7750
7804
|
//#endregion
|
|
7751
7805
|
//#region ../mcp-core/src/tools/list-invoice-submissions.ts
|
|
7752
|
-
const statusEnum$
|
|
7806
|
+
const statusEnum$4 = z.enum([
|
|
7753
7807
|
"Pending",
|
|
7754
7808
|
"Submitted",
|
|
7755
7809
|
"Failed",
|
|
@@ -7762,7 +7816,7 @@ const sortByEnum$1 = z.enum([
|
|
|
7762
7816
|
"TotalAmount"
|
|
7763
7817
|
]);
|
|
7764
7818
|
const ListInvoiceSubmissionsInputSchema = {
|
|
7765
|
-
status: statusEnum$
|
|
7819
|
+
status: statusEnum$4.optional().describe("Filter by status. 'Failed' answers 'which invoices didn't reach the accounting system?' (the actionable one). 'Pending' = queued to submit; 'Submitted' = in the accounting system; 'Projected' = forecast only, not yet generated."),
|
|
7766
7820
|
clientCode: z.string().optional().describe("Filter to one client's invoice submissions."),
|
|
7767
7821
|
billingDateFrom: z.string().optional().describe("Only submissions with billing date on or after this date (YYYY-MM-DD)."),
|
|
7768
7822
|
billingDateTo: z.string().optional().describe("Only submissions with billing date on or before this date (YYYY-MM-DD)."),
|
|
@@ -7867,7 +7921,7 @@ async function handleListServicePackages(api, args) {
|
|
|
7867
7921
|
}
|
|
7868
7922
|
//#endregion
|
|
7869
7923
|
//#region ../mcp-core/src/tools/list-email-broadcasts.ts
|
|
7870
|
-
const statusEnum$
|
|
7924
|
+
const statusEnum$3 = z.enum([
|
|
7871
7925
|
"Draft",
|
|
7872
7926
|
"Queued",
|
|
7873
7927
|
"Sending",
|
|
@@ -7877,7 +7931,7 @@ const statusEnum$2 = z.enum([
|
|
|
7877
7931
|
]);
|
|
7878
7932
|
const sortByEnum = z.enum(["CreatedDate", "Status"]);
|
|
7879
7933
|
const ListEmailBroadcastsInputSchema = {
|
|
7880
|
-
status: statusEnum$
|
|
7934
|
+
status: statusEnum$3.optional().describe("Filter by broadcast status. 'Completed' for sent campaigns, 'Draft' for unsent, 'Failed' for broadcasts that errored."),
|
|
7881
7935
|
sortBy: sortByEnum.optional().describe("Field to sort by. Defaults to CreatedDate — pair with sortDesc=true for newest first."),
|
|
7882
7936
|
sortDesc: z.boolean().optional().describe("Sort in descending order. Defaults to ascending."),
|
|
7883
7937
|
limit: z.number().int().min(0).max(50).optional().describe("Maximum broadcasts per page. Default 10, max 50. Pass 0 for count-only."),
|
|
@@ -8249,7 +8303,8 @@ async function handleGetOnboardingStatus(api, args) {
|
|
|
8249
8303
|
}
|
|
8250
8304
|
lines.push("(Name-matched — verify it's the right AML record.)");
|
|
8251
8305
|
}
|
|
8252
|
-
} else if (aml.status === "rejected")
|
|
8306
|
+
} else if (aml.status === "rejected") if (isAmlNotConfigured(aml.reason)) lines.push(AML_NOT_CONFIGURED);
|
|
8307
|
+
else failures.push("AML");
|
|
8253
8308
|
else lines.push("(Client name too short to search the AML register.)");
|
|
8254
8309
|
lines.push("", "## HMRC agent authorisations");
|
|
8255
8310
|
if (auths.status === "fulfilled") {
|
|
@@ -8308,7 +8363,7 @@ const frequencyEnum = z.enum([
|
|
|
8308
8363
|
"Quarterly",
|
|
8309
8364
|
"Monthly"
|
|
8310
8365
|
]);
|
|
8311
|
-
const statusEnum$
|
|
8366
|
+
const statusEnum$2 = z.enum([
|
|
8312
8367
|
"Active",
|
|
8313
8368
|
"Inactive",
|
|
8314
8369
|
"Paused",
|
|
@@ -8320,7 +8375,7 @@ const AddClientServiceInputSchema = {
|
|
|
8320
8375
|
billingFrequency: frequencyEnum.describe("How the service is billed to this client. Match one of the service's configured pricing options (visible in get_service_details)."),
|
|
8321
8376
|
startDate: z.string().describe("When the service starts for this client (YYYY-MM-DD)."),
|
|
8322
8377
|
endDate: z.string().optional().describe("Optional end date (YYYY-MM-DD). Omit for ongoing."),
|
|
8323
|
-
status: statusEnum$
|
|
8378
|
+
status: statusEnum$2.optional().describe("Service status. Defaults to Active. Use 'Proposed' when the service is being quoted but not yet agreed."),
|
|
8324
8379
|
price: z.number().min(0).optional().describe("Custom base price for this client. Only used with overridePricing=true — omit both to use the service's standard pricing."),
|
|
8325
8380
|
overridePricing: z.boolean().optional().describe("true = use the custom 'price' instead of the service's standard pricing. Must be accompanied by 'price'."),
|
|
8326
8381
|
pricingTierCode: z.string().optional().describe("Required when the service uses CustomTiers pricing (see get_service_details) — the tier code to apply."),
|
|
@@ -8374,6 +8429,66 @@ async function handleAddClientService(api, args) {
|
|
|
8374
8429
|
}
|
|
8375
8430
|
}
|
|
8376
8431
|
//#endregion
|
|
8432
|
+
//#region ../mcp-core/src/tools/apply-service-package.ts
|
|
8433
|
+
const statusEnum$1 = z.enum([
|
|
8434
|
+
"Active",
|
|
8435
|
+
"Inactive",
|
|
8436
|
+
"Paused",
|
|
8437
|
+
"Proposed"
|
|
8438
|
+
]);
|
|
8439
|
+
const ApplyServicePackageInputSchema = {
|
|
8440
|
+
clientCode: z.string().min(1).describe("The client to apply the package to. Get the code from list_clients."),
|
|
8441
|
+
packageCode: z.string().min(1).describe("The service package to apply. Get the code from list_service_packages — check its contents and pricing mode there first so you can tell the user what they are about to get and how it will be billed. Archived packages are rejected by the API."),
|
|
8442
|
+
startDate: z.string().optional().describe("When the package takes effect for this client (YYYY-MM-DD). Defaults to today. Use for 'put them on the Growth package from the 1st'."),
|
|
8443
|
+
status: statusEnum$1.optional().describe("Status the package is applied at. Defaults to Active. Use 'Proposed' when it is being quoted but not yet agreed — that also suppresses onboarding tasks, which are only created for Active services."),
|
|
8444
|
+
createOnboardingTasks: z.boolean().optional().describe("Whether to raise onboarding tasks from each service's templates. Defaults to true, which is right for a client genuinely starting the package now. Pass false when recording an arrangement that is already up and running — migrating historical data, or backdating a package the practice has been delivering for months — so the team isn't handed onboarding work for something already onboarded.")
|
|
8445
|
+
};
|
|
8446
|
+
function formatCreatedService(s) {
|
|
8447
|
+
const name = s.billableService?.name?.trim() || s.billableService?.code || "(unnamed service)";
|
|
8448
|
+
const frequency = s.billingFrequency ? ` · ${s.billingFrequency}` : "";
|
|
8449
|
+
return `- ${name} (${s.code ?? "no code"})${frequency}`;
|
|
8450
|
+
}
|
|
8451
|
+
async function handleApplyServicePackage(api, args) {
|
|
8452
|
+
try {
|
|
8453
|
+
const body = {
|
|
8454
|
+
status: args.status ?? "Active",
|
|
8455
|
+
startDate: args.startDate ?? null,
|
|
8456
|
+
createOnboardingTasks: args.createOnboardingTasks ?? true
|
|
8457
|
+
};
|
|
8458
|
+
const created = await api.applyServicePackageToClient(args.clientCode, args.packageCode, body);
|
|
8459
|
+
if (created.length === 0) return { content: [{
|
|
8460
|
+
type: "text",
|
|
8461
|
+
text: `Package ${args.packageCode} was applied to ${args.clientCode} but created no services — the package appears to be empty. Check its contents with list_service_packages.`
|
|
8462
|
+
}] };
|
|
8463
|
+
const packageName = created[0]?.servicePackage?.name?.trim() || args.packageCode;
|
|
8464
|
+
const startDate = created[0]?.startDate?.slice(0, 10);
|
|
8465
|
+
const status = created[0]?.status ?? args.status ?? "Active";
|
|
8466
|
+
const autoInvoiced = created.filter((s) => s.autoInvoice).length;
|
|
8467
|
+
const lines = [
|
|
8468
|
+
`Package applied: ${packageName} on client ${args.clientCode} — ${created.length} service${created.length === 1 ? "" : "s"} created`,
|
|
8469
|
+
`Status: ${status}${startDate ? ` · starting ${startDate}` : ""}`,
|
|
8470
|
+
"",
|
|
8471
|
+
...created.map(formatCreatedService),
|
|
8472
|
+
"",
|
|
8473
|
+
"What the client is billed follows the package's own pricing setup — either a single package price or each service priced separately. Check list_service_packages for the package's pricing, or get_client_summary for the client's resulting services."
|
|
8474
|
+
];
|
|
8475
|
+
if (args.createOnboardingTasks === false) lines.push("", "Onboarding tasks were suppressed for this application.");
|
|
8476
|
+
if (autoInvoiced > 0) lines.push("", `Auto-invoicing is on for ${autoInvoiced} of these services (the practice has client billing enabled), so they will generate billing lines automatically.`);
|
|
8477
|
+
return { content: [{
|
|
8478
|
+
type: "text",
|
|
8479
|
+
text: lines.join("\n")
|
|
8480
|
+
}] };
|
|
8481
|
+
} catch (error) {
|
|
8482
|
+
return {
|
|
8483
|
+
content: [{
|
|
8484
|
+
type: "text",
|
|
8485
|
+
text: error instanceof SodiumApiError ? `Error applying package ${args.packageCode} to ${args.clientCode}: ${error.message} (correlation: ${error.correlationId})` : `Error applying package ${args.packageCode} to ${args.clientCode}: ${error instanceof Error ? error.message : String(error)}`
|
|
8486
|
+
}],
|
|
8487
|
+
isError: true
|
|
8488
|
+
};
|
|
8489
|
+
}
|
|
8490
|
+
}
|
|
8491
|
+
//#endregion
|
|
8377
8492
|
//#region ../mcp-core/src/tools/update-client-service-stage.ts
|
|
8378
8493
|
const UpdateClientServiceStageInputSchema = {
|
|
8379
8494
|
clientCode: z.string().min(1).describe("The client whose service to move. Get the code from list_clients."),
|
|
@@ -8810,7 +8925,7 @@ async function buildServer(config) {
|
|
|
8810
8925
|
let instructions;
|
|
8811
8926
|
if (config.includeStartupContext !== false) {
|
|
8812
8927
|
const selection = api.hasActiveTenant() ? { kind: "explicit" } : await resolveTenant(api);
|
|
8813
|
-
instructions = await buildInstructions(api, config.context
|
|
8928
|
+
instructions = await buildInstructions(api, config.context, selection);
|
|
8814
8929
|
}
|
|
8815
8930
|
const server = new McpServer({
|
|
8816
8931
|
name: config.serverName,
|
|
@@ -9262,7 +9377,7 @@ async function buildServer(config) {
|
|
|
9262
9377
|
}, (args) => handleListInvoiceSubmissions(api, args));
|
|
9263
9378
|
registerTenantTool(server, api, "list_service_packages", {
|
|
9264
9379
|
title: "List service packages (bundled offerings)",
|
|
9265
|
-
description: "List the practice's service packages — bundled offerings like a 'Growth package' — with contents (which services at which frequency), pricing mode (single package price vs per-service), and approximate annual value. Filters: search, contains-service (billableServiceCode array — 'which packages include bookkeeping?'), pagination. Complements list_services (individual catalogue).
|
|
9380
|
+
description: "List the practice's service packages — bundled offerings like a 'Growth package' — with contents (which services at which frequency), pricing mode (single package price vs per-service), and approximate annual value. Filters: search, contains-service (billableServiceCode array — 'which packages include bookkeeping?'), pagination. Complements list_services (individual catalogue). With write mode enabled, apply_service_package puts a client on one of these.",
|
|
9266
9381
|
inputSchema: ListServicePackagesInputSchema,
|
|
9267
9382
|
annotations: lookupAnnotations
|
|
9268
9383
|
}, (args) => handleListServicePackages(api, args));
|
|
@@ -9307,13 +9422,24 @@ async function buildServer(config) {
|
|
|
9307
9422
|
openWorldHint: true
|
|
9308
9423
|
}
|
|
9309
9424
|
}, (args) => handleAddClientService(api, args));
|
|
9425
|
+
registerWriteTool(server, api, config.context, "apply_service_package", {
|
|
9426
|
+
title: "Apply a service package to a client",
|
|
9427
|
+
description: "Put a client on one of the practice's bundled packages in a single call. The package definition decides everything: which services the client gets, at what frequency, and whether they are billed as one package price or service by service. Requires clientCode (list_clients) and packageCode (list_service_packages — check its contents and pricing mode there first so you can tell the user what they are agreeing to). Optional: startDate (defaults to today), status (defaults to Active; use 'Proposed' when quoting), and createOnboardingTasks (defaults to true; pass false when recording an arrangement that is already running, e.g. migrating or backdating). Use for 'put ACME on the Growth package', 'add the Startup bundle to Bristol Roofing from 1 April'. IMPORTANT: (1) The API does NOT check whether the client already has this package — calling twice applies it a SECOND time. Always check get_client_summary first and tell the user if it is already there rather than applying again. (2) Prefer this over repeated add_client_service calls: only this tool links the result to the package, which is what makes package pricing and package removal work in the Sodium UI. (3) Auto-invoicing follows the practice's client-billing settings; it is not controllable per call. (4) Nothing about the package can be overridden per client — use add_client_service for a bespoke arrangement. Archived packages are rejected.",
|
|
9428
|
+
inputSchema: ApplyServicePackageInputSchema,
|
|
9429
|
+
annotations: {
|
|
9430
|
+
readOnlyHint: false,
|
|
9431
|
+
destructiveHint: false,
|
|
9432
|
+
idempotentHint: false,
|
|
9433
|
+
openWorldHint: true
|
|
9434
|
+
}
|
|
9435
|
+
}, (args) => handleApplyServicePackage(api, args));
|
|
9310
9436
|
registerWriteTool(server, api, config.context, "update_client_service_stage", {
|
|
9311
9437
|
title: "Move a client's service to a different stage (kanban)",
|
|
9312
9438
|
description: "Move one client-service card to a different workflow stage — the kanban move, from chat. Requires the client code, the client's service-subscription code (from get_client_summary's services section — NOT the catalogue service code), and the target stageCode (stage codes are in get_service_details for the underlying service). Pass stageCode=null to clear the stage. Use for 'move ACME's VAT return to Records In', 'mark the bookkeeping as Finished on the board'. Note: workflows can also set stages automatically via SetServiceStage steps — a manual move may be overridden by the next automated step.",
|
|
9313
9439
|
inputSchema: UpdateClientServiceStageInputSchema,
|
|
9314
9440
|
annotations: {
|
|
9315
9441
|
readOnlyHint: false,
|
|
9316
|
-
destructiveHint:
|
|
9442
|
+
destructiveHint: true,
|
|
9317
9443
|
idempotentHint: true,
|
|
9318
9444
|
openWorldHint: true
|
|
9319
9445
|
}
|
|
@@ -9335,7 +9461,7 @@ async function buildServer(config) {
|
|
|
9335
9461
|
inputSchema: SendDataFormInputSchema,
|
|
9336
9462
|
annotations: {
|
|
9337
9463
|
readOnlyHint: false,
|
|
9338
|
-
destructiveHint:
|
|
9464
|
+
destructiveHint: true,
|
|
9339
9465
|
idempotentHint: false,
|
|
9340
9466
|
openWorldHint: true
|
|
9341
9467
|
}
|
|
@@ -9357,7 +9483,7 @@ async function buildServer(config) {
|
|
|
9357
9483
|
inputSchema: UpdateClientDatesInputSchema,
|
|
9358
9484
|
annotations: {
|
|
9359
9485
|
readOnlyHint: false,
|
|
9360
|
-
destructiveHint:
|
|
9486
|
+
destructiveHint: true,
|
|
9361
9487
|
idempotentHint: true,
|
|
9362
9488
|
openWorldHint: true
|
|
9363
9489
|
}
|
|
@@ -9368,7 +9494,7 @@ async function buildServer(config) {
|
|
|
9368
9494
|
inputSchema: UpdateClientBusinessDetailsInputSchema,
|
|
9369
9495
|
annotations: {
|
|
9370
9496
|
readOnlyHint: false,
|
|
9371
|
-
destructiveHint:
|
|
9497
|
+
destructiveHint: true,
|
|
9372
9498
|
idempotentHint: true,
|
|
9373
9499
|
openWorldHint: true
|
|
9374
9500
|
}
|
|
@@ -9390,7 +9516,7 @@ async function buildServer(config) {
|
|
|
9390
9516
|
inputSchema: UpdateWorkflowStepInputSchema,
|
|
9391
9517
|
annotations: {
|
|
9392
9518
|
readOnlyHint: false,
|
|
9393
|
-
destructiveHint:
|
|
9519
|
+
destructiveHint: true,
|
|
9394
9520
|
idempotentHint: true,
|
|
9395
9521
|
openWorldHint: true
|
|
9396
9522
|
}
|
|
@@ -9412,7 +9538,7 @@ async function buildServer(config) {
|
|
|
9412
9538
|
inputSchema: UpdateTaskInputSchema,
|
|
9413
9539
|
annotations: {
|
|
9414
9540
|
readOnlyHint: false,
|
|
9415
|
-
destructiveHint:
|
|
9541
|
+
destructiveHint: true,
|
|
9416
9542
|
idempotentHint: true,
|
|
9417
9543
|
openWorldHint: true
|
|
9418
9544
|
}
|
|
@@ -9467,7 +9593,7 @@ async function buildServer(config) {
|
|
|
9467
9593
|
inputSchema: SetClientCustomFieldsInputSchema,
|
|
9468
9594
|
annotations: {
|
|
9469
9595
|
readOnlyHint: false,
|
|
9470
|
-
destructiveHint:
|
|
9596
|
+
destructiveHint: true,
|
|
9471
9597
|
idempotentHint: true,
|
|
9472
9598
|
openWorldHint: true
|
|
9473
9599
|
}
|
|
@@ -9478,7 +9604,7 @@ async function buildServer(config) {
|
|
|
9478
9604
|
inputSchema: UpdateContactInputSchema,
|
|
9479
9605
|
annotations: {
|
|
9480
9606
|
readOnlyHint: false,
|
|
9481
|
-
destructiveHint:
|
|
9607
|
+
destructiveHint: true,
|
|
9482
9608
|
idempotentHint: true,
|
|
9483
9609
|
openWorldHint: true
|
|
9484
9610
|
}
|