@sodiumhq/mcp-pm 0.1.0-beta.4241 → 0.1.0-beta.4424

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 CHANGED
@@ -161,7 +161,7 @@ Only enable write mode with an AI client you trust — it hands the client the a
161
161
  - **`add_task_note`** — capture a note against a specific task. Attributed to your API user, timestamped to now.
162
162
  - **`add_client_note`** — capture a note against a client record. Same shape as `add_task_note` but scoped to the client.
163
163
  - **`update_client_custom_fields`** — set or clear custom field values on a client. Accepts a map of field codes to values, validates against the field's data type (Text, Number, Date, Boolean, Select, MultiSelect). Pass null to clear a field. Field codes are discoverable via `get_client_summary`.
164
- - **`update_contact`** — update a contact's details: name, email, phone, mobile, date of birth, UTR, NI number, address. Requires the contact code (discoverable via `list_contacts`).
164
+ - **`update_contact`** — update a contact's details: name, preferred name (used in email greetings), email, phone, mobile, date of birth, UTR, NI number, address. Requires the contact code (discoverable via `list_contacts`).
165
165
 
166
166
  More tools land iteratively as the beta progresses.
167
167
 
package/dist/index.js CHANGED
@@ -4771,6 +4771,7 @@ const CreateContactInputSchema = {
4771
4771
  lastName: z.string().min(1, "Last name is required").describe("The contact's last name (required)."),
4772
4772
  title: z.string().nullable().optional().describe("Title (e.g. Mr, Mrs, Dr)."),
4773
4773
  firstName: z.string().nullable().optional().describe("First name."),
4774
+ preferredName: z.string().nullable().optional().describe("The name the contact goes by when it differs from their first name (e.g. Matt for Matthias). Email templates greet with it via the PreferredName token, falling back to the first name."),
4774
4775
  middleName: z.string().nullable().optional().describe("Middle name."),
4775
4776
  email: z.string().nullable().optional().describe("Email address."),
4776
4777
  phone: z.string().nullable().optional().describe("Landline phone number."),
@@ -4854,6 +4855,7 @@ async function handleGetContact(api, args) {
4854
4855
  c.lastName
4855
4856
  ].filter(Boolean).join(" ") || "(no name)";
4856
4857
  lines.push(`Contact: ${name} (${c.code ?? args.contactCode})`);
4858
+ if (c.preferredName) lines.push(`Preferred name: ${c.preferredName}`);
4857
4859
  if (c.email) lines.push(`Email: ${c.email}`);
4858
4860
  if (c.phone) lines.push(`Phone: ${c.phone}`);
4859
4861
  if (c.mobile) lines.push(`Mobile: ${c.mobile}`);
@@ -5399,6 +5401,7 @@ const UpdateContactInputSchema = {
5399
5401
  lastName: z.string().min(1).describe("The contact's last name (required by the API even if unchanged)."),
5400
5402
  title: z.string().nullable().optional().describe("Title (e.g. Mr, Mrs, Dr). Pass null to clear."),
5401
5403
  firstName: z.string().nullable().optional().describe("First name. Pass null to clear."),
5404
+ preferredName: z.string().nullable().optional().describe("The name the contact goes by when it differs from their first name (e.g. Matt for Matthias). Email templates greet with it via the PreferredName token, falling back to the first name. Pass null to clear."),
5402
5405
  middleName: z.string().nullable().optional().describe("Middle name. Pass null to clear."),
5403
5406
  email: z.string().nullable().optional().describe("Email address. Pass null to clear."),
5404
5407
  phone: z.string().nullable().optional().describe("Landline phone number. Pass null to clear."),
@@ -5410,7 +5413,28 @@ const UpdateContactInputSchema = {
5410
5413
  };
5411
5414
  async function handleUpdateContact(api, args) {
5412
5415
  try {
5413
- const { contactCode, ...body } = args;
5416
+ const { contactCode, ...updates } = args;
5417
+ const existing = await api.getContact(contactCode);
5418
+ const body = {
5419
+ title: existing.title ?? null,
5420
+ firstName: existing.firstName ?? null,
5421
+ preferredName: existing.preferredName ?? null,
5422
+ middleName: existing.middleName ?? null,
5423
+ lastName: existing.lastName ?? "",
5424
+ email: existing.email ?? null,
5425
+ phone: existing.phone ?? null,
5426
+ mobile: existing.mobile ?? null,
5427
+ dateOfBirth: existing.dateOfBirth ?? null,
5428
+ utr: existing.utr ?? null,
5429
+ niNumber: existing.niNumber ?? null,
5430
+ personalCode: existing.personalCode ?? null,
5431
+ address: existing.address ?? null,
5432
+ nationality: existing.nationality,
5433
+ maritalStatus: existing.maritalStatus,
5434
+ isDeceased: existing.isDeceased ?? false,
5435
+ deceasedDate: existing.deceasedDate ?? null
5436
+ };
5437
+ for (const [key, value] of Object.entries(updates)) if (value !== void 0) body[key] = value;
5414
5438
  const updated = await api.updateContact(contactCode, body);
5415
5439
  const lines = [`Updated contact: ${[updated.firstName, updated.lastName].filter(Boolean).join(" ") || "(no name)"} (${updated.code ?? contactCode})`];
5416
5440
  if (updated.email) lines.push(`Email: ${updated.email}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sodiumhq/mcp-pm",
3
- "version": "0.1.0-beta.4241",
3
+ "version": "0.1.0-beta.4424",
4
4
  "description": "Sodium Practice Management MCP server — lets AI assistants interact with your Sodium tenant",
5
5
  "type": "module",
6
6
  "bin": {