@sodiumhq/mcp-pm 0.1.0-beta.4579 → 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/dist/http.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-dwGvEajk.mjs → src-DNCbW1Ge.mjs} +34 -15
- package/package.json +1 -1
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";
|
|
@@ -3577,7 +3577,7 @@ var SodiumApiClient = class {
|
|
|
3577
3577
|
//#endregion
|
|
3578
3578
|
//#region ../mcp-core/src/context/instructions.ts
|
|
3579
3579
|
const ROSTER_CAP = 20;
|
|
3580
|
-
async function buildInstructions(api,
|
|
3580
|
+
async function buildInstructions(api, ctx, selection) {
|
|
3581
3581
|
const [user, tenant, practice, team] = await Promise.allSettled([
|
|
3582
3582
|
api.getCurrentUser(),
|
|
3583
3583
|
api.getTenantDetails(),
|
|
@@ -3627,7 +3627,8 @@ async function buildInstructions(api, writesEnabled, selection) {
|
|
|
3627
3627
|
} else lines.push("Call list_practices to see the available practices.");
|
|
3628
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.");
|
|
3629
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.`);
|
|
3630
|
-
|
|
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.");
|
|
3631
3632
|
if (team.status === "fulfilled") {
|
|
3632
3633
|
const members = team.value.data ?? [];
|
|
3633
3634
|
const total = team.value.totalCount ?? members.length;
|
|
@@ -7073,8 +7074,9 @@ function formatThread(t) {
|
|
|
7073
7074
|
const from = t.latestFromName ?? t.latestFromEmail ?? "?";
|
|
7074
7075
|
const counts = `${t.messageCount ?? 0} message${t.messageCount === 1 ? "" : "s"}${t.unreadCount ? `, ${t.unreadCount} unread` : ""}`;
|
|
7075
7076
|
const attach = t.hasAttachments ? " · has attachments" : "";
|
|
7077
|
+
const ids = `\n configCode: ${t.configCode ?? "?"} · conversationId: ${t.conversationId ?? "?"}`;
|
|
7076
7078
|
const snippet = t.snippet ? `\n ${t.snippet.length > 160 ? `${t.snippet.slice(0, 160)}…` : t.snippet}` : "";
|
|
7077
|
-
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}`;
|
|
7078
7080
|
}
|
|
7079
7081
|
async function handleListClientEmails(api, args) {
|
|
7080
7082
|
try {
|
|
@@ -7096,6 +7098,7 @@ async function handleListClientEmails(api, args) {
|
|
|
7096
7098
|
...items.map(formatThread)
|
|
7097
7099
|
];
|
|
7098
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.");
|
|
7099
7102
|
return { content: [{
|
|
7100
7103
|
type: "text",
|
|
7101
7104
|
text: lines.join("\n")
|
|
@@ -7111,6 +7114,12 @@ async function handleListClientEmails(api, args) {
|
|
|
7111
7114
|
}
|
|
7112
7115
|
}
|
|
7113
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
|
|
7114
7123
|
//#region ../mcp-core/src/tools/list-aml-clients.ts
|
|
7115
7124
|
const ListAmlClientsInputSchema = {
|
|
7116
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."),
|
|
@@ -7156,6 +7165,10 @@ async function handleListAmlClients(api, args) {
|
|
|
7156
7165
|
text: lines.join("\n")
|
|
7157
7166
|
}] };
|
|
7158
7167
|
} catch (error) {
|
|
7168
|
+
if (isAmlNotConfigured(error)) return { content: [{
|
|
7169
|
+
type: "text",
|
|
7170
|
+
text: AML_NOT_CONFIGURED
|
|
7171
|
+
}] };
|
|
7159
7172
|
return {
|
|
7160
7173
|
content: [{
|
|
7161
7174
|
type: "text",
|
|
@@ -7214,6 +7227,10 @@ async function handleGetAmlClient(api, args) {
|
|
|
7214
7227
|
text: lines.join("\n")
|
|
7215
7228
|
}] };
|
|
7216
7229
|
} catch (error) {
|
|
7230
|
+
if (isAmlNotConfigured(error)) return { content: [{
|
|
7231
|
+
type: "text",
|
|
7232
|
+
text: AML_NOT_CONFIGURED
|
|
7233
|
+
}] };
|
|
7217
7234
|
return {
|
|
7218
7235
|
content: [{
|
|
7219
7236
|
type: "text",
|
|
@@ -7444,13 +7461,14 @@ async function handleGetClientAgentAuthorisations(api, args) {
|
|
|
7444
7461
|
type: "text",
|
|
7445
7462
|
text: `No agent authorisation records for client ${args.clientCode}. (Authorisations appear once the client has services that require them.)`
|
|
7446
7463
|
}] };
|
|
7447
|
-
const
|
|
7464
|
+
const required = auths.filter((a) => a.isRequired);
|
|
7465
|
+
const missing = required.filter((a) => a.status !== "Granted");
|
|
7448
7466
|
const lines = [
|
|
7449
7467
|
`HMRC agent authorisations for ${args.clientCode}:`,
|
|
7450
7468
|
"",
|
|
7451
7469
|
...auths.map(formatAuth)
|
|
7452
7470
|
];
|
|
7453
|
-
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.`);
|
|
7454
7472
|
return { content: [{
|
|
7455
7473
|
type: "text",
|
|
7456
7474
|
text: lines.join("\n")
|
|
@@ -8285,7 +8303,8 @@ async function handleGetOnboardingStatus(api, args) {
|
|
|
8285
8303
|
}
|
|
8286
8304
|
lines.push("(Name-matched — verify it's the right AML record.)");
|
|
8287
8305
|
}
|
|
8288
|
-
} 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");
|
|
8289
8308
|
else lines.push("(Client name too short to search the AML register.)");
|
|
8290
8309
|
lines.push("", "## HMRC agent authorisations");
|
|
8291
8310
|
if (auths.status === "fulfilled") {
|
|
@@ -8906,7 +8925,7 @@ async function buildServer(config) {
|
|
|
8906
8925
|
let instructions;
|
|
8907
8926
|
if (config.includeStartupContext !== false) {
|
|
8908
8927
|
const selection = api.hasActiveTenant() ? { kind: "explicit" } : await resolveTenant(api);
|
|
8909
|
-
instructions = await buildInstructions(api, config.context
|
|
8928
|
+
instructions = await buildInstructions(api, config.context, selection);
|
|
8910
8929
|
}
|
|
8911
8930
|
const server = new McpServer({
|
|
8912
8931
|
name: config.serverName,
|
|
@@ -9420,7 +9439,7 @@ async function buildServer(config) {
|
|
|
9420
9439
|
inputSchema: UpdateClientServiceStageInputSchema,
|
|
9421
9440
|
annotations: {
|
|
9422
9441
|
readOnlyHint: false,
|
|
9423
|
-
destructiveHint:
|
|
9442
|
+
destructiveHint: true,
|
|
9424
9443
|
idempotentHint: true,
|
|
9425
9444
|
openWorldHint: true
|
|
9426
9445
|
}
|
|
@@ -9442,7 +9461,7 @@ async function buildServer(config) {
|
|
|
9442
9461
|
inputSchema: SendDataFormInputSchema,
|
|
9443
9462
|
annotations: {
|
|
9444
9463
|
readOnlyHint: false,
|
|
9445
|
-
destructiveHint:
|
|
9464
|
+
destructiveHint: true,
|
|
9446
9465
|
idempotentHint: false,
|
|
9447
9466
|
openWorldHint: true
|
|
9448
9467
|
}
|
|
@@ -9464,7 +9483,7 @@ async function buildServer(config) {
|
|
|
9464
9483
|
inputSchema: UpdateClientDatesInputSchema,
|
|
9465
9484
|
annotations: {
|
|
9466
9485
|
readOnlyHint: false,
|
|
9467
|
-
destructiveHint:
|
|
9486
|
+
destructiveHint: true,
|
|
9468
9487
|
idempotentHint: true,
|
|
9469
9488
|
openWorldHint: true
|
|
9470
9489
|
}
|
|
@@ -9475,7 +9494,7 @@ async function buildServer(config) {
|
|
|
9475
9494
|
inputSchema: UpdateClientBusinessDetailsInputSchema,
|
|
9476
9495
|
annotations: {
|
|
9477
9496
|
readOnlyHint: false,
|
|
9478
|
-
destructiveHint:
|
|
9497
|
+
destructiveHint: true,
|
|
9479
9498
|
idempotentHint: true,
|
|
9480
9499
|
openWorldHint: true
|
|
9481
9500
|
}
|
|
@@ -9497,7 +9516,7 @@ async function buildServer(config) {
|
|
|
9497
9516
|
inputSchema: UpdateWorkflowStepInputSchema,
|
|
9498
9517
|
annotations: {
|
|
9499
9518
|
readOnlyHint: false,
|
|
9500
|
-
destructiveHint:
|
|
9519
|
+
destructiveHint: true,
|
|
9501
9520
|
idempotentHint: true,
|
|
9502
9521
|
openWorldHint: true
|
|
9503
9522
|
}
|
|
@@ -9519,7 +9538,7 @@ async function buildServer(config) {
|
|
|
9519
9538
|
inputSchema: UpdateTaskInputSchema,
|
|
9520
9539
|
annotations: {
|
|
9521
9540
|
readOnlyHint: false,
|
|
9522
|
-
destructiveHint:
|
|
9541
|
+
destructiveHint: true,
|
|
9523
9542
|
idempotentHint: true,
|
|
9524
9543
|
openWorldHint: true
|
|
9525
9544
|
}
|
|
@@ -9574,7 +9593,7 @@ async function buildServer(config) {
|
|
|
9574
9593
|
inputSchema: SetClientCustomFieldsInputSchema,
|
|
9575
9594
|
annotations: {
|
|
9576
9595
|
readOnlyHint: false,
|
|
9577
|
-
destructiveHint:
|
|
9596
|
+
destructiveHint: true,
|
|
9578
9597
|
idempotentHint: true,
|
|
9579
9598
|
openWorldHint: true
|
|
9580
9599
|
}
|
|
@@ -9585,7 +9604,7 @@ async function buildServer(config) {
|
|
|
9585
9604
|
inputSchema: UpdateContactInputSchema,
|
|
9586
9605
|
annotations: {
|
|
9587
9606
|
readOnlyHint: false,
|
|
9588
|
-
destructiveHint:
|
|
9607
|
+
destructiveHint: true,
|
|
9589
9608
|
idempotentHint: true,
|
|
9590
9609
|
openWorldHint: true
|
|
9591
9610
|
}
|