conduyt-mcp 4.88.0 → 4.89.0

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.
@@ -1,4 +1,5 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
2
3
  import { ConduytClient } from "../client.js";
3
4
  type DisclosureOn = "inbound" | "outbound" | "both";
4
5
  type RecordingPolicy = {
@@ -20,6 +21,8 @@ type RecordingPolicy = {
20
21
  export declare function effectiveRecordingPolicy(raw: unknown): RecordingPolicy | null;
21
22
  /** the iPhone line has no inbound calls: what its policy does there, the way the server applies it */
22
23
  export declare function iphoneDomain(policy: RecordingPolicy): RecordingPolicy;
24
+ /** 0 = the wrap-up auto-release is off, otherwise 30..3600 seconds (the API refuses anything else with 400) */
25
+ export declare const wrapupAutoReleaseSecondsSchema: z.ZodEffects<z.ZodNumber, number, number>;
23
26
  /**
24
27
  * Smart Dialing policy (GET/PATCH /api/v1/dialer/settings): the account-wide rules every rep's Smart Dialing run
25
28
  * follows. Read needs the dialer scope; update needs the settings scope (admin). (#95/#96, 2026-09-16)
@@ -29,24 +29,27 @@ export function iphoneDomain(policy) {
29
29
  const on = policy.disclosure.on;
30
30
  return { ...policy, inbound: false, disclosure: on === "inbound" ? { enabled: false, on: "outbound" } : { enabled: policy.disclosure.enabled, on: "outbound" } };
31
31
  }
32
+ /** 0 = the wrap-up auto-release is off, otherwise 30..3600 seconds (the API refuses anything else with 400) */
33
+ export const wrapupAutoReleaseSecondsSchema = z.number().int().refine((n) => n === 0 || (n >= 30 && n <= 3600), "wrapupAutoReleaseSeconds must be 0 (off) or a whole number of seconds from 30 to 3600");
32
34
  /**
33
35
  * Smart Dialing policy (GET/PATCH /api/v1/dialer/settings): the account-wide rules every rep's Smart Dialing run
34
36
  * follows. Read needs the dialer scope; update needs the settings scope (admin). (#95/#96, 2026-09-16)
35
37
  */
36
38
  export function registerDialerSettingsTools(server, client) {
37
- server.tool("conduyt_get_dialer_settings", "Read the account's Smart Dialing policy: autoAdvanceEnabled + pauseSeconds + advanceOn ('disposition' = the next dial waits for a saved disposition, 'timer' = the pause starts when the call ends), openLeadOnDial (the lead's record opens as each Smart Dialing call goes out), smartDialCallerId ('local_presence' = an area-code match from the number pool, the rep's own line when no pool exists; 'did' = always the rep's own line), and localPresenceConfigured (whether a number pool exists).", {}, async () => formatResult(await client.get("/api/v1/dialer/settings")));
38
- server.tool("conduyt_update_dialer_settings", "Change the account's Smart Dialing policy (admin: settings scope). Send only the fields to change: autoAdvanceEnabled, pauseSeconds (1-60), advanceOn ('disposition' | 'timer'), openLeadOnDial (true = the lead's record opens as each Smart Dialing call goes out), smartDialCallerId ('local_presence' | 'did'). Returns the policy as saved.", {
39
+ server.tool("conduyt_get_dialer_settings", "Read the account's Smart Dialing policy: autoAdvanceEnabled + pauseSeconds + advanceOn ('disposition' = the next dial waits for a saved disposition, 'timer' = the pause starts when the call ends), openLeadOnDial (the lead's record opens as each Smart Dialing call goes out), smartDialCallerId ('local_presence' = an area-code match from the number pool, the rep's own line when no pool exists; 'did' = always the rep's own line), wrapupAutoReleaseSeconds (seconds of continuous wrap-up after which a rep returns to Available automatically: 0 = off, otherwise 30 to 3600; default 300), and localPresenceConfigured (whether a number pool exists).", {}, async () => formatResult(await client.get("/api/v1/dialer/settings")));
40
+ server.tool("conduyt_update_dialer_settings", "Change the account's Smart Dialing policy (admin: settings scope). Send only the fields to change: autoAdvanceEnabled, pauseSeconds (1-60), advanceOn ('disposition' | 'timer'), openLeadOnDial (true = the lead's record opens as each Smart Dialing call goes out), smartDialCallerId ('local_presence' | 'did'), wrapupAutoReleaseSeconds (0 = off, otherwise 30 to 3600: seconds of continuous wrap-up after which a rep returns to Available automatically). Returns the policy as saved.", {
39
41
  autoAdvanceEnabled: z.boolean().optional().describe("Start the next dial automatically after a call"),
40
42
  pauseSeconds: z.number().int().min(1).max(60).optional().describe("Seconds between calls when auto-advance is on"),
41
43
  advanceOn: z.enum(["disposition", "timer"]).optional().describe("'disposition': wait for a saved disposition; 'timer': the pause starts when the call ends"),
42
44
  openLeadOnDial: z.boolean().optional().describe("Open the lead's record as each Smart Dialing call goes out (default true)"),
43
45
  smartDialCallerId: z.enum(["local_presence", "did"]).optional().describe("Line Smart Dialing calls go out on: Local Presence (default) or the rep's own DID"),
44
- }, async ({ autoAdvanceEnabled, pauseSeconds, advanceOn, openLeadOnDial, smartDialCallerId }) => {
45
- if ([autoAdvanceEnabled, pauseSeconds, advanceOn, openLeadOnDial, smartDialCallerId].every((v) => v === undefined)) {
46
- return { content: [{ type: "text", text: "Nothing to change: pass at least one of autoAdvanceEnabled, pauseSeconds, advanceOn, openLeadOnDial, smartDialCallerId." }], isError: true };
46
+ wrapupAutoReleaseSeconds: wrapupAutoReleaseSecondsSchema.optional().describe("Seconds of continuous wrap-up after which a rep returns to Available automatically: 0 = off, otherwise 30 to 3600 (default 300)"),
47
+ }, async ({ autoAdvanceEnabled, pauseSeconds, advanceOn, openLeadOnDial, smartDialCallerId, wrapupAutoReleaseSeconds }) => {
48
+ if ([autoAdvanceEnabled, pauseSeconds, advanceOn, openLeadOnDial, smartDialCallerId, wrapupAutoReleaseSeconds].every((v) => v === undefined)) {
49
+ return { content: [{ type: "text", text: "Nothing to change: pass at least one of autoAdvanceEnabled, pauseSeconds, advanceOn, openLeadOnDial, smartDialCallerId, wrapupAutoReleaseSeconds." }], isError: true };
47
50
  }
48
51
  // undefined fields drop out of the JSON body, so only the named changes reach the route
49
- const result = await client.patch("/api/v1/dialer/settings", { autoAdvanceEnabled, pauseSeconds, advanceOn, openLeadOnDial, smartDialCallerId });
52
+ const result = await client.patch("/api/v1/dialer/settings", { autoAdvanceEnabled, pauseSeconds, advanceOn, openLeadOnDial, smartDialCallerId, wrapupAutoReleaseSeconds });
50
53
  return formatResult(result);
51
54
  });
52
55
  // Call recording policy (the Call recording card of Settings, released 2026-09-30): which calls are recorded and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conduyt-mcp",
3
- "version": "4.88.0",
3
+ "version": "4.89.0",
4
4
  "mcpName": "com.conduyt/mcp",
5
5
  "description": "MCP server for Conduyt CRM — expose CRM operations as AI-accessible tools",
6
6
  "type": "module",
@@ -10,6 +10,11 @@
10
10
  "status": "planned",
11
11
  "reason": "single-function read; the list tool plus update/delete/test exist, a typed get is wanted but not built (4.23.0)"
12
12
  },
13
+ {
14
+ "match": "POST /api/v1/feature-interest",
15
+ "status": "excluded",
16
+ "reason": "session-only UI endpoint, not an API-key capability (the signed-in user's interest click on an unreleased feature, e.g. the Gmail inbox; no API-key access)"
17
+ },
13
18
  {
14
19
  "match": "/api/health",
15
20
  "status": "excluded",
@@ -1,10 +1,10 @@
1
1
  {
2
- "generatedAt": "2026-10-15T02:16:36.008Z",
2
+ "generatedAt": "2026-10-15T15:19:50.604Z",
3
3
  "toolCount": 350,
4
- "totalEndpoints": 1084,
4
+ "totalEndpoints": 1085,
5
5
  "counts": {
6
6
  "covered": 309,
7
- "excluded": 323,
7
+ "excluded": 324,
8
8
  "planned": 452,
9
9
  "uncategorized": 0
10
10
  },
@@ -2834,6 +2834,10 @@
2834
2834
  "status": "planned",
2835
2835
  "reason": "client error ingestion"
2836
2836
  },
2837
+ "POST /api/v1/feature-interest": {
2838
+ "status": "excluded",
2839
+ "reason": "session-only UI endpoint, not an API-key capability (the signed-in user's interest click on an unreleased feature, e.g. the Gmail inbox; no API-key access)"
2840
+ },
2837
2841
  "GET /api/v1/files": {
2838
2842
  "status": "planned",
2839
2843
  "reason": "file listing/metadata is agent-useful; upload stays browser-side"