@sodiumhq/mcp-pm 0.1.0-beta.2772 → 0.1.0-beta.2774

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.
Files changed (2) hide show
  1. package/dist/index.js +86 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -829,6 +829,26 @@ const listContacts = (options) => (options.client ?? client).get({
829
829
  ...options
830
830
  });
831
831
  /**
832
+ * Create Contact
833
+ *
834
+ * Creates a new Contact for the specified tenant.
835
+ */
836
+ const createContact = (options) => (options.client ?? client).post({
837
+ security: [{
838
+ name: "x-api-key",
839
+ type: "apiKey"
840
+ }, {
841
+ scheme: "bearer",
842
+ type: "http"
843
+ }],
844
+ url: "/tenants/{tenant}/contacts",
845
+ ...options,
846
+ headers: {
847
+ "Content-Type": "application/json",
848
+ ...options.headers
849
+ }
850
+ });
851
+ /**
832
852
  * Get Contact
833
853
  *
834
854
  * Gets a Contact for the specified tenant.
@@ -1576,6 +1596,16 @@ var SodiumApiClient = class {
1576
1596
  if (error !== void 0 || !data) throw this.toError(response, error, correlationId, `get contact ${code}`);
1577
1597
  return data;
1578
1598
  }
1599
+ async createContact(body) {
1600
+ const correlationId = randomUUID();
1601
+ const { data, error, response } = await createContact({
1602
+ path: { tenant: this.ctx.tenant },
1603
+ body,
1604
+ headers: { "X-Correlation-Id": correlationId }
1605
+ });
1606
+ if (error !== void 0 || !data) throw this.toError(response, error, correlationId, "create contact");
1607
+ return data;
1608
+ }
1579
1609
  async updateContact(code, body) {
1580
1610
  const correlationId = randomUUID();
1581
1611
  const { data, error, response } = await updateContact({
@@ -1596,6 +1626,15 @@ var SodiumApiClient = class {
1596
1626
  const obj = error;
1597
1627
  const detail = obj.detail ?? obj.message;
1598
1628
  if (typeof detail === "string") message = `${detail} (HTTP ${status}, ${operation})`;
1629
+ const errors = obj.errors;
1630
+ if (errors && typeof errors === "object" && !Array.isArray(errors)) {
1631
+ const fieldLines = [];
1632
+ for (const [field, msgs] of Object.entries(errors)) {
1633
+ const msgList = Array.isArray(msgs) ? msgs.join("; ") : String(msgs);
1634
+ fieldLines.push(` ${field}: ${msgList}`);
1635
+ }
1636
+ if (fieldLines.length > 0) message += `\nField errors:\n${fieldLines.join("\n")}`;
1637
+ }
1599
1638
  } else if (typeof error === "string") message = error;
1600
1639
  return new SodiumApiError(message, status, correlationId);
1601
1640
  }
@@ -2971,6 +3010,42 @@ async function handleCreateClient(api, args) {
2971
3010
  }
2972
3011
  }
2973
3012
  //#endregion
3013
+ //#region ../mcp-core/src/tools/create-contact.ts
3014
+ const CreateContactInputSchema = {
3015
+ lastName: z.string().min(1, "Last name is required").describe("The contact's last name (required)."),
3016
+ title: z.string().nullable().optional().describe("Title (e.g. Mr, Mrs, Dr)."),
3017
+ firstName: z.string().nullable().optional().describe("First name."),
3018
+ middleName: z.string().nullable().optional().describe("Middle name."),
3019
+ email: z.string().nullable().optional().describe("Email address."),
3020
+ phone: z.string().nullable().optional().describe("Landline phone number."),
3021
+ mobile: z.string().nullable().optional().describe("Mobile phone number."),
3022
+ dateOfBirth: z.string().nullable().optional().describe("Date of birth in ISO 8601 format (e.g. '1985-03-15')."),
3023
+ utr: z.string().nullable().optional().describe("Self Assessment UTR."),
3024
+ niNumber: z.string().nullable().optional().describe("National Insurance Number."),
3025
+ address: z.string().nullable().optional().describe("Contact address.")
3026
+ };
3027
+ async function handleCreateContact(api, args) {
3028
+ try {
3029
+ const created = await api.createContact(args);
3030
+ const lines = [`Created contact: ${[created.firstName, created.lastName].filter(Boolean).join(" ") || "(no name)"} (${created.code ?? "(no code)"})`];
3031
+ if (created.email) lines.push(`Email: ${created.email}`);
3032
+ if (created.phone) lines.push(`Phone: ${created.phone}`);
3033
+ if (created.mobile) lines.push(`Mobile: ${created.mobile}`);
3034
+ return { content: [{
3035
+ type: "text",
3036
+ text: lines.join("\n")
3037
+ }] };
3038
+ } catch (error) {
3039
+ return {
3040
+ content: [{
3041
+ type: "text",
3042
+ text: error instanceof SodiumApiError ? `Error creating contact: ${error.message} (correlation: ${error.correlationId})` : `Error creating contact: ${error instanceof Error ? error.message : String(error)}`
3043
+ }],
3044
+ isError: true
3045
+ };
3046
+ }
3047
+ }
3048
+ //#endregion
2974
3049
  //#region ../mcp-core/src/tools/get-contact.ts
2975
3050
  const GetContactInputSchema = { contactCode: z.string().min(1, "Contact code is required").describe("The contact code (identifier). Discoverable via list_contacts or the contacts section of get_client_summary.") };
2976
3051
  async function handleGetContact(api, args) {
@@ -3458,6 +3533,17 @@ async function buildServer(config) {
3458
3533
  openWorldHint: true
3459
3534
  }
3460
3535
  }, (args) => handleUpdateContact(api, args));
3536
+ registerWriteTool(server, config.context, "create_contact", {
3537
+ title: "Create a new contact",
3538
+ description: "Create a new contact record. Requires at least a last name. Optionally set title, first name, email, phone, mobile, date of birth, UTR, NI number, and address. The contact code is auto-generated. Use when the user says 'add a contact', 'create contact John Smith', 'add a new director for ACME'. Note: this creates the contact record only — to link it to a client, use the Sodium web UI.",
3539
+ inputSchema: CreateContactInputSchema,
3540
+ annotations: {
3541
+ readOnlyHint: false,
3542
+ destructiveHint: false,
3543
+ idempotentHint: false,
3544
+ openWorldHint: true
3545
+ }
3546
+ }, (args) => handleCreateContact(api, args));
3461
3547
  return server;
3462
3548
  }
3463
3549
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sodiumhq/mcp-pm",
3
- "version": "0.1.0-beta.2772",
3
+ "version": "0.1.0-beta.2774",
4
4
  "description": "Sodium Practice Management MCP server — lets AI assistants interact with your Sodium tenant",
5
5
  "type": "module",
6
6
  "bin": {