syncromsp-mcp 0.1.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/LICENSE +21 -0
- package/README.md +244 -0
- package/dist/api-client.d.ts +21 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +117 -0
- package/dist/api-client.js.map +1 -0
- package/dist/auth.d.ts +37 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +133 -0
- package/dist/auth.js.map +1 -0
- package/dist/domains/admin.d.ts +4 -0
- package/dist/domains/admin.d.ts.map +1 -0
- package/dist/domains/admin.js +807 -0
- package/dist/domains/admin.js.map +1 -0
- package/dist/domains/appointments.d.ts +4 -0
- package/dist/domains/appointments.d.ts.map +1 -0
- package/dist/domains/appointments.js +231 -0
- package/dist/domains/appointments.js.map +1 -0
- package/dist/domains/assets.d.ts +4 -0
- package/dist/domains/assets.d.ts.map +1 -0
- package/dist/domains/assets.js +138 -0
- package/dist/domains/assets.js.map +1 -0
- package/dist/domains/contacts.d.ts +4 -0
- package/dist/domains/contacts.d.ts.map +1 -0
- package/dist/domains/contacts.js +148 -0
- package/dist/domains/contacts.js.map +1 -0
- package/dist/domains/contracts.d.ts +4 -0
- package/dist/domains/contracts.d.ts.map +1 -0
- package/dist/domains/contracts.js +125 -0
- package/dist/domains/contracts.js.map +1 -0
- package/dist/domains/customers.d.ts +4 -0
- package/dist/domains/customers.d.ts.map +1 -0
- package/dist/domains/customers.js +323 -0
- package/dist/domains/customers.js.map +1 -0
- package/dist/domains/estimates.d.ts +4 -0
- package/dist/domains/estimates.d.ts.map +1 -0
- package/dist/domains/estimates.js +262 -0
- package/dist/domains/estimates.js.map +1 -0
- package/dist/domains/index.d.ts +5 -0
- package/dist/domains/index.d.ts.map +1 -0
- package/dist/domains/index.js +34 -0
- package/dist/domains/index.js.map +1 -0
- package/dist/domains/invoices.d.ts +4 -0
- package/dist/domains/invoices.d.ts.map +1 -0
- package/dist/domains/invoices.js +292 -0
- package/dist/domains/invoices.js.map +1 -0
- package/dist/domains/leads.d.ts +4 -0
- package/dist/domains/leads.d.ts.map +1 -0
- package/dist/domains/leads.js +135 -0
- package/dist/domains/leads.js.map +1 -0
- package/dist/domains/payments.d.ts +4 -0
- package/dist/domains/payments.d.ts.map +1 -0
- package/dist/domains/payments.js +188 -0
- package/dist/domains/payments.js.map +1 -0
- package/dist/domains/products.d.ts +4 -0
- package/dist/domains/products.d.ts.map +1 -0
- package/dist/domains/products.js +350 -0
- package/dist/domains/products.js.map +1 -0
- package/dist/domains/rmm.d.ts +4 -0
- package/dist/domains/rmm.d.ts.map +1 -0
- package/dist/domains/rmm.js +100 -0
- package/dist/domains/rmm.js.map +1 -0
- package/dist/domains/scheduling.d.ts +4 -0
- package/dist/domains/scheduling.d.ts.map +1 -0
- package/dist/domains/scheduling.js +206 -0
- package/dist/domains/scheduling.js.map +1 -0
- package/dist/domains/tickets.d.ts +4 -0
- package/dist/domains/tickets.d.ts.map +1 -0
- package/dist/domains/tickets.js +533 -0
- package/dist/domains/tickets.js.map +1 -0
- package/dist/domains/time.d.ts +4 -0
- package/dist/domains/time.d.ts.map +1 -0
- package/dist/domains/time.js +93 -0
- package/dist/domains/time.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +137 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +183 -0
- package/dist/server.js.map +1 -0
- package/dist/session.d.ts +12 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +31 -0
- package/dist/session.js.map +1 -0
- package/dist/types.d.ts +46 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +44 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/pagination.d.ts +12 -0
- package/dist/utils/pagination.d.ts.map +1 -0
- package/dist/utils/pagination.js +18 -0
- package/dist/utils/pagination.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +15 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +63 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/dist/utils/validators.d.ts +9 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +59 -0
- package/dist/utils/validators.js.map +1 -0
- package/dist/utils/version-check.d.ts +7 -0
- package/dist/utils/version-check.d.ts.map +1 -0
- package/dist/utils/version-check.js +59 -0
- package/dist/utils/version-check.js.map +1 -0
- package/manifest.json +64 -0
- package/package.json +57 -0
|
@@ -0,0 +1,807 @@
|
|
|
1
|
+
import { jsonResult, textResult } from "../types.js";
|
|
2
|
+
import { requireId, requireString, optionalString, optionalNumber, optionalBoolean, optionalId, pickDefined } from "../utils/validators.js";
|
|
3
|
+
export function createDomain(client) {
|
|
4
|
+
const tools = [
|
|
5
|
+
// === Search ===
|
|
6
|
+
{
|
|
7
|
+
definition: {
|
|
8
|
+
name: "admin_search",
|
|
9
|
+
description: "Global search across Syncro (tickets, customers, assets, invoices, etc.)",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
query: { type: "string", description: "Search query (required)" },
|
|
14
|
+
},
|
|
15
|
+
required: ["query"],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
handler: async (args) => jsonResult(await client.get("/search", { query: args.query })),
|
|
19
|
+
},
|
|
20
|
+
// === Users ===
|
|
21
|
+
{
|
|
22
|
+
definition: {
|
|
23
|
+
name: "admin_get_me",
|
|
24
|
+
description: "Get the currently authenticated user's profile",
|
|
25
|
+
inputSchema: { type: "object", properties: {} },
|
|
26
|
+
},
|
|
27
|
+
handler: async () => jsonResult(await client.get("/me")),
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
definition: {
|
|
31
|
+
name: "admin_list_users",
|
|
32
|
+
description: "List all users/technicians",
|
|
33
|
+
inputSchema: { type: "object", properties: {} },
|
|
34
|
+
},
|
|
35
|
+
handler: async () => jsonResult(await client.get("/users")),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
definition: {
|
|
39
|
+
name: "admin_get_user",
|
|
40
|
+
description: "Get a user by ID",
|
|
41
|
+
inputSchema: {
|
|
42
|
+
type: "object",
|
|
43
|
+
properties: { id: { type: "number", description: "User ID" } },
|
|
44
|
+
required: ["id"],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
handler: async (args) => jsonResult(await client.get(`/users/${requireId(args.id)}`)),
|
|
48
|
+
},
|
|
49
|
+
// === Settings ===
|
|
50
|
+
{
|
|
51
|
+
definition: {
|
|
52
|
+
name: "admin_get_settings",
|
|
53
|
+
description: "Get system settings",
|
|
54
|
+
inputSchema: { type: "object", properties: {} },
|
|
55
|
+
},
|
|
56
|
+
handler: async () => jsonResult(await client.get("/settings")),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
definition: {
|
|
60
|
+
name: "admin_get_tabs",
|
|
61
|
+
description: "Get settings tabs configuration",
|
|
62
|
+
inputSchema: { type: "object", properties: {} },
|
|
63
|
+
},
|
|
64
|
+
handler: async () => jsonResult(await client.get("/settings/tabs")),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
definition: {
|
|
68
|
+
name: "admin_get_printing",
|
|
69
|
+
description: "Get printing settings",
|
|
70
|
+
inputSchema: { type: "object", properties: {} },
|
|
71
|
+
},
|
|
72
|
+
handler: async () => jsonResult(await client.get("/settings/printing")),
|
|
73
|
+
},
|
|
74
|
+
// === Vendors ===
|
|
75
|
+
{
|
|
76
|
+
definition: {
|
|
77
|
+
name: "admin_list_vendors",
|
|
78
|
+
description: "List vendors",
|
|
79
|
+
inputSchema: { type: "object", properties: {} },
|
|
80
|
+
},
|
|
81
|
+
handler: async () => jsonResult(await client.get("/vendors")),
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
definition: {
|
|
85
|
+
name: "admin_get_vendor",
|
|
86
|
+
description: "Get a vendor by ID",
|
|
87
|
+
inputSchema: {
|
|
88
|
+
type: "object",
|
|
89
|
+
properties: { id: { type: "number", description: "Vendor ID" } },
|
|
90
|
+
required: ["id"],
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
handler: async (args) => jsonResult(await client.get(`/vendors/${requireId(args.id)}`)),
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
definition: {
|
|
97
|
+
name: "admin_create_vendor",
|
|
98
|
+
description: "Create a new vendor. Note: there is no delete endpoint for vendors.",
|
|
99
|
+
inputSchema: {
|
|
100
|
+
type: "object",
|
|
101
|
+
properties: {
|
|
102
|
+
name: { type: "string", description: "Vendor name (required)" },
|
|
103
|
+
rep_first_name: { type: "string" }, rep_last_name: { type: "string" },
|
|
104
|
+
email: { type: "string" }, phone: { type: "string" },
|
|
105
|
+
account_number: { type: "string" }, address: { type: "string" },
|
|
106
|
+
city: { type: "string" }, state: { type: "string" },
|
|
107
|
+
zip: { type: "string" }, website: { type: "string" },
|
|
108
|
+
notes: { type: "string" },
|
|
109
|
+
},
|
|
110
|
+
required: ["name"],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
handler: async (args) => {
|
|
114
|
+
const body = pickDefined({
|
|
115
|
+
name: requireString(args.name, "name"),
|
|
116
|
+
rep_first_name: optionalString(args.rep_first_name), rep_last_name: optionalString(args.rep_last_name),
|
|
117
|
+
email: optionalString(args.email), phone: optionalString(args.phone),
|
|
118
|
+
account_number: optionalString(args.account_number), address: optionalString(args.address),
|
|
119
|
+
city: optionalString(args.city), state: optionalString(args.state),
|
|
120
|
+
zip: optionalString(args.zip), website: optionalString(args.website),
|
|
121
|
+
notes: optionalString(args.notes),
|
|
122
|
+
});
|
|
123
|
+
return jsonResult(await client.post("/vendors", body));
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
definition: {
|
|
128
|
+
name: "admin_update_vendor",
|
|
129
|
+
description: "Update a vendor",
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: "object",
|
|
132
|
+
properties: {
|
|
133
|
+
id: { type: "number", description: "Vendor ID (required)" },
|
|
134
|
+
name: { type: "string" }, rep_first_name: { type: "string" },
|
|
135
|
+
rep_last_name: { type: "string" }, email: { type: "string" },
|
|
136
|
+
phone: { type: "string" }, account_number: { type: "string" },
|
|
137
|
+
address: { type: "string" }, city: { type: "string" },
|
|
138
|
+
state: { type: "string" }, zip: { type: "string" },
|
|
139
|
+
website: { type: "string" }, notes: { type: "string" },
|
|
140
|
+
},
|
|
141
|
+
required: ["id"],
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
handler: async (args) => {
|
|
145
|
+
const id = requireId(args.id);
|
|
146
|
+
const body = pickDefined({
|
|
147
|
+
name: optionalString(args.name), rep_first_name: optionalString(args.rep_first_name),
|
|
148
|
+
rep_last_name: optionalString(args.rep_last_name), email: optionalString(args.email),
|
|
149
|
+
phone: optionalString(args.phone), account_number: optionalString(args.account_number),
|
|
150
|
+
address: optionalString(args.address), city: optionalString(args.city),
|
|
151
|
+
state: optionalString(args.state), zip: optionalString(args.zip),
|
|
152
|
+
website: optionalString(args.website), notes: optionalString(args.notes),
|
|
153
|
+
});
|
|
154
|
+
return jsonResult(await client.put(`/vendors/${id}`, body));
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
// === Wiki Pages ===
|
|
158
|
+
{
|
|
159
|
+
definition: {
|
|
160
|
+
name: "admin_list_wiki",
|
|
161
|
+
description: "List wiki pages",
|
|
162
|
+
inputSchema: {
|
|
163
|
+
type: "object",
|
|
164
|
+
properties: { page: { type: "number", description: "Page number" } },
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
handler: async (args) => {
|
|
168
|
+
const params = pickDefined({ page: optionalNumber(args.page) });
|
|
169
|
+
return jsonResult(await client.get("/wiki_pages", params));
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
definition: {
|
|
174
|
+
name: "admin_get_wiki",
|
|
175
|
+
description: "Get a wiki page by ID",
|
|
176
|
+
inputSchema: {
|
|
177
|
+
type: "object",
|
|
178
|
+
properties: { id: { type: "number", description: "Wiki page ID" } },
|
|
179
|
+
required: ["id"],
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
handler: async (args) => jsonResult(await client.get(`/wiki_pages/${requireId(args.id)}`)),
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
definition: {
|
|
186
|
+
name: "admin_create_wiki",
|
|
187
|
+
description: "Create a wiki page",
|
|
188
|
+
inputSchema: {
|
|
189
|
+
type: "object",
|
|
190
|
+
properties: {
|
|
191
|
+
name: { type: "string", description: "Page name (required)" },
|
|
192
|
+
body: { type: "string", description: "Page content (HTML/Markdown)" },
|
|
193
|
+
slug: { type: "string", description: "URL slug" },
|
|
194
|
+
customer_id: { type: "number", description: "Associate with customer" },
|
|
195
|
+
asset_id: { type: "number", description: "Associate with asset" },
|
|
196
|
+
visibility: { type: "string", description: "Visibility level" },
|
|
197
|
+
},
|
|
198
|
+
required: ["name"],
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
handler: async (args) => {
|
|
202
|
+
const body = pickDefined({
|
|
203
|
+
name: requireString(args.name, "name"), body: optionalString(args.body),
|
|
204
|
+
slug: optionalString(args.slug), customer_id: optionalId(args.customer_id),
|
|
205
|
+
asset_id: optionalId(args.asset_id), visibility: optionalString(args.visibility),
|
|
206
|
+
});
|
|
207
|
+
return jsonResult(await client.post("/wiki_pages", body));
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
definition: {
|
|
212
|
+
name: "admin_update_wiki",
|
|
213
|
+
description: "Update a wiki page",
|
|
214
|
+
inputSchema: {
|
|
215
|
+
type: "object",
|
|
216
|
+
properties: {
|
|
217
|
+
id: { type: "number", description: "Wiki page ID (required)" },
|
|
218
|
+
name: { type: "string" }, body: { type: "string" }, slug: { type: "string" },
|
|
219
|
+
customer_id: { type: "number" }, asset_id: { type: "number" },
|
|
220
|
+
visibility: { type: "string" },
|
|
221
|
+
},
|
|
222
|
+
required: ["id"],
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
handler: async (args) => {
|
|
226
|
+
const id = requireId(args.id);
|
|
227
|
+
const body = pickDefined({
|
|
228
|
+
name: optionalString(args.name), body: optionalString(args.body),
|
|
229
|
+
slug: optionalString(args.slug), customer_id: optionalId(args.customer_id),
|
|
230
|
+
asset_id: optionalId(args.asset_id), visibility: optionalString(args.visibility),
|
|
231
|
+
});
|
|
232
|
+
return jsonResult(await client.put(`/wiki_pages/${id}`, body));
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
definition: {
|
|
237
|
+
name: "admin_delete_wiki",
|
|
238
|
+
description: "DELETE a wiki page. The user MUST confirm.",
|
|
239
|
+
inputSchema: {
|
|
240
|
+
type: "object",
|
|
241
|
+
properties: {
|
|
242
|
+
id: { type: "number", description: "Wiki page ID" },
|
|
243
|
+
confirmed: { type: "boolean", description: "Must be true" },
|
|
244
|
+
},
|
|
245
|
+
required: ["id", "confirmed"],
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
handler: async (args) => {
|
|
249
|
+
const id = requireId(args.id);
|
|
250
|
+
if (args.confirmed !== true)
|
|
251
|
+
return textResult(`⚠️ CONFIRMATION REQUIRED: Delete wiki page #${id}? Call again with confirmed: true.`);
|
|
252
|
+
const result = await client.delete(`/wiki_pages/${id}`);
|
|
253
|
+
return result ? jsonResult(result) : textResult(`Wiki page #${id} deleted.`);
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
// === Portal Users ===
|
|
257
|
+
{
|
|
258
|
+
definition: {
|
|
259
|
+
name: "admin_list_portal_users",
|
|
260
|
+
description: "List customer portal users",
|
|
261
|
+
inputSchema: { type: "object", properties: {} },
|
|
262
|
+
},
|
|
263
|
+
handler: async () => jsonResult(await client.get("/portal_users")),
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
definition: {
|
|
267
|
+
name: "admin_create_portal_user",
|
|
268
|
+
description: "Create a customer portal user. Always provide contact_id to associate a person/name -- without it the portal user shows as an anonymous email.",
|
|
269
|
+
inputSchema: {
|
|
270
|
+
type: "object",
|
|
271
|
+
properties: {
|
|
272
|
+
contact_id: { type: "number", description: "Contact ID (strongly recommended -- associates a name with the portal user)" },
|
|
273
|
+
customer_id: { type: "number", description: "Customer ID" },
|
|
274
|
+
email: { type: "string", description: "Email (required)" },
|
|
275
|
+
password: { type: "string", description: "Password" },
|
|
276
|
+
password_confirmation: { type: "string", description: "Password confirmation" },
|
|
277
|
+
portal_group_id: { type: "number", description: "Portal group ID" },
|
|
278
|
+
},
|
|
279
|
+
required: ["email"],
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
handler: async (args) => {
|
|
283
|
+
const body = pickDefined({
|
|
284
|
+
contact_id: optionalId(args.contact_id), customer_id: optionalId(args.customer_id),
|
|
285
|
+
email: args.email, password: optionalString(args.password),
|
|
286
|
+
password_confirmation: optionalString(args.password_confirmation),
|
|
287
|
+
portal_group_id: optionalId(args.portal_group_id),
|
|
288
|
+
});
|
|
289
|
+
return jsonResult(await client.post("/portal_users", body));
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
definition: {
|
|
294
|
+
name: "admin_update_portal_user",
|
|
295
|
+
description: "Update a portal user",
|
|
296
|
+
inputSchema: {
|
|
297
|
+
type: "object",
|
|
298
|
+
properties: {
|
|
299
|
+
id: { type: "number", description: "Portal user ID (required)" },
|
|
300
|
+
email: { type: "string" }, password: { type: "string" },
|
|
301
|
+
password_confirmation: { type: "string" }, portal_group_id: { type: "number" },
|
|
302
|
+
},
|
|
303
|
+
required: ["id"],
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
handler: async (args) => {
|
|
307
|
+
const id = requireId(args.id);
|
|
308
|
+
const body = pickDefined({
|
|
309
|
+
email: optionalString(args.email), password: optionalString(args.password),
|
|
310
|
+
password_confirmation: optionalString(args.password_confirmation),
|
|
311
|
+
portal_group_id: optionalId(args.portal_group_id),
|
|
312
|
+
});
|
|
313
|
+
return jsonResult(await client.put(`/portal_users/${id}`, body));
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
definition: {
|
|
318
|
+
name: "admin_delete_portal_user",
|
|
319
|
+
description: "DELETE a portal user. The user MUST confirm.",
|
|
320
|
+
inputSchema: {
|
|
321
|
+
type: "object",
|
|
322
|
+
properties: {
|
|
323
|
+
id: { type: "number", description: "Portal user ID" },
|
|
324
|
+
confirmed: { type: "boolean", description: "Must be true" },
|
|
325
|
+
},
|
|
326
|
+
required: ["id", "confirmed"],
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
handler: async (args) => {
|
|
330
|
+
const id = requireId(args.id);
|
|
331
|
+
if (args.confirmed !== true)
|
|
332
|
+
return textResult(`⚠️ CONFIRMATION REQUIRED: Delete portal user #${id}? Call again with confirmed: true.`);
|
|
333
|
+
const result = await client.delete(`/portal_users/${id}`);
|
|
334
|
+
return result ? jsonResult(result) : textResult(`Portal user #${id} deleted.`);
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
definition: {
|
|
339
|
+
name: "admin_create_portal_invitation",
|
|
340
|
+
description: "Send a portal invitation to a user",
|
|
341
|
+
inputSchema: {
|
|
342
|
+
type: "object",
|
|
343
|
+
properties: {
|
|
344
|
+
id: { type: "number", description: "Portal user ID" },
|
|
345
|
+
},
|
|
346
|
+
required: ["id"],
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
handler: async (args) => jsonResult(await client.post("/portal_users/create_invitation", { id: requireId(args.id) })),
|
|
350
|
+
},
|
|
351
|
+
// === Canned Responses ===
|
|
352
|
+
{
|
|
353
|
+
definition: {
|
|
354
|
+
name: "admin_list_canned_responses",
|
|
355
|
+
description: "List canned ticket responses",
|
|
356
|
+
inputSchema: { type: "object", properties: {} },
|
|
357
|
+
},
|
|
358
|
+
handler: async () => jsonResult(await client.get("/canned_responses")),
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
definition: {
|
|
362
|
+
name: "admin_create_canned_response",
|
|
363
|
+
description: "Create a canned response",
|
|
364
|
+
inputSchema: {
|
|
365
|
+
type: "object",
|
|
366
|
+
properties: {
|
|
367
|
+
title: { type: "string", description: "Title (required)" },
|
|
368
|
+
body: { type: "string", description: "Response body" },
|
|
369
|
+
subject: { type: "string", description: "Email subject" },
|
|
370
|
+
canned_response_category_id: { type: "number", description: "Category ID" },
|
|
371
|
+
},
|
|
372
|
+
required: ["title"],
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
handler: async (args) => {
|
|
376
|
+
const body = pickDefined({
|
|
377
|
+
title: requireString(args.title, "title"), body: optionalString(args.body),
|
|
378
|
+
subject: optionalString(args.subject),
|
|
379
|
+
canned_response_category_id: optionalId(args.canned_response_category_id),
|
|
380
|
+
});
|
|
381
|
+
return jsonResult(await client.post("/canned_responses", body));
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
definition: {
|
|
386
|
+
name: "admin_update_canned_response",
|
|
387
|
+
description: "Update a canned response",
|
|
388
|
+
inputSchema: {
|
|
389
|
+
type: "object",
|
|
390
|
+
properties: {
|
|
391
|
+
id: { type: "number", description: "Canned response ID (required)" },
|
|
392
|
+
title: { type: "string" }, body: { type: "string" },
|
|
393
|
+
subject: { type: "string" }, canned_response_category_id: { type: "number" },
|
|
394
|
+
},
|
|
395
|
+
required: ["id"],
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
handler: async (args) => {
|
|
399
|
+
const id = requireId(args.id);
|
|
400
|
+
const body = pickDefined({
|
|
401
|
+
title: optionalString(args.title), body: optionalString(args.body),
|
|
402
|
+
subject: optionalString(args.subject),
|
|
403
|
+
canned_response_category_id: optionalId(args.canned_response_category_id),
|
|
404
|
+
});
|
|
405
|
+
return jsonResult(await client.patch(`/canned_responses/${id}`, body));
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
definition: {
|
|
410
|
+
name: "admin_delete_canned_response",
|
|
411
|
+
description: "DELETE a canned response. The user MUST confirm.",
|
|
412
|
+
inputSchema: {
|
|
413
|
+
type: "object",
|
|
414
|
+
properties: {
|
|
415
|
+
id: { type: "number", description: "Canned response ID" },
|
|
416
|
+
confirmed: { type: "boolean", description: "Must be true" },
|
|
417
|
+
},
|
|
418
|
+
required: ["id", "confirmed"],
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
handler: async (args) => {
|
|
422
|
+
const id = requireId(args.id);
|
|
423
|
+
if (args.confirmed !== true)
|
|
424
|
+
return textResult(`⚠️ CONFIRMATION REQUIRED: Delete canned response #${id}? Call again with confirmed: true.`);
|
|
425
|
+
const result = await client.delete(`/canned_responses/${id}`);
|
|
426
|
+
return result ? jsonResult(result) : textResult(`Canned response #${id} deleted.`);
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
definition: {
|
|
431
|
+
name: "admin_get_canned_settings",
|
|
432
|
+
description: "Get canned response settings",
|
|
433
|
+
inputSchema: { type: "object", properties: {} },
|
|
434
|
+
},
|
|
435
|
+
handler: async () => jsonResult(await client.get("/canned_responses/settings")),
|
|
436
|
+
},
|
|
437
|
+
// === Caller ID ===
|
|
438
|
+
{
|
|
439
|
+
definition: {
|
|
440
|
+
name: "admin_caller_id",
|
|
441
|
+
description: "Look up caller information by phone number",
|
|
442
|
+
inputSchema: {
|
|
443
|
+
type: "object",
|
|
444
|
+
properties: {
|
|
445
|
+
phone_number: { type: "string", description: "Phone number to look up" },
|
|
446
|
+
},
|
|
447
|
+
required: ["phone_number"],
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
handler: async (args) => jsonResult(await client.get("/callerid", { phone_number: args.phone_number })),
|
|
451
|
+
},
|
|
452
|
+
// === User Devices ===
|
|
453
|
+
{
|
|
454
|
+
definition: {
|
|
455
|
+
name: "admin_create_user_device",
|
|
456
|
+
description: "Register a user device for push notifications",
|
|
457
|
+
inputSchema: {
|
|
458
|
+
type: "object",
|
|
459
|
+
properties: {
|
|
460
|
+
device_uuid: { type: "string", description: "Device UUID" },
|
|
461
|
+
device_name: { type: "string", description: "Device name" },
|
|
462
|
+
registration_token_gcm: { type: "string", description: "GCM registration token" },
|
|
463
|
+
system_name: { type: "string", description: "OS name" },
|
|
464
|
+
model: { type: "string", description: "Device model" },
|
|
465
|
+
screen_size: { type: "string", description: "Screen size" },
|
|
466
|
+
},
|
|
467
|
+
},
|
|
468
|
+
},
|
|
469
|
+
handler: async (args) => {
|
|
470
|
+
const body = pickDefined({
|
|
471
|
+
device_uuid: optionalString(args.device_uuid), device_name: optionalString(args.device_name),
|
|
472
|
+
registration_token_gcm: optionalString(args.registration_token_gcm),
|
|
473
|
+
system_name: optionalString(args.system_name), model: optionalString(args.model),
|
|
474
|
+
screen_size: optionalString(args.screen_size),
|
|
475
|
+
});
|
|
476
|
+
return jsonResult(await client.post("/user_devices", body));
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
definition: {
|
|
481
|
+
name: "admin_get_user_device",
|
|
482
|
+
description: "Get a user device by ID",
|
|
483
|
+
inputSchema: {
|
|
484
|
+
type: "object",
|
|
485
|
+
properties: { id: { type: "number", description: "Device ID" } },
|
|
486
|
+
required: ["id"],
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
handler: async (args) => jsonResult(await client.get(`/user_devices/${requireId(args.id)}`)),
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
definition: {
|
|
493
|
+
name: "admin_update_user_device",
|
|
494
|
+
description: "Update a user device",
|
|
495
|
+
inputSchema: {
|
|
496
|
+
type: "object",
|
|
497
|
+
properties: {
|
|
498
|
+
id: { type: "number", description: "Device ID (required)" },
|
|
499
|
+
registration_token_gcm: { type: "string", description: "GCM token" },
|
|
500
|
+
},
|
|
501
|
+
required: ["id"],
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
handler: async (args) => {
|
|
505
|
+
const id = requireId(args.id);
|
|
506
|
+
return jsonResult(await client.put(`/user_devices/${id}`, { registration_token_gcm: optionalString(args.registration_token_gcm) }));
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
// === Ticket Forms ===
|
|
510
|
+
{
|
|
511
|
+
definition: {
|
|
512
|
+
name: "admin_list_ticket_forms",
|
|
513
|
+
description: "List new ticket forms",
|
|
514
|
+
inputSchema: { type: "object", properties: {} },
|
|
515
|
+
},
|
|
516
|
+
handler: async () => jsonResult(await client.get("/new_ticket_forms")),
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
definition: {
|
|
520
|
+
name: "admin_get_ticket_form",
|
|
521
|
+
description: "Get a ticket form by ID",
|
|
522
|
+
inputSchema: {
|
|
523
|
+
type: "object",
|
|
524
|
+
properties: { id: { type: "number", description: "Form ID" } },
|
|
525
|
+
required: ["id"],
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
handler: async (args) => jsonResult(await client.get(`/new_ticket_forms/${requireId(args.id)}`)),
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
definition: {
|
|
532
|
+
name: "admin_process_ticket_form",
|
|
533
|
+
description: "Submit/process a new ticket form",
|
|
534
|
+
inputSchema: {
|
|
535
|
+
type: "object",
|
|
536
|
+
properties: {
|
|
537
|
+
id: { type: "number", description: "Form ID" },
|
|
538
|
+
customer_details: { type: "object", description: "Customer details" },
|
|
539
|
+
ticket_details: { type: "object", description: "Ticket details" },
|
|
540
|
+
appointments: { type: "object", description: "Appointment details" },
|
|
541
|
+
},
|
|
542
|
+
required: ["id"],
|
|
543
|
+
},
|
|
544
|
+
},
|
|
545
|
+
handler: async (args) => {
|
|
546
|
+
const id = requireId(args.id);
|
|
547
|
+
const body = pickDefined({
|
|
548
|
+
customer_details: args.customer_details,
|
|
549
|
+
ticket_details: args.ticket_details,
|
|
550
|
+
appointments: args.appointments,
|
|
551
|
+
});
|
|
552
|
+
return jsonResult(await client.post(`/new_ticket_forms/${id}/process_form`, body));
|
|
553
|
+
},
|
|
554
|
+
},
|
|
555
|
+
// === Worksheet Results ===
|
|
556
|
+
{
|
|
557
|
+
definition: {
|
|
558
|
+
name: "admin_list_worksheets",
|
|
559
|
+
description: "List worksheet results for a ticket",
|
|
560
|
+
inputSchema: {
|
|
561
|
+
type: "object",
|
|
562
|
+
properties: { ticket_id: { type: "number", description: "Ticket ID" } },
|
|
563
|
+
required: ["ticket_id"],
|
|
564
|
+
},
|
|
565
|
+
},
|
|
566
|
+
handler: async (args) => {
|
|
567
|
+
const ticketId = requireId(args.ticket_id, "ticket_id");
|
|
568
|
+
return jsonResult(await client.get(`/tickets/${ticketId}/worksheet_results`));
|
|
569
|
+
},
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
definition: {
|
|
573
|
+
name: "admin_get_worksheet",
|
|
574
|
+
description: "Get a worksheet result by ID",
|
|
575
|
+
inputSchema: {
|
|
576
|
+
type: "object",
|
|
577
|
+
properties: {
|
|
578
|
+
ticket_id: { type: "number", description: "Ticket ID" },
|
|
579
|
+
id: { type: "number", description: "Worksheet result ID" },
|
|
580
|
+
},
|
|
581
|
+
required: ["ticket_id", "id"],
|
|
582
|
+
},
|
|
583
|
+
},
|
|
584
|
+
handler: async (args) => {
|
|
585
|
+
const ticketId = requireId(args.ticket_id, "ticket_id");
|
|
586
|
+
const id = requireId(args.id);
|
|
587
|
+
return jsonResult(await client.get(`/tickets/${ticketId}/worksheet_results/${id}`));
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
definition: {
|
|
592
|
+
name: "admin_create_worksheet",
|
|
593
|
+
description: "Create a worksheet result for a ticket. Note: worksheet_template_id is required and must reference an existing admin-configured template.",
|
|
594
|
+
inputSchema: {
|
|
595
|
+
type: "object",
|
|
596
|
+
properties: {
|
|
597
|
+
ticket_id: { type: "number", description: "Ticket ID" },
|
|
598
|
+
worksheet_template_id: { type: "number", description: "Worksheet template ID (required -- must reference an existing template)" },
|
|
599
|
+
title: { type: "string", description: "Title" },
|
|
600
|
+
},
|
|
601
|
+
required: ["ticket_id"],
|
|
602
|
+
},
|
|
603
|
+
},
|
|
604
|
+
handler: async (args) => {
|
|
605
|
+
const ticketId = requireId(args.ticket_id, "ticket_id");
|
|
606
|
+
const body = pickDefined({
|
|
607
|
+
worksheet_template_id: optionalId(args.worksheet_template_id),
|
|
608
|
+
title: optionalString(args.title),
|
|
609
|
+
});
|
|
610
|
+
return jsonResult(await client.post(`/tickets/${ticketId}/worksheet_results`, body));
|
|
611
|
+
},
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
definition: {
|
|
615
|
+
name: "admin_update_worksheet",
|
|
616
|
+
description: "Update a worksheet result",
|
|
617
|
+
inputSchema: {
|
|
618
|
+
type: "object",
|
|
619
|
+
properties: {
|
|
620
|
+
ticket_id: { type: "number", description: "Ticket ID" },
|
|
621
|
+
id: { type: "number", description: "Worksheet result ID" },
|
|
622
|
+
title: { type: "string" }, complete: { type: "boolean" },
|
|
623
|
+
public: { type: "boolean" }, required: { type: "boolean" },
|
|
624
|
+
user_id: { type: "number" }, answers: { type: "object", description: "Worksheet answers" },
|
|
625
|
+
},
|
|
626
|
+
required: ["ticket_id", "id"],
|
|
627
|
+
},
|
|
628
|
+
},
|
|
629
|
+
handler: async (args) => {
|
|
630
|
+
const ticketId = requireId(args.ticket_id, "ticket_id");
|
|
631
|
+
const id = requireId(args.id);
|
|
632
|
+
const body = pickDefined({
|
|
633
|
+
title: optionalString(args.title), complete: optionalBoolean(args.complete),
|
|
634
|
+
public: optionalBoolean(args.public), required: optionalBoolean(args.required),
|
|
635
|
+
user_id: optionalId(args.user_id), answers: args.answers,
|
|
636
|
+
});
|
|
637
|
+
return jsonResult(await client.put(`/tickets/${ticketId}/worksheet_results/${id}`, body));
|
|
638
|
+
},
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
definition: {
|
|
642
|
+
name: "admin_delete_worksheet",
|
|
643
|
+
description: "DELETE a worksheet result. The user MUST confirm.",
|
|
644
|
+
inputSchema: {
|
|
645
|
+
type: "object",
|
|
646
|
+
properties: {
|
|
647
|
+
ticket_id: { type: "number", description: "Ticket ID" },
|
|
648
|
+
id: { type: "number", description: "Worksheet result ID" },
|
|
649
|
+
confirmed: { type: "boolean", description: "Must be true" },
|
|
650
|
+
},
|
|
651
|
+
required: ["ticket_id", "id", "confirmed"],
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
handler: async (args) => {
|
|
655
|
+
const ticketId = requireId(args.ticket_id, "ticket_id");
|
|
656
|
+
const id = requireId(args.id);
|
|
657
|
+
if (args.confirmed !== true)
|
|
658
|
+
return textResult(`⚠️ CONFIRMATION REQUIRED: Delete worksheet #${id}? Call again with confirmed: true.`);
|
|
659
|
+
const result = await client.delete(`/tickets/${ticketId}/worksheet_results/${id}`);
|
|
660
|
+
return result ? jsonResult(result) : textResult(`Worksheet deleted.`);
|
|
661
|
+
},
|
|
662
|
+
},
|
|
663
|
+
// === Purchase Orders ===
|
|
664
|
+
{
|
|
665
|
+
definition: {
|
|
666
|
+
name: "admin_list_purchase_orders",
|
|
667
|
+
description: "List purchase orders",
|
|
668
|
+
inputSchema: {
|
|
669
|
+
type: "object",
|
|
670
|
+
properties: { page: { type: "number", description: "Page number" } },
|
|
671
|
+
},
|
|
672
|
+
},
|
|
673
|
+
handler: async (args) => {
|
|
674
|
+
const params = pickDefined({ page: optionalNumber(args.page) });
|
|
675
|
+
return jsonResult(await client.get("/purchase_orders", params));
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
definition: {
|
|
680
|
+
name: "admin_get_purchase_order",
|
|
681
|
+
description: "Get a purchase order by ID",
|
|
682
|
+
inputSchema: {
|
|
683
|
+
type: "object",
|
|
684
|
+
properties: { id: { type: "number", description: "PO ID" } },
|
|
685
|
+
required: ["id"],
|
|
686
|
+
},
|
|
687
|
+
},
|
|
688
|
+
handler: async (args) => jsonResult(await client.get(`/purchase_orders/${requireId(args.id)}`)),
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
definition: {
|
|
692
|
+
name: "admin_create_purchase_order",
|
|
693
|
+
description: "Create a purchase order",
|
|
694
|
+
inputSchema: {
|
|
695
|
+
type: "object",
|
|
696
|
+
properties: {
|
|
697
|
+
vendor_id: { type: "number", description: "Vendor ID (required)" },
|
|
698
|
+
user_id: { type: "number", description: "User ID" },
|
|
699
|
+
location_id: { type: "number", description: "Location ID" },
|
|
700
|
+
expected_date: { type: "string", description: "Expected delivery date" },
|
|
701
|
+
due_date: { type: "string", description: "Due date" },
|
|
702
|
+
order_date: { type: "string", description: "Order date" },
|
|
703
|
+
paid_date: { type: "string", description: "Paid date" },
|
|
704
|
+
general_notes: { type: "string", description: "Notes" },
|
|
705
|
+
shipping_notes: { type: "string", description: "Shipping notes" },
|
|
706
|
+
shipping_cents: { type: "number", description: "Shipping cost in cents" },
|
|
707
|
+
other_cents: { type: "number", description: "Other costs in cents" },
|
|
708
|
+
discount_percent: { type: "number", description: "Discount %" },
|
|
709
|
+
delivery_tracking: { type: "string", description: "Tracking number" },
|
|
710
|
+
},
|
|
711
|
+
required: ["vendor_id"],
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
handler: async (args) => {
|
|
715
|
+
const body = pickDefined({
|
|
716
|
+
vendor_id: requireId(args.vendor_id, "vendor_id"),
|
|
717
|
+
user_id: optionalId(args.user_id), location_id: optionalId(args.location_id),
|
|
718
|
+
expected_date: optionalString(args.expected_date), due_date: optionalString(args.due_date),
|
|
719
|
+
order_date: optionalString(args.order_date), paid_date: optionalString(args.paid_date),
|
|
720
|
+
general_notes: optionalString(args.general_notes), shipping_notes: optionalString(args.shipping_notes),
|
|
721
|
+
shipping_cents: optionalNumber(args.shipping_cents), other_cents: optionalNumber(args.other_cents),
|
|
722
|
+
discount_percent: optionalNumber(args.discount_percent),
|
|
723
|
+
delivery_tracking: optionalString(args.delivery_tracking),
|
|
724
|
+
});
|
|
725
|
+
return jsonResult(await client.post("/purchase_orders", body));
|
|
726
|
+
},
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
definition: {
|
|
730
|
+
name: "admin_receive_purchase_order",
|
|
731
|
+
description: "Receive a line item on a purchase order",
|
|
732
|
+
inputSchema: {
|
|
733
|
+
type: "object",
|
|
734
|
+
properties: {
|
|
735
|
+
id: { type: "number", description: "PO ID" },
|
|
736
|
+
line_item_id: { type: "number", description: "Line item ID to receive" },
|
|
737
|
+
},
|
|
738
|
+
required: ["id", "line_item_id"],
|
|
739
|
+
},
|
|
740
|
+
},
|
|
741
|
+
handler: async (args) => {
|
|
742
|
+
const id = requireId(args.id);
|
|
743
|
+
return jsonResult(await client.post(`/purchase_orders/${id}/receive`, { line_item_id: requireId(args.line_item_id, "line_item_id") }));
|
|
744
|
+
},
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
definition: {
|
|
748
|
+
name: "admin_add_po_line_item",
|
|
749
|
+
description: "Add a line item to a purchase order. Note: the product must have maintain_stock=true or the API returns 422.",
|
|
750
|
+
inputSchema: {
|
|
751
|
+
type: "object",
|
|
752
|
+
properties: {
|
|
753
|
+
id: { type: "number", description: "PO ID" },
|
|
754
|
+
product_id: { type: "number", description: "Product ID" },
|
|
755
|
+
quantity: { type: "number", description: "Quantity" },
|
|
756
|
+
},
|
|
757
|
+
required: ["id", "product_id", "quantity"],
|
|
758
|
+
},
|
|
759
|
+
},
|
|
760
|
+
handler: async (args) => {
|
|
761
|
+
const id = requireId(args.id);
|
|
762
|
+
return jsonResult(await client.post(`/purchase_orders/${id}/create_po_line_item`, {
|
|
763
|
+
product_id: requireId(args.product_id, "product_id"),
|
|
764
|
+
quantity: args.quantity,
|
|
765
|
+
}));
|
|
766
|
+
},
|
|
767
|
+
},
|
|
768
|
+
// === Items & Line Items ===
|
|
769
|
+
{
|
|
770
|
+
definition: {
|
|
771
|
+
name: "admin_list_items",
|
|
772
|
+
description: "List items (global item catalog)",
|
|
773
|
+
inputSchema: { type: "object", properties: {} },
|
|
774
|
+
},
|
|
775
|
+
handler: async () => jsonResult(await client.get("/items")),
|
|
776
|
+
},
|
|
777
|
+
{
|
|
778
|
+
definition: {
|
|
779
|
+
name: "admin_list_line_items",
|
|
780
|
+
description: "List line items across invoices/tickets",
|
|
781
|
+
inputSchema: { type: "object", properties: {} },
|
|
782
|
+
},
|
|
783
|
+
handler: async () => jsonResult(await client.get("/line_items")),
|
|
784
|
+
},
|
|
785
|
+
// === OTP Login ===
|
|
786
|
+
{
|
|
787
|
+
definition: {
|
|
788
|
+
name: "admin_otp_login",
|
|
789
|
+
description: "Login with a one-time password code",
|
|
790
|
+
inputSchema: {
|
|
791
|
+
type: "object",
|
|
792
|
+
properties: {
|
|
793
|
+
code: { type: "string", description: "OTP code" },
|
|
794
|
+
},
|
|
795
|
+
required: ["code"],
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
handler: async (args) => jsonResult(await client.post("/otp_login", { code: args.code })),
|
|
799
|
+
},
|
|
800
|
+
];
|
|
801
|
+
return {
|
|
802
|
+
name: "admin",
|
|
803
|
+
description: "Search, users, vendors, wiki, portal users, canned responses, settings, worksheets, purchase orders, devices, ticket forms",
|
|
804
|
+
getTools: () => tools,
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
//# sourceMappingURL=admin.js.map
|