@vitrion/zentria-mcp 1.0.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.
@@ -0,0 +1,76 @@
1
+ import * as z from "zod/v4";
2
+ import { compactBody, encodePathSegment, paginationQuery, paginationSchema, registerJsonTool, } from "./_shared.js";
3
+ export function registerSalesDealTools(server, client) {
4
+ registerJsonTool(server, "list-deals", {
5
+ description: "List sales deals (GET /api/public/sales/deals). Optional pipelineId filter. Scope: sales:read.",
6
+ annotations: { readOnlyHint: true },
7
+ inputSchema: z.object({
8
+ ...paginationSchema,
9
+ pipelineId: z.number().int().positive().optional().describe("Filter by pipeline id."),
10
+ }),
11
+ }, async (input) => {
12
+ const { pipelineId, ...pagination } = input;
13
+ const query = paginationQuery(pagination);
14
+ if (pipelineId !== undefined) {
15
+ query.pipelineId = pipelineId;
16
+ }
17
+ return client.request({ path: "/api/public/sales/deals", query });
18
+ });
19
+ registerJsonTool(server, "create-deal", {
20
+ description: "Create a sales deal (POST /api/public/sales/deals). pipelineId is required. Scope: sales:write.",
21
+ inputSchema: z.object({
22
+ title: z.string().min(1).describe("Deal title."),
23
+ pipelineId: z.number().int().positive().describe("Pipeline id."),
24
+ value: z.number().optional().describe("Deal value."),
25
+ personId: z.number().int().positive().optional(),
26
+ organizationId: z.number().int().positive().optional(),
27
+ stageId: z.number().int().positive().optional(),
28
+ ownerUserId: z.number().int().positive().optional(),
29
+ expectedCloseDate: z.string().optional().describe("ISO date YYYY-MM-DD."),
30
+ lostReason: z.string().optional(),
31
+ }),
32
+ }, async (input) => client.request({
33
+ method: "POST",
34
+ path: "/api/public/sales/deals",
35
+ body: compactBody(input) ?? {},
36
+ }));
37
+ registerJsonTool(server, "get-deal", {
38
+ description: "Fetch a sales deal (GET /api/public/sales/deals/{id}). Scope: sales:read.",
39
+ annotations: { readOnlyHint: true },
40
+ inputSchema: z.object({
41
+ id: z.number().int().positive().describe("Deal id."),
42
+ }),
43
+ }, async (input) => client.request({ path: `/api/public/sales/deals/${encodePathSegment(input.id)}` }));
44
+ registerJsonTool(server, "update-deal", {
45
+ description: "Update a sales deal (PUT /api/public/sales/deals/{id}). Scope: sales:write.",
46
+ inputSchema: z.object({
47
+ id: z.number().int().positive().describe("Deal id."),
48
+ title: z.string().optional(),
49
+ value: z.number().nullable().optional(),
50
+ personId: z.number().int().positive().nullable().optional(),
51
+ organizationId: z.number().int().positive().nullable().optional(),
52
+ stageId: z.number().int().positive().optional(),
53
+ ownerUserId: z.number().int().positive().nullable().optional(),
54
+ expectedCloseDate: z.string().nullable().optional(),
55
+ lostReason: z.string().nullable().optional(),
56
+ }),
57
+ }, async (input) => {
58
+ const { id, ...body } = input;
59
+ return client.request({
60
+ method: "PUT",
61
+ path: `/api/public/sales/deals/${encodePathSegment(id)}`,
62
+ body: compactBody(body) ?? {},
63
+ });
64
+ });
65
+ registerJsonTool(server, "move-deal-stage", {
66
+ description: "Move a deal to another pipeline stage (PATCH /api/public/sales/deals/{id}/stage). Scope: sales:write.",
67
+ inputSchema: z.object({
68
+ id: z.number().int().positive().describe("Deal id."),
69
+ stageId: z.number().int().positive().describe("Target stage id."),
70
+ }),
71
+ }, async (input) => client.request({
72
+ method: "PATCH",
73
+ path: `/api/public/sales/deals/${encodePathSegment(input.id)}/stage`,
74
+ body: { stageId: input.stageId },
75
+ }));
76
+ }
@@ -0,0 +1,74 @@
1
+ import * as z from "zod/v4";
2
+ import { compactBody, encodePathSegment, paginationQuery, paginationSchema, registerJsonTool, } from "./_shared.js";
3
+ export function registerSalesFormTools(server, client) {
4
+ registerJsonTool(server, "list-forms", {
5
+ description: "List sales forms (GET /api/public/sales/forms). Scope: sales:read.",
6
+ annotations: { readOnlyHint: true },
7
+ inputSchema: z.object({ ...paginationSchema }),
8
+ }, async (input) => client.request({
9
+ path: "/api/public/sales/forms",
10
+ query: paginationQuery(input),
11
+ }));
12
+ registerJsonTool(server, "create-form", {
13
+ description: "Create a sales form (POST /api/public/sales/forms). Scope: sales:write.",
14
+ inputSchema: z.object({
15
+ name: z.string().min(1),
16
+ pipelineId: z.number().int().positive(),
17
+ allowedOrigins: z.array(z.string()).optional(),
18
+ canvasHtml: z.string().optional(),
19
+ canvasCss: z.string().optional(),
20
+ canvasJs: z.string().optional(),
21
+ leadContract: z.record(z.string(), z.unknown()).optional(),
22
+ isActive: z.boolean().optional(),
23
+ }),
24
+ }, async (input) => client.request({
25
+ method: "POST",
26
+ path: "/api/public/sales/forms",
27
+ body: compactBody(input) ?? {},
28
+ }));
29
+ registerJsonTool(server, "get-form", {
30
+ description: "Fetch a sales form (GET /api/public/sales/forms/{id}). Scope: sales:read.",
31
+ annotations: { readOnlyHint: true },
32
+ inputSchema: z.object({
33
+ id: z.number().int().positive().describe("Form id."),
34
+ }),
35
+ }, async (input) => client.request({ path: `/api/public/sales/forms/${encodePathSegment(input.id)}` }));
36
+ registerJsonTool(server, "update-form", {
37
+ description: "Update a sales form (PUT /api/public/sales/forms/{id}). Scope: sales:write.",
38
+ inputSchema: z.object({
39
+ id: z.number().int().positive().describe("Form id."),
40
+ name: z.string().optional(),
41
+ pipelineId: z.number().int().positive().optional(),
42
+ allowedOrigins: z.array(z.string()).optional(),
43
+ canvasHtml: z.string().optional(),
44
+ canvasCss: z.string().optional(),
45
+ canvasJs: z.string().optional(),
46
+ leadContract: z.record(z.string(), z.unknown()).optional(),
47
+ isActive: z.boolean().optional(),
48
+ }),
49
+ }, async (input) => {
50
+ const { id, ...body } = input;
51
+ return client.request({
52
+ method: "PUT",
53
+ path: `/api/public/sales/forms/${encodePathSegment(id)}`,
54
+ body: compactBody(body) ?? {},
55
+ });
56
+ });
57
+ }
58
+ export function registerSalesSubmissionTools(server, client) {
59
+ registerJsonTool(server, "list-form-submissions", {
60
+ description: "List sales form submissions (GET /api/public/sales/submissions). Scope: sales:read.",
61
+ annotations: { readOnlyHint: true },
62
+ inputSchema: z.object({ ...paginationSchema }),
63
+ }, async (input) => client.request({
64
+ path: "/api/public/sales/submissions",
65
+ query: paginationQuery(input),
66
+ }));
67
+ registerJsonTool(server, "get-form-submission", {
68
+ description: "Fetch a sales form submission (GET /api/public/sales/submissions/{id}). Scope: sales:read.",
69
+ annotations: { readOnlyHint: true },
70
+ inputSchema: z.object({
71
+ id: z.number().int().positive().describe("Submission id."),
72
+ }),
73
+ }, async (input) => client.request({ path: `/api/public/sales/submissions/${encodePathSegment(input.id)}` }));
74
+ }
@@ -0,0 +1,58 @@
1
+ import * as z from "zod/v4";
2
+ import { compactBody, encodePathSegment, paginationQuery, paginationSchema, registerJsonTool, } from "./_shared.js";
3
+ export function registerSalesNoteTools(server, client) {
4
+ registerJsonTool(server, "list-notes", {
5
+ description: "List sales notes (GET /api/public/sales/notes). Scope: sales:read.",
6
+ annotations: { readOnlyHint: true },
7
+ inputSchema: z.object({ ...paginationSchema }),
8
+ }, async (input) => client.request({
9
+ path: "/api/public/sales/notes",
10
+ query: paginationQuery(input),
11
+ }));
12
+ registerJsonTool(server, "create-note", {
13
+ description: "Create a sales note (POST /api/public/sales/notes). Scope: sales:write.",
14
+ inputSchema: z.object({
15
+ body: z.string().min(1).describe("Note body."),
16
+ dealId: z.number().int().positive().optional(),
17
+ personId: z.number().int().positive().optional(),
18
+ organizationId: z.number().int().positive().optional(),
19
+ pinned: z.boolean().optional(),
20
+ }),
21
+ }, async (input) => client.request({
22
+ method: "POST",
23
+ path: "/api/public/sales/notes",
24
+ body: compactBody(input) ?? {},
25
+ }));
26
+ registerJsonTool(server, "get-note", {
27
+ description: "Fetch a sales note (GET /api/public/sales/notes/{id}). Scope: sales:read.",
28
+ annotations: { readOnlyHint: true },
29
+ inputSchema: z.object({
30
+ id: z.number().int().positive().describe("Note id."),
31
+ }),
32
+ }, async (input) => client.request({ path: `/api/public/sales/notes/${encodePathSegment(input.id)}` }));
33
+ registerJsonTool(server, "update-note", {
34
+ description: "Update a sales note (PATCH /api/public/sales/notes/{id}). Scope: sales:write.",
35
+ inputSchema: z.object({
36
+ id: z.number().int().positive().describe("Note id."),
37
+ body: z.string().optional(),
38
+ pinned: z.boolean().optional(),
39
+ }),
40
+ }, async (input) => {
41
+ const { id, ...body } = input;
42
+ return client.request({
43
+ method: "PATCH",
44
+ path: `/api/public/sales/notes/${encodePathSegment(id)}`,
45
+ body: compactBody(body) ?? {},
46
+ });
47
+ });
48
+ registerJsonTool(server, "delete-note", {
49
+ description: "Delete a sales note (DELETE /api/public/sales/notes/{id}). Scope: sales:write.",
50
+ annotations: { destructiveHint: true },
51
+ inputSchema: z.object({
52
+ id: z.number().int().positive().describe("Note id."),
53
+ }),
54
+ }, async (input) => client.request({
55
+ method: "DELETE",
56
+ path: `/api/public/sales/notes/${encodePathSegment(input.id)}`,
57
+ }));
58
+ }
@@ -0,0 +1,49 @@
1
+ import * as z from "zod/v4";
2
+ import { compactBody, encodePathSegment, paginationQuery, paginationSchema, registerJsonTool, } from "./_shared.js";
3
+ export function registerSalesOrganizationTools(server, client) {
4
+ registerJsonTool(server, "list-organizations", {
5
+ description: "List sales organizations (GET /api/public/sales/organizations). Scope: sales:read.",
6
+ annotations: { readOnlyHint: true },
7
+ inputSchema: z.object({ ...paginationSchema }),
8
+ }, async (input) => client.request({
9
+ path: "/api/public/sales/organizations",
10
+ query: paginationQuery(input),
11
+ }));
12
+ registerJsonTool(server, "create-organization", {
13
+ description: "Create a sales organization (POST /api/public/sales/organizations). Scope: sales:write.",
14
+ inputSchema: z.object({
15
+ name: z.string().min(1).describe("Organization name."),
16
+ email: z.string().email().optional(),
17
+ phone: z.string().optional(),
18
+ }),
19
+ }, async (input) => client.request({
20
+ method: "POST",
21
+ path: "/api/public/sales/organizations",
22
+ body: compactBody(input) ?? {},
23
+ }));
24
+ registerJsonTool(server, "get-organization", {
25
+ description: "Fetch a sales organization (GET /api/public/sales/organizations/{id}). Scope: sales:read.",
26
+ annotations: { readOnlyHint: true },
27
+ inputSchema: z.object({
28
+ id: z.number().int().positive().describe("Organization id."),
29
+ }),
30
+ }, async (input) => client.request({
31
+ path: `/api/public/sales/organizations/${encodePathSegment(input.id)}`,
32
+ }));
33
+ registerJsonTool(server, "update-organization", {
34
+ description: "Update a sales organization (PUT /api/public/sales/organizations/{id}). Scope: sales:write.",
35
+ inputSchema: z.object({
36
+ id: z.number().int().positive().describe("Organization id."),
37
+ name: z.string().optional(),
38
+ email: z.string().email().nullable().optional(),
39
+ phone: z.string().nullable().optional(),
40
+ }),
41
+ }, async (input) => {
42
+ const { id, ...body } = input;
43
+ return client.request({
44
+ method: "PUT",
45
+ path: `/api/public/sales/organizations/${encodePathSegment(id)}`,
46
+ body: compactBody(body) ?? {},
47
+ });
48
+ });
49
+ }
@@ -0,0 +1,49 @@
1
+ import * as z from "zod/v4";
2
+ import { compactBody, encodePathSegment, paginationQuery, paginationSchema, registerJsonTool, } from "./_shared.js";
3
+ export function registerSalesPeopleTools(server, client) {
4
+ registerJsonTool(server, "list-people", {
5
+ description: "List sales people/contacts (GET /api/public/sales/people). Scope: sales:read.",
6
+ annotations: { readOnlyHint: true },
7
+ inputSchema: z.object({ ...paginationSchema }),
8
+ }, async (input) => client.request({
9
+ path: "/api/public/sales/people",
10
+ query: paginationQuery(input),
11
+ }));
12
+ registerJsonTool(server, "create-person", {
13
+ description: "Create a sales person (POST /api/public/sales/people). Scope: sales:write.",
14
+ inputSchema: z.object({
15
+ name: z.string().min(1).describe("Person name."),
16
+ email: z.string().email().optional().describe("Email address."),
17
+ phone: z.string().optional().describe("Phone number."),
18
+ organizationId: z.number().int().positive().optional().describe("Linked organization id."),
19
+ }),
20
+ }, async (input) => client.request({
21
+ method: "POST",
22
+ path: "/api/public/sales/people",
23
+ body: compactBody(input) ?? {},
24
+ }));
25
+ registerJsonTool(server, "get-person", {
26
+ description: "Fetch a sales person (GET /api/public/sales/people/{id}). Scope: sales:read.",
27
+ annotations: { readOnlyHint: true },
28
+ inputSchema: z.object({
29
+ id: z.number().int().positive().describe("Person id."),
30
+ }),
31
+ }, async (input) => client.request({ path: `/api/public/sales/people/${encodePathSegment(input.id)}` }));
32
+ registerJsonTool(server, "update-person", {
33
+ description: "Update a sales person (PUT /api/public/sales/people/{id}). Scope: sales:write.",
34
+ inputSchema: z.object({
35
+ id: z.number().int().positive().describe("Person id."),
36
+ name: z.string().optional().describe("Person name."),
37
+ email: z.string().email().optional().describe("Email address."),
38
+ phone: z.string().optional().describe("Phone number."),
39
+ organizationId: z.number().int().positive().nullable().optional(),
40
+ }),
41
+ }, async (input) => {
42
+ const { id, ...body } = input;
43
+ return client.request({
44
+ method: "PUT",
45
+ path: `/api/public/sales/people/${encodePathSegment(id)}`,
46
+ body: compactBody(body) ?? {},
47
+ });
48
+ });
49
+ }
@@ -0,0 +1,24 @@
1
+ import * as z from "zod/v4";
2
+ import { encodePathSegment, paginationQuery, paginationSchema, registerJsonTool, } from "./_shared.js";
3
+ export function registerSalesPipelineTools(server, client) {
4
+ registerJsonTool(server, "list-pipelines", {
5
+ description: "List sales pipelines (GET /api/public/sales/pipelines). Scope: sales:read.",
6
+ annotations: { readOnlyHint: true },
7
+ inputSchema: z.object({ ...paginationSchema }),
8
+ }, async (input) => client.request({
9
+ path: "/api/public/sales/pipelines",
10
+ query: paginationQuery(input),
11
+ }));
12
+ registerJsonTool(server, "get-pipeline", {
13
+ description: "Fetch a sales pipeline with stages (GET /api/public/sales/pipelines/{id}). Scope: sales:read.",
14
+ annotations: { readOnlyHint: true },
15
+ inputSchema: z.object({
16
+ id: z.number().int().positive().describe("Pipeline id."),
17
+ }),
18
+ }, async (input) => client.request({ path: `/api/public/sales/pipelines/${encodePathSegment(input.id)}` }));
19
+ registerJsonTool(server, "get-default-pipeline", {
20
+ description: "Fetch the team default sales pipeline (GET /api/public/sales/pipeline). Scope: sales:read.",
21
+ annotations: { readOnlyHint: true },
22
+ inputSchema: z.object({}),
23
+ }, async () => client.request({ path: "/api/public/sales/pipeline" }));
24
+ }
@@ -0,0 +1,137 @@
1
+ import * as z from "zod/v4";
2
+ import { compactBody, encodePathSegment, paginationQuery, paginationSchema, registerJsonTool, } from "./_shared.js";
3
+ export function registerStlTools(server, client) {
4
+ registerJsonTool(server, "list-stl-flows", {
5
+ description: "List Speed to Lead flows (GET /api/public/stl/flows). Scope: stl:read.",
6
+ annotations: { readOnlyHint: true },
7
+ inputSchema: z.object({ ...paginationSchema }),
8
+ }, async (input) => client.request({
9
+ path: "/api/public/stl/flows",
10
+ query: paginationQuery(input),
11
+ }));
12
+ registerJsonTool(server, "create-stl-flow", {
13
+ description: "Create a Speed to Lead flow (POST /api/public/stl/flows). Scope: stl:write.",
14
+ inputSchema: z.object({
15
+ name: z.string().min(1),
16
+ customerIntegrationId: z.number().int().positive(),
17
+ receivingPhone: z.string().min(1),
18
+ status: z.enum(["draft", "active", "inactive"]).optional(),
19
+ templateJson: z.record(z.string(), z.unknown()).optional(),
20
+ }),
21
+ }, async (input) => client.request({
22
+ method: "POST",
23
+ path: "/api/public/stl/flows",
24
+ body: compactBody(input) ?? {},
25
+ }));
26
+ registerJsonTool(server, "get-stl-flow", {
27
+ description: "Fetch a Speed to Lead flow (GET /api/public/stl/flows/{id}). Scope: stl:read.",
28
+ annotations: { readOnlyHint: true },
29
+ inputSchema: z.object({
30
+ id: z.number().int().positive().describe("Flow id."),
31
+ }),
32
+ }, async (input) => client.request({ path: `/api/public/stl/flows/${encodePathSegment(input.id)}` }));
33
+ registerJsonTool(server, "update-stl-flow", {
34
+ description: "Update a Speed to Lead flow (PUT /api/public/stl/flows/{id}). Scope: stl:write.",
35
+ inputSchema: z.object({
36
+ id: z.number().int().positive().describe("Flow id."),
37
+ name: z.string().optional(),
38
+ customerIntegrationId: z.number().int().positive().optional(),
39
+ receivingPhone: z.string().optional(),
40
+ status: z.enum(["draft", "active", "inactive"]).optional(),
41
+ templateJson: z.record(z.string(), z.unknown()).optional(),
42
+ }),
43
+ }, async (input) => {
44
+ const { id, ...body } = input;
45
+ return client.request({
46
+ method: "PUT",
47
+ path: `/api/public/stl/flows/${encodePathSegment(id)}`,
48
+ body: compactBody(body) ?? {},
49
+ });
50
+ });
51
+ registerJsonTool(server, "delete-stl-flow", {
52
+ description: "Delete a Speed to Lead flow (DELETE /api/public/stl/flows/{id}). Scope: stl:write.",
53
+ annotations: { destructiveHint: true },
54
+ inputSchema: z.object({
55
+ id: z.number().int().positive().describe("Flow id."),
56
+ }),
57
+ }, async (input) => client.request({
58
+ method: "DELETE",
59
+ path: `/api/public/stl/flows/${encodePathSegment(input.id)}`,
60
+ }));
61
+ registerJsonTool(server, "list-stl-sms-templates", {
62
+ description: "List STL SMS templates (GET /api/public/stl/sms-templates). Scope: stl:read.",
63
+ annotations: { readOnlyHint: true },
64
+ inputSchema: z.object({ ...paginationSchema }),
65
+ }, async (input) => client.request({
66
+ path: "/api/public/stl/sms-templates",
67
+ query: paginationQuery(input),
68
+ }));
69
+ registerJsonTool(server, "create-stl-sms-template", {
70
+ description: "Create an STL SMS template (POST /api/public/stl/sms-templates). Scope: stl:write.",
71
+ inputSchema: z.object({
72
+ name: z.string().min(1),
73
+ body: z.string().min(1).describe("SMS template body."),
74
+ }),
75
+ }, async (input) => client.request({
76
+ method: "POST",
77
+ path: "/api/public/stl/sms-templates",
78
+ body: compactBody(input) ?? {},
79
+ }));
80
+ registerJsonTool(server, "get-stl-sms-template", {
81
+ description: "Fetch an STL SMS template (GET /api/public/stl/sms-templates/{id}). Scope: stl:read.",
82
+ annotations: { readOnlyHint: true },
83
+ inputSchema: z.object({
84
+ id: z.number().int().positive().describe("Template id."),
85
+ }),
86
+ }, async (input) => client.request({ path: `/api/public/stl/sms-templates/${encodePathSegment(input.id)}` }));
87
+ registerJsonTool(server, "update-stl-sms-template", {
88
+ description: "Update an STL SMS template (PUT /api/public/stl/sms-templates/{id}). Scope: stl:write.",
89
+ inputSchema: z.object({
90
+ id: z.number().int().positive().describe("Template id."),
91
+ name: z.string().optional(),
92
+ body: z.string().optional(),
93
+ }),
94
+ }, async (input) => {
95
+ const { id, ...body } = input;
96
+ return client.request({
97
+ method: "PUT",
98
+ path: `/api/public/stl/sms-templates/${encodePathSegment(id)}`,
99
+ body: compactBody(body) ?? {},
100
+ });
101
+ });
102
+ registerJsonTool(server, "delete-stl-sms-template", {
103
+ description: "Delete an STL SMS template (DELETE /api/public/stl/sms-templates/{id}). Scope: stl:write.",
104
+ annotations: { destructiveHint: true },
105
+ inputSchema: z.object({
106
+ id: z.number().int().positive().describe("Template id."),
107
+ }),
108
+ }, async (input) => client.request({
109
+ method: "DELETE",
110
+ path: `/api/public/stl/sms-templates/${encodePathSegment(input.id)}`,
111
+ }));
112
+ registerJsonTool(server, "list-stl-leads", {
113
+ description: "List Speed to Lead leads (GET /api/public/stl/leads). Scope: stl:read.",
114
+ annotations: { readOnlyHint: true },
115
+ inputSchema: z.object({ ...paginationSchema }),
116
+ }, async (input) => client.request({
117
+ path: "/api/public/stl/leads",
118
+ query: paginationQuery(input),
119
+ }));
120
+ registerJsonTool(server, "get-stl-lead", {
121
+ description: "Fetch an STL lead (GET /api/public/stl/leads/{id}). Scope: stl:read.",
122
+ annotations: { readOnlyHint: true },
123
+ inputSchema: z.object({
124
+ id: z.number().int().positive().describe("Lead id."),
125
+ }),
126
+ }, async (input) => client.request({ path: `/api/public/stl/leads/${encodePathSegment(input.id)}` }));
127
+ registerJsonTool(server, "delete-stl-lead", {
128
+ description: "Delete an STL lead (DELETE /api/public/stl/leads/{id}). Scope: stl:write.",
129
+ annotations: { destructiveHint: true },
130
+ inputSchema: z.object({
131
+ id: z.number().int().positive().describe("Lead id."),
132
+ }),
133
+ }, async (input) => client.request({
134
+ method: "DELETE",
135
+ path: `/api/public/stl/leads/${encodePathSegment(input.id)}`,
136
+ }));
137
+ }
@@ -0,0 +1,63 @@
1
+ import * as z from "zod/v4";
2
+ import { compactBody, encodePathSegment, paginationQuery, paginationSchema, registerJsonTool, } from "./_shared.js";
3
+ export function registerTodoTools(server, client) {
4
+ registerJsonTool(server, "list-todos", {
5
+ description: "List to-dos for the PAT-bound team (GET /api/public/teams/{teamId}/todos). Scope: todos:read.",
6
+ annotations: { readOnlyHint: true },
7
+ inputSchema: z.object({ ...paginationSchema }),
8
+ }, async (input) => {
9
+ const teamId = await client.getBoundTeamId();
10
+ return client.request({
11
+ path: `/api/public/teams/${encodePathSegment(teamId)}/todos`,
12
+ query: paginationQuery(input),
13
+ });
14
+ });
15
+ registerJsonTool(server, "create-todo", {
16
+ description: "Create a to-do on the PAT-bound team (POST /api/public/teams/{teamId}/todos). Scope: todos:write.",
17
+ inputSchema: z.object({
18
+ title: z.string().min(1).describe("To-do title."),
19
+ description: z.string().optional().describe("Optional description."),
20
+ isCompleted: z.boolean().optional().describe("Mark completed on create."),
21
+ }),
22
+ }, async (input) => {
23
+ const teamId = await client.getBoundTeamId();
24
+ return client.request({
25
+ method: "POST",
26
+ path: `/api/public/teams/${encodePathSegment(teamId)}/todos`,
27
+ body: compactBody(input) ?? {},
28
+ });
29
+ });
30
+ registerJsonTool(server, "get-todo", {
31
+ description: "Fetch a to-do by id (GET /api/public/todos/{id}). Scope: todos:read.",
32
+ annotations: { readOnlyHint: true },
33
+ inputSchema: z.object({
34
+ id: z.number().int().positive().describe("To-do id."),
35
+ }),
36
+ }, async (input) => client.request({ path: `/api/public/todos/${encodePathSegment(input.id)}` }));
37
+ registerJsonTool(server, "update-todo", {
38
+ description: "Update a to-do (PUT /api/public/todos/{id}). Scope: todos:write.",
39
+ inputSchema: z.object({
40
+ id: z.number().int().positive().describe("To-do id."),
41
+ title: z.string().optional().describe("New title."),
42
+ description: z.string().optional().describe("New description."),
43
+ isCompleted: z.boolean().optional().describe("Completion state."),
44
+ }),
45
+ }, async (input) => {
46
+ const { id, ...body } = input;
47
+ return client.request({
48
+ method: "PUT",
49
+ path: `/api/public/todos/${encodePathSegment(id)}`,
50
+ body: compactBody(body) ?? {},
51
+ });
52
+ });
53
+ registerJsonTool(server, "delete-todo", {
54
+ description: "Delete a to-do (DELETE /api/public/todos/{id}). Scope: todos:write.",
55
+ annotations: { destructiveHint: true },
56
+ inputSchema: z.object({
57
+ id: z.number().int().positive().describe("To-do id."),
58
+ }),
59
+ }, async (input) => client.request({
60
+ method: "DELETE",
61
+ path: `/api/public/todos/${encodePathSegment(input.id)}`,
62
+ }));
63
+ }
@@ -0,0 +1,62 @@
1
+ import * as z from "zod/v4";
2
+ import { compactBody, encodePathSegment, paginationQuery, paginationSchema, registerJsonTool, } from "./_shared.js";
3
+ export function registerWebhookTools(server, client) {
4
+ registerJsonTool(server, "list-webhooks", {
5
+ description: "List outbound webhook endpoints (GET /api/public/webhooks). Scope: webhooks:read.",
6
+ annotations: { readOnlyHint: true },
7
+ inputSchema: z.object({ ...paginationSchema }),
8
+ }, async (input) => client.request({
9
+ path: "/api/public/webhooks",
10
+ query: paginationQuery(input),
11
+ }));
12
+ registerJsonTool(server, "create-webhook", {
13
+ description: "Create a webhook endpoint. Signing secret returned once (POST /api/public/webhooks). Scope: webhooks:write.",
14
+ inputSchema: z.object({
15
+ url: z.string().url().describe("HTTPS callback URL."),
16
+ events: z.array(z.string()).min(1).describe("Event names, e.g. sales.deal.updated."),
17
+ description: z.string().optional(),
18
+ filters: z.record(z.string(), z.unknown()).optional(),
19
+ source: z.string().optional().describe("Source label (default api)."),
20
+ isActive: z.boolean().optional(),
21
+ }),
22
+ }, async (input) => client.request({
23
+ method: "POST",
24
+ path: "/api/public/webhooks",
25
+ body: compactBody(input) ?? {},
26
+ }));
27
+ registerJsonTool(server, "get-webhook", {
28
+ description: "Fetch a webhook endpoint (GET /api/public/webhooks/{id}). Scope: webhooks:read.",
29
+ annotations: { readOnlyHint: true },
30
+ inputSchema: z.object({
31
+ id: z.number().int().positive().describe("Webhook id."),
32
+ }),
33
+ }, async (input) => client.request({ path: `/api/public/webhooks/${encodePathSegment(input.id)}` }));
34
+ registerJsonTool(server, "update-webhook", {
35
+ description: "Update a webhook endpoint (PATCH /api/public/webhooks/{id}). Scope: webhooks:write.",
36
+ inputSchema: z.object({
37
+ id: z.number().int().positive().describe("Webhook id."),
38
+ url: z.string().url().optional(),
39
+ events: z.array(z.string()).optional(),
40
+ description: z.string().nullable().optional(),
41
+ filters: z.record(z.string(), z.unknown()).nullable().optional(),
42
+ isActive: z.boolean().optional(),
43
+ }),
44
+ }, async (input) => {
45
+ const { id, ...body } = input;
46
+ return client.request({
47
+ method: "PATCH",
48
+ path: `/api/public/webhooks/${encodePathSegment(id)}`,
49
+ body: compactBody(body) ?? {},
50
+ });
51
+ });
52
+ registerJsonTool(server, "delete-webhook", {
53
+ description: "Delete a webhook endpoint (DELETE /api/public/webhooks/{id}). Scope: webhooks:write.",
54
+ annotations: { destructiveHint: true },
55
+ inputSchema: z.object({
56
+ id: z.number().int().positive().describe("Webhook id."),
57
+ }),
58
+ }, async (input) => client.request({
59
+ method: "DELETE",
60
+ path: `/api/public/webhooks/${encodePathSegment(input.id)}`,
61
+ }));
62
+ }
@@ -0,0 +1,2 @@
1
+ export const PACKAGE_NAME = "@vitrion/zentria-mcp";
2
+ export const PACKAGE_VERSION = "1.0.0";