@l4yercak3/cli 1.1.12 → 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 +54 -1
- 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,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool Registry
|
|
3
|
+
*
|
|
4
|
+
* Central registry for all MCP tools organized by domain.
|
|
5
|
+
* Handles tool discovery, filtering by auth context, and execution.
|
|
6
|
+
*
|
|
7
|
+
* @module mcp/registry
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { requireAuth, hasPermission } = require('../auth');
|
|
11
|
+
|
|
12
|
+
// Import tool domains
|
|
13
|
+
const coreDomain = require('./domains/core');
|
|
14
|
+
const crmDomain = require('./domains/crm');
|
|
15
|
+
const eventsDomain = require('./domains/events');
|
|
16
|
+
const formsDomain = require('./domains/forms');
|
|
17
|
+
const codegenDomain = require('./domains/codegen');
|
|
18
|
+
const applicationsDomain = require('./domains/applications');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {Object} ToolDefinition
|
|
22
|
+
* @property {string} name - Tool name (e.g., 'l4yercak3_get_capabilities')
|
|
23
|
+
* @property {string} description - Human-readable description
|
|
24
|
+
* @property {Object} inputSchema - JSON Schema for tool parameters
|
|
25
|
+
* @property {Function} handler - Async function(params, authContext) => result
|
|
26
|
+
* @property {boolean} requiresAuth - Whether auth is required
|
|
27
|
+
* @property {string[]} [requiredPermissions] - Permissions needed to use this tool
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {Object} ToolDomain
|
|
32
|
+
* @property {string} name - Domain name (e.g., 'crm')
|
|
33
|
+
* @property {string} description - Domain description
|
|
34
|
+
* @property {ToolDefinition[]} tools - Tools in this domain
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* All registered tool domains
|
|
39
|
+
* @type {ToolDomain[]}
|
|
40
|
+
*/
|
|
41
|
+
const toolDomains = [
|
|
42
|
+
coreDomain,
|
|
43
|
+
applicationsDomain,
|
|
44
|
+
crmDomain,
|
|
45
|
+
eventsDomain,
|
|
46
|
+
formsDomain,
|
|
47
|
+
codegenDomain,
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get all available tools for the current auth context
|
|
52
|
+
*
|
|
53
|
+
* @param {Object|null} authContext - Current auth context
|
|
54
|
+
* @returns {ToolDefinition[]} Available tools
|
|
55
|
+
*/
|
|
56
|
+
function getAvailableTools(authContext) {
|
|
57
|
+
const tools = [];
|
|
58
|
+
|
|
59
|
+
for (const domain of toolDomains) {
|
|
60
|
+
for (const tool of domain.tools) {
|
|
61
|
+
// Include if no auth required
|
|
62
|
+
if (!tool.requiresAuth) {
|
|
63
|
+
tools.push(tool);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Skip if auth required but not authenticated
|
|
68
|
+
if (!authContext) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check required permissions
|
|
73
|
+
if (tool.requiredPermissions && tool.requiredPermissions.length > 0) {
|
|
74
|
+
const hasAllPermissions = tool.requiredPermissions.every(perm =>
|
|
75
|
+
hasPermission(authContext, perm)
|
|
76
|
+
);
|
|
77
|
+
if (!hasAllPermissions) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
tools.push(tool);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return tools;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Find a tool by name
|
|
91
|
+
*
|
|
92
|
+
* @param {string} name - Tool name
|
|
93
|
+
* @returns {ToolDefinition|null}
|
|
94
|
+
*/
|
|
95
|
+
function findTool(name) {
|
|
96
|
+
for (const domain of toolDomains) {
|
|
97
|
+
const tool = domain.tools.find(t => t.name === name);
|
|
98
|
+
if (tool) {
|
|
99
|
+
return tool;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Execute a tool
|
|
107
|
+
*
|
|
108
|
+
* @param {string} name - Tool name
|
|
109
|
+
* @param {Object} params - Tool parameters
|
|
110
|
+
* @param {Object|null} authContext - Current auth context
|
|
111
|
+
* @returns {Promise<any>} Tool result
|
|
112
|
+
*/
|
|
113
|
+
async function executeTool(name, params, authContext) {
|
|
114
|
+
const tool = findTool(name);
|
|
115
|
+
|
|
116
|
+
if (!tool) {
|
|
117
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Check auth requirements
|
|
121
|
+
if (tool.requiresAuth) {
|
|
122
|
+
requireAuth(authContext);
|
|
123
|
+
|
|
124
|
+
// Check permissions
|
|
125
|
+
if (tool.requiredPermissions && tool.requiredPermissions.length > 0) {
|
|
126
|
+
for (const perm of tool.requiredPermissions) {
|
|
127
|
+
if (!hasPermission(authContext, perm)) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
`Permission denied: ${perm} required for tool ${name}`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Execute the tool
|
|
137
|
+
try {
|
|
138
|
+
return await tool.handler(params, authContext);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
// Re-throw with context
|
|
141
|
+
const enhancedError = new Error(`Tool ${name} failed: ${error.message}`);
|
|
142
|
+
enhancedError.toolName = name;
|
|
143
|
+
enhancedError.originalError = error;
|
|
144
|
+
throw enhancedError;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get all domains (for documentation/discovery)
|
|
150
|
+
*
|
|
151
|
+
* @returns {ToolDomain[]}
|
|
152
|
+
*/
|
|
153
|
+
function getDomains() {
|
|
154
|
+
return toolDomains;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
module.exports = {
|
|
158
|
+
getAvailableTools,
|
|
159
|
+
findTool,
|
|
160
|
+
executeTool,
|
|
161
|
+
getDomains,
|
|
162
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L4YERCAK3 MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Exposes L4YERCAK3 backend capabilities to Claude Code via MCP protocol.
|
|
5
|
+
* This allows Claude Code to discover and use L4YERCAK3 features to help
|
|
6
|
+
* users integrate their projects.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* - Users add via: claude mcp add l4yercak3 -- npx l4yercak3 mcp-server
|
|
10
|
+
* - Reads auth from ~/.l4yercak3/config.json (created by l4yercak3 login)
|
|
11
|
+
*
|
|
12
|
+
* @module mcp/server
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
|
|
16
|
+
const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
17
|
+
const {
|
|
18
|
+
CallToolRequestSchema,
|
|
19
|
+
ListToolsRequestSchema,
|
|
20
|
+
} = require('@modelcontextprotocol/sdk/types.js');
|
|
21
|
+
|
|
22
|
+
const { getAuthContext } = require('./auth');
|
|
23
|
+
const { getAvailableTools, executeTool } = require('./registry');
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create and configure the MCP server
|
|
27
|
+
*/
|
|
28
|
+
function createServer() {
|
|
29
|
+
const server = new Server(
|
|
30
|
+
{
|
|
31
|
+
name: 'l4yercak3',
|
|
32
|
+
version: require('../../package.json').version,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
capabilities: {
|
|
36
|
+
tools: {},
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// Handle ListTools request
|
|
42
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
43
|
+
const authContext = await getAuthContext();
|
|
44
|
+
const tools = getAvailableTools(authContext);
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
tools: tools.map(tool => ({
|
|
48
|
+
name: tool.name,
|
|
49
|
+
description: tool.description,
|
|
50
|
+
inputSchema: tool.inputSchema,
|
|
51
|
+
})),
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Handle CallTool request
|
|
56
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
57
|
+
const { name, arguments: args } = request.params;
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const authContext = await getAuthContext();
|
|
61
|
+
const result = await executeTool(name, args || {}, authContext);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: 'text',
|
|
67
|
+
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: 'text',
|
|
76
|
+
text: `Error: ${error.message}`,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
isError: true,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return server;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Start the MCP server
|
|
89
|
+
*/
|
|
90
|
+
async function startServer() {
|
|
91
|
+
const server = createServer();
|
|
92
|
+
const transport = new StdioServerTransport();
|
|
93
|
+
|
|
94
|
+
await server.connect(transport);
|
|
95
|
+
|
|
96
|
+
// Log startup to stderr (stdout is used for MCP protocol)
|
|
97
|
+
console.error('[L4YERCAK3 MCP] Server started');
|
|
98
|
+
|
|
99
|
+
// Handle graceful shutdown
|
|
100
|
+
process.on('SIGINT', async () => {
|
|
101
|
+
console.error('[L4YERCAK3 MCP] Shutting down...');
|
|
102
|
+
await server.close();
|
|
103
|
+
process.exit(0);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
process.on('SIGTERM', async () => {
|
|
107
|
+
console.error('[L4YERCAK3 MCP] Shutting down...');
|
|
108
|
+
await server.close();
|
|
109
|
+
process.exit(0);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = {
|
|
114
|
+
createServer,
|
|
115
|
+
startServer,
|
|
116
|
+
};
|