@l4yercak3/cli 1.2.12 → 1.2.14
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/docs/mcp_server/MCP_EXTENSION_GUIDE.md +1313 -0
- package/package.json +1 -1
- package/src/commands/spread.js +25 -2
|
@@ -0,0 +1,1313 @@
|
|
|
1
|
+
# L4YERCAK3 MCP Server Extension Guide
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
This document outlines the MCP (Model Context Protocol) tools needed to enable Claude Code to effectively build mobile applications that integrate with the L4YERCAK3 backend. The goal is to expose read/write capabilities for core business objects so AI assistants can generate, test, and iterate on mobile app features.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Current State
|
|
10
|
+
|
|
11
|
+
### Existing MCP Tools
|
|
12
|
+
|
|
13
|
+
| Tool | Purpose | Status |
|
|
14
|
+
|------|---------|--------|
|
|
15
|
+
| `l4yercak3_check_auth_status` | Verify user authentication | ✅ Working |
|
|
16
|
+
| `l4yercak3_get_capabilities` | List available features by category | ✅ Working |
|
|
17
|
+
| `l4yercak3_list_organizations` | Get user's organizations | ✅ Working |
|
|
18
|
+
| `l4yercak3_switch_organization` | Change org context | ✅ Working |
|
|
19
|
+
| `l4yercak3_create_organization` | Create new org | ✅ Working |
|
|
20
|
+
| `l4yercak3_get_application` | Get connected app details | ✅ Working |
|
|
21
|
+
| `l4yercak3_list_applications` | List connected apps | ⚠️ Error |
|
|
22
|
+
| `l4yercak3_analyze_schema` | Analyze database schemas | ✅ Working |
|
|
23
|
+
| `l4yercak3_suggest_model_mappings` | Suggest L4YERCAK3 type mappings | ✅ Working |
|
|
24
|
+
| `l4yercak3_generate_api_client` | Generate TypeScript client | ✅ Working |
|
|
25
|
+
| `l4yercak3_generate_sync_adapter` | Generate sync code | ✅ Working |
|
|
26
|
+
| `l4yercak3_generate_webhook_handler` | Generate webhook handlers | ✅ Working |
|
|
27
|
+
| `l4yercak3_generate_env_template` | Generate .env template | ✅ Working |
|
|
28
|
+
|
|
29
|
+
### What's Missing
|
|
30
|
+
|
|
31
|
+
The current MCP server is optimized for **code generation** but lacks **data access** capabilities. To build and test mobile apps effectively, Claude needs to:
|
|
32
|
+
|
|
33
|
+
1. **Read real data** to understand schemas and test UI
|
|
34
|
+
2. **Write test data** to verify functionality
|
|
35
|
+
3. **Query relationships** between objects
|
|
36
|
+
4. **Validate business logic** against actual backend behavior
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Required New MCP Tools
|
|
41
|
+
|
|
42
|
+
### Priority 1: Core Data Access (Must Have)
|
|
43
|
+
|
|
44
|
+
These tools are essential for building any mobile app feature.
|
|
45
|
+
|
|
46
|
+
#### 1.1 Events Module
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// l4yercak3_events_list
|
|
50
|
+
{
|
|
51
|
+
name: "l4yercak3_events_list",
|
|
52
|
+
description: "List events for the current organization. Returns published and draft events with pagination.",
|
|
53
|
+
parameters: {
|
|
54
|
+
status?: "draft" | "published" | "cancelled" | "completed",
|
|
55
|
+
limit?: number, // Default: 20, Max: 100
|
|
56
|
+
offset?: number, // For pagination
|
|
57
|
+
startDateAfter?: string, // ISO date - filter future events
|
|
58
|
+
startDateBefore?: string, // ISO date - filter past events
|
|
59
|
+
search?: string, // Search by name/description
|
|
60
|
+
},
|
|
61
|
+
returns: {
|
|
62
|
+
events: Array<{
|
|
63
|
+
id: string,
|
|
64
|
+
name: string,
|
|
65
|
+
description: string,
|
|
66
|
+
status: string,
|
|
67
|
+
startDate: string,
|
|
68
|
+
endDate: string,
|
|
69
|
+
venue: { name: string, address: string, city: string } | null,
|
|
70
|
+
imageUrl: string | null,
|
|
71
|
+
ticketCount: number,
|
|
72
|
+
attendeeCount: number,
|
|
73
|
+
}>,
|
|
74
|
+
total: number,
|
|
75
|
+
hasMore: boolean,
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// l4yercak3_events_get
|
|
80
|
+
{
|
|
81
|
+
name: "l4yercak3_events_get",
|
|
82
|
+
description: "Get detailed information about a specific event including tickets, agenda, and sponsors.",
|
|
83
|
+
parameters: {
|
|
84
|
+
eventId: string, // Required
|
|
85
|
+
include?: Array<"tickets" | "agenda" | "sponsors" | "forms">,
|
|
86
|
+
},
|
|
87
|
+
returns: {
|
|
88
|
+
event: {
|
|
89
|
+
id: string,
|
|
90
|
+
name: string,
|
|
91
|
+
description: string,
|
|
92
|
+
status: string,
|
|
93
|
+
startDate: string,
|
|
94
|
+
endDate: string,
|
|
95
|
+
timezone: string,
|
|
96
|
+
venue: { ... } | null,
|
|
97
|
+
imageUrl: string | null,
|
|
98
|
+
bannerUrl: string | null,
|
|
99
|
+
// Included if requested:
|
|
100
|
+
tickets?: Array<{ id, name, price, currency, available, sold }>,
|
|
101
|
+
agenda?: Array<{ id, title, startTime, endTime, speaker, track }>,
|
|
102
|
+
sponsors?: Array<{ id, name, tier, logoUrl }>,
|
|
103
|
+
forms?: Array<{ id, name, type, fieldCount }>,
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// l4yercak3_events_get_attendees
|
|
109
|
+
{
|
|
110
|
+
name: "l4yercak3_events_get_attendees",
|
|
111
|
+
description: "Get attendees for an event with their ticket and check-in status.",
|
|
112
|
+
parameters: {
|
|
113
|
+
eventId: string,
|
|
114
|
+
status?: "registered" | "checked_in" | "cancelled",
|
|
115
|
+
ticketId?: string, // Filter by ticket type
|
|
116
|
+
search?: string, // Search by name/email
|
|
117
|
+
limit?: number,
|
|
118
|
+
offset?: number,
|
|
119
|
+
},
|
|
120
|
+
returns: {
|
|
121
|
+
attendees: Array<{
|
|
122
|
+
id: string,
|
|
123
|
+
contactId: string,
|
|
124
|
+
name: string,
|
|
125
|
+
email: string,
|
|
126
|
+
ticketName: string,
|
|
127
|
+
ticketId: string,
|
|
128
|
+
status: string,
|
|
129
|
+
checkedInAt: string | null,
|
|
130
|
+
registeredAt: string,
|
|
131
|
+
formResponses?: Record<string, any>,
|
|
132
|
+
}>,
|
|
133
|
+
total: number,
|
|
134
|
+
hasMore: boolean,
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### 1.2 Tickets Module
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// l4yercak3_tickets_list
|
|
143
|
+
{
|
|
144
|
+
name: "l4yercak3_tickets_list",
|
|
145
|
+
description: "List ticket products for an event or all tickets in the organization.",
|
|
146
|
+
parameters: {
|
|
147
|
+
eventId?: string, // Filter by event
|
|
148
|
+
status?: "active" | "sold_out" | "hidden",
|
|
149
|
+
limit?: number,
|
|
150
|
+
offset?: number,
|
|
151
|
+
},
|
|
152
|
+
returns: {
|
|
153
|
+
tickets: Array<{
|
|
154
|
+
id: string,
|
|
155
|
+
eventId: string,
|
|
156
|
+
eventName: string,
|
|
157
|
+
name: string,
|
|
158
|
+
description: string,
|
|
159
|
+
price: number,
|
|
160
|
+
currency: string,
|
|
161
|
+
quantity: number,
|
|
162
|
+
sold: number,
|
|
163
|
+
available: number,
|
|
164
|
+
salesStart: string | null,
|
|
165
|
+
salesEnd: string | null,
|
|
166
|
+
status: string,
|
|
167
|
+
}>,
|
|
168
|
+
total: number,
|
|
169
|
+
hasMore: boolean,
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// l4yercak3_tickets_get_purchased
|
|
174
|
+
{
|
|
175
|
+
name: "l4yercak3_tickets_get_purchased",
|
|
176
|
+
description: "Get purchased tickets for a contact or the current user.",
|
|
177
|
+
parameters: {
|
|
178
|
+
contactId?: string, // If omitted, returns current user's tickets
|
|
179
|
+
eventId?: string, // Filter by event
|
|
180
|
+
status?: "valid" | "used" | "refunded" | "expired",
|
|
181
|
+
limit?: number,
|
|
182
|
+
offset?: number,
|
|
183
|
+
},
|
|
184
|
+
returns: {
|
|
185
|
+
purchasedTickets: Array<{
|
|
186
|
+
id: string,
|
|
187
|
+
ticketId: string,
|
|
188
|
+
ticketName: string,
|
|
189
|
+
eventId: string,
|
|
190
|
+
eventName: string,
|
|
191
|
+
eventDate: string,
|
|
192
|
+
purchasedAt: string,
|
|
193
|
+
status: string,
|
|
194
|
+
qrCode: string, // QR code data for scanning
|
|
195
|
+
confirmationNumber: string,
|
|
196
|
+
price: number,
|
|
197
|
+
currency: string,
|
|
198
|
+
}>,
|
|
199
|
+
total: number,
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
#### 1.3 CRM Module
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// l4yercak3_crm_list_contacts
|
|
208
|
+
{
|
|
209
|
+
name: "l4yercak3_crm_list_contacts",
|
|
210
|
+
description: "List contacts in the CRM with filtering and search.",
|
|
211
|
+
parameters: {
|
|
212
|
+
type?: "individual" | "organization",
|
|
213
|
+
status?: "active" | "archived",
|
|
214
|
+
tags?: string[],
|
|
215
|
+
pipelineStage?: string,
|
|
216
|
+
search?: string, // Search name, email, phone
|
|
217
|
+
limit?: number,
|
|
218
|
+
offset?: number,
|
|
219
|
+
orderBy?: "name" | "createdAt" | "updatedAt",
|
|
220
|
+
orderDir?: "asc" | "desc",
|
|
221
|
+
},
|
|
222
|
+
returns: {
|
|
223
|
+
contacts: Array<{
|
|
224
|
+
id: string,
|
|
225
|
+
type: string,
|
|
226
|
+
firstName: string | null,
|
|
227
|
+
lastName: string | null,
|
|
228
|
+
displayName: string,
|
|
229
|
+
email: string | null,
|
|
230
|
+
phone: string | null,
|
|
231
|
+
organizationId: string | null,
|
|
232
|
+
organizationName: string | null,
|
|
233
|
+
tags: string[],
|
|
234
|
+
pipelineStage: string | null,
|
|
235
|
+
avatarUrl: string | null,
|
|
236
|
+
createdAt: string,
|
|
237
|
+
}>,
|
|
238
|
+
total: number,
|
|
239
|
+
hasMore: boolean,
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// l4yercak3_crm_get_contact
|
|
244
|
+
{
|
|
245
|
+
name: "l4yercak3_crm_get_contact",
|
|
246
|
+
description: "Get detailed contact information including activities and linked objects.",
|
|
247
|
+
parameters: {
|
|
248
|
+
contactId: string,
|
|
249
|
+
include?: Array<"activities" | "notes" | "tickets" | "invoices" | "forms">,
|
|
250
|
+
},
|
|
251
|
+
returns: {
|
|
252
|
+
contact: {
|
|
253
|
+
id: string,
|
|
254
|
+
type: string,
|
|
255
|
+
firstName: string | null,
|
|
256
|
+
lastName: string | null,
|
|
257
|
+
displayName: string,
|
|
258
|
+
email: string | null,
|
|
259
|
+
phone: string | null,
|
|
260
|
+
address: { street, city, state, postalCode, country } | null,
|
|
261
|
+
organizationId: string | null,
|
|
262
|
+
organizationName: string | null,
|
|
263
|
+
tags: string[],
|
|
264
|
+
customFields: Record<string, any>,
|
|
265
|
+
pipelineStage: string | null,
|
|
266
|
+
avatarUrl: string | null,
|
|
267
|
+
createdAt: string,
|
|
268
|
+
updatedAt: string,
|
|
269
|
+
// Included if requested:
|
|
270
|
+
activities?: Array<{ id, type, subject, date, notes }>,
|
|
271
|
+
notes?: Array<{ id, content, createdAt, createdBy }>,
|
|
272
|
+
tickets?: Array<{ id, eventName, ticketName, status }>,
|
|
273
|
+
invoices?: Array<{ id, number, amount, status, dueDate }>,
|
|
274
|
+
forms?: Array<{ id, formName, submittedAt }>,
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// l4yercak3_crm_create_contact
|
|
280
|
+
{
|
|
281
|
+
name: "l4yercak3_crm_create_contact",
|
|
282
|
+
description: "Create a new contact in the CRM.",
|
|
283
|
+
parameters: {
|
|
284
|
+
type: "individual" | "organization",
|
|
285
|
+
firstName?: string,
|
|
286
|
+
lastName?: string,
|
|
287
|
+
email?: string,
|
|
288
|
+
phone?: string,
|
|
289
|
+
organizationId?: string, // Link to parent organization
|
|
290
|
+
address?: { street?, city?, state?, postalCode?, country? },
|
|
291
|
+
tags?: string[],
|
|
292
|
+
customFields?: Record<string, any>,
|
|
293
|
+
pipelineStage?: string,
|
|
294
|
+
},
|
|
295
|
+
returns: {
|
|
296
|
+
contactId: string,
|
|
297
|
+
contact: { ... },
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// l4yercak3_crm_update_contact
|
|
302
|
+
{
|
|
303
|
+
name: "l4yercak3_crm_update_contact",
|
|
304
|
+
description: "Update an existing contact.",
|
|
305
|
+
parameters: {
|
|
306
|
+
contactId: string,
|
|
307
|
+
firstName?: string,
|
|
308
|
+
lastName?: string,
|
|
309
|
+
email?: string,
|
|
310
|
+
phone?: string,
|
|
311
|
+
organizationId?: string,
|
|
312
|
+
address?: { ... },
|
|
313
|
+
tags?: string[],
|
|
314
|
+
customFields?: Record<string, any>,
|
|
315
|
+
pipelineStage?: string,
|
|
316
|
+
},
|
|
317
|
+
returns: {
|
|
318
|
+
success: boolean,
|
|
319
|
+
contact: { ... },
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// l4yercak3_crm_list_organizations
|
|
324
|
+
{
|
|
325
|
+
name: "l4yercak3_crm_list_organizations",
|
|
326
|
+
description: "List organization contacts (companies, employers) in the CRM.",
|
|
327
|
+
parameters: {
|
|
328
|
+
status?: "active" | "archived",
|
|
329
|
+
industry?: string,
|
|
330
|
+
search?: string,
|
|
331
|
+
limit?: number,
|
|
332
|
+
offset?: number,
|
|
333
|
+
},
|
|
334
|
+
returns: {
|
|
335
|
+
organizations: Array<{
|
|
336
|
+
id: string,
|
|
337
|
+
name: string,
|
|
338
|
+
industry: string | null,
|
|
339
|
+
website: string | null,
|
|
340
|
+
email: string | null,
|
|
341
|
+
phone: string | null,
|
|
342
|
+
employeeCount: number,
|
|
343
|
+
address: { ... } | null,
|
|
344
|
+
createdAt: string,
|
|
345
|
+
}>,
|
|
346
|
+
total: number,
|
|
347
|
+
hasMore: boolean,
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
#### 1.4 Forms Module
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
// l4yercak3_forms_list
|
|
356
|
+
{
|
|
357
|
+
name: "l4yercak3_forms_list",
|
|
358
|
+
description: "List forms in the organization.",
|
|
359
|
+
parameters: {
|
|
360
|
+
type?: "registration" | "survey" | "application" | "feedback",
|
|
361
|
+
eventId?: string,
|
|
362
|
+
status?: "draft" | "active" | "closed",
|
|
363
|
+
limit?: number,
|
|
364
|
+
offset?: number,
|
|
365
|
+
},
|
|
366
|
+
returns: {
|
|
367
|
+
forms: Array<{
|
|
368
|
+
id: string,
|
|
369
|
+
name: string,
|
|
370
|
+
type: string,
|
|
371
|
+
status: string,
|
|
372
|
+
eventId: string | null,
|
|
373
|
+
eventName: string | null,
|
|
374
|
+
fieldCount: number,
|
|
375
|
+
responseCount: number,
|
|
376
|
+
createdAt: string,
|
|
377
|
+
}>,
|
|
378
|
+
total: number,
|
|
379
|
+
hasMore: boolean,
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// l4yercak3_forms_get
|
|
384
|
+
{
|
|
385
|
+
name: "l4yercak3_forms_get",
|
|
386
|
+
description: "Get form details including field definitions.",
|
|
387
|
+
parameters: {
|
|
388
|
+
formId: string,
|
|
389
|
+
},
|
|
390
|
+
returns: {
|
|
391
|
+
form: {
|
|
392
|
+
id: string,
|
|
393
|
+
name: string,
|
|
394
|
+
description: string,
|
|
395
|
+
type: string,
|
|
396
|
+
status: string,
|
|
397
|
+
eventId: string | null,
|
|
398
|
+
fields: Array<{
|
|
399
|
+
id: string,
|
|
400
|
+
type: "text" | "email" | "phone" | "select" | "multiselect" | "checkbox" | "date" | "file" | "number",
|
|
401
|
+
label: string,
|
|
402
|
+
required: boolean,
|
|
403
|
+
options?: string[],
|
|
404
|
+
placeholder?: string,
|
|
405
|
+
validation?: { min?, max?, pattern? },
|
|
406
|
+
conditionalOn?: { fieldId: string, value: any },
|
|
407
|
+
}>,
|
|
408
|
+
settings: {
|
|
409
|
+
submitButtonText: string,
|
|
410
|
+
confirmationMessage: string,
|
|
411
|
+
redirectUrl: string | null,
|
|
412
|
+
notifyEmails: string[],
|
|
413
|
+
},
|
|
414
|
+
createdAt: string,
|
|
415
|
+
updatedAt: string,
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// l4yercak3_forms_get_responses
|
|
421
|
+
{
|
|
422
|
+
name: "l4yercak3_forms_get_responses",
|
|
423
|
+
description: "Get form submissions/responses.",
|
|
424
|
+
parameters: {
|
|
425
|
+
formId: string,
|
|
426
|
+
contactId?: string,
|
|
427
|
+
startDate?: string,
|
|
428
|
+
endDate?: string,
|
|
429
|
+
limit?: number,
|
|
430
|
+
offset?: number,
|
|
431
|
+
},
|
|
432
|
+
returns: {
|
|
433
|
+
responses: Array<{
|
|
434
|
+
id: string,
|
|
435
|
+
formId: string,
|
|
436
|
+
contactId: string | null,
|
|
437
|
+
contactName: string | null,
|
|
438
|
+
contactEmail: string | null,
|
|
439
|
+
data: Record<string, any>, // Field responses
|
|
440
|
+
submittedAt: string,
|
|
441
|
+
status: "submitted" | "reviewed" | "approved" | "rejected",
|
|
442
|
+
}>,
|
|
443
|
+
total: number,
|
|
444
|
+
hasMore: boolean,
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### Priority 2: User & Auth Context (Important)
|
|
450
|
+
|
|
451
|
+
These tools provide user context needed for personalization.
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
// l4yercak3_get_current_user
|
|
455
|
+
{
|
|
456
|
+
name: "l4yercak3_get_current_user",
|
|
457
|
+
description: "Get the currently authenticated user's profile and permissions.",
|
|
458
|
+
parameters: {},
|
|
459
|
+
returns: {
|
|
460
|
+
user: {
|
|
461
|
+
id: string,
|
|
462
|
+
email: string,
|
|
463
|
+
firstName: string | null,
|
|
464
|
+
lastName: string | null,
|
|
465
|
+
displayName: string,
|
|
466
|
+
avatarUrl: string | null,
|
|
467
|
+
role: string,
|
|
468
|
+
permissions: string[],
|
|
469
|
+
preferences: {
|
|
470
|
+
language: string,
|
|
471
|
+
timezone: string,
|
|
472
|
+
theme: "light" | "dark" | "system",
|
|
473
|
+
},
|
|
474
|
+
organizations: Array<{
|
|
475
|
+
id: string,
|
|
476
|
+
name: string,
|
|
477
|
+
slug: string,
|
|
478
|
+
role: string,
|
|
479
|
+
isDefault: boolean,
|
|
480
|
+
}>,
|
|
481
|
+
currentOrganization: {
|
|
482
|
+
id: string,
|
|
483
|
+
name: string,
|
|
484
|
+
slug: string,
|
|
485
|
+
role: string,
|
|
486
|
+
} | null,
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// l4yercak3_get_organization_details
|
|
492
|
+
{
|
|
493
|
+
name: "l4yercak3_get_organization_details",
|
|
494
|
+
description: "Get detailed information about an organization including settings and subscription.",
|
|
495
|
+
parameters: {
|
|
496
|
+
organizationId?: string, // If omitted, uses current org
|
|
497
|
+
},
|
|
498
|
+
returns: {
|
|
499
|
+
organization: {
|
|
500
|
+
id: string,
|
|
501
|
+
name: string,
|
|
502
|
+
slug: string,
|
|
503
|
+
businessName: string | null,
|
|
504
|
+
logo: string | null,
|
|
505
|
+
website: string | null,
|
|
506
|
+
industry: string | null,
|
|
507
|
+
address: { ... } | null,
|
|
508
|
+
subscription: {
|
|
509
|
+
plan: "free" | "pro" | "business" | "enterprise",
|
|
510
|
+
status: "active" | "trialing" | "past_due" | "cancelled",
|
|
511
|
+
trialEndsAt: string | null,
|
|
512
|
+
currentPeriodEnd: string | null,
|
|
513
|
+
},
|
|
514
|
+
settings: {
|
|
515
|
+
defaultCurrency: string,
|
|
516
|
+
defaultTimezone: string,
|
|
517
|
+
defaultLanguage: string,
|
|
518
|
+
},
|
|
519
|
+
features: string[], // Enabled features based on plan
|
|
520
|
+
memberCount: number,
|
|
521
|
+
createdAt: string,
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### Priority 3: Invoicing & Payments (Nice to Have)
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
// l4yercak3_invoices_list
|
|
531
|
+
{
|
|
532
|
+
name: "l4yercak3_invoices_list",
|
|
533
|
+
description: "List invoices for the organization.",
|
|
534
|
+
parameters: {
|
|
535
|
+
contactId?: string,
|
|
536
|
+
status?: "draft" | "sent" | "paid" | "overdue" | "cancelled",
|
|
537
|
+
type?: "b2b" | "b2c",
|
|
538
|
+
startDate?: string,
|
|
539
|
+
endDate?: string,
|
|
540
|
+
limit?: number,
|
|
541
|
+
offset?: number,
|
|
542
|
+
},
|
|
543
|
+
returns: {
|
|
544
|
+
invoices: Array<{
|
|
545
|
+
id: string,
|
|
546
|
+
number: string,
|
|
547
|
+
contactId: string,
|
|
548
|
+
contactName: string,
|
|
549
|
+
type: string,
|
|
550
|
+
status: string,
|
|
551
|
+
amount: number,
|
|
552
|
+
currency: string,
|
|
553
|
+
dueDate: string,
|
|
554
|
+
paidAt: string | null,
|
|
555
|
+
lineItemCount: number,
|
|
556
|
+
createdAt: string,
|
|
557
|
+
}>,
|
|
558
|
+
total: number,
|
|
559
|
+
hasMore: boolean,
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// l4yercak3_invoices_get
|
|
564
|
+
{
|
|
565
|
+
name: "l4yercak3_invoices_get",
|
|
566
|
+
description: "Get detailed invoice information.",
|
|
567
|
+
parameters: {
|
|
568
|
+
invoiceId: string,
|
|
569
|
+
},
|
|
570
|
+
returns: {
|
|
571
|
+
invoice: {
|
|
572
|
+
id: string,
|
|
573
|
+
number: string,
|
|
574
|
+
contactId: string,
|
|
575
|
+
contact: { name, email, address },
|
|
576
|
+
type: string,
|
|
577
|
+
status: string,
|
|
578
|
+
issueDate: string,
|
|
579
|
+
dueDate: string,
|
|
580
|
+
paidAt: string | null,
|
|
581
|
+
lineItems: Array<{
|
|
582
|
+
description: string,
|
|
583
|
+
quantity: number,
|
|
584
|
+
unitPrice: number,
|
|
585
|
+
amount: number,
|
|
586
|
+
}>,
|
|
587
|
+
subtotal: number,
|
|
588
|
+
tax: number,
|
|
589
|
+
taxRate: number,
|
|
590
|
+
total: number,
|
|
591
|
+
currency: string,
|
|
592
|
+
notes: string | null,
|
|
593
|
+
pdfUrl: string | null,
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// l4yercak3_payments_list
|
|
599
|
+
{
|
|
600
|
+
name: "l4yercak3_payments_list",
|
|
601
|
+
description: "List payment transactions.",
|
|
602
|
+
parameters: {
|
|
603
|
+
contactId?: string,
|
|
604
|
+
status?: "pending" | "succeeded" | "failed" | "refunded",
|
|
605
|
+
startDate?: string,
|
|
606
|
+
endDate?: string,
|
|
607
|
+
limit?: number,
|
|
608
|
+
offset?: number,
|
|
609
|
+
},
|
|
610
|
+
returns: {
|
|
611
|
+
payments: Array<{
|
|
612
|
+
id: string,
|
|
613
|
+
amount: number,
|
|
614
|
+
currency: string,
|
|
615
|
+
status: string,
|
|
616
|
+
method: "card" | "bank_transfer" | "paypal",
|
|
617
|
+
contactId: string,
|
|
618
|
+
contactName: string,
|
|
619
|
+
invoiceId: string | null,
|
|
620
|
+
invoiceNumber: string | null,
|
|
621
|
+
description: string,
|
|
622
|
+
processedAt: string,
|
|
623
|
+
}>,
|
|
624
|
+
total: number,
|
|
625
|
+
hasMore: boolean,
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Priority 4: Check-in & Scanning (Mobile-Specific)
|
|
631
|
+
|
|
632
|
+
```typescript
|
|
633
|
+
// l4yercak3_checkin_scan
|
|
634
|
+
{
|
|
635
|
+
name: "l4yercak3_checkin_scan",
|
|
636
|
+
description: "Validate and check-in an attendee by scanning their ticket QR code.",
|
|
637
|
+
parameters: {
|
|
638
|
+
qrCode: string, // The scanned QR code data
|
|
639
|
+
eventId: string, // Event context for validation
|
|
640
|
+
},
|
|
641
|
+
returns: {
|
|
642
|
+
valid: boolean,
|
|
643
|
+
status: "success" | "already_checked_in" | "invalid" | "wrong_event" | "expired",
|
|
644
|
+
message: string,
|
|
645
|
+
attendee?: {
|
|
646
|
+
id: string,
|
|
647
|
+
name: string,
|
|
648
|
+
email: string,
|
|
649
|
+
ticketName: string,
|
|
650
|
+
checkedInAt: string,
|
|
651
|
+
photoUrl: string | null,
|
|
652
|
+
},
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// l4yercak3_checkin_manual
|
|
657
|
+
{
|
|
658
|
+
name: "l4yercak3_checkin_manual",
|
|
659
|
+
description: "Manually check-in an attendee by name or email lookup.",
|
|
660
|
+
parameters: {
|
|
661
|
+
eventId: string,
|
|
662
|
+
search: string, // Name or email to search
|
|
663
|
+
},
|
|
664
|
+
returns: {
|
|
665
|
+
matches: Array<{
|
|
666
|
+
attendeeId: string,
|
|
667
|
+
name: string,
|
|
668
|
+
email: string,
|
|
669
|
+
ticketName: string,
|
|
670
|
+
status: "registered" | "checked_in",
|
|
671
|
+
checkedInAt: string | null,
|
|
672
|
+
}>,
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// l4yercak3_checkin_confirm
|
|
677
|
+
{
|
|
678
|
+
name: "l4yercak3_checkin_confirm",
|
|
679
|
+
description: "Confirm check-in for a specific attendee (after manual lookup).",
|
|
680
|
+
parameters: {
|
|
681
|
+
attendeeId: string,
|
|
682
|
+
eventId: string,
|
|
683
|
+
},
|
|
684
|
+
returns: {
|
|
685
|
+
success: boolean,
|
|
686
|
+
attendee: {
|
|
687
|
+
id: string,
|
|
688
|
+
name: string,
|
|
689
|
+
checkedInAt: string,
|
|
690
|
+
},
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### Priority 5: Certificates (Professional Use)
|
|
696
|
+
|
|
697
|
+
```typescript
|
|
698
|
+
// l4yercak3_certificates_list
|
|
699
|
+
{
|
|
700
|
+
name: "l4yercak3_certificates_list",
|
|
701
|
+
description: "List certificates issued to a contact or for an event.",
|
|
702
|
+
parameters: {
|
|
703
|
+
contactId?: string,
|
|
704
|
+
eventId?: string,
|
|
705
|
+
type?: "cme" | "cle" | "cpe" | "attendance" | "completion",
|
|
706
|
+
limit?: number,
|
|
707
|
+
offset?: number,
|
|
708
|
+
},
|
|
709
|
+
returns: {
|
|
710
|
+
certificates: Array<{
|
|
711
|
+
id: string,
|
|
712
|
+
type: string,
|
|
713
|
+
title: string,
|
|
714
|
+
recipientId: string,
|
|
715
|
+
recipientName: string,
|
|
716
|
+
eventId: string | null,
|
|
717
|
+
eventName: string | null,
|
|
718
|
+
credits: number | null,
|
|
719
|
+
creditType: string | null,
|
|
720
|
+
issuedAt: string,
|
|
721
|
+
expiresAt: string | null,
|
|
722
|
+
verificationUrl: string,
|
|
723
|
+
pdfUrl: string,
|
|
724
|
+
}>,
|
|
725
|
+
total: number,
|
|
726
|
+
hasMore: boolean,
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// l4yercak3_certificates_verify
|
|
731
|
+
{
|
|
732
|
+
name: "l4yercak3_certificates_verify",
|
|
733
|
+
description: "Verify a certificate by its verification code.",
|
|
734
|
+
parameters: {
|
|
735
|
+
verificationCode: string,
|
|
736
|
+
},
|
|
737
|
+
returns: {
|
|
738
|
+
valid: boolean,
|
|
739
|
+
certificate?: {
|
|
740
|
+
id: string,
|
|
741
|
+
type: string,
|
|
742
|
+
title: string,
|
|
743
|
+
recipientName: string,
|
|
744
|
+
issuedAt: string,
|
|
745
|
+
expiresAt: string | null,
|
|
746
|
+
credits: number | null,
|
|
747
|
+
creditType: string | null,
|
|
748
|
+
issuerOrganization: string,
|
|
749
|
+
},
|
|
750
|
+
message?: string, // If invalid
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
---
|
|
756
|
+
|
|
757
|
+
## Implementation Guidelines
|
|
758
|
+
|
|
759
|
+
### Authentication
|
|
760
|
+
|
|
761
|
+
All MCP tools should use the existing authentication flow:
|
|
762
|
+
|
|
763
|
+
```typescript
|
|
764
|
+
// Every tool should validate auth first
|
|
765
|
+
const authStatus = await checkAuthStatus();
|
|
766
|
+
if (!authStatus.authenticated) {
|
|
767
|
+
return {
|
|
768
|
+
error: "Not authenticated",
|
|
769
|
+
loginInstructions: "Run 'l4yercak3 login' in terminal",
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
### Organization Context
|
|
775
|
+
|
|
776
|
+
Tools that access org-scoped data should:
|
|
777
|
+
|
|
778
|
+
1. Use the current organization from auth context
|
|
779
|
+
2. Optionally accept `organizationId` parameter to override
|
|
780
|
+
3. Validate user has access to the specified org
|
|
781
|
+
|
|
782
|
+
```typescript
|
|
783
|
+
// Pattern for org-scoped tools
|
|
784
|
+
parameters: {
|
|
785
|
+
organizationId?: string, // Optional override
|
|
786
|
+
// ... other params
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// In handler:
|
|
790
|
+
const orgId = args.organizationId || authContext.currentOrganizationId;
|
|
791
|
+
if (!orgId) {
|
|
792
|
+
return { error: "No organization selected. Use l4yercak3_switch_organization first." };
|
|
793
|
+
}
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### Error Handling
|
|
797
|
+
|
|
798
|
+
Return structured errors:
|
|
799
|
+
|
|
800
|
+
```typescript
|
|
801
|
+
// Success
|
|
802
|
+
{ success: true, data: { ... } }
|
|
803
|
+
|
|
804
|
+
// Client error (4xx equivalent)
|
|
805
|
+
{ error: "Contact not found", code: "NOT_FOUND" }
|
|
806
|
+
|
|
807
|
+
// Validation error
|
|
808
|
+
{ error: "Invalid email format", code: "VALIDATION_ERROR", field: "email" }
|
|
809
|
+
|
|
810
|
+
// Permission error
|
|
811
|
+
{ error: "Access denied", code: "FORBIDDEN" }
|
|
812
|
+
|
|
813
|
+
// Server error (5xx equivalent)
|
|
814
|
+
{ error: "Internal server error", code: "INTERNAL_ERROR" }
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### Pagination Pattern
|
|
818
|
+
|
|
819
|
+
Use consistent pagination:
|
|
820
|
+
|
|
821
|
+
```typescript
|
|
822
|
+
parameters: {
|
|
823
|
+
limit?: number, // Default: 20, Max: 100
|
|
824
|
+
offset?: number, // Default: 0
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
returns: {
|
|
828
|
+
items: [...],
|
|
829
|
+
total: number,
|
|
830
|
+
hasMore: boolean,
|
|
831
|
+
// Optionally:
|
|
832
|
+
nextOffset?: number,
|
|
833
|
+
}
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
### Backend Mapping
|
|
837
|
+
|
|
838
|
+
Map MCP tools to existing Convex functions:
|
|
839
|
+
|
|
840
|
+
| MCP Tool | Convex Function |
|
|
841
|
+
|----------|-----------------|
|
|
842
|
+
| `l4yercak3_events_list` | `eventsOntology.getEvents` |
|
|
843
|
+
| `l4yercak3_crm_list_contacts` | `crmOntology.getContacts` |
|
|
844
|
+
| `l4yercak3_forms_get_responses` | `formsOntology.getFormResponses` |
|
|
845
|
+
|
|
846
|
+
Reference the existing HTTP API routes in `convex/http.ts` and the ontology files for the correct query/mutation signatures.
|
|
847
|
+
|
|
848
|
+
---
|
|
849
|
+
|
|
850
|
+
## Testing Checklist
|
|
851
|
+
|
|
852
|
+
For each new MCP tool:
|
|
853
|
+
|
|
854
|
+
- [ ] Tool appears in `l4yercak3_get_capabilities` output
|
|
855
|
+
- [ ] Tool works without organizationId (uses current org)
|
|
856
|
+
- [ ] Tool works with explicit organizationId
|
|
857
|
+
- [ ] Tool returns proper error for unauthenticated requests
|
|
858
|
+
- [ ] Tool returns proper error for unauthorized org access
|
|
859
|
+
- [ ] Pagination works correctly (limit, offset, hasMore)
|
|
860
|
+
- [ ] Search/filter parameters work as expected
|
|
861
|
+
- [ ] Response matches documented schema
|
|
862
|
+
- [ ] Tool is usable by Claude Code to build mobile features
|
|
863
|
+
|
|
864
|
+
---
|
|
865
|
+
|
|
866
|
+
## File Locations
|
|
867
|
+
|
|
868
|
+
| Component | Path |
|
|
869
|
+
|-----------|------|
|
|
870
|
+
| MCP Server Entry | `packages/cli/src/mcp/server.ts` |
|
|
871
|
+
| Tool Definitions | `packages/cli/src/mcp/tools/` |
|
|
872
|
+
| Convex HTTP Routes | `convex/http.ts` |
|
|
873
|
+
| Ontology Files | `convex/*Ontology.ts` |
|
|
874
|
+
| API v1 Routes | `convex/api/v1/` |
|
|
875
|
+
| Schema Definitions | `convex/schema/` |
|
|
876
|
+
|
|
877
|
+
---
|
|
878
|
+
|
|
879
|
+
## Questions?
|
|
880
|
+
|
|
881
|
+
Contact the mobile app development team or refer to the existing MCP tool implementations for patterns and examples.
|
|
882
|
+
|
|
883
|
+
---
|
|
884
|
+
|
|
885
|
+
---
|
|
886
|
+
|
|
887
|
+
## Priority 0: AI Agent & Chat System (HIGHEST PRIORITY)
|
|
888
|
+
|
|
889
|
+
This is the **killer feature** for mobile. Users should be able to chat with the AI assistant directly from their phone, execute business tasks via natural language, and approve/reject tool executions on the go.
|
|
890
|
+
|
|
891
|
+
### Architecture Overview
|
|
892
|
+
|
|
893
|
+
The L4YERCAK3 AI system consists of:
|
|
894
|
+
|
|
895
|
+
1. **AI Conversations** - Chat sessions between user and AI assistant
|
|
896
|
+
2. **AI Messages** - Individual messages in conversations
|
|
897
|
+
3. **AI Tool Registry** - 40+ tools the AI can execute (CRM, Events, Forms, Projects, etc.)
|
|
898
|
+
4. **AI Tool Executions** - Human-in-the-loop approval workflow for tool calls
|
|
899
|
+
5. **AI Work Items** - Preview/approve workflow for batch operations
|
|
900
|
+
6. **AI Settings** - Per-org model selection, budgets, approval modes
|
|
901
|
+
|
|
902
|
+
### 0.1 Conversation Management
|
|
903
|
+
|
|
904
|
+
```typescript
|
|
905
|
+
// l4yercak3_ai_create_conversation
|
|
906
|
+
{
|
|
907
|
+
name: "l4yercak3_ai_create_conversation",
|
|
908
|
+
description: "Create a new AI conversation session.",
|
|
909
|
+
parameters: {},
|
|
910
|
+
returns: {
|
|
911
|
+
conversationId: string,
|
|
912
|
+
createdAt: string,
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// l4yercak3_ai_list_conversations
|
|
917
|
+
{
|
|
918
|
+
name: "l4yercak3_ai_list_conversations",
|
|
919
|
+
description: "List AI conversations for the current user.",
|
|
920
|
+
parameters: {
|
|
921
|
+
status?: "active" | "archived",
|
|
922
|
+
limit?: number,
|
|
923
|
+
offset?: number,
|
|
924
|
+
},
|
|
925
|
+
returns: {
|
|
926
|
+
conversations: Array<{
|
|
927
|
+
id: string,
|
|
928
|
+
title: string | null,
|
|
929
|
+
status: string,
|
|
930
|
+
modelName: string | null,
|
|
931
|
+
messageCount: number,
|
|
932
|
+
createdAt: string,
|
|
933
|
+
updatedAt: string,
|
|
934
|
+
}>,
|
|
935
|
+
total: number,
|
|
936
|
+
hasMore: boolean,
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
// l4yercak3_ai_get_conversation
|
|
941
|
+
{
|
|
942
|
+
name: "l4yercak3_ai_get_conversation",
|
|
943
|
+
description: "Get a conversation with its messages.",
|
|
944
|
+
parameters: {
|
|
945
|
+
conversationId: string,
|
|
946
|
+
messageLimit?: number, // Default: 50
|
|
947
|
+
messageOffset?: number,
|
|
948
|
+
},
|
|
949
|
+
returns: {
|
|
950
|
+
conversation: {
|
|
951
|
+
id: string,
|
|
952
|
+
title: string | null,
|
|
953
|
+
status: string,
|
|
954
|
+
modelId: string | null,
|
|
955
|
+
modelName: string | null,
|
|
956
|
+
messageCount: number,
|
|
957
|
+
createdAt: string,
|
|
958
|
+
updatedAt: string,
|
|
959
|
+
},
|
|
960
|
+
messages: Array<{
|
|
961
|
+
id: string,
|
|
962
|
+
role: "system" | "user" | "assistant" | "tool",
|
|
963
|
+
content: string,
|
|
964
|
+
modelId: string | null,
|
|
965
|
+
toolCalls: Array<{
|
|
966
|
+
id: string,
|
|
967
|
+
name: string,
|
|
968
|
+
arguments: object,
|
|
969
|
+
result: any | null,
|
|
970
|
+
status: "success" | "failed",
|
|
971
|
+
error: string | null,
|
|
972
|
+
}> | null,
|
|
973
|
+
timestamp: string,
|
|
974
|
+
}>,
|
|
975
|
+
hasMoreMessages: boolean,
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
// l4yercak3_ai_archive_conversation
|
|
980
|
+
{
|
|
981
|
+
name: "l4yercak3_ai_archive_conversation",
|
|
982
|
+
description: "Archive a conversation (soft delete).",
|
|
983
|
+
parameters: {
|
|
984
|
+
conversationId: string,
|
|
985
|
+
},
|
|
986
|
+
returns: {
|
|
987
|
+
success: boolean,
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
```
|
|
991
|
+
|
|
992
|
+
### 0.2 Chat Messaging (Core Feature)
|
|
993
|
+
|
|
994
|
+
```typescript
|
|
995
|
+
// l4yercak3_ai_send_message
|
|
996
|
+
{
|
|
997
|
+
name: "l4yercak3_ai_send_message",
|
|
998
|
+
description: "Send a message to the AI assistant and get a response. This is the main chat endpoint. The AI may propose tool executions that require approval.",
|
|
999
|
+
parameters: {
|
|
1000
|
+
conversationId?: string, // If omitted, creates new conversation
|
|
1001
|
+
message: string, // User's message
|
|
1002
|
+
selectedModel?: string, // Override model (e.g., "anthropic/claude-3-5-sonnet")
|
|
1003
|
+
attachments?: Array<{ // For multimodal (images, files)
|
|
1004
|
+
type: "image" | "file",
|
|
1005
|
+
url: string,
|
|
1006
|
+
mimeType: string,
|
|
1007
|
+
fileName?: string,
|
|
1008
|
+
}>,
|
|
1009
|
+
},
|
|
1010
|
+
returns: {
|
|
1011
|
+
conversationId: string,
|
|
1012
|
+
message: string, // AI's response
|
|
1013
|
+
toolCalls: Array<{
|
|
1014
|
+
id: string,
|
|
1015
|
+
name: string,
|
|
1016
|
+
arguments: object,
|
|
1017
|
+
result: any | null,
|
|
1018
|
+
status: "success" | "failed" | "pending_approval",
|
|
1019
|
+
error: string | null,
|
|
1020
|
+
}>,
|
|
1021
|
+
usage: {
|
|
1022
|
+
prompt_tokens: number,
|
|
1023
|
+
completion_tokens: number,
|
|
1024
|
+
total_tokens: number,
|
|
1025
|
+
},
|
|
1026
|
+
cost: number, // Cost in USD
|
|
1027
|
+
pendingApprovals: number, // Number of tool executions awaiting approval
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// l4yercak3_ai_stream_message (FUTURE - for real-time streaming)
|
|
1032
|
+
{
|
|
1033
|
+
name: "l4yercak3_ai_stream_message",
|
|
1034
|
+
description: "Send a message with streaming response. Returns a stream ID to poll for chunks.",
|
|
1035
|
+
parameters: {
|
|
1036
|
+
conversationId?: string,
|
|
1037
|
+
message: string,
|
|
1038
|
+
selectedModel?: string,
|
|
1039
|
+
},
|
|
1040
|
+
returns: {
|
|
1041
|
+
streamId: string,
|
|
1042
|
+
conversationId: string,
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// l4yercak3_ai_get_stream_chunk (FUTURE)
|
|
1047
|
+
{
|
|
1048
|
+
name: "l4yercak3_ai_get_stream_chunk",
|
|
1049
|
+
description: "Get the next chunk of a streaming response.",
|
|
1050
|
+
parameters: {
|
|
1051
|
+
streamId: string,
|
|
1052
|
+
},
|
|
1053
|
+
returns: {
|
|
1054
|
+
chunk: string | null,
|
|
1055
|
+
isComplete: boolean,
|
|
1056
|
+
toolCalls: Array<...> | null, // Populated when complete
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
```
|
|
1060
|
+
|
|
1061
|
+
### 0.3 Tool Execution Approval (Human-in-the-Loop)
|
|
1062
|
+
|
|
1063
|
+
```typescript
|
|
1064
|
+
// l4yercak3_ai_list_pending_approvals
|
|
1065
|
+
{
|
|
1066
|
+
name: "l4yercak3_ai_list_pending_approvals",
|
|
1067
|
+
description: "Get all tool executions awaiting user approval.",
|
|
1068
|
+
parameters: {
|
|
1069
|
+
conversationId?: string, // Filter to specific conversation
|
|
1070
|
+
limit?: number,
|
|
1071
|
+
offset?: number,
|
|
1072
|
+
},
|
|
1073
|
+
returns: {
|
|
1074
|
+
pendingApprovals: Array<{
|
|
1075
|
+
id: string,
|
|
1076
|
+
conversationId: string,
|
|
1077
|
+
toolName: string,
|
|
1078
|
+
parameters: object,
|
|
1079
|
+
proposalMessage: string, // AI's explanation of what it wants to do
|
|
1080
|
+
status: "proposed",
|
|
1081
|
+
createdAt: string,
|
|
1082
|
+
}>,
|
|
1083
|
+
total: number,
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
// l4yercak3_ai_approve_tool
|
|
1088
|
+
{
|
|
1089
|
+
name: "l4yercak3_ai_approve_tool",
|
|
1090
|
+
description: "Approve a proposed tool execution. The tool will execute and results will be fed back to the AI.",
|
|
1091
|
+
parameters: {
|
|
1092
|
+
executionId: string,
|
|
1093
|
+
approvalType: "approve" | "approve_always", // approve_always = don't ask again for this tool
|
|
1094
|
+
},
|
|
1095
|
+
returns: {
|
|
1096
|
+
success: boolean,
|
|
1097
|
+
result: any, // Tool execution result
|
|
1098
|
+
error: string | null,
|
|
1099
|
+
aiResponse: string | null, // AI's follow-up response after seeing result
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
// l4yercak3_ai_reject_tool
|
|
1104
|
+
{
|
|
1105
|
+
name: "l4yercak3_ai_reject_tool",
|
|
1106
|
+
description: "Reject a proposed tool execution. Optionally provide feedback to the AI.",
|
|
1107
|
+
parameters: {
|
|
1108
|
+
executionId: string,
|
|
1109
|
+
feedback?: string, // Optional: tell AI why you rejected
|
|
1110
|
+
},
|
|
1111
|
+
returns: {
|
|
1112
|
+
success: boolean,
|
|
1113
|
+
aiResponse: string | null, // AI's response to rejection/feedback
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
// l4yercak3_ai_cancel_tool
|
|
1118
|
+
{
|
|
1119
|
+
name: "l4yercak3_ai_cancel_tool",
|
|
1120
|
+
description: "Cancel/dismiss a proposed tool execution without feedback to AI.",
|
|
1121
|
+
parameters: {
|
|
1122
|
+
executionId: string,
|
|
1123
|
+
},
|
|
1124
|
+
returns: {
|
|
1125
|
+
success: boolean,
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
```
|
|
1129
|
+
|
|
1130
|
+
### 0.4 Work Items (Batch Operations)
|
|
1131
|
+
|
|
1132
|
+
```typescript
|
|
1133
|
+
// l4yercak3_ai_list_work_items
|
|
1134
|
+
{
|
|
1135
|
+
name: "l4yercak3_ai_list_work_items",
|
|
1136
|
+
description: "Get AI work items (batch operations) awaiting approval or in progress.",
|
|
1137
|
+
parameters: {
|
|
1138
|
+
status?: "preview" | "approved" | "executing" | "completed" | "failed" | "cancelled",
|
|
1139
|
+
conversationId?: string,
|
|
1140
|
+
limit?: number,
|
|
1141
|
+
offset?: number,
|
|
1142
|
+
},
|
|
1143
|
+
returns: {
|
|
1144
|
+
workItems: Array<{
|
|
1145
|
+
id: string,
|
|
1146
|
+
type: string, // "crm_create_organization", "contact_sync", etc.
|
|
1147
|
+
name: string, // User-friendly name
|
|
1148
|
+
status: string,
|
|
1149
|
+
previewData: Array<any> | null, // What will happen (for preview status)
|
|
1150
|
+
results: any | null, // What happened (for completed status)
|
|
1151
|
+
progress: {
|
|
1152
|
+
total: number,
|
|
1153
|
+
completed: number,
|
|
1154
|
+
failed: number,
|
|
1155
|
+
} | null,
|
|
1156
|
+
createdAt: string,
|
|
1157
|
+
completedAt: string | null,
|
|
1158
|
+
}>,
|
|
1159
|
+
total: number,
|
|
1160
|
+
hasMore: boolean,
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
// l4yercak3_ai_approve_work_item
|
|
1165
|
+
{
|
|
1166
|
+
name: "l4yercak3_ai_approve_work_item",
|
|
1167
|
+
description: "Approve a work item to execute the batch operation.",
|
|
1168
|
+
parameters: {
|
|
1169
|
+
workItemId: string,
|
|
1170
|
+
},
|
|
1171
|
+
returns: {
|
|
1172
|
+
success: boolean,
|
|
1173
|
+
status: string, // New status after approval
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
// l4yercak3_ai_cancel_work_item
|
|
1178
|
+
{
|
|
1179
|
+
name: "l4yercak3_ai_cancel_work_item",
|
|
1180
|
+
description: "Cancel a work item.",
|
|
1181
|
+
parameters: {
|
|
1182
|
+
workItemId: string,
|
|
1183
|
+
},
|
|
1184
|
+
returns: {
|
|
1185
|
+
success: boolean,
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
```
|
|
1189
|
+
|
|
1190
|
+
### 0.5 AI Settings & Models
|
|
1191
|
+
|
|
1192
|
+
```typescript
|
|
1193
|
+
// l4yercak3_ai_get_settings
|
|
1194
|
+
{
|
|
1195
|
+
name: "l4yercak3_ai_get_settings",
|
|
1196
|
+
description: "Get AI settings for the current organization.",
|
|
1197
|
+
parameters: {},
|
|
1198
|
+
returns: {
|
|
1199
|
+
enabled: boolean,
|
|
1200
|
+
tier: "standard" | "privacy-enhanced" | "private-llm" | null,
|
|
1201
|
+
llm: {
|
|
1202
|
+
enabledModels: Array<{
|
|
1203
|
+
modelId: string,
|
|
1204
|
+
name: string,
|
|
1205
|
+
isDefault: boolean,
|
|
1206
|
+
customLabel: string | null,
|
|
1207
|
+
}>,
|
|
1208
|
+
defaultModelId: string | null,
|
|
1209
|
+
temperature: number,
|
|
1210
|
+
maxTokens: number,
|
|
1211
|
+
},
|
|
1212
|
+
budget: {
|
|
1213
|
+
monthlyBudgetUsd: number | null,
|
|
1214
|
+
currentMonthSpend: number,
|
|
1215
|
+
remainingBudget: number | null,
|
|
1216
|
+
},
|
|
1217
|
+
humanInLoopEnabled: boolean,
|
|
1218
|
+
toolApprovalMode: "all" | "dangerous" | "none",
|
|
1219
|
+
autoRecovery: {
|
|
1220
|
+
enabled: boolean,
|
|
1221
|
+
maxRetries: number,
|
|
1222
|
+
} | null,
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
// l4yercak3_ai_list_models
|
|
1227
|
+
{
|
|
1228
|
+
name: "l4yercak3_ai_list_models",
|
|
1229
|
+
description: "List available AI models the user can select.",
|
|
1230
|
+
parameters: {
|
|
1231
|
+
includeDisabled?: boolean, // Include models not enabled for org
|
|
1232
|
+
},
|
|
1233
|
+
returns: {
|
|
1234
|
+
models: Array<{
|
|
1235
|
+
modelId: string, // "anthropic/claude-3-5-sonnet"
|
|
1236
|
+
name: string, // "Claude 3.5 Sonnet"
|
|
1237
|
+
provider: string, // "anthropic"
|
|
1238
|
+
isEnabled: boolean, // Enabled for this org
|
|
1239
|
+
isDefault: boolean, // Is org's default model
|
|
1240
|
+
isSystemDefault: boolean, // Is platform-recommended
|
|
1241
|
+
pricing: {
|
|
1242
|
+
promptPerMToken: number,
|
|
1243
|
+
completionPerMToken: number,
|
|
1244
|
+
},
|
|
1245
|
+
capabilities: {
|
|
1246
|
+
toolCalling: boolean,
|
|
1247
|
+
multimodal: boolean,
|
|
1248
|
+
vision: boolean,
|
|
1249
|
+
},
|
|
1250
|
+
contextLength: number,
|
|
1251
|
+
}>,
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
// l4yercak3_ai_set_default_model
|
|
1256
|
+
{
|
|
1257
|
+
name: "l4yercak3_ai_set_default_model",
|
|
1258
|
+
description: "Set the default AI model for the organization.",
|
|
1259
|
+
parameters: {
|
|
1260
|
+
modelId: string,
|
|
1261
|
+
},
|
|
1262
|
+
returns: {
|
|
1263
|
+
success: boolean,
|
|
1264
|
+
model: { modelId, name, provider },
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
```
|
|
1268
|
+
|
|
1269
|
+
### 0.6 Available AI Tools Reference
|
|
1270
|
+
|
|
1271
|
+
The AI assistant has access to 40+ tools across these categories:
|
|
1272
|
+
|
|
1273
|
+
| Category | Ready Tools | Placeholder Tools |
|
|
1274
|
+
|----------|-------------|-------------------|
|
|
1275
|
+
| **Meta** | `request_feature` | - |
|
|
1276
|
+
| **OAuth** | `check_oauth_connection` | - |
|
|
1277
|
+
| **CRM** | `manage_crm`, `sync_contacts`, `send_bulk_crm_email`, `create_contact` | `search_contacts`, `update_contact`, `tag_contacts` |
|
|
1278
|
+
| **Events** | `create_event` | `list_events`, `update_event`, `register_attendee` |
|
|
1279
|
+
| **Projects** | `manage_projects` | - |
|
|
1280
|
+
| **Benefits** | `manage_benefits` | - |
|
|
1281
|
+
| **Forms** | `create_form`, `manage_forms` | `list_forms`, `publish_form`, `get_form_responses` |
|
|
1282
|
+
| **Products** | `create_product` | `list_products`, `set_product_price` |
|
|
1283
|
+
| **Payments** | - | `create_invoice`, `send_invoice`, `process_payment` |
|
|
1284
|
+
| **Tickets** | - | `create_ticket`, `update_ticket_status`, `list_tickets` |
|
|
1285
|
+
| **Workflows** | - | `create_workflow`, `enable_workflow` |
|
|
1286
|
+
| **Media** | - | `upload_media`, `search_media` |
|
|
1287
|
+
| **Templates** | - | `create_template`, `send_email_from_template` |
|
|
1288
|
+
| **Publishing** | - | `create_page`, `publish_page` |
|
|
1289
|
+
| **Checkout** | - | `create_checkout_page` |
|
|
1290
|
+
| **Certificates** | - | `generate_certificate` |
|
|
1291
|
+
| **Settings** | - | `update_organization_settings`, `configure_ai_models` |
|
|
1292
|
+
|
|
1293
|
+
**Tool Statuses:**
|
|
1294
|
+
- **ready**: Fully implemented, executes immediately (with approval if enabled)
|
|
1295
|
+
- **placeholder**: Returns tutorial steps for manual completion
|
|
1296
|
+
- **beta**: Implemented but may have limitations
|
|
1297
|
+
|
|
1298
|
+
### Mobile-Specific Considerations for AI Chat
|
|
1299
|
+
|
|
1300
|
+
1. **Push Notifications**: When AI proposes a tool execution, send push notification
|
|
1301
|
+
2. **Quick Actions**: Pre-built quick action buttons for common tasks
|
|
1302
|
+
3. **Voice Input**: Support voice-to-text for hands-free messaging
|
|
1303
|
+
4. **Offline Queue**: Queue messages when offline, sync when connected
|
|
1304
|
+
5. **Attachment Support**: Camera/photo library integration for multimodal
|
|
1305
|
+
6. **Haptic Feedback**: Vibrate on new AI response or approval request
|
|
1306
|
+
|
|
1307
|
+
---
|
|
1308
|
+
|
|
1309
|
+
**Document Version:** 1.1
|
|
1310
|
+
**Created:** 2025-01-07
|
|
1311
|
+
**Updated:** 2025-01-07
|
|
1312
|
+
**Author:** Claude Code (AI Assistant)
|
|
1313
|
+
**For:** L4YERCAK3 MCP Development Team
|
package/package.json
CHANGED
package/src/commands/spread.js
CHANGED
|
@@ -351,10 +351,33 @@ async function handleSpread() {
|
|
|
351
351
|
console.log(chalk.gray(' • Delete an existing key at https://app.l4yercak3.com?openWindow=integrations&panel=api-keys'));
|
|
352
352
|
console.log(chalk.gray(' • Upgrade your plan at https://app.l4yercak3.com?openWindow=store\n'));
|
|
353
353
|
process.exit(0);
|
|
354
|
-
} else if (error.code === '
|
|
354
|
+
} else if (error.code === 'API_KEY_ALREADY_LINKED') {
|
|
355
|
+
console.log(chalk.yellow(`\n ⚠️ ${error.message}`));
|
|
356
|
+
if (error.suggestion) {
|
|
357
|
+
console.log(chalk.gray(` ${error.suggestion}`));
|
|
358
|
+
}
|
|
359
|
+
console.log(chalk.cyan('\n Each API key can only be connected to one application.'));
|
|
360
|
+
console.log(chalk.gray(' Generate a new API key for this project.\n'));
|
|
361
|
+
|
|
362
|
+
// Offer to generate a new key
|
|
363
|
+
const { generateNew } = await inquirer.prompt([
|
|
364
|
+
{
|
|
365
|
+
type: 'confirm',
|
|
366
|
+
name: 'generateNew',
|
|
367
|
+
message: 'Generate a new API key for this project?',
|
|
368
|
+
default: true,
|
|
369
|
+
},
|
|
370
|
+
]);
|
|
371
|
+
|
|
372
|
+
if (generateNew) {
|
|
373
|
+
apiKey = await generateNewApiKey(organizationId);
|
|
374
|
+
} else {
|
|
375
|
+
process.exit(0);
|
|
376
|
+
}
|
|
377
|
+
} else if (error.code === 'SESSION_EXPIRED' || error.code === 'INVALID_SESSION') {
|
|
355
378
|
console.log(chalk.red(`\n ❌ Session expired. Please run "l4yercak3 login" again.\n`));
|
|
356
379
|
process.exit(1);
|
|
357
|
-
} else if (error.code === 'NOT_AUTHORIZED') {
|
|
380
|
+
} else if (error.code === 'NOT_AUTHORIZED' || error.code === 'UNAUTHORIZED') {
|
|
358
381
|
console.log(chalk.red(`\n ❌ You don't have permission to manage API keys for this organization.\n`));
|
|
359
382
|
process.exit(1);
|
|
360
383
|
} else {
|