@sodiumhq/mcp-pm 0.1.0-beta.6354 → 0.1.0-beta.6355
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-Cf9c-hOi.mjs → src--vw5xenq.mjs} +24 -24
- 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--vw5xenq.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { SUPPORTED_PROTOCOL_VERSIONS, createMcpHandler } from "@modelcontextprotocol/server";
|
|
5
5
|
import { createHash, randomUUID } from "node:crypto";
|
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--vw5xenq.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { serveStdio } from "@modelcontextprotocol/server/stdio";
|
|
5
5
|
import { parseArgs } from "node:util";
|
|
@@ -9600,7 +9600,7 @@ async function buildServer(config) {
|
|
|
9600
9600
|
}, (args) => handleListClients(api, args));
|
|
9601
9601
|
registerTenantTool(server, api, "get_client_summary", {
|
|
9602
9602
|
title: "Get a full summary of one client",
|
|
9603
|
-
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), custom fields (all user-defined fields with current values, data types, and field codes — use these codes with update_client_custom_fields), 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.
|
|
9603
|
+
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), custom fields (all user-defined fields with current values, data types, and field codes — use these codes with update_client_custom_fields), 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. Takes a client code, as returned by list_clients or given by the user. Also answers 'when is ACME's year-end?' / 'is ACME VAT registered?' / 'what are ACME's custom fields?' 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.",
|
|
9604
9604
|
inputSchema: GetClientSummaryInputSchema,
|
|
9605
9605
|
annotations: {
|
|
9606
9606
|
readOnlyHint: true,
|
|
@@ -9630,7 +9630,7 @@ async function buildServer(config) {
|
|
|
9630
9630
|
}, (args) => handleListClientNotes(api, args));
|
|
9631
9631
|
registerTenantTool(server, api, "list_tasks", {
|
|
9632
9632
|
title: "List / filter tasks across the practice",
|
|
9633
|
-
description: "List tasks with any combination of filters: assigned user(s), unassigned, client(s), the primary client's client manager / partner (portfolio views: 'tasks across the clients Jane manages'), status, overdue flag, preset date range (Today / ThisWeek / Next7Days / CustomDateRange etc), category, team, billable service, workflow, workflow step type, current step name, recurring task template, free-text search, saved filter, include-projected, include-workflow-steps (Agenda Mode), sort, and pagination. Use for: 'my tasks' (
|
|
9633
|
+
description: "List tasks with any combination of filters: assigned user(s), unassigned, client(s), the primary client's client manager / partner (portfolio views: 'tasks across the clients Jane manages'), status, overdue flag, preset date range (Today / ThisWeek / Next7Days / CustomDateRange etc), category, team, billable service, workflow, workflow step type, current step name, recurring task template, free-text search, saved filter, include-projected, include-workflow-steps (Agenda Mode), sort, and pagination. Use for: 'my tasks' (user = the signed-in user's practice user code, which whoami shows), 'Jane's overdue tasks' (user + isOverdue), 'tasks for ACME due this week' (client + dateRange=Next7Days + dateBasis=DueDate), 'what is the team working on this month' (dateRange=ThisMonth, no user filter). Returns up to 50 tasks per page; each row shows due date, statutory due date (when set), client, billable service (name + code), assignee, status and workflow progress. Constraints that avoid API errors and keep queries efficient: (1) Querying NotStarted tasks requires one of — a dateRange, isOverdue=true, or restricting status to non-NotStarted values. (2) Narrow date ranges are cheaper: broad ranges (quarterly/yearly) are expensive, and Today / ThisWeek / Next7Days / ThisMonth answer most questions. (3) For 'oldest incomplete tasks', status=['InProgress','Blocked'] with sortBy=StartDate needs no date range; add isOverdue=true if 'oldest overdue' is meant. (4) For 'how many X?' questions, pass limit=0 to get just the total count without fetching any task data — much cheaper than fetching a full page and counting.",
|
|
9634
9634
|
inputSchema: ListTasksInputSchema,
|
|
9635
9635
|
annotations: {
|
|
9636
9636
|
readOnlyHint: true,
|
|
@@ -9640,7 +9640,7 @@ async function buildServer(config) {
|
|
|
9640
9640
|
}, (args) => handleListTasks(api, args));
|
|
9641
9641
|
registerTenantTool(server, api, "get_task_context", {
|
|
9642
9642
|
title: "Get full context for a single task",
|
|
9643
|
-
description: "Get a consolidated view of one task by code: identity (name, code, status, overdue flag, start/due/statutory dates, time estimate, assignee, category, billable service, recurring/workflow templates), description, task-level checklist, workflow progress (groups and steps with status, assignee, and completion info — only if the task has a workflow attached), notes (pinned first, then newest first), and the parent client.
|
|
9643
|
+
description: "Get a consolidated view of one task by code: identity (name, code, status, overdue flag, start/due/statutory dates, time estimate, assignee, category, billable service, recurring/workflow templates), description, task-level checklist, workflow progress (groups and steps with status, assignee, and completion info — only if the task has a workflow attached), notes (pinned first, then newest first), and the parent client. Takes a task code, as returned by list_tasks or given by the user. Tolerates partial failures — if notes or workflow steps can't be loaded, the task details are still returned with a note about what's missing. Only fails outright if the task itself can't be fetched (e.g. unknown code).",
|
|
9644
9644
|
inputSchema: GetTaskContextInputSchema,
|
|
9645
9645
|
annotations: {
|
|
9646
9646
|
readOnlyHint: true,
|
|
@@ -9670,7 +9670,7 @@ async function buildServer(config) {
|
|
|
9670
9670
|
}, (args) => handleListEngagements(api, args));
|
|
9671
9671
|
registerTenantTool(server, api, "get_proposal_summary", {
|
|
9672
9672
|
title: "Get full detail of one proposal",
|
|
9673
|
-
description: "Get a consolidated view of a single proposal by engagement code: identity (code, status, type, date), client, recipient, value breakdown (annual / quarterly / monthly / one-off incl. catch-up fees / total), the proposed services with pricing (and each service's catch-up fee share), acceptance record (if accepted), PDF availability (proposal + letter of engagement), email history, and the acceptance link.
|
|
9673
|
+
description: "Get a consolidated view of a single proposal by engagement code: identity (code, status, type, date), client, recipient, value breakdown (annual / quarterly / monthly / one-off incl. catch-up fees / total), the proposed services with pricing (and each service's catch-up fee share), acceptance record (if accepted), PDF availability (proposal + letter of engagement), email history, and the acceptance link. Requires a concrete engagement code as input. list_proposals returns the codes and filters by status, client and date, which covers descriptions such as 'the unsent proposal', 'the proposal for ACME', 'our most recent proposal' or 'the rejected one'. Returns identical data to get_engagement_letter_summary — both aliases back the same Engagement entity. Tolerates partial failures (email history or the practice's catch-up fee label may be missing with a note); only fails hard if the engagement itself can't be fetched.",
|
|
9674
9674
|
inputSchema: GetEngagementSummaryInputSchema,
|
|
9675
9675
|
annotations: {
|
|
9676
9676
|
readOnlyHint: true,
|
|
@@ -9680,7 +9680,7 @@ async function buildServer(config) {
|
|
|
9680
9680
|
}, (args) => handleGetEngagementSummary(api, args));
|
|
9681
9681
|
registerTenantTool(server, api, "get_engagement_letter_summary", {
|
|
9682
9682
|
title: "Get full detail of one letter of engagement",
|
|
9683
|
-
description: "Get a consolidated view of a single letter of engagement by code: identity (code, status, type, date), client, recipient, value breakdown (annual / quarterly / monthly / one-off incl. catch-up fees / total), services included with pricing (and each service's catch-up fee share), acceptance record (accepted date, whether accepted via portal or recorded manually), PDF availability (proposal + letter of engagement), email history, and the acceptance link.
|
|
9683
|
+
description: "Get a consolidated view of a single letter of engagement by code: identity (code, status, type, date), client, recipient, value breakdown (annual / quarterly / monthly / one-off incl. catch-up fees / total), services included with pricing (and each service's catch-up fee share), acceptance record (accepted date, whether accepted via portal or recorded manually), PDF availability (proposal + letter of engagement), email history, and the acceptance link. Requires a concrete engagement code as input. list_engagement_letters returns the codes and filters by status, search text and date, which covers descriptions such as 'ACME's letter of engagement', 'the most recent signed engagement' or 'the live engagement for Smith & Co'. Returns identical data to get_proposal_summary — both aliases back the same Engagement entity. Tolerates partial failures (email history or the practice's catch-up fee label may be missing with a note); only fails hard if the engagement itself can't be fetched.",
|
|
9684
9684
|
inputSchema: GetEngagementSummaryInputSchema,
|
|
9685
9685
|
annotations: {
|
|
9686
9686
|
readOnlyHint: true,
|
|
@@ -9700,7 +9700,7 @@ async function buildServer(config) {
|
|
|
9700
9700
|
}, (args) => handleListServices(api, args));
|
|
9701
9701
|
registerTenantTool(server, api, "get_service_details", {
|
|
9702
9702
|
title: "Get a single service's full configuration",
|
|
9703
|
-
description: "Get a consolidated view of one billable service by code: identity (name, code, category, status, VAT rate, accounting code, description, default manager, pricing mode), applicable client types (explicit list, or 'all client types' if unrestricted), HMRC agent authorisations, pricing options (one per billing frequency with base price + override counts), custom pricing tiers (only when pricingMode=CustomTiers), professional clearance request items, and pricing-factor presence (count + factor questions only — exact factor band values are intentionally not dumped; computed pricing per client lives in the proposal tools).
|
|
9703
|
+
description: "Get a consolidated view of one billable service by code: identity (name, code, category, status, VAT rate, accounting code, description, default manager, pricing mode), applicable client types (explicit list, or 'all client types' if unrestricted), HMRC agent authorisations, pricing options (one per billing frequency with base price + override counts), custom pricing tiers (only when pricingMode=CustomTiers), professional clearance request items, and pricing-factor presence (count + factor questions only — exact factor band values are intentionally not dumped; computed pricing per client lives in the proposal tools). Takes a service code, as returned by list_services or given by the user. Enables service-audit workflows like 'is Self Assessment correctly restricted to Individual clients?' and 'what clearance items do we request for new bookkeeping clients?'",
|
|
9704
9704
|
inputSchema: GetServiceDetailsInputSchema,
|
|
9705
9705
|
annotations: {
|
|
9706
9706
|
readOnlyHint: true,
|
|
@@ -9745,13 +9745,13 @@ async function buildServer(config) {
|
|
|
9745
9745
|
};
|
|
9746
9746
|
registerTenantTool(server, api, "get_service_delivery_report", {
|
|
9747
9747
|
title: "Service delivery turnaround report",
|
|
9748
|
-
description: "Are we delivering client services as quickly as we should? Cohort = tasks COMPLETED in the window. Summary KPIs (count, avg/median turnaround from planned start to completion, on-time %, statutory compliance %, currently-overdue snapshot) plus a breakdown grouped by Service (default), Client, AssignedUser, or Month. Answers 'how fast do we turn around VAT returns?', 'which clients' work runs late?', 'is our turnaround improving month on month?' (groupBy=Month over a long window).
|
|
9748
|
+
description: "Are we delivering client services as quickly as we should? Cohort = tasks COMPLETED in the window. Summary KPIs (count, avg/median turnaround from planned start to completion, on-time %, statutory compliance %, currently-overdue snapshot) plus a breakdown grouped by Service (default), Client, AssignedUser, or Month. Answers 'how fast do we turn around VAT returns?', 'which clients' work runs late?', 'is our turnaround improving month on month?' (groupBy=Month over a long window). It does not cover missed deadlines — a task still open past its deadline never completed, so it isn't in this cohort; get_deadline_compliance_report covers those. For per-step bottlenecks within one service, follow up with get_service_delivery_steps. Constraints: dateRange='CustomDateRange' requires both startDate and endDate; summary always covers the whole cohort even when breakdown rows are paged.",
|
|
9749
9749
|
inputSchema: GetServiceDeliveryReportInputSchema,
|
|
9750
9750
|
annotations: reportAnnotations
|
|
9751
9751
|
}, (args) => handleGetServiceDeliveryReport(api, args));
|
|
9752
9752
|
registerTenantTool(server, api, "get_service_delivery_steps", {
|
|
9753
9753
|
title: "Per-step bottlenecks for one service",
|
|
9754
|
-
description: "Where does the time go inside one billable service's workflow? For tasks of the given service completed in the window: average elapsed days per workflow step (measured from the previous step's completion, so queue/idle time counts), skip counts, chase counts, and each step flagged client-wait (waiting on the client: document requests, approvals, confirmations, data forms) vs internal — splitting 'we were slow' from 'the client was slow'.
|
|
9754
|
+
description: "Where does the time go inside one billable service's workflow? For tasks of the given service completed in the window: average elapsed days per workflow step (measured from the previous step's completion, so queue/idle time counts), skip counts, chase counts, and each step flagged client-wait (waiting on the client: document requests, approvals, confirmations, data forms) vs internal — splitting 'we were slow' from 'the client was slow'. Follows on from get_service_delivery_report when it flags a slow service, and answers 'why do accounts jobs take so long?' directly. Requires serviceCode (from list_services). Note: steps are compared by name across tasks, so a renamed workflow step appears as separate rows.",
|
|
9755
9755
|
inputSchema: GetServiceDeliveryStepsInputSchema,
|
|
9756
9756
|
annotations: reportAnnotations
|
|
9757
9757
|
}, (args) => handleGetServiceDeliverySteps(api, args));
|
|
@@ -9814,7 +9814,7 @@ async function buildServer(config) {
|
|
|
9814
9814
|
}, (args) => handleListWorkflows(api, args));
|
|
9815
9815
|
registerTenantTool(server, api, "get_workflow", {
|
|
9816
9816
|
title: "Get one workflow template's full structure",
|
|
9817
|
-
description: "Get a single workflow template by code: the ordered groups and steps with step types (email, document request, approval, client confirmation, data form, etc.), assignment rules, auto-execute flags, dependencies, time estimates, and conditions. Answers 'what are the steps in our VAT return workflow?' and 'which steps in this workflow wait on the client?'.
|
|
9817
|
+
description: "Get a single workflow template by code: the ordered groups and steps with step types (email, document request, approval, client confirmation, data form, etc.), assignment rules, auto-execute flags, dependencies, time estimates, and conditions. Answers 'what are the steps in our VAT return workflow?' and 'which steps in this workflow wait on the client?'. Requires a concrete workflow code, as listed by list_workflows. For how the workflow performs in practice (durations, bottlenecks), use get_workflow_step_analysis.",
|
|
9818
9818
|
inputSchema: GetWorkflowInputSchema,
|
|
9819
9819
|
annotations: lookupAnnotations
|
|
9820
9820
|
}, (args) => handleGetWorkflow(api, args));
|
|
@@ -9838,25 +9838,25 @@ async function buildServer(config) {
|
|
|
9838
9838
|
}, (args) => handleListServiceCategories(api, args));
|
|
9839
9839
|
registerTenantTool(server, api, "list_saved_task_filters", {
|
|
9840
9840
|
title: "List saved task views",
|
|
9841
|
-
description: "List the user's saved task views/filters, showing each view's code AND the criteria it encodes (statuses, date range, users, teams, clients, categories, overdue/unassigned flags). Use when the user references a saved view by name ('run my Weekly Review', 'my compliance filter') — resolve the code here, then pass it as list_tasks' savedFilter. The echoed criteria also let you answer 'what does my Weekly Review view actually show?' without running it.
|
|
9841
|
+
description: "List the user's saved task views/filters, showing each view's code AND the criteria it encodes (statuses, date range, users, teams, clients, categories, overdue/unassigned flags). Use when the user references a saved view by name ('run my Weekly Review', 'my compliance filter') — resolve the code here, then pass it as list_tasks' savedFilter. The echoed criteria also let you answer 'what does my Weekly Review view actually show?' without running it. menuOnly=true returns only the views pinned to the user's menu, which are the ones they use daily.",
|
|
9842
9842
|
inputSchema: ListSavedTaskFiltersInputSchema,
|
|
9843
9843
|
annotations: lookupAnnotations
|
|
9844
9844
|
}, (args) => handleListSavedTaskFilters(api, args));
|
|
9845
9845
|
registerTenantTool(server, api, "list_saved_client_filters", {
|
|
9846
9846
|
title: "List saved client views",
|
|
9847
|
-
description: "List the user's saved client views/filters, showing each view's code AND the criteria it encodes (statuses, client types, managers, partners, services, teams). Use when the user references a saved view by name ('my VAT clients view') — resolve the code here, then pass it as list_clients' savedFilter.
|
|
9847
|
+
description: "List the user's saved client views/filters, showing each view's code AND the criteria it encodes (statuses, client types, managers, partners, services, teams). Use when the user references a saved view by name ('my VAT clients view') — resolve the code here, then pass it as list_clients' savedFilter. menuOnly=true returns only the views pinned to the user's menu.",
|
|
9848
9848
|
inputSchema: ListSavedClientFiltersInputSchema,
|
|
9849
9849
|
annotations: lookupAnnotations
|
|
9850
9850
|
}, (args) => handleListSavedClientFilters(api, args));
|
|
9851
9851
|
registerTenantTool(server, api, "search_companies_house", {
|
|
9852
9852
|
title: "Search Companies House",
|
|
9853
|
-
description: "Search the Companies House public register by company name (full or partial) or company number. Returns matches with number, status, type, incorporation date, and registered address — live data from the register, not limited to the practice's clients. Use for prospect due diligence ('look up Bristol Roofing'), finding a company number before get_companies_house_profile, or checking name availability.
|
|
9853
|
+
description: "Search the Companies House public register by company name (full or partial) or company number. Returns matches with number, status, type, incorporation date, and registered address — live data from the register, not limited to the practice's clients. Use for prospect due diligence ('look up Bristol Roofing'), finding a company number before get_companies_house_profile, or checking name availability. An existing client's company number is in get_client_summary's business details.",
|
|
9854
9854
|
inputSchema: SearchCompaniesHouseInputSchema,
|
|
9855
9855
|
annotations: lookupAnnotations
|
|
9856
9856
|
}, (args) => handleSearchCompaniesHouse(api, args));
|
|
9857
9857
|
registerTenantTool(server, api, "get_companies_house_profile", {
|
|
9858
9858
|
title: "Get a company's full Companies House profile",
|
|
9859
|
-
description: "Get the live Companies House record for one company number: legal status, incorporation date, registered office, SIC codes, accounts and confirmation-statement deadlines (with OVERDUE flags), last-filed accounts, charges/insolvency/liquidation flags, and current + resigned officers. Answers 'when are ACME's accounts due at Companies House?', 'who are the directors?', 'does this prospect have insolvency history?'.
|
|
9859
|
+
description: "Get the live Companies House record for one company number: legal status, incorporation date, registered office, SIC codes, accounts and confirmation-statement deadlines (with OVERDUE flags), last-filed accounts, charges/insolvency/liquidation flags, and current + resigned officers. Answers 'when are ACME's accounts due at Companies House?', 'who are the directors?', 'does this prospect have insolvency history?'. Requires a company number: search_companies_house finds one by name, and get_client_summary's business details holds an existing client's. Pass includeOfficers=false when only filing dates matter. Officers tolerate partial failure — the profile still returns if they can't be loaded.",
|
|
9860
9860
|
inputSchema: GetCompaniesHouseProfileInputSchema,
|
|
9861
9861
|
annotations: lookupAnnotations
|
|
9862
9862
|
}, (args) => handleGetCompaniesHouseProfile(api, args));
|
|
@@ -9874,7 +9874,7 @@ async function buildServer(config) {
|
|
|
9874
9874
|
}, (args) => handleListDataFormRequests(api, args));
|
|
9875
9875
|
registerTenantTool(server, api, "list_time_entries", {
|
|
9876
9876
|
title: "List / filter time entries",
|
|
9877
|
-
description: "List recorded time entries with filters: team member, client, task, preset date range (or CustomDateRange + fromDate/toDate), billable flag, billed flag, search, sort, pagination. Answers 'how much time have I logged this week?' (userCode = current user, dateRange=ThisWeek), 'time spent on ACME this month' (clientCode + dateRange=ThisMonth), 'what unbilled time do we have?' (isBillable=true, isBilled=false — the WIP question), 'biggest time entries on this job' (taskItemCode, sortBy=DurationMinutes, sortDesc=true). Each page also shows its summed duration.
|
|
9877
|
+
description: "List recorded time entries with filters: team member, client, task, preset date range (or CustomDateRange + fromDate/toDate), billable flag, billed flag, search, sort, pagination. Answers 'how much time have I logged this week?' (userCode = current user, dateRange=ThisWeek), 'time spent on ACME this month' (clientCode + dateRange=ThisMonth), 'what unbilled time do we have?' (isBillable=true, isBilled=false — the WIP question), 'biggest time entries on this job' (taskItemCode, sortBy=DurationMinutes, sortDesc=true). Each page also shows its summed duration. Unwindowed queries scan all history, so a narrow dateRange is much faster. For 'how many entries?' pass limit=0. get_service_time_report gives aggregate per-service/per-client totals over a period, summing the whole window in one call instead of paging entries.",
|
|
9878
9878
|
inputSchema: ListTimeEntriesInputSchema,
|
|
9879
9879
|
annotations: lookupAnnotations
|
|
9880
9880
|
}, (args) => handleListTimeEntries(api, args));
|
|
@@ -9898,7 +9898,7 @@ async function buildServer(config) {
|
|
|
9898
9898
|
}, (args) => handleListRecurringTasks(api, args));
|
|
9899
9899
|
registerTenantTool(server, api, "list_sent_emails", {
|
|
9900
9900
|
title: "List emails Sodium sent (delivery audit trail)",
|
|
9901
|
-
description: "List the emails Sodium sent on the practice's behalf — proposal/engagement emails, document-request chases, portal invitations, broadcasts — with delivery status (Queued/Processing/Sent/Failed/Cancelled), recipient, subject, date window, search, sort, pagination. THE tool for 'did the proposal email to ACME actually go out?', 'which emails failed this week?' (status=Failed + fromDate), 'what chases went to John?' (search on his address). This is the OUTBOUND SYSTEM audit trail only — for two-way email correspondence with a client (their replies, ad-hoc emails) use list_client_emails instead.
|
|
9901
|
+
description: "List the emails Sodium sent on the practice's behalf — proposal/engagement emails, document-request chases, portal invitations, broadcasts — with delivery status (Queued/Processing/Sent/Failed/Cancelled), recipient, subject, date window, search, sort, pagination. THE tool for 'did the proposal email to ACME actually go out?', 'which emails failed this week?' (status=Failed + fromDate), 'what chases went to John?' (search on his address). This is the OUTBOUND SYSTEM audit trail only — for two-way email correspondence with a client (their replies, ad-hoc emails) use list_client_emails instead. A fromDate/toDate window keeps results small; limit=0 returns a count only. Follow up with get_sent_email for full recipient/error detail.",
|
|
9902
9902
|
inputSchema: ListSentEmailsInputSchema,
|
|
9903
9903
|
annotations: lookupAnnotations
|
|
9904
9904
|
}, (args) => handleListSentEmails(api, args));
|
|
@@ -9964,7 +9964,7 @@ async function buildServer(config) {
|
|
|
9964
9964
|
}, (args) => handleListUnbilledTimeClients(api, args));
|
|
9965
9965
|
registerTenantTool(server, api, "get_engagement_pipeline_summary", {
|
|
9966
9966
|
title: "Proposal pipeline totals (counts + values by status)",
|
|
9967
|
-
description: "One-call aggregate of the engagement pipeline: counts and total values for Unsent / Sent / Viewed / Accepted / Rejected, plus the open pipeline (sent + viewed awaiting a decision). Answers 'what's our proposal pipeline worth?', 'how much did we win this quarter?' (dateRange=ThisQuarter, read the Accepted line), 'how much value is sitting unsigned?'. Omit the window for the all-time picture. Much cheaper than paging list_proposals and adding up
|
|
9967
|
+
description: "One-call aggregate of the engagement pipeline: counts and total values for Unsent / Sent / Viewed / Accepted / Rejected, plus the open pipeline (sent + viewed awaiting a decision). Answers 'what's our proposal pipeline worth?', 'how much did we win this quarter?' (dateRange=ThisQuarter, read the Accepted line), 'how much value is sitting unsigned?'. Omit the window for the all-time picture. Much cheaper than paging list_proposals and adding up, so it suits any totals question; list_proposals lists the individual engagements. Constraints: dateRange='CustomDateRange' requires dateFrom and dateTo.",
|
|
9968
9968
|
inputSchema: GetEngagementPipelineSummaryInputSchema,
|
|
9969
9969
|
annotations: lookupAnnotations
|
|
9970
9970
|
}, (args) => handleGetEngagementPipelineSummary(api, args));
|
|
@@ -10018,7 +10018,7 @@ async function buildServer(config) {
|
|
|
10018
10018
|
}, (args) => handleGetEmailBroadcast(api, args));
|
|
10019
10019
|
registerTenantTool(server, api, "get_client_email_thread", {
|
|
10020
10020
|
title: "Read one email conversation (synced mailbox)",
|
|
10021
|
-
description: "Drill into one email thread from the synced mailbox: every message in order with date, sender, read/attachment flags, and preview text, plus which clients and tasks the thread is linked to. Requires configCode AND conversationId
|
|
10021
|
+
description: "Drill into one email thread from the synced mailbox: every message in order with date, sender, read/attachment flags, and preview text, plus which clients and tasks the thread is linked to. Requires configCode AND conversationId, both shown per thread in list_client_emails output. Answers 'what did ACME actually say in that thread?', 'show me the whole conversation about the VAT surcharge'. Message previews are snippets, not complete bodies — full bodies and attachments are opened in Sodium.",
|
|
10022
10022
|
inputSchema: GetClientEmailThreadInputSchema,
|
|
10023
10023
|
annotations: lookupAnnotations
|
|
10024
10024
|
}, (args) => handleGetClientEmailThread(api, args));
|
|
@@ -10063,7 +10063,7 @@ async function buildServer(config) {
|
|
|
10063
10063
|
}, (args) => handleUpdateServiceCategory(api, args));
|
|
10064
10064
|
registerWriteTool(server, api, config.context, "apply_service_package", {
|
|
10065
10065
|
title: "Apply a service package to a client",
|
|
10066
|
-
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'.
|
|
10066
|
+
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'. Notes: (1) The API does not check whether the client already has this package, so calling twice applies it a second time; get_client_summary shows whether it is already there. (2) Unlike 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.",
|
|
10067
10067
|
inputSchema: ApplyServicePackageInputSchema,
|
|
10068
10068
|
annotations: {
|
|
10069
10069
|
readOnlyHint: false,
|
|
@@ -10085,7 +10085,7 @@ async function buildServer(config) {
|
|
|
10085
10085
|
}, (args) => handleUpdateClientServiceStage(api, args));
|
|
10086
10086
|
registerWriteTool(server, api, config.context, "create_document_request", {
|
|
10087
10087
|
title: "Draft a document request for a client",
|
|
10088
|
-
description: "Create a document request as a DRAFT — nothing is sent and the client is not notified. Requires clientCode and a title; optional client-facing description (write it as the client will read it), deadline, and a team member to notify on submission. Use for 'ask ACME for their year-end records', 'request the Jan–Mar bank statements from Greggs'.
|
|
10088
|
+
description: "Create a document request as a DRAFT — nothing is sent and the client is not notified. Requires clientCode and a title; optional client-facing description (write it as the client will read it), deadline, and a team member to notify on submission. Use for 'ask ACME for their year-end records', 'request the Jan–Mar bank statements from Greggs'. It is saved as a draft and not sent; the user reviews and sends it from the client's Documents tab in Sodium. Track it afterwards with list_document_requests (status=Draft).",
|
|
10089
10089
|
inputSchema: CreateDocumentRequestInputSchema,
|
|
10090
10090
|
annotations: {
|
|
10091
10091
|
readOnlyHint: false,
|
|
@@ -10107,7 +10107,7 @@ async function buildServer(config) {
|
|
|
10107
10107
|
}, (args) => handleSendDataForm(api, args));
|
|
10108
10108
|
registerWriteTool(server, api, config.context, "create_proposal", {
|
|
10109
10109
|
title: "Draft a proposal / letter of engagement",
|
|
10110
|
-
description: "Create an engagement in UNSENT (draft) state — the client is NOT emailed; sending is a deliberate separate action in the Sodium UI. Requires clientCode and date. type defaults to ProposalAndEngagementLetter ('EngagementLetter' for existing clients needing only the letter). clientBillableServiceCodes are the CLIENT'S service-subscription codes (get_client_summary's services section), not catalogue codes — to propose a service the client doesn't have yet, first add_client_service with status 'Proposed', then include its new code here. Recipient defaults to the client's main contact when omitted; only use an email from the client's contacts or given by the user. Use for 'draft a proposal for Bristol Roofing covering bookkeeping and VAT'.
|
|
10110
|
+
description: "Create an engagement in UNSENT (draft) state — the client is NOT emailed; sending is a deliberate separate action in the Sodium UI. Requires clientCode and date. type defaults to ProposalAndEngagementLetter ('EngagementLetter' for existing clients needing only the letter). clientBillableServiceCodes are the CLIENT'S service-subscription codes (get_client_summary's services section), not catalogue codes — to propose a service the client doesn't have yet, first add_client_service with status 'Proposed', then include its new code here. Recipient defaults to the client's main contact when omitted; only use an email from the client's contacts or given by the user. Use for 'draft a proposal for Bristol Roofing covering bookkeeping and VAT'. The result states the drafted value and that it has not been sent; full detail via get_proposal_summary.",
|
|
10111
10111
|
inputSchema: CreateProposalInputSchema,
|
|
10112
10112
|
annotations: {
|
|
10113
10113
|
readOnlyHint: false,
|
|
@@ -10118,7 +10118,7 @@ async function buildServer(config) {
|
|
|
10118
10118
|
}, (args) => handleCreateProposal(api, args));
|
|
10119
10119
|
registerWriteTool(server, api, config.context, "update_client_dates", {
|
|
10120
10120
|
title: "Set key/statutory dates on a client",
|
|
10121
|
-
description: "Set one or more of a client's key dates (year-end, VAT return due, PAYE/CIS filing due, pension re-enrolment...). Takes an array of { dateType, date } — only the types you pass change; pass date=null to clear one. Current values are in get_client_summary's key-dates section. Use for 'set ACME's year-end to 31 March', 'record the pension re-enrolment date'.
|
|
10121
|
+
description: "Set one or more of a client's key dates (year-end, VAT return due, PAYE/CIS filing due, pension re-enrolment...). Takes an array of { dateType, date } — only the types you pass change; pass date=null to clear one. Current values are in get_client_summary's key-dates section. Use for 'set ACME's year-end to 31 March', 'record the pension re-enrolment date'. For clients connected to Companies House, register-derived dates (accounts due, confirmation statement) are synced automatically and manual values may be overwritten; YearEnd, VAT, PAYE and pension dates are safe to set on connected clients.",
|
|
10122
10122
|
inputSchema: UpdateClientDatesInputSchema,
|
|
10123
10123
|
annotations: {
|
|
10124
10124
|
readOnlyHint: false,
|
|
@@ -10151,7 +10151,7 @@ async function buildServer(config) {
|
|
|
10151
10151
|
}, (args) => handleCreateSavedTaskFilter(api, args));
|
|
10152
10152
|
registerWriteTool(server, api, config.context, "update_workflow_step", {
|
|
10153
10153
|
title: "Update a workflow step (complete, skip, block, reassign)",
|
|
10154
|
-
description: "Update one workflow step on a task: set status (Completed / Skipped / InProgress / Blocked with a blockedReason) and/or reassign to a user or team. Identify the step by taskCode + groupNumber + stepNumber exactly as shown in get_task_context's workflow section
|
|
10154
|
+
description: "Update one workflow step on a task: set status (Completed / Skipped / InProgress / Blocked with a blockedReason) and/or reassign to a user or team. Identify the step by taskCode + groupNumber + stepNumber exactly as shown in get_task_context's workflow section, which also shows each step's current status. Use for 'mark the review step on TSK-123 as done', 'skip the client-approval step, they confirmed by phone', 'assign the bookkeeping steps to Jane'. Constraints: steps with dependencies may be rejected until prior steps complete — report the API's reason rather than retrying; auto-executing steps (emails, document requests) fire when their turn comes, so completing them manually may skip the automated action — warn the user if get_task_context showed the step as auto-executing. Step content/configuration is not editable here — that's done in the Sodium UI.",
|
|
10155
10155
|
inputSchema: UpdateWorkflowStepInputSchema,
|
|
10156
10156
|
annotations: {
|
|
10157
10157
|
readOnlyHint: false,
|
|
@@ -10162,7 +10162,7 @@ async function buildServer(config) {
|
|
|
10162
10162
|
}, (args) => handleUpdateWorkflowStep(api, args));
|
|
10163
10163
|
registerWriteTool(server, api, config.context, "create_task", {
|
|
10164
10164
|
title: "Create a new task",
|
|
10165
|
-
description: "Create a one-off task. Requires name, startDate, and dueDate (YYYY-MM-DD — 'due Friday' resolves against today
|
|
10165
|
+
description: "Create a one-off task. Requires name, startDate, and dueDate (YYYY-MM-DD — 'due Friday' resolves against today's date). Optional: description, status (defaults NotStarted), statutory due date, time estimate, client(s) (codes from list_clients), assignee (user code from the roster/list_users, or team code from list_teams), linked client-billable-service, category (list_task_categories), and a checklist (array of item texts). Use for 'create a task to chase ACME's rental schedule, due Friday', 'add a task for Jane to review the draft accounts'. Do NOT use for recurring schedules or workflow-driven tasks — those are set up in the Sodium UI. If the user gave a client or person by name, resolve codes first; ask rather than guess when multiple matches exist.",
|
|
10166
10166
|
inputSchema: CreateTaskInputSchema,
|
|
10167
10167
|
annotations: {
|
|
10168
10168
|
readOnlyHint: false,
|
|
@@ -10184,7 +10184,7 @@ async function buildServer(config) {
|
|
|
10184
10184
|
}, (args) => handleUpdateTask(api, args));
|
|
10185
10185
|
registerWriteTool(server, api, config.context, "log_time_entry", {
|
|
10186
10186
|
title: "Log a time entry",
|
|
10187
|
-
description: "Record time spent, after the fact. Requires entryDate (YYYY-MM-DD —
|
|
10187
|
+
description: "Record time spent, after the fact. Requires entryDate (YYYY-MM-DD — today's date applies when none is given) and durationMinutes ('2 hours' → 120). Optional: description (strongly recommended — it feeds billing narratives), client code, task code, workflow group/step numbers (from get_task_context), billable flag, hourly rate, and userCode when logging on someone else's behalf (defaults to the authenticated user). Use for 'log 2 hours on ACME for today — reviewing the draft accounts', 'add 45 minutes against the Greggs VAT task'. Billable and rate default from practice/team-member configuration — only pass them when the user is explicit. Some practices require a client or task link; if the API rejects the entry saying so, ask the user which client/task to attach.",
|
|
10188
10188
|
inputSchema: LogTimeEntryInputSchema,
|
|
10189
10189
|
annotations: {
|
|
10190
10190
|
readOnlyHint: false,
|