conduyt-mcp 4.63.0 → 4.65.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.
package/README.md CHANGED
@@ -117,6 +117,8 @@ MCP server for [Conduyt CRM](https://conduyt.app) — expose your CRM as AI-acce
117
117
  | `conduyt_get_appointment` | Get appointment with contact and assignee details |
118
118
  | `conduyt_create_appointment` | Create an appointment (times require timezone) |
119
119
  | `conduyt_update_appointment` | Reschedule, reassign, or cancel |
120
+ | `conduyt_appointment_outcome` | Completed / no-show / cancelled / rescheduled: sets the status and moves the deal to the mapped stage |
121
+ | `conduyt_appointment_outcome_undo` | Reverse the last outcome: status back, deal back to its previous stage when untouched since |
120
122
 
121
123
  ### Forms
122
124
  | Tool | Description |
@@ -78,4 +78,19 @@ export function registerCalendarTools(server, client) {
78
78
  const result = await client.patch(`/api/v1/appointments/${id}`, updates);
79
79
  return formatResult(result);
80
80
  });
81
+ server.tool("conduyt_appointment_outcome", "Record an appointment's outcome (completed, no_show, cancelled) in one action: sets the appointment status AND moves the contact's most recently updated open deal to the stage the account mapped for that outcome in Pipeline settings (appointmentOutcomeStages). Returns { appointment, stageMove, reason }; reason explains when nothing moved (no_contact, no_deal, no_mapping, already_there, stage_move_failed).", {
82
+ id: z.string().describe("Appointment UUID"),
83
+ outcome: z.enum(["completed", "no_show", "cancelled", "rescheduled"]).describe("The outcome to record. rescheduled moves the appointment to startTime/endTime (both required then) and keeps its status."),
84
+ startTime: z.string().optional().describe("rescheduled only: new start, ISO 8601 with timezone offset"),
85
+ endTime: z.string().optional().describe("rescheduled only: new end, ISO 8601 with timezone offset"),
86
+ }, async ({ id, outcome, startTime, endTime }) => {
87
+ const result = await client.post(`/api/v1/appointments/${id}/outcome`, { outcome, ...(startTime ? { startTime } : {}), ...(endTime ? { endTime } : {}) });
88
+ return formatResult(result);
89
+ });
90
+ server.tool("conduyt_appointment_outcome_undo", "Undo the last outcome recorded on an appointment: the status returns to what it was before, and the deal returns to the stage the outcome moved it from — only if it is still in the stage the outcome put it in (a stage changed by hand since is left alone; the answer says stageRestored and reason).", {
91
+ id: z.string().describe("Appointment UUID"),
92
+ }, async ({ id }) => {
93
+ const result = await client.post(`/api/v1/appointments/${id}/outcome/undo`, {});
94
+ return formatResult(result);
95
+ });
81
96
  }
@@ -103,7 +103,7 @@ export function registerDealTools(server, client) {
103
103
  probability: z.number().min(0).max(1).optional().describe("Win probability as a 0–1 fraction (e.g. 0.75 = 75%)"),
104
104
  expectedCloseDate: z.string().optional().describe("Expected close date (ISO 8601)"),
105
105
  assignedTo: z.string().optional().describe("Reassign to user (owner) UUID"),
106
- source: z.string().trim().min(1).max(500).nullable().optional().describe("Attribution source for THIS deal (the trigger that produced it) — distinct from the contact's first-touch source. Pass null to clear it; a blank string is rejected. 1-500 chars."),
106
+ source: z.string().trim().min(1).max(500).optional().describe("Attribution source for THIS deal (the trigger that produced it) — distinct from the contact's first-touch source. Every deal keeps a source (#129): it can be changed, never cleared (null/blank are rejected). 1-500 chars."),
107
107
  lostReason: z.string().optional().describe("Reason for a lost/disqualified deal. Some stages REQUIRE this on entry (the move fails with code STAGE_REQUIREMENTS listing lostReasonOptions when the stage has a configured dropdown — resend with one of those exact values)."),
108
108
  customFields: z.record(z.any()).optional().describe("Structured custom-field values to merge, keyed by field key"),
109
109
  }, async ({ id, ...updates }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conduyt-mcp",
3
- "version": "4.63.0",
3
+ "version": "4.65.0",
4
4
  "description": "MCP server for Conduyt CRM — expose CRM operations as AI-accessible tools",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,11 +1,11 @@
1
1
  {
2
- "generatedAt": "2026-09-18T04:50:57.467Z",
3
- "toolCount": 280,
4
- "totalEndpoints": 984,
2
+ "generatedAt": "2026-09-22T10:41:04.677Z",
3
+ "toolCount": 282,
4
+ "totalEndpoints": 998,
5
5
  "counts": {
6
- "covered": 260,
7
- "excluded": 289,
8
- "planned": 435,
6
+ "covered": 262,
7
+ "excluded": 291,
8
+ "planned": 445,
9
9
  "uncategorized": 0
10
10
  },
11
11
  "matrix": {
@@ -61,6 +61,18 @@
61
61
  "status": "planned",
62
62
  "reason": "appointment mutation subroutes beyond booking tools"
63
63
  },
64
+ "POST /api/v1/appointments/:id/outcome": {
65
+ "status": "covered",
66
+ "tools": [
67
+ "conduyt_appointment_outcome"
68
+ ]
69
+ },
70
+ "POST /api/v1/appointments/:id/outcome/undo": {
71
+ "status": "covered",
72
+ "tools": [
73
+ "conduyt_appointment_outcome_undo"
74
+ ]
75
+ },
64
76
  "GET /api/public/forms/:slug": {
65
77
  "status": "excluded",
66
78
  "reason": "public unauthenticated surfaces (forms, booking, unsubscribe) — no key semantics"
@@ -1186,6 +1198,14 @@
1186
1198
  "conduyt_voice_drop"
1187
1199
  ]
1188
1200
  },
1201
+ "POST /api/v1/chat/ask": {
1202
+ "status": "planned",
1203
+ "reason": "team chat read/post for agents"
1204
+ },
1205
+ "POST /api/v1/chat/celebrate": {
1206
+ "status": "planned",
1207
+ "reason": "team chat read/post for agents"
1208
+ },
1189
1209
  "GET /api/v1/chat/channels": {
1190
1210
  "status": "planned",
1191
1211
  "reason": "team chat read/post for agents"
@@ -1222,6 +1242,18 @@
1222
1242
  "status": "planned",
1223
1243
  "reason": "team chat read/post for agents"
1224
1244
  },
1245
+ "POST /api/v1/chat/channels/:id/messages/:messageId/claim": {
1246
+ "status": "planned",
1247
+ "reason": "team chat read/post for agents"
1248
+ },
1249
+ "POST /api/v1/chat/channels/:id/messages/:messageId/handoff": {
1250
+ "status": "planned",
1251
+ "reason": "team chat read/post for agents"
1252
+ },
1253
+ "POST /api/v1/chat/channels/:id/messages/:messageId/pin": {
1254
+ "status": "planned",
1255
+ "reason": "team chat read/post for agents"
1256
+ },
1225
1257
  "POST /api/v1/chat/channels/:id/messages/:messageId/reactions": {
1226
1258
  "status": "planned",
1227
1259
  "reason": "team chat read/post for agents"
@@ -1230,6 +1262,10 @@
1230
1262
  "status": "planned",
1231
1263
  "reason": "team chat read/post for agents"
1232
1264
  },
1265
+ "GET /api/v1/chat/channels/:id/pins": {
1266
+ "status": "planned",
1267
+ "reason": "team chat read/post for agents"
1268
+ },
1233
1269
  "GET /api/v1/chat/channels/:id/typing": {
1234
1270
  "status": "planned",
1235
1271
  "reason": "team chat read/post for agents"
@@ -1246,6 +1282,22 @@
1246
1282
  "status": "planned",
1247
1283
  "reason": "team chat read/post for agents"
1248
1284
  },
1285
+ "GET /api/v1/chat/floor": {
1286
+ "status": "planned",
1287
+ "reason": "team chat read/post for agents"
1288
+ },
1289
+ "POST /api/v1/chat/handoff": {
1290
+ "status": "planned",
1291
+ "reason": "team chat read/post for agents"
1292
+ },
1293
+ "GET /api/v1/chat/presence": {
1294
+ "status": "planned",
1295
+ "reason": "team chat read/post for agents"
1296
+ },
1297
+ "GET /api/v1/chat/search": {
1298
+ "status": "planned",
1299
+ "reason": "team chat read/post for agents"
1300
+ },
1249
1301
  "GET /api/v1/companies": {
1250
1302
  "status": "covered",
1251
1303
  "tools": [
@@ -1729,6 +1781,10 @@
1729
1781
  "status": "excluded",
1730
1782
  "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
1731
1783
  },
1784
+ "GET /api/v1/cron/process-trial-signup-alerts": {
1785
+ "status": "excluded",
1786
+ "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
1787
+ },
1732
1788
  "GET /api/v1/cron/process-unattended-leads": {
1733
1789
  "status": "excluded",
1734
1790
  "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
@@ -1877,6 +1933,10 @@
1877
1933
  "status": "excluded",
1878
1934
  "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
1879
1935
  },
1936
+ "GET /api/v1/cron/team-chat-daily": {
1937
+ "status": "excluded",
1938
+ "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
1939
+ },
1880
1940
  "GET /api/v1/cron/trial-lifecycle-emails": {
1881
1941
  "status": "excluded",
1882
1942
  "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"