@vantageos/vantage-crm-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/README.md +260 -0
- package/dist/convex/crm/_helpers.js +24 -0
- package/dist/convex/crm/activities.js +220 -0
- package/dist/convex/crm/briefing.js +198 -0
- package/dist/convex/crm/calendarCron.js +92 -0
- package/dist/convex/crm/calendarCronDispatch.js +83 -0
- package/dist/convex/crm/calendarSync.js +294 -0
- package/dist/convex/crm/companies.js +323 -0
- package/dist/convex/crm/contacts.js +346 -0
- package/dist/convex/crm/deals.js +481 -0
- package/dist/convex/crm/emailActions.js +158 -0
- package/dist/convex/crm/emailCron.js +210 -0
- package/dist/convex/crm/emailCronDispatch.js +76 -0
- package/dist/convex/crm/emailSync.js +260 -0
- package/dist/convex/crm/onboarding.js +185 -0
- package/dist/convex/crm/stats.js +75 -0
- package/dist/convex/crm/tasks.js +109 -0
- package/dist/convex/crons.js +25 -0
- package/dist/convex/integrations.js +183 -0
- package/dist/convex/lib/auditLog.js +109 -0
- package/dist/convex/lib/auth.js +372 -0
- package/dist/convex/lib/rbac.js +123 -0
- package/dist/convex/lib/workspace.js +171 -0
- package/dist/convex/organizations.js +192 -0
- package/dist/convex/schema.js +690 -0
- package/dist/convex/users.js +217 -0
- package/dist/convex/workspaces.js +603 -0
- package/dist/mcp-server/lib/convexClient.js +50 -0
- package/dist/mcp-server/lib/scopeEnforcement.js +76 -0
- package/dist/mcp-server/registry.js +116 -0
- package/dist/mcp-server/server.js +97 -0
- package/dist/mcp-server/tests/registry.test.js +163 -0
- package/dist/mcp-server/tests/scopeEnforcement.test.js +137 -0
- package/dist/mcp-server/tests/security.test.js +257 -0
- package/dist/mcp-server/tests/tools.test.js +272 -0
- package/dist/mcp-server/tools/activities.js +207 -0
- package/dist/mcp-server/tools/admin.js +190 -0
- package/dist/mcp-server/tools/companies.js +233 -0
- package/dist/mcp-server/tools/contacts.js +306 -0
- package/dist/mcp-server/tools/customFields.js +222 -0
- package/dist/mcp-server/tools/customObjects.js +235 -0
- package/dist/mcp-server/tools/deals.js +297 -0
- package/dist/mcp-server/tools/rbac.js +177 -0
- package/dist/mcp-server/tools/search.js +155 -0
- package/dist/mcp-server/tools/workflows.js +234 -0
- package/dist/mcp-server/transport/http.js +257 -0
- package/dist/mcp-server/transport/stdio.js +90 -0
- package/package.json +45 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* VantageCRM MCP — RBAC tools (5 tools)
|
|
4
|
+
*
|
|
5
|
+
* Tools: list_workspace_members, add_workspace_member, update_member_role,
|
|
6
|
+
* remove_workspace_member, update_member_permissions
|
|
7
|
+
*
|
|
8
|
+
* Scope: read for list, admin for mutations
|
|
9
|
+
* Ref: spec §3.11
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RBAC_TOOLS = void 0;
|
|
13
|
+
exports.list_workspace_members = list_workspace_members;
|
|
14
|
+
exports.add_workspace_member = add_workspace_member;
|
|
15
|
+
exports.update_member_role = update_member_role;
|
|
16
|
+
exports.remove_workspace_member = remove_workspace_member;
|
|
17
|
+
exports.update_member_permissions = update_member_permissions;
|
|
18
|
+
const zod_1 = require("zod");
|
|
19
|
+
const api_1 = require("../../convex/_generated/api");
|
|
20
|
+
const convexClient_1 = require("../lib/convexClient");
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Zod schemas
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
const MEMBER_ROLES = ['owner', 'admin', 'editor', 'viewer'];
|
|
25
|
+
const ListWorkspaceMembersSchema = zod_1.z.object({
|
|
26
|
+
workspaceId: zod_1.z.string().min(1),
|
|
27
|
+
});
|
|
28
|
+
const AddWorkspaceMemberSchema = zod_1.z.object({
|
|
29
|
+
workspaceId: zod_1.z.string().min(1),
|
|
30
|
+
userId: zod_1.z.string().min(1),
|
|
31
|
+
role: zod_1.z.enum(MEMBER_ROLES).default('editor'),
|
|
32
|
+
});
|
|
33
|
+
const UpdateMemberRoleSchema = zod_1.z.object({
|
|
34
|
+
workspaceId: zod_1.z.string().min(1),
|
|
35
|
+
userId: zod_1.z.string().min(1),
|
|
36
|
+
newRole: zod_1.z.enum(MEMBER_ROLES),
|
|
37
|
+
});
|
|
38
|
+
const RemoveWorkspaceMemberSchema = zod_1.z.object({
|
|
39
|
+
workspaceId: zod_1.z.string().min(1),
|
|
40
|
+
userId: zod_1.z.string().min(1),
|
|
41
|
+
});
|
|
42
|
+
const UpdateMemberPermissionsSchema = zod_1.z.object({
|
|
43
|
+
workspaceId: zod_1.z.string().min(1),
|
|
44
|
+
userId: zod_1.z.string().min(1),
|
|
45
|
+
permissions: zod_1.z.object({
|
|
46
|
+
canExportData: zod_1.z.boolean().optional(),
|
|
47
|
+
canManageIntegrations: zod_1.z.boolean().optional(),
|
|
48
|
+
canManageBilling: zod_1.z.boolean().optional(),
|
|
49
|
+
canInviteMembers: zod_1.z.boolean().optional(),
|
|
50
|
+
canManageWorkflows: zod_1.z.boolean().optional(),
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Handlers
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
async function list_workspace_members(rawArgs) {
|
|
57
|
+
const args = ListWorkspaceMembersSchema.parse(rawArgs);
|
|
58
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().query(api_1.api.workspaces.getMembers, {
|
|
59
|
+
workspaceId: args.workspaceId,
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
async function add_workspace_member(rawArgs) {
|
|
63
|
+
const args = AddWorkspaceMemberSchema.parse(rawArgs);
|
|
64
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().mutation(api_1.api.workspaces.addMember, {
|
|
65
|
+
workspaceId: args.workspaceId,
|
|
66
|
+
userId: args.userId,
|
|
67
|
+
role: args.role,
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
async function update_member_role(rawArgs) {
|
|
71
|
+
UpdateMemberRoleSchema.parse(rawArgs);
|
|
72
|
+
// Dedicated updateRole mutation not yet in V0.1.0 — stable NOT_IMPLEMENTED envelope
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
error: {
|
|
76
|
+
code: 'NOT_IMPLEMENTED',
|
|
77
|
+
message: 'update_member_role: reserved for V0.2. Use add_workspace_member with the new role to update.',
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
async function remove_workspace_member(rawArgs) {
|
|
82
|
+
const args = RemoveWorkspaceMemberSchema.parse(rawArgs);
|
|
83
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().mutation(api_1.api.workspaces.removeMember, {
|
|
84
|
+
workspaceId: args.workspaceId,
|
|
85
|
+
userId: args.userId,
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
async function update_member_permissions(rawArgs) {
|
|
89
|
+
UpdateMemberPermissionsSchema.parse(rawArgs);
|
|
90
|
+
// Dedicated updatePermissions mutation not yet in V0.1.0 — stable NOT_IMPLEMENTED envelope
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
error: {
|
|
94
|
+
code: 'NOT_IMPLEMENTED',
|
|
95
|
+
message: 'update_member_permissions: reserved for V0.2. Requires crm.rbac.updatePermissions mutation.',
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Tool definitions
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
exports.RBAC_TOOLS = [
|
|
103
|
+
{
|
|
104
|
+
name: 'list_workspace_members',
|
|
105
|
+
description: 'List all members of a workspace with their roles',
|
|
106
|
+
requiredScope: 'read',
|
|
107
|
+
inputSchema: {
|
|
108
|
+
type: 'object',
|
|
109
|
+
properties: { workspaceId: { type: 'string' } },
|
|
110
|
+
required: ['workspaceId'],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'add_workspace_member',
|
|
115
|
+
description: 'Invite a user to a workspace and assign a role (admin only)',
|
|
116
|
+
requiredScope: 'admin',
|
|
117
|
+
inputSchema: {
|
|
118
|
+
type: 'object',
|
|
119
|
+
properties: {
|
|
120
|
+
workspaceId: { type: 'string' },
|
|
121
|
+
userId: { type: 'string' },
|
|
122
|
+
role: { type: 'string', enum: ['owner', 'admin', 'editor', 'viewer'] },
|
|
123
|
+
},
|
|
124
|
+
required: ['workspaceId', 'userId'],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'update_member_role',
|
|
129
|
+
description: 'Change a member\'s role in a workspace (admin only)',
|
|
130
|
+
requiredScope: 'admin',
|
|
131
|
+
inputSchema: {
|
|
132
|
+
type: 'object',
|
|
133
|
+
properties: {
|
|
134
|
+
workspaceId: { type: 'string' },
|
|
135
|
+
userId: { type: 'string' },
|
|
136
|
+
newRole: { type: 'string', enum: ['owner', 'admin', 'editor', 'viewer'] },
|
|
137
|
+
},
|
|
138
|
+
required: ['workspaceId', 'userId', 'newRole'],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'remove_workspace_member',
|
|
143
|
+
description: 'Remove a member from a workspace (admin only)',
|
|
144
|
+
requiredScope: 'admin',
|
|
145
|
+
inputSchema: {
|
|
146
|
+
type: 'object',
|
|
147
|
+
properties: {
|
|
148
|
+
workspaceId: { type: 'string' },
|
|
149
|
+
userId: { type: 'string' },
|
|
150
|
+
},
|
|
151
|
+
required: ['workspaceId', 'userId'],
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: 'update_member_permissions',
|
|
156
|
+
description: 'Set granular permission overrides for a workspace member (admin only)',
|
|
157
|
+
requiredScope: 'admin',
|
|
158
|
+
inputSchema: {
|
|
159
|
+
type: 'object',
|
|
160
|
+
properties: {
|
|
161
|
+
workspaceId: { type: 'string' },
|
|
162
|
+
userId: { type: 'string' },
|
|
163
|
+
permissions: {
|
|
164
|
+
type: 'object',
|
|
165
|
+
properties: {
|
|
166
|
+
canExportData: { type: 'boolean' },
|
|
167
|
+
canManageIntegrations: { type: 'boolean' },
|
|
168
|
+
canManageBilling: { type: 'boolean' },
|
|
169
|
+
canInviteMembers: { type: 'boolean' },
|
|
170
|
+
canManageWorkflows: { type: 'boolean' },
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
required: ['workspaceId', 'userId', 'permissions'],
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
];
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* VantageCRM MCP — Search / Analytics tools (4 tools)
|
|
4
|
+
*
|
|
5
|
+
* Tools: pipeline_value, win_rate, conversion_rate, activity_summary
|
|
6
|
+
*
|
|
7
|
+
* All analytics are read-only.
|
|
8
|
+
* Scope: read
|
|
9
|
+
* Ref: spec §3.9
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SEARCH_TOOLS = void 0;
|
|
13
|
+
exports.pipeline_value = pipeline_value;
|
|
14
|
+
exports.win_rate = win_rate;
|
|
15
|
+
exports.conversion_rate = conversion_rate;
|
|
16
|
+
exports.activity_summary = activity_summary;
|
|
17
|
+
const zod_1 = require("zod");
|
|
18
|
+
const api_1 = require("../../convex/_generated/api");
|
|
19
|
+
const convexClient_1 = require("../lib/convexClient");
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Zod schemas
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
const PipelineValueSchema = zod_1.z.object({
|
|
24
|
+
workspaceId: zod_1.z.string().min(1),
|
|
25
|
+
});
|
|
26
|
+
const WinRateSchema = zod_1.z.object({
|
|
27
|
+
workspaceId: zod_1.z.string().min(1),
|
|
28
|
+
since: zod_1.z.number().optional(),
|
|
29
|
+
until: zod_1.z.number().optional(),
|
|
30
|
+
});
|
|
31
|
+
const ConversionRateSchema = zod_1.z.object({
|
|
32
|
+
workspaceId: zod_1.z.string().min(1),
|
|
33
|
+
since: zod_1.z.number().optional(),
|
|
34
|
+
until: zod_1.z.number().optional(),
|
|
35
|
+
});
|
|
36
|
+
const ActivitySummarySchema = zod_1.z.object({
|
|
37
|
+
workspaceId: zod_1.z.string().min(1),
|
|
38
|
+
ownerId: zod_1.z.string().optional(),
|
|
39
|
+
since: zod_1.z.number().optional(),
|
|
40
|
+
until: zod_1.z.number().optional(),
|
|
41
|
+
});
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Handlers
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
async function pipeline_value(rawArgs) {
|
|
46
|
+
const args = PipelineValueSchema.parse(rawArgs);
|
|
47
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().query(api_1.api.crm.deals.forecast, {
|
|
48
|
+
workspaceId: args.workspaceId,
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
async function win_rate(rawArgs) {
|
|
52
|
+
const args = WinRateSchema.parse(rawArgs);
|
|
53
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().query(api_1.api.crm.stats.conversionRate, {
|
|
54
|
+
workspaceId: args.workspaceId,
|
|
55
|
+
startDate: args.since,
|
|
56
|
+
endDate: args.until,
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
async function conversion_rate(rawArgs) {
|
|
60
|
+
const args = ConversionRateSchema.parse(rawArgs);
|
|
61
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().query(api_1.api.crm.stats.conversionRate, {
|
|
62
|
+
workspaceId: args.workspaceId,
|
|
63
|
+
startDate: args.since,
|
|
64
|
+
endDate: args.until,
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
async function activity_summary(rawArgs) {
|
|
68
|
+
const args = ActivitySummarySchema.parse(rawArgs);
|
|
69
|
+
// activities.summary is crm.deals.summary (pipeline) — use list + aggregate
|
|
70
|
+
return (0, convexClient_1.withEnvelope)(async () => {
|
|
71
|
+
const activities = await (0, convexClient_1.getConvexClient)().query(api_1.api.crm.activities.list, {
|
|
72
|
+
workspaceId: args.workspaceId,
|
|
73
|
+
limit: 500,
|
|
74
|
+
});
|
|
75
|
+
let results = activities;
|
|
76
|
+
if (args.ownerId !== undefined) {
|
|
77
|
+
results = results.filter((a) => a['ownerId'] === args.ownerId);
|
|
78
|
+
}
|
|
79
|
+
if (args.since !== undefined) {
|
|
80
|
+
results = results.filter((a) => a['occurredAt'] >= args.since);
|
|
81
|
+
}
|
|
82
|
+
if (args.until !== undefined) {
|
|
83
|
+
results = results.filter((a) => a['occurredAt'] <= args.until);
|
|
84
|
+
}
|
|
85
|
+
// Aggregate by type
|
|
86
|
+
const byType = {};
|
|
87
|
+
for (const a of results) {
|
|
88
|
+
const t = String(a['type'] ?? 'unknown');
|
|
89
|
+
byType[t] = (byType[t] ?? 0) + 1;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
total: results.length,
|
|
93
|
+
byType,
|
|
94
|
+
ownerId: args.ownerId ?? 'all',
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Tool definitions
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
exports.SEARCH_TOOLS = [
|
|
102
|
+
{
|
|
103
|
+
name: 'pipeline_value',
|
|
104
|
+
description: 'Compute weighted pipeline value (Σ value × probability) for a workspace',
|
|
105
|
+
requiredScope: 'read',
|
|
106
|
+
inputSchema: {
|
|
107
|
+
type: 'object',
|
|
108
|
+
properties: { workspaceId: { type: 'string' } },
|
|
109
|
+
required: ['workspaceId'],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'win_rate',
|
|
114
|
+
description: 'Win rate: deals won / total closed deals in a period',
|
|
115
|
+
requiredScope: 'read',
|
|
116
|
+
inputSchema: {
|
|
117
|
+
type: 'object',
|
|
118
|
+
properties: {
|
|
119
|
+
workspaceId: { type: 'string' },
|
|
120
|
+
since: { type: 'number', description: 'Unix ms start' },
|
|
121
|
+
until: { type: 'number', description: 'Unix ms end' },
|
|
122
|
+
},
|
|
123
|
+
required: ['workspaceId'],
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'conversion_rate',
|
|
128
|
+
description: 'Stage conversion rate for a workspace over a time period',
|
|
129
|
+
requiredScope: 'read',
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: 'object',
|
|
132
|
+
properties: {
|
|
133
|
+
workspaceId: { type: 'string' },
|
|
134
|
+
since: { type: 'number' },
|
|
135
|
+
until: { type: 'number' },
|
|
136
|
+
},
|
|
137
|
+
required: ['workspaceId'],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: 'activity_summary',
|
|
142
|
+
description: 'Activity count summary grouped by type, optionally filtered by owner/period',
|
|
143
|
+
requiredScope: 'read',
|
|
144
|
+
inputSchema: {
|
|
145
|
+
type: 'object',
|
|
146
|
+
properties: {
|
|
147
|
+
workspaceId: { type: 'string' },
|
|
148
|
+
ownerId: { type: 'string' },
|
|
149
|
+
since: { type: 'number' },
|
|
150
|
+
until: { type: 'number' },
|
|
151
|
+
},
|
|
152
|
+
required: ['workspaceId'],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
];
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* VantageCRM MCP — Workflows tools (7 tools)
|
|
4
|
+
*
|
|
5
|
+
* Tools: create_workflow, update_workflow, list_workflows, pause_workflow,
|
|
6
|
+
* resume_workflow, list_executions, replay_execution
|
|
7
|
+
*
|
|
8
|
+
* Scope: read for queries, write for mutations, workflow-trigger for replay
|
|
9
|
+
* Ref: spec §3.8
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.WORKFLOW_TOOLS = void 0;
|
|
13
|
+
exports.create_workflow = create_workflow;
|
|
14
|
+
exports.update_workflow = update_workflow;
|
|
15
|
+
exports.list_workflows = list_workflows;
|
|
16
|
+
exports.pause_workflow = pause_workflow;
|
|
17
|
+
exports.resume_workflow = resume_workflow;
|
|
18
|
+
exports.list_executions = list_executions;
|
|
19
|
+
exports.replay_execution = replay_execution;
|
|
20
|
+
const zod_1 = require("zod");
|
|
21
|
+
const server_1 = require("convex/server");
|
|
22
|
+
const convexClient_1 = require("../lib/convexClient");
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Zod schemas
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
const CreateWorkflowSchema = zod_1.z.object({
|
|
27
|
+
workspaceId: zod_1.z.string().min(1),
|
|
28
|
+
name: zod_1.z.string().min(1).max(200),
|
|
29
|
+
description: zod_1.z.string().max(1000).optional(),
|
|
30
|
+
trigger: zod_1.z.object({
|
|
31
|
+
type: zod_1.z.string().min(1),
|
|
32
|
+
config: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
|
|
33
|
+
}),
|
|
34
|
+
actions: zod_1.z.array(zod_1.z.object({
|
|
35
|
+
type: zod_1.z.string().min(1),
|
|
36
|
+
config: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
|
|
37
|
+
order: zod_1.z.number().int().min(0),
|
|
38
|
+
})),
|
|
39
|
+
});
|
|
40
|
+
const UpdateWorkflowSchema = zod_1.z.object({
|
|
41
|
+
workflowId: zod_1.z.string().min(1),
|
|
42
|
+
name: zod_1.z.string().min(1).max(200).optional(),
|
|
43
|
+
description: zod_1.z.string().max(1000).optional(),
|
|
44
|
+
trigger: zod_1.z.object({
|
|
45
|
+
type: zod_1.z.string().min(1),
|
|
46
|
+
config: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
|
|
47
|
+
}).optional(),
|
|
48
|
+
actions: zod_1.z.array(zod_1.z.object({
|
|
49
|
+
type: zod_1.z.string().min(1),
|
|
50
|
+
config: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()),
|
|
51
|
+
order: zod_1.z.number().int().min(0),
|
|
52
|
+
})).optional(),
|
|
53
|
+
});
|
|
54
|
+
const ListWorkflowsSchema = zod_1.z.object({
|
|
55
|
+
workspaceId: zod_1.z.string().min(1),
|
|
56
|
+
isActive: zod_1.z.boolean().optional(),
|
|
57
|
+
});
|
|
58
|
+
const PauseWorkflowSchema = zod_1.z.object({
|
|
59
|
+
workflowId: zod_1.z.string().min(1),
|
|
60
|
+
reason: zod_1.z.string().max(500).optional(),
|
|
61
|
+
});
|
|
62
|
+
const ResumeWorkflowSchema = zod_1.z.object({
|
|
63
|
+
workflowId: zod_1.z.string().min(1),
|
|
64
|
+
});
|
|
65
|
+
const ListExecutionsSchema = zod_1.z.object({
|
|
66
|
+
workspaceId: zod_1.z.string().min(1),
|
|
67
|
+
workflowId: zod_1.z.string().optional(),
|
|
68
|
+
status: zod_1.z.enum(['pending', 'running', 'completed', 'failed', 'cancelled']).optional(),
|
|
69
|
+
limit: zod_1.z.number().int().min(1).max(100).default(20),
|
|
70
|
+
});
|
|
71
|
+
const ReplayExecutionSchema = zod_1.z.object({
|
|
72
|
+
executionId: zod_1.z.string().min(1),
|
|
73
|
+
});
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Handlers
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
async function create_workflow(rawArgs) {
|
|
78
|
+
const args = CreateWorkflowSchema.parse(rawArgs);
|
|
79
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().mutation(server_1.anyApi.crm.workflows.createWorkflowDefinition, {
|
|
80
|
+
workspaceId: args.workspaceId,
|
|
81
|
+
name: args.name,
|
|
82
|
+
description: args.description,
|
|
83
|
+
trigger: args.trigger,
|
|
84
|
+
actions: args.actions,
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
async function update_workflow(rawArgs) {
|
|
88
|
+
const args = UpdateWorkflowSchema.parse(rawArgs);
|
|
89
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().mutation(server_1.anyApi.crm.workflows.updateWorkflowDefinition, {
|
|
90
|
+
workflowId: args.workflowId,
|
|
91
|
+
name: args.name,
|
|
92
|
+
description: args.description,
|
|
93
|
+
trigger: args.trigger,
|
|
94
|
+
actions: args.actions,
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
async function list_workflows(rawArgs) {
|
|
98
|
+
const args = ListWorkflowsSchema.parse(rawArgs);
|
|
99
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().query(server_1.anyApi.crm.workflows.listWorkflowDefinitions, {
|
|
100
|
+
workspaceId: args.workspaceId,
|
|
101
|
+
isActive: args.isActive,
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
async function pause_workflow(rawArgs) {
|
|
105
|
+
const args = PauseWorkflowSchema.parse(rawArgs);
|
|
106
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().mutation(server_1.anyApi.crm.workflows.disableWorkflow, {
|
|
107
|
+
workflowId: args.workflowId,
|
|
108
|
+
reason: args.reason,
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
async function resume_workflow(rawArgs) {
|
|
112
|
+
const args = ResumeWorkflowSchema.parse(rawArgs);
|
|
113
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().mutation(server_1.anyApi.crm.workflows.enableWorkflow, {
|
|
114
|
+
workflowId: args.workflowId,
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
async function list_executions(rawArgs) {
|
|
118
|
+
const args = ListExecutionsSchema.parse(rawArgs);
|
|
119
|
+
return (0, convexClient_1.withEnvelope)(() => (0, convexClient_1.getConvexClient)().query(server_1.anyApi.crm.workflows.listWorkflowExecutions, {
|
|
120
|
+
workspaceId: args.workspaceId,
|
|
121
|
+
workflowId: args.workflowId,
|
|
122
|
+
status: args.status,
|
|
123
|
+
limit: args.limit,
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
async function replay_execution(rawArgs) {
|
|
127
|
+
ReplayExecutionSchema.parse(rawArgs);
|
|
128
|
+
// replayExecution not yet in Convex layer V0.1.0 — stable NOT_IMPLEMENTED envelope
|
|
129
|
+
return {
|
|
130
|
+
success: false,
|
|
131
|
+
error: {
|
|
132
|
+
code: 'NOT_IMPLEMENTED',
|
|
133
|
+
message: 'replay_execution: reserved for V0.2. Requires crm.workflows.replayExecution mutation.',
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// Tool definitions
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
exports.WORKFLOW_TOOLS = [
|
|
141
|
+
{
|
|
142
|
+
name: 'create_workflow',
|
|
143
|
+
description: 'Create a workflow definition with trigger and actions',
|
|
144
|
+
requiredScope: 'write',
|
|
145
|
+
inputSchema: {
|
|
146
|
+
type: 'object',
|
|
147
|
+
properties: {
|
|
148
|
+
workspaceId: { type: 'string' },
|
|
149
|
+
name: { type: 'string' },
|
|
150
|
+
description: { type: 'string' },
|
|
151
|
+
trigger: { type: 'object', properties: { type: { type: 'string' }, config: { type: 'object' } }, required: ['type', 'config'] },
|
|
152
|
+
actions: { type: 'array', items: { type: 'object' } },
|
|
153
|
+
},
|
|
154
|
+
required: ['workspaceId', 'name', 'trigger', 'actions'],
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'update_workflow',
|
|
159
|
+
description: 'Update a workflow definition (must be disabled first)',
|
|
160
|
+
requiredScope: 'write',
|
|
161
|
+
inputSchema: {
|
|
162
|
+
type: 'object',
|
|
163
|
+
properties: {
|
|
164
|
+
workflowId: { type: 'string' },
|
|
165
|
+
name: { type: 'string' },
|
|
166
|
+
description: { type: 'string' },
|
|
167
|
+
trigger: { type: 'object' },
|
|
168
|
+
actions: { type: 'array' },
|
|
169
|
+
},
|
|
170
|
+
required: ['workflowId'],
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: 'list_workflows',
|
|
175
|
+
description: 'List workflow definitions, optionally filtered by active status',
|
|
176
|
+
requiredScope: 'read',
|
|
177
|
+
inputSchema: {
|
|
178
|
+
type: 'object',
|
|
179
|
+
properties: {
|
|
180
|
+
workspaceId: { type: 'string' },
|
|
181
|
+
isActive: { type: 'boolean' },
|
|
182
|
+
},
|
|
183
|
+
required: ['workspaceId'],
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: 'pause_workflow',
|
|
188
|
+
description: 'Pause (disable) a workflow — sets isActive=false',
|
|
189
|
+
requiredScope: 'write',
|
|
190
|
+
inputSchema: {
|
|
191
|
+
type: 'object',
|
|
192
|
+
properties: {
|
|
193
|
+
workflowId: { type: 'string' },
|
|
194
|
+
reason: { type: 'string' },
|
|
195
|
+
},
|
|
196
|
+
required: ['workflowId'],
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: 'resume_workflow',
|
|
201
|
+
description: 'Resume (enable) a workflow — sets isActive=true',
|
|
202
|
+
requiredScope: 'write',
|
|
203
|
+
inputSchema: {
|
|
204
|
+
type: 'object',
|
|
205
|
+
properties: { workflowId: { type: 'string' } },
|
|
206
|
+
required: ['workflowId'],
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: 'list_executions',
|
|
211
|
+
description: 'List workflow executions by workspace/workflow/status',
|
|
212
|
+
requiredScope: 'read',
|
|
213
|
+
inputSchema: {
|
|
214
|
+
type: 'object',
|
|
215
|
+
properties: {
|
|
216
|
+
workspaceId: { type: 'string' },
|
|
217
|
+
workflowId: { type: 'string' },
|
|
218
|
+
status: { type: 'string', enum: ['pending', 'running', 'completed', 'failed', 'cancelled'] },
|
|
219
|
+
limit: { type: 'number' },
|
|
220
|
+
},
|
|
221
|
+
required: ['workspaceId'],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: 'replay_execution',
|
|
226
|
+
description: 'Replay a workflow execution (requires workflow-trigger scope)',
|
|
227
|
+
requiredScope: 'workflow-trigger',
|
|
228
|
+
inputSchema: {
|
|
229
|
+
type: 'object',
|
|
230
|
+
properties: { executionId: { type: 'string' } },
|
|
231
|
+
required: ['executionId'],
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
];
|