@sodiumhq/mcp-pm 0.1.0-beta.2592 → 0.1.0-beta.2593
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 +110 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -622,6 +622,20 @@ const client = createClient(createConfig());
|
|
|
622
622
|
//#endregion
|
|
623
623
|
//#region ../mcp-core/src/generated/sdk.gen.ts
|
|
624
624
|
/**
|
|
625
|
+
* Get BusinessDetails for a client
|
|
626
|
+
*/
|
|
627
|
+
const getBusinessDetailsForClient = (options) => (options.client ?? client).get({
|
|
628
|
+
security: [{
|
|
629
|
+
name: "x-api-key",
|
|
630
|
+
type: "apiKey"
|
|
631
|
+
}, {
|
|
632
|
+
scheme: "bearer",
|
|
633
|
+
type: "http"
|
|
634
|
+
}],
|
|
635
|
+
url: "/tenants/{tenant}/clients/{client}/businessdetails",
|
|
636
|
+
...options
|
|
637
|
+
});
|
|
638
|
+
/**
|
|
625
639
|
* List Contacts for Client
|
|
626
640
|
*
|
|
627
641
|
* Lists all Contacts for the specified client.
|
|
@@ -638,6 +652,22 @@ const listClientContactsForClient = (options) => (options.client ?? client).get(
|
|
|
638
652
|
...options
|
|
639
653
|
});
|
|
640
654
|
/**
|
|
655
|
+
* Get Client Dates
|
|
656
|
+
*
|
|
657
|
+
* Returns all key dates for the specified client
|
|
658
|
+
*/
|
|
659
|
+
const getClientDates = (options) => (options.client ?? client).get({
|
|
660
|
+
security: [{
|
|
661
|
+
name: "x-api-key",
|
|
662
|
+
type: "apiKey"
|
|
663
|
+
}, {
|
|
664
|
+
scheme: "bearer",
|
|
665
|
+
type: "http"
|
|
666
|
+
}],
|
|
667
|
+
url: "/tenants/{tenant}/clients/{code}/dates",
|
|
668
|
+
...options
|
|
669
|
+
});
|
|
670
|
+
/**
|
|
641
671
|
* List Client Services for Client
|
|
642
672
|
*
|
|
643
673
|
* Lists all Client Services for the specified client.
|
|
@@ -961,6 +991,30 @@ var SodiumApiClient = class {
|
|
|
961
991
|
if (error !== void 0 || !data) throw this.toError(response, error, correlationId, `list services for client ${clientCode}`);
|
|
962
992
|
return data;
|
|
963
993
|
}
|
|
994
|
+
async getClientBusinessDetails(clientCode) {
|
|
995
|
+
const correlationId = randomUUID();
|
|
996
|
+
const { data, error, response } = await getBusinessDetailsForClient({
|
|
997
|
+
path: {
|
|
998
|
+
tenant: this.ctx.tenant,
|
|
999
|
+
client: clientCode
|
|
1000
|
+
},
|
|
1001
|
+
headers: { "X-Correlation-Id": correlationId }
|
|
1002
|
+
});
|
|
1003
|
+
if (error !== void 0 || !data) throw this.toError(response, error, correlationId, `get business details for client ${clientCode}`);
|
|
1004
|
+
return data;
|
|
1005
|
+
}
|
|
1006
|
+
async getClientDates(clientCode) {
|
|
1007
|
+
const correlationId = randomUUID();
|
|
1008
|
+
const { data, error, response } = await getClientDates({
|
|
1009
|
+
path: {
|
|
1010
|
+
tenant: this.ctx.tenant,
|
|
1011
|
+
code: clientCode
|
|
1012
|
+
},
|
|
1013
|
+
headers: { "X-Correlation-Id": correlationId }
|
|
1014
|
+
});
|
|
1015
|
+
if (error !== void 0 || !data) throw this.toError(response, error, correlationId, `get client dates for ${clientCode}`);
|
|
1016
|
+
return data;
|
|
1017
|
+
}
|
|
964
1018
|
async listUsers(query = {}) {
|
|
965
1019
|
const correlationId = randomUUID();
|
|
966
1020
|
const { data, error, response } = await listTenantUsers({
|
|
@@ -1228,10 +1282,12 @@ function describeFilters$2(args) {
|
|
|
1228
1282
|
//#region ../mcp-core/src/tools/get-client-summary.ts
|
|
1229
1283
|
const GetClientSummaryInputSchema = { code: z.string().min(1, "Client code is required").describe("The client code (identifier). Usually discovered via list_clients first.") };
|
|
1230
1284
|
async function handleGetClientSummary(api, { code }) {
|
|
1231
|
-
const [clientResult, contactsResult, servicesResult, overdueResult, upcomingResult] = await Promise.allSettled([
|
|
1285
|
+
const [clientResult, contactsResult, servicesResult, businessResult, datesResult, overdueResult, upcomingResult] = await Promise.allSettled([
|
|
1232
1286
|
api.getClient(code),
|
|
1233
1287
|
api.listClientContacts(code),
|
|
1234
1288
|
api.listClientServices(code),
|
|
1289
|
+
api.getClientBusinessDetails(code),
|
|
1290
|
+
api.getClientDates(code),
|
|
1235
1291
|
api.listTasks({
|
|
1236
1292
|
client: [code],
|
|
1237
1293
|
isOverdue: true,
|
|
@@ -1260,11 +1316,15 @@ async function handleGetClientSummary(api, { code }) {
|
|
|
1260
1316
|
client: clientResult.value,
|
|
1261
1317
|
contacts: extract(contactsResult),
|
|
1262
1318
|
services: extract(servicesResult),
|
|
1319
|
+
businessDetails: businessResult.status === "fulfilled" ? businessResult.value : null,
|
|
1320
|
+
clientDates: datesResult.status === "fulfilled" ? datesResult.value : [],
|
|
1263
1321
|
overdueTasks: extract(overdueResult),
|
|
1264
1322
|
upcomingTasks: extract(upcomingResult),
|
|
1265
1323
|
gaps: [
|
|
1266
1324
|
contactsResult.status === "rejected" ? "contacts" : null,
|
|
1267
1325
|
servicesResult.status === "rejected" ? "services" : null,
|
|
1326
|
+
businessResult.status === "rejected" ? "business details" : null,
|
|
1327
|
+
datesResult.status === "rejected" ? "key dates" : null,
|
|
1268
1328
|
overdueResult.status === "rejected" ? "overdue tasks" : null,
|
|
1269
1329
|
upcomingResult.status === "rejected" ? "upcoming tasks" : null
|
|
1270
1330
|
].filter((v) => v !== null)
|
|
@@ -1276,7 +1336,7 @@ function extract(result) {
|
|
|
1276
1336
|
return result.value.data ?? [];
|
|
1277
1337
|
}
|
|
1278
1338
|
function format$1(input) {
|
|
1279
|
-
const { client, contacts, services, overdueTasks, upcomingTasks, gaps } = input;
|
|
1339
|
+
const { client, contacts, services, businessDetails, clientDates, overdueTasks, upcomingTasks, gaps } = input;
|
|
1280
1340
|
const lines = [];
|
|
1281
1341
|
const name = client.name ?? "(no name)";
|
|
1282
1342
|
const code = client.code ?? "(no code)";
|
|
@@ -1289,6 +1349,15 @@ function format$1(input) {
|
|
|
1289
1349
|
if (client.manager) lines.push(`Manager: ${client.manager.name} (${client.manager.code})`);
|
|
1290
1350
|
if (client.partner) lines.push(`Partner: ${client.partner.name} (${client.partner.code})`);
|
|
1291
1351
|
if (client.associate) lines.push(`Associate: ${client.associate.name} (${client.associate.code})`);
|
|
1352
|
+
const businessLines = formatBusinessDetails(businessDetails);
|
|
1353
|
+
if (businessLines.length > 0) lines.push("", "--- Business Details ---", ...businessLines);
|
|
1354
|
+
if (clientDates.length > 0) {
|
|
1355
|
+
lines.push("", `--- Key Dates (${clientDates.length}) ---`);
|
|
1356
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
1357
|
+
const upcoming = clientDates.filter((d) => (d.date ?? "") >= today).sort((a, b) => (a.date ?? "").localeCompare(b.date ?? ""));
|
|
1358
|
+
const past = clientDates.filter((d) => (d.date ?? "") < today).sort((a, b) => (b.date ?? "").localeCompare(a.date ?? ""));
|
|
1359
|
+
for (const d of [...upcoming, ...past]) lines.push(formatClientDate(d));
|
|
1360
|
+
}
|
|
1292
1361
|
lines.push("", `--- Contacts (${contacts.length}) ---`);
|
|
1293
1362
|
if (contacts.length === 0) lines.push("No contacts.");
|
|
1294
1363
|
else for (const c of contacts) {
|
|
@@ -1327,6 +1396,44 @@ function formatTask$1(t) {
|
|
|
1327
1396
|
const taskCode = t.code ?? "(no code)";
|
|
1328
1397
|
return `${t.name ?? "(unnamed)"} (${taskCode})${t.dueDate ? ` — due ${t.dueDate}` : ""}${t.assignedUser?.name ? ` — ${t.assignedUser.name}` : ""}${t.workflow ? ` — workflow ${t.workflowStepsComplete ?? 0}/${t.workflowSteps ?? 0}` : ""}`;
|
|
1329
1398
|
}
|
|
1399
|
+
function formatBusinessDetails(bd) {
|
|
1400
|
+
if (!bd) return [];
|
|
1401
|
+
const out = [];
|
|
1402
|
+
const company = bd.company;
|
|
1403
|
+
if (company?.number) {
|
|
1404
|
+
const status = company.status ? ` · ${company.status}` : "";
|
|
1405
|
+
out.push(`Company number: ${company.number}${status}`);
|
|
1406
|
+
}
|
|
1407
|
+
if (company?.incorporationDate) out.push(`Incorporated: ${company.incorporationDate}`);
|
|
1408
|
+
if (bd.tradingAs) out.push(`Trading as: ${bd.tradingAs}`);
|
|
1409
|
+
if (company?.registeredAddress) out.push(`Registered address: ${company.registeredAddress}`);
|
|
1410
|
+
if (bd.postalAddress && bd.postalAddress !== company?.registeredAddress) out.push(`Postal address: ${bd.postalAddress}`);
|
|
1411
|
+
if (bd.natureOfBusiness) out.push(`Nature of business: ${bd.natureOfBusiness}`);
|
|
1412
|
+
if (bd.vat) if (bd.vat.registered) out.push(`VAT: registered${bd.vat.number ? ` (${bd.vat.number})` : ""}`);
|
|
1413
|
+
else out.push("VAT: not registered");
|
|
1414
|
+
if (bd.utr) out.push(`UTR: ${bd.utr}`);
|
|
1415
|
+
if (bd.payeRef) out.push(`PAYE ref: ${bd.payeRef}`);
|
|
1416
|
+
if (bd.accountsOfficeRef) out.push(`Accounts office ref: ${bd.accountsOfficeRef}`);
|
|
1417
|
+
return out;
|
|
1418
|
+
}
|
|
1419
|
+
function formatClientDate(d) {
|
|
1420
|
+
return `- ${humanizeDateType(d.dateType ?? "")}: ${d.date ?? "(no date)"}${d.description ? ` — ${d.description}` : ""}`;
|
|
1421
|
+
}
|
|
1422
|
+
function humanizeDateType(type) {
|
|
1423
|
+
if (!type) return "(unknown)";
|
|
1424
|
+
const words = type.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(" ");
|
|
1425
|
+
const acronyms = new Set([
|
|
1426
|
+
"VAT",
|
|
1427
|
+
"PAYE",
|
|
1428
|
+
"CIS",
|
|
1429
|
+
"UTR"
|
|
1430
|
+
]);
|
|
1431
|
+
return words.map((w, i) => {
|
|
1432
|
+
const upper = w.toUpperCase();
|
|
1433
|
+
if (acronyms.has(upper)) return upper;
|
|
1434
|
+
return i === 0 ? w.charAt(0).toUpperCase() + w.slice(1).toLowerCase() : w.toLowerCase();
|
|
1435
|
+
}).join(" ");
|
|
1436
|
+
}
|
|
1330
1437
|
//#endregion
|
|
1331
1438
|
//#region ../mcp-core/src/tools/get-task-context.ts
|
|
1332
1439
|
const GetTaskContextInputSchema = { code: z.string().min(1, "Task code is required").describe("The task code (identifier). Usually discovered via list_tasks first, or supplied directly by the user when they quote a task code.") };
|
|
@@ -1716,7 +1823,7 @@ async function buildServer(config) {
|
|
|
1716
1823
|
}, (args) => handleListClients(api, args));
|
|
1717
1824
|
server.registerTool("get_client_summary", {
|
|
1718
1825
|
title: "Get a full summary of one client",
|
|
1719
|
-
description: "Get a consolidated overview of a single client by code: identity (name, status, type, assignments), all contacts, active services with pricing, overdue task count + top 5, and tasks due in the next 7 days. Use this AFTER list_clients identifies the client of interest, or when the user references a specific client by code. Tolerates partial failures — if one section can't be loaded, the rest is still returned with a note about what's missing.",
|
|
1826
|
+
description: "Get a consolidated overview of a single client by code: identity (name, status, type, assignments), business details (company number, incorporation date, trading name, registered address, VAT status, UTR, PAYE ref), key statutory dates (year-end, accounts due, VAT return due, confirmation statement due, etc. — upcoming first, then past), all contacts, active services with pricing, overdue task count + top 5, and tasks due in the next 7 days. Use this AFTER list_clients identifies the client of interest, or when the user references a specific client by code. Also answers 'when is ACME's year-end?' / 'is ACME VAT registered?' in a single call. Tolerates partial failures — if one section can't be loaded, the rest is still returned with a note about what's missing.",
|
|
1720
1827
|
inputSchema: GetClientSummaryInputSchema,
|
|
1721
1828
|
annotations: {
|
|
1722
1829
|
readOnlyHint: true,
|