@l4yercak3/cli 1.1.11 → 1.2.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/bin/cli.js +6 -0
- package/docs/mcp_server/MCP_SERVER_ARCHITECTURE.md +1481 -0
- package/docs/mcp_server/applicationOntology.ts +817 -0
- package/docs/mcp_server/cliApplications.ts +639 -0
- package/docs/mcp_server/crmOntology.ts +1063 -0
- package/docs/mcp_server/eventOntology.ts +1183 -0
- package/docs/mcp_server/formsOntology.ts +1401 -0
- package/docs/mcp_server/ontologySchemas.ts +185 -0
- package/docs/mcp_server/schema.ts +250 -0
- package/package.json +5 -2
- package/src/commands/login.js +0 -6
- package/src/commands/mcp-server.js +32 -0
- package/src/commands/spread.js +57 -4
- package/src/mcp/auth.js +127 -0
- package/src/mcp/registry/domains/applications.js +516 -0
- package/src/mcp/registry/domains/codegen.js +894 -0
- package/src/mcp/registry/domains/core.js +326 -0
- package/src/mcp/registry/domains/crm.js +591 -0
- package/src/mcp/registry/domains/events.js +649 -0
- package/src/mcp/registry/domains/forms.js +696 -0
- package/src/mcp/registry/index.js +162 -0
- package/src/mcp/server.js +116 -0
|
@@ -0,0 +1,1481 @@
|
|
|
1
|
+
# L4YERCAK3 MCP Server Architecture
|
|
2
|
+
|
|
3
|
+
> Comprehensive documentation for the L4YERCAK3 MCP (Model Context Protocol) server that exposes all backend capabilities to Claude Code and other MCP-compatible AI assistants.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Overview](#overview)
|
|
8
|
+
2. [Architecture](#architecture)
|
|
9
|
+
3. [Authentication](#authentication)
|
|
10
|
+
4. [Tool Registry Pattern](#tool-registry-pattern)
|
|
11
|
+
5. [Phase 1: Core Infrastructure](#phase-1-core-infrastructure)
|
|
12
|
+
6. [Phase 2: CRM & Contacts](#phase-2-crm--contacts)
|
|
13
|
+
7. [Phase 3: Invoicing & Payments](#phase-3-invoicing--payments)
|
|
14
|
+
8. [Phase 4: Events, Forms & Workflows](#phase-4-events-forms--workflows)
|
|
15
|
+
9. [Phase 5: Code Generation & Scaffolding](#phase-5-code-generation--scaffolding)
|
|
16
|
+
10. [Phase 6: Advanced Capabilities](#phase-6-advanced-capabilities)
|
|
17
|
+
11. [Extension Pattern](#extension-pattern)
|
|
18
|
+
12. [Testing Strategy](#testing-strategy)
|
|
19
|
+
13. [Deployment](#deployment)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Overview
|
|
24
|
+
|
|
25
|
+
### The Problem
|
|
26
|
+
|
|
27
|
+
Users want to integrate L4YERCAK3 capabilities into their projects, but:
|
|
28
|
+
- They don't know our system yet
|
|
29
|
+
- Every project is different (different frameworks, databases, patterns)
|
|
30
|
+
- Traditional CLI flows can't handle the variety of use cases
|
|
31
|
+
- We can't anticipate every integration scenario
|
|
32
|
+
|
|
33
|
+
### The Solution
|
|
34
|
+
|
|
35
|
+
Expose L4YERCAK3's capabilities via MCP so that Claude Code (which already understands the user's project) can:
|
|
36
|
+
1. **Discover** what L4YERCAK3 offers
|
|
37
|
+
2. **Understand** how to map it to the user's project
|
|
38
|
+
3. **Execute** the integration using our tools
|
|
39
|
+
4. **Maintain** the integration over time
|
|
40
|
+
|
|
41
|
+
### Key Insight
|
|
42
|
+
|
|
43
|
+
Users running our CLI are likely already using Claude Code. Instead of building another AI layer, we **leverage Claude Code's existing capabilities** and just provide the tools it needs to work with L4YERCAK3.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Architecture
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
51
|
+
│ Claude Code │
|
|
52
|
+
│ │
|
|
53
|
+
│ • Understands user's codebase (can read/write files) │
|
|
54
|
+
│ • Natural language interface │
|
|
55
|
+
│ • Reasoning and planning capabilities │
|
|
56
|
+
│ • User's choice of Claude model │
|
|
57
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
58
|
+
│
|
|
59
|
+
│ MCP Protocol (stdio/SSE)
|
|
60
|
+
▼
|
|
61
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
62
|
+
│ L4YERCAK3 MCP Server │
|
|
63
|
+
│ │
|
|
64
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
65
|
+
│ │ Auth │ │ Tool │ │ Response │ │
|
|
66
|
+
│ │ Layer │ │ Registry │ │ Formatter │ │
|
|
67
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
68
|
+
│ │
|
|
69
|
+
│ Tools organized by domain: │
|
|
70
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
71
|
+
│ │ Core │ │ CRM │ │ Invoice │ │ Events │ │
|
|
72
|
+
│ │ Tools │ │ Tools │ │ Tools │ │ Tools │ │
|
|
73
|
+
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
74
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
75
|
+
│ │ Forms │ │ Workflow │ │ Codegen │ │ Media │ │
|
|
76
|
+
│ │ Tools │ │ Tools │ │ Tools │ │ Tools │ │
|
|
77
|
+
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
78
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
79
|
+
│
|
|
80
|
+
│ HTTPS API Calls
|
|
81
|
+
▼
|
|
82
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
83
|
+
│ L4YERCAK3 Backend (Convex) │
|
|
84
|
+
│ │
|
|
85
|
+
│ Existing infrastructure: │
|
|
86
|
+
│ • Organizations & Users │
|
|
87
|
+
│ • CRM (Contacts, Pipelines) │
|
|
88
|
+
│ • Invoicing & Payments │
|
|
89
|
+
│ • Events & Tickets │
|
|
90
|
+
│ • Forms & Workflows │
|
|
91
|
+
│ • Media Library │
|
|
92
|
+
│ • Templates │
|
|
93
|
+
│ • And more... │
|
|
94
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Installation
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Users add the MCP server to their Claude Code configuration
|
|
101
|
+
claude mcp add l4yercak3 -- npx l4yercak3 mcp-server
|
|
102
|
+
|
|
103
|
+
# Or with explicit auth
|
|
104
|
+
claude mcp add l4yercak3 -- npx l4yercak3 mcp-server --session <session-token>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Configuration File
|
|
108
|
+
|
|
109
|
+
The MCP server reads from `~/.l4yercak3/config.json` (created during `l4yercak3 login`):
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"session": {
|
|
114
|
+
"token": "cli_session_xxx",
|
|
115
|
+
"userId": "user_id",
|
|
116
|
+
"expiresAt": 1234567890
|
|
117
|
+
},
|
|
118
|
+
"currentOrganization": {
|
|
119
|
+
"id": "org_id",
|
|
120
|
+
"name": "My Org",
|
|
121
|
+
"slug": "my-org"
|
|
122
|
+
},
|
|
123
|
+
"apiKey": "sk_live_xxx"
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Authentication
|
|
130
|
+
|
|
131
|
+
### Auth Flow
|
|
132
|
+
|
|
133
|
+
1. User runs `l4yercak3 login` (existing CLI command)
|
|
134
|
+
2. OAuth flow authenticates user, stores session in `~/.l4yercak3/config.json`
|
|
135
|
+
3. MCP server reads config on startup
|
|
136
|
+
4. All tool calls include auth context automatically
|
|
137
|
+
|
|
138
|
+
### Auth Layer Implementation
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// mcp-server/auth.ts
|
|
142
|
+
|
|
143
|
+
interface AuthContext {
|
|
144
|
+
userId: string;
|
|
145
|
+
organizationId: string;
|
|
146
|
+
sessionToken: string;
|
|
147
|
+
apiKey?: string;
|
|
148
|
+
permissions: string[];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function getAuthContext(): Promise<AuthContext | null> {
|
|
152
|
+
const configPath = path.join(os.homedir(), '.l4yercak3', 'config.json');
|
|
153
|
+
|
|
154
|
+
if (!fs.existsSync(configPath)) {
|
|
155
|
+
return null; // Not authenticated
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
159
|
+
|
|
160
|
+
// Validate session is still valid
|
|
161
|
+
if (config.session.expiresAt < Date.now()) {
|
|
162
|
+
return null; // Session expired
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
userId: config.session.userId,
|
|
167
|
+
organizationId: config.currentOrganization.id,
|
|
168
|
+
sessionToken: config.session.token,
|
|
169
|
+
apiKey: config.apiKey,
|
|
170
|
+
permissions: await fetchUserPermissions(config.session.token),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Unauthenticated Tools
|
|
176
|
+
|
|
177
|
+
Some tools work without auth (for discovery):
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const PUBLIC_TOOLS = [
|
|
181
|
+
'l4yercak3_get_capabilities',
|
|
182
|
+
'l4yercak3_check_auth_status',
|
|
183
|
+
'l4yercak3_get_login_instructions',
|
|
184
|
+
];
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Tool Registry Pattern
|
|
190
|
+
|
|
191
|
+
### Why a Registry?
|
|
192
|
+
|
|
193
|
+
As we extend L4YERCAK3, we need to easily add new MCP tools. The registry pattern:
|
|
194
|
+
1. Keeps tools organized by domain
|
|
195
|
+
2. Makes it easy to add new tools
|
|
196
|
+
3. Enables conditional tool availability (based on org features/permissions)
|
|
197
|
+
4. Provides consistent error handling and logging
|
|
198
|
+
|
|
199
|
+
### Registry Structure
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// mcp-server/registry/index.ts
|
|
203
|
+
|
|
204
|
+
interface ToolDefinition {
|
|
205
|
+
name: string;
|
|
206
|
+
description: string;
|
|
207
|
+
inputSchema: JSONSchema;
|
|
208
|
+
handler: (params: unknown, auth: AuthContext) => Promise<ToolResult>;
|
|
209
|
+
requiresAuth: boolean;
|
|
210
|
+
requiredPermissions?: string[];
|
|
211
|
+
requiredFeatures?: string[]; // Org must have these features enabled
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
interface ToolDomain {
|
|
215
|
+
name: string;
|
|
216
|
+
description: string;
|
|
217
|
+
tools: ToolDefinition[];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Registry of all tool domains
|
|
221
|
+
const toolDomains: ToolDomain[] = [
|
|
222
|
+
coreDomain,
|
|
223
|
+
crmDomain,
|
|
224
|
+
invoicingDomain,
|
|
225
|
+
eventsDomain,
|
|
226
|
+
formsDomain,
|
|
227
|
+
workflowsDomain,
|
|
228
|
+
codegenDomain,
|
|
229
|
+
mediaDomain,
|
|
230
|
+
];
|
|
231
|
+
|
|
232
|
+
// Get all available tools for current auth context
|
|
233
|
+
function getAvailableTools(auth: AuthContext | null): ToolDefinition[] {
|
|
234
|
+
const tools: ToolDefinition[] = [];
|
|
235
|
+
|
|
236
|
+
for (const domain of toolDomains) {
|
|
237
|
+
for (const tool of domain.tools) {
|
|
238
|
+
// Include if no auth required, or auth is valid
|
|
239
|
+
if (!tool.requiresAuth || auth) {
|
|
240
|
+
// Check permissions
|
|
241
|
+
if (tool.requiredPermissions) {
|
|
242
|
+
if (!tool.requiredPermissions.every(p => auth?.permissions.includes(p))) {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Check org features
|
|
247
|
+
if (tool.requiredFeatures) {
|
|
248
|
+
// TODO: Check if org has these features enabled
|
|
249
|
+
}
|
|
250
|
+
tools.push(tool);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return tools;
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Adding a New Tool
|
|
260
|
+
|
|
261
|
+
When we add new backend capabilities, we add corresponding MCP tools:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
// mcp-server/registry/domains/crm.ts
|
|
265
|
+
|
|
266
|
+
export const crmDomain: ToolDomain = {
|
|
267
|
+
name: 'crm',
|
|
268
|
+
description: 'Customer Relationship Management tools',
|
|
269
|
+
tools: [
|
|
270
|
+
// Existing tools...
|
|
271
|
+
|
|
272
|
+
// NEW TOOL: Just add to the array
|
|
273
|
+
{
|
|
274
|
+
name: 'l4yercak3_crm_create_pipeline',
|
|
275
|
+
description: 'Create a new CRM pipeline for tracking deals or processes',
|
|
276
|
+
inputSchema: {
|
|
277
|
+
type: 'object',
|
|
278
|
+
properties: {
|
|
279
|
+
name: { type: 'string', description: 'Pipeline name' },
|
|
280
|
+
stages: {
|
|
281
|
+
type: 'array',
|
|
282
|
+
items: { type: 'string' },
|
|
283
|
+
description: 'List of stage names in order'
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
required: ['name', 'stages'],
|
|
287
|
+
},
|
|
288
|
+
requiresAuth: true,
|
|
289
|
+
requiredPermissions: ['manage_crm'],
|
|
290
|
+
handler: async (params, auth) => {
|
|
291
|
+
// Implementation
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
],
|
|
295
|
+
};
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Phase 1: Core Infrastructure
|
|
301
|
+
|
|
302
|
+
### Goals
|
|
303
|
+
- Basic MCP server setup
|
|
304
|
+
- Authentication integration
|
|
305
|
+
- Discovery tools
|
|
306
|
+
- Application management
|
|
307
|
+
|
|
308
|
+
### Tools
|
|
309
|
+
|
|
310
|
+
#### `l4yercak3_get_capabilities`
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
{
|
|
314
|
+
name: 'l4yercak3_get_capabilities',
|
|
315
|
+
description: `Get a list of all L4YERCAK3 capabilities and features.
|
|
316
|
+
Use this first to understand what L4YERCAK3 can do.`,
|
|
317
|
+
inputSchema: {
|
|
318
|
+
type: 'object',
|
|
319
|
+
properties: {
|
|
320
|
+
category: {
|
|
321
|
+
type: 'string',
|
|
322
|
+
enum: ['all', 'crm', 'invoicing', 'events', 'forms', 'workflows', 'media', 'codegen'],
|
|
323
|
+
description: 'Filter capabilities by category (default: all)',
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
requiresAuth: false,
|
|
328
|
+
handler: async (params) => {
|
|
329
|
+
return {
|
|
330
|
+
capabilities: [
|
|
331
|
+
{
|
|
332
|
+
name: 'CRM',
|
|
333
|
+
description: 'Contact management, organizations, pipelines, deal tracking',
|
|
334
|
+
features: ['contacts', 'organizations', 'pipelines', 'notes', 'activities'],
|
|
335
|
+
tools: ['l4yercak3_crm_*'],
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: 'Invoicing',
|
|
339
|
+
description: 'Invoice generation, payment tracking, PDF generation',
|
|
340
|
+
features: ['invoices', 'payments', 'pdf_generation', 'email_delivery'],
|
|
341
|
+
tools: ['l4yercak3_invoice_*'],
|
|
342
|
+
},
|
|
343
|
+
// ... all capabilities
|
|
344
|
+
],
|
|
345
|
+
};
|
|
346
|
+
},
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
#### `l4yercak3_check_auth_status`
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
{
|
|
354
|
+
name: 'l4yercak3_check_auth_status',
|
|
355
|
+
description: 'Check if the user is authenticated with L4YERCAK3',
|
|
356
|
+
inputSchema: { type: 'object', properties: {} },
|
|
357
|
+
requiresAuth: false,
|
|
358
|
+
handler: async (params) => {
|
|
359
|
+
const auth = await getAuthContext();
|
|
360
|
+
if (!auth) {
|
|
361
|
+
return {
|
|
362
|
+
authenticated: false,
|
|
363
|
+
message: 'Not authenticated. Run "l4yercak3 login" to authenticate.',
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
authenticated: true,
|
|
368
|
+
userId: auth.userId,
|
|
369
|
+
organizationId: auth.organizationId,
|
|
370
|
+
organizationName: auth.organizationName,
|
|
371
|
+
};
|
|
372
|
+
},
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
#### `l4yercak3_list_organizations`
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
{
|
|
380
|
+
name: 'l4yercak3_list_organizations',
|
|
381
|
+
description: 'List all organizations the user has access to',
|
|
382
|
+
inputSchema: { type: 'object', properties: {} },
|
|
383
|
+
requiresAuth: true,
|
|
384
|
+
handler: async (params, auth) => {
|
|
385
|
+
const response = await apiCall('/api/v1/auth/cli/organizations', auth);
|
|
386
|
+
return { organizations: response.organizations };
|
|
387
|
+
},
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
#### `l4yercak3_switch_organization`
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
{
|
|
395
|
+
name: 'l4yercak3_switch_organization',
|
|
396
|
+
description: 'Switch to a different organization context',
|
|
397
|
+
inputSchema: {
|
|
398
|
+
type: 'object',
|
|
399
|
+
properties: {
|
|
400
|
+
organizationId: { type: 'string', description: 'Organization ID to switch to' },
|
|
401
|
+
},
|
|
402
|
+
required: ['organizationId'],
|
|
403
|
+
},
|
|
404
|
+
requiresAuth: true,
|
|
405
|
+
handler: async (params, auth) => {
|
|
406
|
+
// Update config file with new organization
|
|
407
|
+
await updateConfig({ currentOrganization: { id: params.organizationId } });
|
|
408
|
+
return { success: true, message: `Switched to organization ${params.organizationId}` };
|
|
409
|
+
},
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
#### `l4yercak3_register_application`
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
{
|
|
417
|
+
name: 'l4yercak3_register_application',
|
|
418
|
+
description: `Register a new application with L4YERCAK3.
|
|
419
|
+
This connects your local project to the L4YERCAK3 backend.`,
|
|
420
|
+
inputSchema: {
|
|
421
|
+
type: 'object',
|
|
422
|
+
properties: {
|
|
423
|
+
name: { type: 'string', description: 'Application name' },
|
|
424
|
+
framework: {
|
|
425
|
+
type: 'string',
|
|
426
|
+
enum: ['nextjs', 'remix', 'astro', 'nuxt', 'sveltekit', 'vite', 'other'],
|
|
427
|
+
description: 'Framework being used',
|
|
428
|
+
},
|
|
429
|
+
features: {
|
|
430
|
+
type: 'array',
|
|
431
|
+
items: { type: 'string', enum: ['crm', 'invoicing', 'events', 'forms', 'checkout', 'workflows'] },
|
|
432
|
+
description: 'L4YERCAK3 features to enable',
|
|
433
|
+
},
|
|
434
|
+
databaseType: {
|
|
435
|
+
type: 'string',
|
|
436
|
+
enum: ['none', 'convex', 'supabase', 'prisma', 'drizzle', 'other'],
|
|
437
|
+
description: 'Database type in use (if any)',
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
required: ['name', 'framework', 'features'],
|
|
441
|
+
},
|
|
442
|
+
requiresAuth: true,
|
|
443
|
+
handler: async (params, auth) => {
|
|
444
|
+
const response = await apiCall('/api/v1/cli/applications', auth, {
|
|
445
|
+
method: 'POST',
|
|
446
|
+
body: params,
|
|
447
|
+
});
|
|
448
|
+
return {
|
|
449
|
+
success: true,
|
|
450
|
+
applicationId: response.id,
|
|
451
|
+
apiKey: response.apiKey,
|
|
452
|
+
message: 'Application registered successfully',
|
|
453
|
+
};
|
|
454
|
+
},
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
#### `l4yercak3_get_application`
|
|
459
|
+
|
|
460
|
+
```typescript
|
|
461
|
+
{
|
|
462
|
+
name: 'l4yercak3_get_application',
|
|
463
|
+
description: 'Get details about a registered application',
|
|
464
|
+
inputSchema: {
|
|
465
|
+
type: 'object',
|
|
466
|
+
properties: {
|
|
467
|
+
applicationId: { type: 'string', description: 'Application ID (optional, uses current if not specified)' },
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
requiresAuth: true,
|
|
471
|
+
handler: async (params, auth) => {
|
|
472
|
+
const appId = params.applicationId || await getCurrentApplicationId();
|
|
473
|
+
const response = await apiCall(`/api/v1/cli/applications/${appId}`, auth);
|
|
474
|
+
return response;
|
|
475
|
+
},
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## Phase 2: CRM & Contacts
|
|
482
|
+
|
|
483
|
+
### Goals
|
|
484
|
+
- Full CRM functionality via MCP
|
|
485
|
+
- Contact CRUD operations
|
|
486
|
+
- Pipeline management
|
|
487
|
+
- Activity tracking
|
|
488
|
+
|
|
489
|
+
### Tools
|
|
490
|
+
|
|
491
|
+
#### `l4yercak3_crm_list_contacts`
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
{
|
|
495
|
+
name: 'l4yercak3_crm_list_contacts',
|
|
496
|
+
description: 'List contacts from the CRM with optional filtering',
|
|
497
|
+
inputSchema: {
|
|
498
|
+
type: 'object',
|
|
499
|
+
properties: {
|
|
500
|
+
limit: { type: 'number', description: 'Max contacts to return (default 50)' },
|
|
501
|
+
offset: { type: 'number', description: 'Offset for pagination' },
|
|
502
|
+
search: { type: 'string', description: 'Search by name or email' },
|
|
503
|
+
status: { type: 'string', enum: ['active', 'inactive', 'all'] },
|
|
504
|
+
pipelineId: { type: 'string', description: 'Filter by pipeline' },
|
|
505
|
+
stageId: { type: 'string', description: 'Filter by pipeline stage' },
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
requiresAuth: true,
|
|
509
|
+
requiredPermissions: ['view_crm'],
|
|
510
|
+
handler: async (params, auth) => {
|
|
511
|
+
// Implementation
|
|
512
|
+
},
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
#### `l4yercak3_crm_create_contact`
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
{
|
|
520
|
+
name: 'l4yercak3_crm_create_contact',
|
|
521
|
+
description: 'Create a new contact in the CRM',
|
|
522
|
+
inputSchema: {
|
|
523
|
+
type: 'object',
|
|
524
|
+
properties: {
|
|
525
|
+
name: { type: 'string', description: 'Contact full name' },
|
|
526
|
+
email: { type: 'string', description: 'Email address' },
|
|
527
|
+
phone: { type: 'string', description: 'Phone number' },
|
|
528
|
+
company: { type: 'string', description: 'Company name' },
|
|
529
|
+
subtype: {
|
|
530
|
+
type: 'string',
|
|
531
|
+
enum: ['lead', 'prospect', 'customer', 'partner', 'other'],
|
|
532
|
+
description: 'Contact type',
|
|
533
|
+
},
|
|
534
|
+
customFields: {
|
|
535
|
+
type: 'object',
|
|
536
|
+
description: 'Additional custom fields as key-value pairs',
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
required: ['name'],
|
|
540
|
+
},
|
|
541
|
+
requiresAuth: true,
|
|
542
|
+
requiredPermissions: ['manage_crm'],
|
|
543
|
+
handler: async (params, auth) => {
|
|
544
|
+
// Implementation
|
|
545
|
+
},
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
#### `l4yercak3_crm_update_contact`
|
|
550
|
+
|
|
551
|
+
```typescript
|
|
552
|
+
{
|
|
553
|
+
name: 'l4yercak3_crm_update_contact',
|
|
554
|
+
description: 'Update an existing contact',
|
|
555
|
+
inputSchema: {
|
|
556
|
+
type: 'object',
|
|
557
|
+
properties: {
|
|
558
|
+
contactId: { type: 'string', description: 'Contact ID to update' },
|
|
559
|
+
name: { type: 'string' },
|
|
560
|
+
email: { type: 'string' },
|
|
561
|
+
phone: { type: 'string' },
|
|
562
|
+
company: { type: 'string' },
|
|
563
|
+
subtype: { type: 'string' },
|
|
564
|
+
customFields: { type: 'object' },
|
|
565
|
+
},
|
|
566
|
+
required: ['contactId'],
|
|
567
|
+
},
|
|
568
|
+
requiresAuth: true,
|
|
569
|
+
requiredPermissions: ['manage_crm'],
|
|
570
|
+
handler: async (params, auth) => {
|
|
571
|
+
// Implementation
|
|
572
|
+
},
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
#### `l4yercak3_crm_get_contact`
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
{
|
|
580
|
+
name: 'l4yercak3_crm_get_contact',
|
|
581
|
+
description: 'Get detailed information about a specific contact',
|
|
582
|
+
inputSchema: {
|
|
583
|
+
type: 'object',
|
|
584
|
+
properties: {
|
|
585
|
+
contactId: { type: 'string', description: 'Contact ID' },
|
|
586
|
+
includeActivities: { type: 'boolean', description: 'Include recent activities' },
|
|
587
|
+
includeNotes: { type: 'boolean', description: 'Include notes' },
|
|
588
|
+
},
|
|
589
|
+
required: ['contactId'],
|
|
590
|
+
},
|
|
591
|
+
requiresAuth: true,
|
|
592
|
+
requiredPermissions: ['view_crm'],
|
|
593
|
+
handler: async (params, auth) => {
|
|
594
|
+
// Implementation
|
|
595
|
+
},
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
#### `l4yercak3_crm_delete_contact`
|
|
600
|
+
|
|
601
|
+
```typescript
|
|
602
|
+
{
|
|
603
|
+
name: 'l4yercak3_crm_delete_contact',
|
|
604
|
+
description: 'Delete a contact (soft delete - can be restored)',
|
|
605
|
+
inputSchema: {
|
|
606
|
+
type: 'object',
|
|
607
|
+
properties: {
|
|
608
|
+
contactId: { type: 'string', description: 'Contact ID to delete' },
|
|
609
|
+
},
|
|
610
|
+
required: ['contactId'],
|
|
611
|
+
},
|
|
612
|
+
requiresAuth: true,
|
|
613
|
+
requiredPermissions: ['manage_crm'],
|
|
614
|
+
handler: async (params, auth) => {
|
|
615
|
+
// Implementation
|
|
616
|
+
},
|
|
617
|
+
}
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
#### `l4yercak3_crm_list_pipelines`
|
|
621
|
+
|
|
622
|
+
```typescript
|
|
623
|
+
{
|
|
624
|
+
name: 'l4yercak3_crm_list_pipelines',
|
|
625
|
+
description: 'List all CRM pipelines',
|
|
626
|
+
inputSchema: { type: 'object', properties: {} },
|
|
627
|
+
requiresAuth: true,
|
|
628
|
+
requiredPermissions: ['view_crm'],
|
|
629
|
+
handler: async (params, auth) => {
|
|
630
|
+
// Implementation
|
|
631
|
+
},
|
|
632
|
+
}
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
#### `l4yercak3_crm_create_pipeline`
|
|
636
|
+
|
|
637
|
+
```typescript
|
|
638
|
+
{
|
|
639
|
+
name: 'l4yercak3_crm_create_pipeline',
|
|
640
|
+
description: 'Create a new CRM pipeline',
|
|
641
|
+
inputSchema: {
|
|
642
|
+
type: 'object',
|
|
643
|
+
properties: {
|
|
644
|
+
name: { type: 'string', description: 'Pipeline name' },
|
|
645
|
+
description: { type: 'string', description: 'Pipeline description' },
|
|
646
|
+
stages: {
|
|
647
|
+
type: 'array',
|
|
648
|
+
items: {
|
|
649
|
+
type: 'object',
|
|
650
|
+
properties: {
|
|
651
|
+
name: { type: 'string' },
|
|
652
|
+
color: { type: 'string' },
|
|
653
|
+
},
|
|
654
|
+
required: ['name'],
|
|
655
|
+
},
|
|
656
|
+
description: 'Pipeline stages in order',
|
|
657
|
+
},
|
|
658
|
+
},
|
|
659
|
+
required: ['name', 'stages'],
|
|
660
|
+
},
|
|
661
|
+
requiresAuth: true,
|
|
662
|
+
requiredPermissions: ['manage_crm'],
|
|
663
|
+
handler: async (params, auth) => {
|
|
664
|
+
// Implementation
|
|
665
|
+
},
|
|
666
|
+
}
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
#### `l4yercak3_crm_move_contact_stage`
|
|
670
|
+
|
|
671
|
+
```typescript
|
|
672
|
+
{
|
|
673
|
+
name: 'l4yercak3_crm_move_contact_stage',
|
|
674
|
+
description: 'Move a contact to a different pipeline stage',
|
|
675
|
+
inputSchema: {
|
|
676
|
+
type: 'object',
|
|
677
|
+
properties: {
|
|
678
|
+
contactId: { type: 'string' },
|
|
679
|
+
pipelineId: { type: 'string' },
|
|
680
|
+
stageId: { type: 'string' },
|
|
681
|
+
},
|
|
682
|
+
required: ['contactId', 'pipelineId', 'stageId'],
|
|
683
|
+
},
|
|
684
|
+
requiresAuth: true,
|
|
685
|
+
requiredPermissions: ['manage_crm'],
|
|
686
|
+
handler: async (params, auth) => {
|
|
687
|
+
// Implementation
|
|
688
|
+
},
|
|
689
|
+
}
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
#### `l4yercak3_crm_add_note`
|
|
693
|
+
|
|
694
|
+
```typescript
|
|
695
|
+
{
|
|
696
|
+
name: 'l4yercak3_crm_add_note',
|
|
697
|
+
description: 'Add a note to a contact',
|
|
698
|
+
inputSchema: {
|
|
699
|
+
type: 'object',
|
|
700
|
+
properties: {
|
|
701
|
+
contactId: { type: 'string' },
|
|
702
|
+
content: { type: 'string', description: 'Note content (supports markdown)' },
|
|
703
|
+
},
|
|
704
|
+
required: ['contactId', 'content'],
|
|
705
|
+
},
|
|
706
|
+
requiresAuth: true,
|
|
707
|
+
requiredPermissions: ['manage_crm'],
|
|
708
|
+
handler: async (params, auth) => {
|
|
709
|
+
// Implementation
|
|
710
|
+
},
|
|
711
|
+
}
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
#### `l4yercak3_crm_log_activity`
|
|
715
|
+
|
|
716
|
+
```typescript
|
|
717
|
+
{
|
|
718
|
+
name: 'l4yercak3_crm_log_activity',
|
|
719
|
+
description: 'Log an activity for a contact (call, email, meeting, etc.)',
|
|
720
|
+
inputSchema: {
|
|
721
|
+
type: 'object',
|
|
722
|
+
properties: {
|
|
723
|
+
contactId: { type: 'string' },
|
|
724
|
+
type: {
|
|
725
|
+
type: 'string',
|
|
726
|
+
enum: ['call', 'email', 'meeting', 'note', 'task', 'other'],
|
|
727
|
+
},
|
|
728
|
+
summary: { type: 'string' },
|
|
729
|
+
details: { type: 'string' },
|
|
730
|
+
scheduledAt: { type: 'string', description: 'ISO datetime for scheduled activities' },
|
|
731
|
+
},
|
|
732
|
+
required: ['contactId', 'type', 'summary'],
|
|
733
|
+
},
|
|
734
|
+
requiresAuth: true,
|
|
735
|
+
requiredPermissions: ['manage_crm'],
|
|
736
|
+
handler: async (params, auth) => {
|
|
737
|
+
// Implementation
|
|
738
|
+
},
|
|
739
|
+
}
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
---
|
|
743
|
+
|
|
744
|
+
## Phase 3: Invoicing & Payments
|
|
745
|
+
|
|
746
|
+
### Goals
|
|
747
|
+
- Invoice creation and management
|
|
748
|
+
- Payment tracking
|
|
749
|
+
- PDF generation
|
|
750
|
+
- Email delivery
|
|
751
|
+
|
|
752
|
+
### Tools
|
|
753
|
+
|
|
754
|
+
#### `l4yercak3_invoice_create`
|
|
755
|
+
|
|
756
|
+
```typescript
|
|
757
|
+
{
|
|
758
|
+
name: 'l4yercak3_invoice_create',
|
|
759
|
+
description: 'Create a new invoice',
|
|
760
|
+
inputSchema: {
|
|
761
|
+
type: 'object',
|
|
762
|
+
properties: {
|
|
763
|
+
contactId: { type: 'string', description: 'Contact/customer to invoice' },
|
|
764
|
+
items: {
|
|
765
|
+
type: 'array',
|
|
766
|
+
items: {
|
|
767
|
+
type: 'object',
|
|
768
|
+
properties: {
|
|
769
|
+
description: { type: 'string' },
|
|
770
|
+
quantity: { type: 'number' },
|
|
771
|
+
unitPrice: { type: 'number', description: 'Price in cents' },
|
|
772
|
+
taxRate: { type: 'number', description: 'Tax rate as percentage' },
|
|
773
|
+
},
|
|
774
|
+
required: ['description', 'quantity', 'unitPrice'],
|
|
775
|
+
},
|
|
776
|
+
},
|
|
777
|
+
dueDate: { type: 'string', description: 'Due date (ISO format)' },
|
|
778
|
+
notes: { type: 'string', description: 'Notes to include on invoice' },
|
|
779
|
+
currency: { type: 'string', default: 'EUR' },
|
|
780
|
+
},
|
|
781
|
+
required: ['contactId', 'items'],
|
|
782
|
+
},
|
|
783
|
+
requiresAuth: true,
|
|
784
|
+
requiredPermissions: ['manage_invoices'],
|
|
785
|
+
handler: async (params, auth) => {
|
|
786
|
+
// Implementation
|
|
787
|
+
},
|
|
788
|
+
}
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
#### `l4yercak3_invoice_list`
|
|
792
|
+
|
|
793
|
+
```typescript
|
|
794
|
+
{
|
|
795
|
+
name: 'l4yercak3_invoice_list',
|
|
796
|
+
description: 'List invoices with optional filtering',
|
|
797
|
+
inputSchema: {
|
|
798
|
+
type: 'object',
|
|
799
|
+
properties: {
|
|
800
|
+
status: { type: 'string', enum: ['draft', 'sent', 'paid', 'overdue', 'cancelled'] },
|
|
801
|
+
contactId: { type: 'string' },
|
|
802
|
+
fromDate: { type: 'string' },
|
|
803
|
+
toDate: { type: 'string' },
|
|
804
|
+
limit: { type: 'number' },
|
|
805
|
+
},
|
|
806
|
+
},
|
|
807
|
+
requiresAuth: true,
|
|
808
|
+
requiredPermissions: ['view_invoices'],
|
|
809
|
+
handler: async (params, auth) => {
|
|
810
|
+
// Implementation
|
|
811
|
+
},
|
|
812
|
+
}
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
#### `l4yercak3_invoice_send`
|
|
816
|
+
|
|
817
|
+
```typescript
|
|
818
|
+
{
|
|
819
|
+
name: 'l4yercak3_invoice_send',
|
|
820
|
+
description: 'Send an invoice to the customer via email',
|
|
821
|
+
inputSchema: {
|
|
822
|
+
type: 'object',
|
|
823
|
+
properties: {
|
|
824
|
+
invoiceId: { type: 'string' },
|
|
825
|
+
emailSubject: { type: 'string', description: 'Custom email subject (optional)' },
|
|
826
|
+
emailBody: { type: 'string', description: 'Custom email body (optional)' },
|
|
827
|
+
},
|
|
828
|
+
required: ['invoiceId'],
|
|
829
|
+
},
|
|
830
|
+
requiresAuth: true,
|
|
831
|
+
requiredPermissions: ['manage_invoices'],
|
|
832
|
+
handler: async (params, auth) => {
|
|
833
|
+
// Implementation
|
|
834
|
+
},
|
|
835
|
+
}
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
#### `l4yercak3_invoice_mark_paid`
|
|
839
|
+
|
|
840
|
+
```typescript
|
|
841
|
+
{
|
|
842
|
+
name: 'l4yercak3_invoice_mark_paid',
|
|
843
|
+
description: 'Mark an invoice as paid',
|
|
844
|
+
inputSchema: {
|
|
845
|
+
type: 'object',
|
|
846
|
+
properties: {
|
|
847
|
+
invoiceId: { type: 'string' },
|
|
848
|
+
paidAt: { type: 'string', description: 'Payment date (ISO format, defaults to now)' },
|
|
849
|
+
paymentMethod: { type: 'string', enum: ['bank_transfer', 'card', 'cash', 'other'] },
|
|
850
|
+
reference: { type: 'string', description: 'Payment reference number' },
|
|
851
|
+
},
|
|
852
|
+
required: ['invoiceId'],
|
|
853
|
+
},
|
|
854
|
+
requiresAuth: true,
|
|
855
|
+
requiredPermissions: ['manage_invoices'],
|
|
856
|
+
handler: async (params, auth) => {
|
|
857
|
+
// Implementation
|
|
858
|
+
},
|
|
859
|
+
}
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
#### `l4yercak3_invoice_get_pdf`
|
|
863
|
+
|
|
864
|
+
```typescript
|
|
865
|
+
{
|
|
866
|
+
name: 'l4yercak3_invoice_get_pdf',
|
|
867
|
+
description: 'Get the PDF URL for an invoice',
|
|
868
|
+
inputSchema: {
|
|
869
|
+
type: 'object',
|
|
870
|
+
properties: {
|
|
871
|
+
invoiceId: { type: 'string' },
|
|
872
|
+
regenerate: { type: 'boolean', description: 'Force regenerate the PDF' },
|
|
873
|
+
},
|
|
874
|
+
required: ['invoiceId'],
|
|
875
|
+
},
|
|
876
|
+
requiresAuth: true,
|
|
877
|
+
requiredPermissions: ['view_invoices'],
|
|
878
|
+
handler: async (params, auth) => {
|
|
879
|
+
// Returns URL to download PDF
|
|
880
|
+
},
|
|
881
|
+
}
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
---
|
|
885
|
+
|
|
886
|
+
## Phase 4: Events, Forms & Workflows
|
|
887
|
+
|
|
888
|
+
### Goals
|
|
889
|
+
- Event management
|
|
890
|
+
- Form builder integration
|
|
891
|
+
- Workflow automation
|
|
892
|
+
|
|
893
|
+
### Events Tools
|
|
894
|
+
|
|
895
|
+
#### `l4yercak3_event_create`
|
|
896
|
+
|
|
897
|
+
```typescript
|
|
898
|
+
{
|
|
899
|
+
name: 'l4yercak3_event_create',
|
|
900
|
+
description: 'Create a new event',
|
|
901
|
+
inputSchema: {
|
|
902
|
+
type: 'object',
|
|
903
|
+
properties: {
|
|
904
|
+
name: { type: 'string' },
|
|
905
|
+
description: { type: 'string' },
|
|
906
|
+
startDate: { type: 'string' },
|
|
907
|
+
endDate: { type: 'string' },
|
|
908
|
+
location: { type: 'string' },
|
|
909
|
+
capacity: { type: 'number' },
|
|
910
|
+
ticketTypes: {
|
|
911
|
+
type: 'array',
|
|
912
|
+
items: {
|
|
913
|
+
type: 'object',
|
|
914
|
+
properties: {
|
|
915
|
+
name: { type: 'string' },
|
|
916
|
+
price: { type: 'number' },
|
|
917
|
+
quantity: { type: 'number' },
|
|
918
|
+
},
|
|
919
|
+
},
|
|
920
|
+
},
|
|
921
|
+
},
|
|
922
|
+
required: ['name', 'startDate'],
|
|
923
|
+
},
|
|
924
|
+
requiresAuth: true,
|
|
925
|
+
requiredPermissions: ['manage_events'],
|
|
926
|
+
handler: async (params, auth) => {
|
|
927
|
+
// Implementation
|
|
928
|
+
},
|
|
929
|
+
}
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
#### `l4yercak3_event_list`
|
|
933
|
+
|
|
934
|
+
```typescript
|
|
935
|
+
{
|
|
936
|
+
name: 'l4yercak3_event_list',
|
|
937
|
+
description: 'List events',
|
|
938
|
+
inputSchema: {
|
|
939
|
+
type: 'object',
|
|
940
|
+
properties: {
|
|
941
|
+
status: { type: 'string', enum: ['draft', 'published', 'cancelled', 'completed'] },
|
|
942
|
+
fromDate: { type: 'string' },
|
|
943
|
+
toDate: { type: 'string' },
|
|
944
|
+
},
|
|
945
|
+
},
|
|
946
|
+
requiresAuth: true,
|
|
947
|
+
requiredPermissions: ['view_events'],
|
|
948
|
+
handler: async (params, auth) => {
|
|
949
|
+
// Implementation
|
|
950
|
+
},
|
|
951
|
+
}
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
### Forms Tools
|
|
955
|
+
|
|
956
|
+
#### `l4yercak3_form_create`
|
|
957
|
+
|
|
958
|
+
```typescript
|
|
959
|
+
{
|
|
960
|
+
name: 'l4yercak3_form_create',
|
|
961
|
+
description: 'Create a new form',
|
|
962
|
+
inputSchema: {
|
|
963
|
+
type: 'object',
|
|
964
|
+
properties: {
|
|
965
|
+
name: { type: 'string' },
|
|
966
|
+
description: { type: 'string' },
|
|
967
|
+
fields: {
|
|
968
|
+
type: 'array',
|
|
969
|
+
items: {
|
|
970
|
+
type: 'object',
|
|
971
|
+
properties: {
|
|
972
|
+
type: { type: 'string', enum: ['text', 'email', 'number', 'select', 'checkbox', 'textarea'] },
|
|
973
|
+
label: { type: 'string' },
|
|
974
|
+
required: { type: 'boolean' },
|
|
975
|
+
options: { type: 'array', items: { type: 'string' } }, // For select fields
|
|
976
|
+
},
|
|
977
|
+
required: ['type', 'label'],
|
|
978
|
+
},
|
|
979
|
+
},
|
|
980
|
+
workflowId: { type: 'string', description: 'Workflow to trigger on submission' },
|
|
981
|
+
},
|
|
982
|
+
required: ['name', 'fields'],
|
|
983
|
+
},
|
|
984
|
+
requiresAuth: true,
|
|
985
|
+
requiredPermissions: ['manage_forms'],
|
|
986
|
+
handler: async (params, auth) => {
|
|
987
|
+
// Implementation
|
|
988
|
+
},
|
|
989
|
+
}
|
|
990
|
+
```
|
|
991
|
+
|
|
992
|
+
#### `l4yercak3_form_list_submissions`
|
|
993
|
+
|
|
994
|
+
```typescript
|
|
995
|
+
{
|
|
996
|
+
name: 'l4yercak3_form_list_submissions',
|
|
997
|
+
description: 'List form submissions',
|
|
998
|
+
inputSchema: {
|
|
999
|
+
type: 'object',
|
|
1000
|
+
properties: {
|
|
1001
|
+
formId: { type: 'string' },
|
|
1002
|
+
limit: { type: 'number' },
|
|
1003
|
+
fromDate: { type: 'string' },
|
|
1004
|
+
},
|
|
1005
|
+
required: ['formId'],
|
|
1006
|
+
},
|
|
1007
|
+
requiresAuth: true,
|
|
1008
|
+
requiredPermissions: ['view_forms'],
|
|
1009
|
+
handler: async (params, auth) => {
|
|
1010
|
+
// Implementation
|
|
1011
|
+
},
|
|
1012
|
+
}
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
### Workflows Tools
|
|
1016
|
+
|
|
1017
|
+
#### `l4yercak3_workflow_create`
|
|
1018
|
+
|
|
1019
|
+
```typescript
|
|
1020
|
+
{
|
|
1021
|
+
name: 'l4yercak3_workflow_create',
|
|
1022
|
+
description: 'Create an automated workflow',
|
|
1023
|
+
inputSchema: {
|
|
1024
|
+
type: 'object',
|
|
1025
|
+
properties: {
|
|
1026
|
+
name: { type: 'string' },
|
|
1027
|
+
trigger: {
|
|
1028
|
+
type: 'object',
|
|
1029
|
+
properties: {
|
|
1030
|
+
type: { type: 'string', enum: ['form_submission', 'contact_created', 'invoice_paid', 'manual'] },
|
|
1031
|
+
config: { type: 'object' },
|
|
1032
|
+
},
|
|
1033
|
+
required: ['type'],
|
|
1034
|
+
},
|
|
1035
|
+
actions: {
|
|
1036
|
+
type: 'array',
|
|
1037
|
+
items: {
|
|
1038
|
+
type: 'object',
|
|
1039
|
+
properties: {
|
|
1040
|
+
type: { type: 'string', enum: ['send_email', 'create_contact', 'create_invoice', 'webhook', 'delay'] },
|
|
1041
|
+
config: { type: 'object' },
|
|
1042
|
+
},
|
|
1043
|
+
required: ['type'],
|
|
1044
|
+
},
|
|
1045
|
+
},
|
|
1046
|
+
},
|
|
1047
|
+
required: ['name', 'trigger', 'actions'],
|
|
1048
|
+
},
|
|
1049
|
+
requiresAuth: true,
|
|
1050
|
+
requiredPermissions: ['manage_workflows'],
|
|
1051
|
+
handler: async (params, auth) => {
|
|
1052
|
+
// Implementation
|
|
1053
|
+
},
|
|
1054
|
+
}
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1057
|
+
#### `l4yercak3_workflow_list`
|
|
1058
|
+
|
|
1059
|
+
```typescript
|
|
1060
|
+
{
|
|
1061
|
+
name: 'l4yercak3_workflow_list',
|
|
1062
|
+
description: 'List workflows',
|
|
1063
|
+
inputSchema: {
|
|
1064
|
+
type: 'object',
|
|
1065
|
+
properties: {
|
|
1066
|
+
status: { type: 'string', enum: ['active', 'paused', 'draft'] },
|
|
1067
|
+
},
|
|
1068
|
+
},
|
|
1069
|
+
requiresAuth: true,
|
|
1070
|
+
requiredPermissions: ['view_workflows'],
|
|
1071
|
+
handler: async (params, auth) => {
|
|
1072
|
+
// Implementation
|
|
1073
|
+
},
|
|
1074
|
+
}
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
---
|
|
1078
|
+
|
|
1079
|
+
## Phase 5: Code Generation & Scaffolding
|
|
1080
|
+
|
|
1081
|
+
### Goals
|
|
1082
|
+
- Generate API clients
|
|
1083
|
+
- Generate components
|
|
1084
|
+
- Generate database schemas
|
|
1085
|
+
- Suggest model mappings
|
|
1086
|
+
|
|
1087
|
+
### Tools
|
|
1088
|
+
|
|
1089
|
+
#### `l4yercak3_codegen_api_client`
|
|
1090
|
+
|
|
1091
|
+
```typescript
|
|
1092
|
+
{
|
|
1093
|
+
name: 'l4yercak3_codegen_api_client',
|
|
1094
|
+
description: `Generate a TypeScript API client for L4YERCAK3.
|
|
1095
|
+
Returns the code as a string - Claude Code should write it to a file.`,
|
|
1096
|
+
inputSchema: {
|
|
1097
|
+
type: 'object',
|
|
1098
|
+
properties: {
|
|
1099
|
+
features: {
|
|
1100
|
+
type: 'array',
|
|
1101
|
+
items: { type: 'string', enum: ['crm', 'invoicing', 'events', 'forms', 'workflows'] },
|
|
1102
|
+
description: 'Features to include in the client',
|
|
1103
|
+
},
|
|
1104
|
+
framework: {
|
|
1105
|
+
type: 'string',
|
|
1106
|
+
enum: ['nextjs', 'remix', 'generic'],
|
|
1107
|
+
description: 'Target framework for optimizations',
|
|
1108
|
+
},
|
|
1109
|
+
},
|
|
1110
|
+
required: ['features'],
|
|
1111
|
+
},
|
|
1112
|
+
requiresAuth: true,
|
|
1113
|
+
handler: async (params, auth) => {
|
|
1114
|
+
// Generate and return code
|
|
1115
|
+
return {
|
|
1116
|
+
filename: 'src/lib/l4yercak3/client.ts',
|
|
1117
|
+
code: `// Generated L4YERCAK3 API Client\n...`,
|
|
1118
|
+
};
|
|
1119
|
+
},
|
|
1120
|
+
}
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1123
|
+
#### `l4yercak3_codegen_sync_adapter`
|
|
1124
|
+
|
|
1125
|
+
```typescript
|
|
1126
|
+
{
|
|
1127
|
+
name: 'l4yercak3_codegen_sync_adapter',
|
|
1128
|
+
description: `Generate a sync adapter to map local models to L4YERCAK3 types.
|
|
1129
|
+
Use this after analyzing the user's existing schema.`,
|
|
1130
|
+
inputSchema: {
|
|
1131
|
+
type: 'object',
|
|
1132
|
+
properties: {
|
|
1133
|
+
localModel: { type: 'string', description: 'Name of local model (e.g., "User")' },
|
|
1134
|
+
l4yercak3Type: { type: 'string', enum: ['contact', 'event', 'transaction', 'form_submission'] },
|
|
1135
|
+
fieldMappings: {
|
|
1136
|
+
type: 'array',
|
|
1137
|
+
items: {
|
|
1138
|
+
type: 'object',
|
|
1139
|
+
properties: {
|
|
1140
|
+
localField: { type: 'string' },
|
|
1141
|
+
l4yercak3Field: { type: 'string' },
|
|
1142
|
+
transform: { type: 'string', description: 'Optional transformation expression' },
|
|
1143
|
+
},
|
|
1144
|
+
required: ['localField', 'l4yercak3Field'],
|
|
1145
|
+
},
|
|
1146
|
+
},
|
|
1147
|
+
syncDirection: { type: 'string', enum: ['push', 'pull', 'bidirectional'] },
|
|
1148
|
+
},
|
|
1149
|
+
required: ['localModel', 'l4yercak3Type', 'fieldMappings'],
|
|
1150
|
+
},
|
|
1151
|
+
requiresAuth: true,
|
|
1152
|
+
handler: async (params, auth) => {
|
|
1153
|
+
return {
|
|
1154
|
+
filename: `src/lib/l4yercak3/sync/${params.localModel.toLowerCase()}-adapter.ts`,
|
|
1155
|
+
code: `// Sync adapter: ${params.localModel} → ${params.l4yercak3Type}\n...`,
|
|
1156
|
+
};
|
|
1157
|
+
},
|
|
1158
|
+
}
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
#### `l4yercak3_codegen_schema`
|
|
1162
|
+
|
|
1163
|
+
```typescript
|
|
1164
|
+
{
|
|
1165
|
+
name: 'l4yercak3_codegen_schema',
|
|
1166
|
+
description: `Generate a database schema that follows L4YERCAK3's ontology pattern.
|
|
1167
|
+
Supports Convex, Prisma, and Supabase.`,
|
|
1168
|
+
inputSchema: {
|
|
1169
|
+
type: 'object',
|
|
1170
|
+
properties: {
|
|
1171
|
+
databaseType: { type: 'string', enum: ['convex', 'prisma', 'supabase'] },
|
|
1172
|
+
features: {
|
|
1173
|
+
type: 'array',
|
|
1174
|
+
items: { type: 'string', enum: ['crm', 'invoicing', 'events', 'forms'] },
|
|
1175
|
+
},
|
|
1176
|
+
includeSync: { type: 'boolean', description: 'Include sync metadata fields' },
|
|
1177
|
+
},
|
|
1178
|
+
required: ['databaseType', 'features'],
|
|
1179
|
+
},
|
|
1180
|
+
requiresAuth: true,
|
|
1181
|
+
handler: async (params, auth) => {
|
|
1182
|
+
// Generate schema based on database type
|
|
1183
|
+
return {
|
|
1184
|
+
filename: params.databaseType === 'prisma' ? 'prisma/schema.prisma' :
|
|
1185
|
+
params.databaseType === 'convex' ? 'convex/schema.ts' :
|
|
1186
|
+
'supabase/migrations/001_initial.sql',
|
|
1187
|
+
code: `// Generated schema for ${params.databaseType}\n...`,
|
|
1188
|
+
};
|
|
1189
|
+
},
|
|
1190
|
+
}
|
|
1191
|
+
```
|
|
1192
|
+
|
|
1193
|
+
#### `l4yercak3_codegen_suggest_mappings`
|
|
1194
|
+
|
|
1195
|
+
```typescript
|
|
1196
|
+
{
|
|
1197
|
+
name: 'l4yercak3_codegen_suggest_mappings',
|
|
1198
|
+
description: `Analyze a schema and suggest mappings to L4YERCAK3 types.
|
|
1199
|
+
Provide the schema as a string (Prisma, SQL, or Convex format).`,
|
|
1200
|
+
inputSchema: {
|
|
1201
|
+
type: 'object',
|
|
1202
|
+
properties: {
|
|
1203
|
+
schema: { type: 'string', description: 'The database schema to analyze' },
|
|
1204
|
+
schemaFormat: { type: 'string', enum: ['prisma', 'sql', 'convex', 'typescript'] },
|
|
1205
|
+
},
|
|
1206
|
+
required: ['schema', 'schemaFormat'],
|
|
1207
|
+
},
|
|
1208
|
+
requiresAuth: true,
|
|
1209
|
+
handler: async (params, auth) => {
|
|
1210
|
+
// Analyze schema and return suggestions
|
|
1211
|
+
return {
|
|
1212
|
+
suggestions: [
|
|
1213
|
+
{
|
|
1214
|
+
localModel: 'User',
|
|
1215
|
+
suggestedType: 'contact',
|
|
1216
|
+
confidence: 0.9,
|
|
1217
|
+
reasoning: 'Has email, name, phone fields typical of contacts',
|
|
1218
|
+
fieldMappings: [
|
|
1219
|
+
{ localField: 'email', l4yercak3Field: 'email', confidence: 1.0 },
|
|
1220
|
+
{ localField: 'fullName', l4yercak3Field: 'name', confidence: 0.95 },
|
|
1221
|
+
],
|
|
1222
|
+
},
|
|
1223
|
+
// ... more suggestions
|
|
1224
|
+
],
|
|
1225
|
+
};
|
|
1226
|
+
},
|
|
1227
|
+
}
|
|
1228
|
+
```
|
|
1229
|
+
|
|
1230
|
+
#### `l4yercak3_codegen_component`
|
|
1231
|
+
|
|
1232
|
+
```typescript
|
|
1233
|
+
{
|
|
1234
|
+
name: 'l4yercak3_codegen_component',
|
|
1235
|
+
description: `Generate a React component that integrates with L4YERCAK3.
|
|
1236
|
+
Returns code that Claude Code should write to a file.`,
|
|
1237
|
+
inputSchema: {
|
|
1238
|
+
type: 'object',
|
|
1239
|
+
properties: {
|
|
1240
|
+
componentType: {
|
|
1241
|
+
type: 'string',
|
|
1242
|
+
enum: ['contact-list', 'contact-form', 'invoice-list', 'event-list', 'checkout-button'],
|
|
1243
|
+
},
|
|
1244
|
+
framework: { type: 'string', enum: ['nextjs', 'remix', 'react'] },
|
|
1245
|
+
styling: { type: 'string', enum: ['tailwind', 'css-modules', 'styled-components', 'none'] },
|
|
1246
|
+
},
|
|
1247
|
+
required: ['componentType'],
|
|
1248
|
+
},
|
|
1249
|
+
requiresAuth: true,
|
|
1250
|
+
handler: async (params, auth) => {
|
|
1251
|
+
return {
|
|
1252
|
+
filename: `src/components/l4yercak3/${params.componentType}.tsx`,
|
|
1253
|
+
code: `// Generated ${params.componentType} component\n...`,
|
|
1254
|
+
};
|
|
1255
|
+
},
|
|
1256
|
+
}
|
|
1257
|
+
```
|
|
1258
|
+
|
|
1259
|
+
---
|
|
1260
|
+
|
|
1261
|
+
## Phase 6: Advanced Capabilities
|
|
1262
|
+
|
|
1263
|
+
### Goals
|
|
1264
|
+
- Media management
|
|
1265
|
+
- Template management
|
|
1266
|
+
- Analytics and reporting
|
|
1267
|
+
- Webhook management
|
|
1268
|
+
|
|
1269
|
+
### Future Tools (To Be Defined)
|
|
1270
|
+
|
|
1271
|
+
- `l4yercak3_media_upload`
|
|
1272
|
+
- `l4yercak3_media_list`
|
|
1273
|
+
- `l4yercak3_template_list`
|
|
1274
|
+
- `l4yercak3_template_render`
|
|
1275
|
+
- `l4yercak3_analytics_get_metrics`
|
|
1276
|
+
- `l4yercak3_webhook_create`
|
|
1277
|
+
- `l4yercak3_webhook_list`
|
|
1278
|
+
|
|
1279
|
+
---
|
|
1280
|
+
|
|
1281
|
+
## Extension Pattern
|
|
1282
|
+
|
|
1283
|
+
### When Adding New Backend Capabilities
|
|
1284
|
+
|
|
1285
|
+
Every time we add new functionality to L4YERCAK3, follow this checklist:
|
|
1286
|
+
|
|
1287
|
+
1. **Identify the domain**: Does this belong to an existing domain (CRM, Invoicing, etc.) or need a new one?
|
|
1288
|
+
|
|
1289
|
+
2. **Define the tools**: What operations does this capability enable?
|
|
1290
|
+
- List/query operations
|
|
1291
|
+
- Create operations
|
|
1292
|
+
- Update operations
|
|
1293
|
+
- Delete operations
|
|
1294
|
+
- Special actions
|
|
1295
|
+
|
|
1296
|
+
3. **Design the schemas**: Define input/output schemas for each tool
|
|
1297
|
+
|
|
1298
|
+
4. **Implement handlers**: Connect tools to backend APIs
|
|
1299
|
+
|
|
1300
|
+
5. **Add to registry**: Add tools to appropriate domain file
|
|
1301
|
+
|
|
1302
|
+
6. **Update documentation**: Add to this document
|
|
1303
|
+
|
|
1304
|
+
7. **Test**: Write tests for new tools
|
|
1305
|
+
|
|
1306
|
+
### Example: Adding a New "Projects" Domain
|
|
1307
|
+
|
|
1308
|
+
```typescript
|
|
1309
|
+
// mcp-server/registry/domains/projects.ts
|
|
1310
|
+
|
|
1311
|
+
export const projectsDomain: ToolDomain = {
|
|
1312
|
+
name: 'projects',
|
|
1313
|
+
description: 'Project management tools',
|
|
1314
|
+
tools: [
|
|
1315
|
+
{
|
|
1316
|
+
name: 'l4yercak3_project_create',
|
|
1317
|
+
description: 'Create a new project',
|
|
1318
|
+
// ... full definition
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
name: 'l4yercak3_project_list',
|
|
1322
|
+
// ...
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
name: 'l4yercak3_project_add_member',
|
|
1326
|
+
// ...
|
|
1327
|
+
},
|
|
1328
|
+
// ... more tools
|
|
1329
|
+
],
|
|
1330
|
+
};
|
|
1331
|
+
|
|
1332
|
+
// Register in mcp-server/registry/index.ts
|
|
1333
|
+
import { projectsDomain } from './domains/projects';
|
|
1334
|
+
|
|
1335
|
+
const toolDomains: ToolDomain[] = [
|
|
1336
|
+
// ... existing domains
|
|
1337
|
+
projectsDomain, // Add new domain
|
|
1338
|
+
];
|
|
1339
|
+
```
|
|
1340
|
+
|
|
1341
|
+
---
|
|
1342
|
+
|
|
1343
|
+
## Testing Strategy
|
|
1344
|
+
|
|
1345
|
+
### Unit Tests
|
|
1346
|
+
|
|
1347
|
+
Test each tool handler in isolation:
|
|
1348
|
+
|
|
1349
|
+
```typescript
|
|
1350
|
+
describe('l4yercak3_crm_create_contact', () => {
|
|
1351
|
+
it('creates a contact with valid data', async () => {
|
|
1352
|
+
const result = await tools.l4yercak3_crm_create_contact.handler(
|
|
1353
|
+
{ name: 'John Doe', email: 'john@example.com' },
|
|
1354
|
+
mockAuthContext
|
|
1355
|
+
);
|
|
1356
|
+
expect(result.contactId).toBeDefined();
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
it('fails without required fields', async () => {
|
|
1360
|
+
await expect(
|
|
1361
|
+
tools.l4yercak3_crm_create_contact.handler({}, mockAuthContext)
|
|
1362
|
+
).rejects.toThrow();
|
|
1363
|
+
});
|
|
1364
|
+
});
|
|
1365
|
+
```
|
|
1366
|
+
|
|
1367
|
+
### Integration Tests
|
|
1368
|
+
|
|
1369
|
+
Test the full MCP protocol flow:
|
|
1370
|
+
|
|
1371
|
+
```typescript
|
|
1372
|
+
describe('MCP Server Integration', () => {
|
|
1373
|
+
it('lists tools correctly', async () => {
|
|
1374
|
+
const response = await mcpClient.listTools();
|
|
1375
|
+
expect(response.tools).toContainEqual(
|
|
1376
|
+
expect.objectContaining({ name: 'l4yercak3_get_capabilities' })
|
|
1377
|
+
);
|
|
1378
|
+
});
|
|
1379
|
+
|
|
1380
|
+
it('executes tools correctly', async () => {
|
|
1381
|
+
const response = await mcpClient.callTool('l4yercak3_get_capabilities', {});
|
|
1382
|
+
expect(response.capabilities).toBeDefined();
|
|
1383
|
+
});
|
|
1384
|
+
});
|
|
1385
|
+
```
|
|
1386
|
+
|
|
1387
|
+
### End-to-End Tests
|
|
1388
|
+
|
|
1389
|
+
Test with actual Claude Code (or mock):
|
|
1390
|
+
|
|
1391
|
+
```typescript
|
|
1392
|
+
describe('E2E Workflow', () => {
|
|
1393
|
+
it('can set up a new project', async () => {
|
|
1394
|
+
// Simulate Claude Code calling tools in sequence
|
|
1395
|
+
const auth = await mcpClient.callTool('l4yercak3_check_auth_status', {});
|
|
1396
|
+
expect(auth.authenticated).toBe(true);
|
|
1397
|
+
|
|
1398
|
+
const app = await mcpClient.callTool('l4yercak3_register_application', {
|
|
1399
|
+
name: 'Test App',
|
|
1400
|
+
framework: 'nextjs',
|
|
1401
|
+
features: ['crm'],
|
|
1402
|
+
});
|
|
1403
|
+
expect(app.success).toBe(true);
|
|
1404
|
+
|
|
1405
|
+
// ... more steps
|
|
1406
|
+
});
|
|
1407
|
+
});
|
|
1408
|
+
```
|
|
1409
|
+
|
|
1410
|
+
---
|
|
1411
|
+
|
|
1412
|
+
## Deployment
|
|
1413
|
+
|
|
1414
|
+
### Package Structure
|
|
1415
|
+
|
|
1416
|
+
```
|
|
1417
|
+
l4yercak3/
|
|
1418
|
+
├── cli/
|
|
1419
|
+
│ ├── commands/
|
|
1420
|
+
│ │ ├── login.ts
|
|
1421
|
+
│ │ ├── spread.ts
|
|
1422
|
+
│ │ └── mcp-server.ts # New command
|
|
1423
|
+
│ └── index.ts
|
|
1424
|
+
├── mcp-server/
|
|
1425
|
+
│ ├── index.ts # Server entry point
|
|
1426
|
+
│ ├── auth.ts # Auth layer
|
|
1427
|
+
│ ├── api.ts # API client
|
|
1428
|
+
│ └── registry/
|
|
1429
|
+
│ ├── index.ts # Tool registry
|
|
1430
|
+
│ └── domains/
|
|
1431
|
+
│ ├── core.ts
|
|
1432
|
+
│ ├── crm.ts
|
|
1433
|
+
│ ├── invoicing.ts
|
|
1434
|
+
│ ├── events.ts
|
|
1435
|
+
│ ├── forms.ts
|
|
1436
|
+
│ ├── workflows.ts
|
|
1437
|
+
│ └── codegen.ts
|
|
1438
|
+
└── package.json
|
|
1439
|
+
```
|
|
1440
|
+
|
|
1441
|
+
### CLI Command
|
|
1442
|
+
|
|
1443
|
+
```bash
|
|
1444
|
+
# User runs this to start the MCP server
|
|
1445
|
+
l4yercak3 mcp-server
|
|
1446
|
+
|
|
1447
|
+
# Or via npx (for claude mcp add)
|
|
1448
|
+
npx l4yercak3 mcp-server
|
|
1449
|
+
```
|
|
1450
|
+
|
|
1451
|
+
### Adding to Claude Code
|
|
1452
|
+
|
|
1453
|
+
```bash
|
|
1454
|
+
# Users add with one command
|
|
1455
|
+
claude mcp add l4yercak3 -- npx l4yercak3 mcp-server
|
|
1456
|
+
|
|
1457
|
+
# Or manually edit ~/.claude/mcp.json
|
|
1458
|
+
{
|
|
1459
|
+
"servers": {
|
|
1460
|
+
"l4yercak3": {
|
|
1461
|
+
"command": "npx",
|
|
1462
|
+
"args": ["l4yercak3", "mcp-server"]
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
```
|
|
1467
|
+
|
|
1468
|
+
---
|
|
1469
|
+
|
|
1470
|
+
## Document History
|
|
1471
|
+
|
|
1472
|
+
- **2024-01-07**: Initial creation with full phase breakdown
|
|
1473
|
+
- Future: Update as phases are implemented
|
|
1474
|
+
|
|
1475
|
+
---
|
|
1476
|
+
|
|
1477
|
+
## Related Documents
|
|
1478
|
+
|
|
1479
|
+
- [AGENT_FIRST_ARCHITECTURE.md](./AGENT_FIRST_ARCHITECTURE.md) - Overall vision
|
|
1480
|
+
- [CLI documentation](../packages/cli/README.md) - CLI usage
|
|
1481
|
+
- [API documentation](./API.md) - Backend API reference
|