@maka/maka-cli 5.1.41 → 5.1.43
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/.claude/settings.local.json +4 -1
- package/bundle/typescript/package.json +8 -2
- package/bundle/typescript/src/commands/_index.d.ts +1 -1
- package/bundle/typescript/src/commands/_index.js +1 -1
- package/bundle/typescript/src/commands/_index.js.map +1 -1
- package/bundle/typescript/src/commands/ai/_index.d.ts +2 -0
- package/bundle/typescript/src/commands/ai/_index.js +3 -0
- package/bundle/typescript/src/commands/ai/_index.js.map +1 -0
- package/bundle/typescript/src/commands/ai/ai.command.d.ts +3 -0
- package/bundle/typescript/src/commands/{ai.js → ai/ai.command.js} +9 -7
- package/bundle/typescript/src/commands/ai/ai.command.js.map +1 -0
- package/bundle/typescript/src/commands/ai/mcp.sub.cmd.js +605 -0
- package/bundle/typescript/src/commands/ai/mcp.sub.cmd.js.map +1 -0
- package/bundle/typescript/src/commands/create.js +79 -35
- package/bundle/typescript/src/commands/create.js.map +1 -1
- package/bundle/typescript/src/generators/api.js +3 -1
- package/bundle/typescript/src/generators/api.js.map +1 -1
- package/bundle/typescript/src/generators/component.js +3 -1
- package/bundle/typescript/src/generators/component.js.map +1 -1
- package/bundle/typescript/src/generators/hook.js +3 -1
- package/bundle/typescript/src/generators/hook.js.map +1 -1
- package/bundle/typescript/src/generators/kits/_index.d.ts +1 -0
- package/bundle/typescript/src/generators/kits/_index.js +1 -0
- package/bundle/typescript/src/generators/kits/_index.js.map +1 -1
- package/bundle/typescript/src/generators/kits/frames/_index.d.ts +1 -0
- package/bundle/typescript/src/generators/kits/frames/_index.js +2 -0
- package/bundle/typescript/src/generators/kits/frames/_index.js.map +1 -0
- package/bundle/typescript/src/generators/kits/frames/frames.generator.d.ts +3 -0
- package/bundle/typescript/src/generators/kits/frames/frames.generator.js +166 -0
- package/bundle/typescript/src/generators/kits/frames/frames.generator.js.map +1 -0
- package/bundle/typescript/src/generators/kits/mui/auth.mui.gen.js +3 -2
- package/bundle/typescript/src/generators/kits/mui/auth.mui.gen.js.map +1 -1
- package/bundle/typescript/src/generators/layout.js +3 -1
- package/bundle/typescript/src/generators/layout.js.map +1 -1
- package/bundle/typescript/src/generators/package.js +3 -1
- package/bundle/typescript/src/generators/package.js.map +1 -1
- package/bundle/typescript/src/generators/page.js +3 -1
- package/bundle/typescript/src/generators/page.js.map +1 -1
- package/bundle/typescript/src/templates/meteor/template/template-tests.js.jsx +2 -2
- package/bundle/typescript/src/templates/meteor/template/template-tests.js.tsx +2 -2
- package/bundle/typescript/src/templates/meteor/template/template.js.jsx +2 -2
- package/bundle/typescript/src/templates/meteor/template/template.js.tsx +2 -2
- package/bundle/typescript/src/templates/react/hook/hook.js.jsx +1 -1
- package/bundle/typescript/src/templates/react/kit/auth/service/meteor-auth-service.js.jsx +4 -2
- package/bundle/typescript/src/templates/react/kit/frames/frames-demo.css +63 -0
- package/bundle/typescript/src/templates/react/kit/frames/frames-demo.jsx +153 -0
- package/bundle/typescript/src/templates/react/kit/frames/frames-demo.tsx +164 -0
- package/bundle/typescript/src/templates/react/kit/frames/workspace-manager.css +105 -0
- package/bundle/typescript/src/templates/react/kit/frames/workspace-manager.jsx +158 -0
- package/bundle/typescript/src/templates/react/kit/frames/workspace-manager.tsx +166 -0
- package/bundle/typescript/src/templates/react/kit/mui/auth/login/basic-login-page.js.jsx +3 -1
- package/bundle/typescript/src/templates/react/kit/mui/auth/login/basic-login-page.js.tsx +3 -1
- package/bundle/typescript/src/templates/react/test/test.js.jsx +2 -2
- package/bundle/typescript/src/templates/react/test/test.js.tsx +2 -2
- package/bundle/typescript/src/tools/fsi/fsi.interfaces.d.ts +3 -0
- package/bundle/typescript/src/tools/fsi/fsi.interfaces.js +3 -1
- package/bundle/typescript/src/tools/fsi/fsi.interfaces.js.map +1 -1
- package/docs/MCP_SERVER.md +396 -0
- package/package.json +8 -2
- package/bundle/typescript/src/commands/ai.js.map +0 -1
- /package/bundle/typescript/src/commands/{ai.d.ts → ai/mcp.sub.cmd.d.ts} +0 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import './<%= fileName %>.css';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Component } from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import { WorkspaceManager, WorkspaceStore } from 'meteor/maka:maka-frames';
|
|
6
|
+
|
|
7
|
+
interface <%= className %>Props {
|
|
8
|
+
currentWorkspaceId: string;
|
|
9
|
+
allWorkspaces: any[];
|
|
10
|
+
user?: any;
|
|
11
|
+
onWorkspaceSwitch?: (workspaceId: string) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* <%= className %> Component
|
|
16
|
+
*
|
|
17
|
+
* UI component for managing workspaces in the maka-frames package.
|
|
18
|
+
* Provides controls for creating, switching, renaming, and deleting workspaces.
|
|
19
|
+
*/
|
|
20
|
+
class <%= className %>Component extends Component<<%= className %>Props> {
|
|
21
|
+
static propTypes = {
|
|
22
|
+
currentWorkspaceId: PropTypes.string.isRequired,
|
|
23
|
+
allWorkspaces: PropTypes.array.isRequired,
|
|
24
|
+
user: PropTypes.object,
|
|
25
|
+
onWorkspaceSwitch: PropTypes.func
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
handleCreateWorkspace = () => {
|
|
29
|
+
const { user, onWorkspaceSwitch } = this.props;
|
|
30
|
+
|
|
31
|
+
const workspaceName = prompt('Enter workspace name:', `Workspace ${new Date().toLocaleTimeString()}`);
|
|
32
|
+
if (!workspaceName) return;
|
|
33
|
+
|
|
34
|
+
const workspaceId = `workspace-${Date.now()}`;
|
|
35
|
+
const workspaceData = {
|
|
36
|
+
id: workspaceId,
|
|
37
|
+
name: workspaceName,
|
|
38
|
+
frames: [],
|
|
39
|
+
createdAt: new Date(),
|
|
40
|
+
updatedAt: new Date()
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Use WorkspaceManager for logged-in users, WorkspaceStore for anonymous
|
|
44
|
+
if (user) {
|
|
45
|
+
WorkspaceManager.createWorkspace(workspaceData.id, workspaceData.name)
|
|
46
|
+
.then(() => {
|
|
47
|
+
console.log('Workspace created:', workspaceData.id);
|
|
48
|
+
if (onWorkspaceSwitch) onWorkspaceSwitch(workspaceData.id);
|
|
49
|
+
})
|
|
50
|
+
.catch((error: any) => {
|
|
51
|
+
console.error('Error creating workspace:', error);
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
WorkspaceStore.setWorkspace(workspaceData);
|
|
55
|
+
if (onWorkspaceSwitch) onWorkspaceSwitch(workspaceData.id);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
handleDeleteWorkspace = (workspaceId: string) => {
|
|
60
|
+
const { user, allWorkspaces, onWorkspaceSwitch } = this.props;
|
|
61
|
+
|
|
62
|
+
const workspace = allWorkspaces.find(ws => ws.id === workspaceId);
|
|
63
|
+
if (!workspace) return;
|
|
64
|
+
|
|
65
|
+
const confirmed = confirm(`Are you sure you want to delete "${workspace.name}"?`);
|
|
66
|
+
if (!confirmed) return;
|
|
67
|
+
|
|
68
|
+
// Use WorkspaceManager for logged-in users, WorkspaceStore for anonymous
|
|
69
|
+
if (user) {
|
|
70
|
+
WorkspaceManager.deleteWorkspace(workspaceId)
|
|
71
|
+
.then(() => {
|
|
72
|
+
console.log('Workspace deleted:', workspaceId);
|
|
73
|
+
// Switch to first available workspace
|
|
74
|
+
const remainingWorkspaces = allWorkspaces.filter(ws => ws.id !== workspaceId);
|
|
75
|
+
if (remainingWorkspaces.length > 0 && onWorkspaceSwitch) {
|
|
76
|
+
onWorkspaceSwitch(remainingWorkspaces[0].id);
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
.catch((error: any) => {
|
|
80
|
+
// Handle error (e.g., last workspace can't be deleted)
|
|
81
|
+
alert(error.message || 'Cannot delete workspace');
|
|
82
|
+
console.error('Error deleting workspace:', error);
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
const success = WorkspaceStore.deleteWorkspace(workspaceId);
|
|
86
|
+
if (success) {
|
|
87
|
+
// Switch to first available workspace
|
|
88
|
+
const remainingWorkspaces = allWorkspaces.filter(ws => ws.id !== workspaceId);
|
|
89
|
+
if (remainingWorkspaces.length > 0 && onWorkspaceSwitch) {
|
|
90
|
+
onWorkspaceSwitch(remainingWorkspaces[0].id);
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
alert('Cannot delete the last workspace');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
handleRenameWorkspace = (workspaceId: string) => {
|
|
99
|
+
const { user, allWorkspaces } = this.props;
|
|
100
|
+
|
|
101
|
+
const workspace = allWorkspaces.find(ws => ws.id === workspaceId);
|
|
102
|
+
if (!workspace) return;
|
|
103
|
+
|
|
104
|
+
const newName = prompt('Enter new workspace name:', workspace.name);
|
|
105
|
+
if (!newName || newName === workspace.name) return;
|
|
106
|
+
|
|
107
|
+
// Use WorkspaceManager for logged-in users, WorkspaceStore for anonymous
|
|
108
|
+
if (user) {
|
|
109
|
+
WorkspaceManager.updateWorkspace(workspaceId, { name: newName });
|
|
110
|
+
} else {
|
|
111
|
+
const localWorkspace = WorkspaceStore.getWorkspace(workspaceId);
|
|
112
|
+
if (localWorkspace) {
|
|
113
|
+
localWorkspace.name = newName;
|
|
114
|
+
localWorkspace.updatedAt = new Date();
|
|
115
|
+
WorkspaceStore.setWorkspace(localWorkspace);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
render() {
|
|
121
|
+
const { currentWorkspaceId, allWorkspaces, onWorkspaceSwitch } = this.props;
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<div className="<%= fileName %>">
|
|
125
|
+
<div className="workspace-selector">
|
|
126
|
+
<select
|
|
127
|
+
value={currentWorkspaceId}
|
|
128
|
+
onChange={(e) => onWorkspaceSwitch && onWorkspaceSwitch(e.target.value)}
|
|
129
|
+
className="workspace-select"
|
|
130
|
+
>
|
|
131
|
+
{allWorkspaces.map(ws => (
|
|
132
|
+
<option key={ws.id} value={ws.id}>{ws.name}</option>
|
|
133
|
+
))}
|
|
134
|
+
</select>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<div className="workspace-actions">
|
|
138
|
+
<button
|
|
139
|
+
onClick={this.handleCreateWorkspace}
|
|
140
|
+
className="workspace-btn workspace-create-btn"
|
|
141
|
+
>
|
|
142
|
+
+ New Workspace
|
|
143
|
+
</button>
|
|
144
|
+
|
|
145
|
+
<button
|
|
146
|
+
onClick={() => this.handleRenameWorkspace(currentWorkspaceId)}
|
|
147
|
+
className="workspace-btn workspace-rename-btn"
|
|
148
|
+
>
|
|
149
|
+
Rename Workspace
|
|
150
|
+
</button>
|
|
151
|
+
|
|
152
|
+
{allWorkspaces.length > 1 && (
|
|
153
|
+
<button
|
|
154
|
+
onClick={() => this.handleDeleteWorkspace(currentWorkspaceId)}
|
|
155
|
+
className="workspace-btn workspace-delete-btn"
|
|
156
|
+
>
|
|
157
|
+
Delete Workspace
|
|
158
|
+
</button>
|
|
159
|
+
)}
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export { <%= className %>Component };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, { useContext, useEffect } from 'react';
|
|
2
2
|
import { Container, Paper, Typography, TextField, Button, Grid, Link } from '@mui/material';
|
|
3
|
-
import { useNavigate } from 'react-router-dom'
|
|
3
|
+
import { useNavigate } from 'react-router-dom';<% if (isSsr) { %>
|
|
4
|
+
import { AuthContext } from '/imports/startup/lib/authentication-provider';<% } else { %>
|
|
5
|
+
import { AuthContext } from '/imports/startup/client/authentication-provider';<% } %>
|
|
4
6
|
|
|
5
7
|
export const BasicLoginPage = () => {
|
|
6
8
|
const { currentUser, login } = useContext(AuthContext);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, { useContext, useEffect } from 'react';
|
|
2
2
|
import { Container, Paper, Typography, TextField, Button, Grid, Link } from '@mui/material';
|
|
3
|
-
import { useNavigate } from 'react-router-dom'
|
|
3
|
+
import { useNavigate } from 'react-router-dom';<% if (isSsr) { %>
|
|
4
|
+
import { AuthContext } from '/imports/startup/lib/authentication-provider';<% } else { %>
|
|
5
|
+
import { AuthContext } from '/imports/startup/client/authentication-provider';<% } %>
|
|
4
6
|
|
|
5
7
|
export const BasicLoginPage = () => {
|
|
6
8
|
const { currentUser, login } = useContext(AuthContext);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render } from '@testing-library/react';
|
|
2
2
|
<% if (test === 'mocha') { %>import { expect } from 'chai';<% } %>
|
|
3
3
|
|
|
4
|
-
<% if(
|
|
4
|
+
<% if(clientGraphql === 'apollo') { %>
|
|
5
5
|
import { MockedProvider } from '@apollo/react-testing';
|
|
6
6
|
import gql from 'graphql-tag';
|
|
7
7
|
const mocks = [
|
|
@@ -24,7 +24,7 @@ const { <%=className%>%> } = require('./<%= fileName %>');
|
|
|
24
24
|
describe('<<%= className %>/>', function() {
|
|
25
25
|
|
|
26
26
|
it('did render', () => {
|
|
27
|
-
<%if(
|
|
27
|
+
<%if(clientGraphql === 'apollo') { %>
|
|
28
28
|
const <%=camelCaseName%> = render(
|
|
29
29
|
<MockedProvider mocks={mocks} addTypename={false}>
|
|
30
30
|
<<%= className %>/>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render } from '@testing-library/react';
|
|
2
2
|
<% if (test === 'mocha') { %>import { expect } from 'chai';<% } %>
|
|
3
3
|
|
|
4
|
-
<% if(
|
|
4
|
+
<% if(clientGraphql === 'apollo') { %>
|
|
5
5
|
import { MockedProvider } from '@apollo/react-testing';
|
|
6
6
|
import gql from 'graphql-tag';
|
|
7
7
|
const mocks = [
|
|
@@ -24,7 +24,7 @@ const { <%=className%>%> } = require('./<%= fileName %>');
|
|
|
24
24
|
describe('<<%= className %>/>', function() {
|
|
25
25
|
|
|
26
26
|
it('did render', () => {
|
|
27
|
-
<%if(
|
|
27
|
+
<%if(clientGraphql === 'apollo') { %>
|
|
28
28
|
const <%=camelCaseName%> = render(
|
|
29
29
|
<MockedProvider mocks={mocks} addTypename={false}>
|
|
30
30
|
<<%= className %>/>
|
|
@@ -136,6 +136,8 @@ export declare enum CssEngines {
|
|
|
136
136
|
}
|
|
137
137
|
export declare enum ApiEngines {
|
|
138
138
|
REST = "rest",
|
|
139
|
+
RPC = "rpc",
|
|
140
|
+
GRAPHQL = "graphql",
|
|
139
141
|
NONE = "none"
|
|
140
142
|
}
|
|
141
143
|
export declare enum TestEngines {
|
|
@@ -164,6 +166,7 @@ export interface IEngines {
|
|
|
164
166
|
js?: JsEngines;
|
|
165
167
|
css?: CssEngines;
|
|
166
168
|
api?: ApiEngines;
|
|
169
|
+
apis?: ApiEngines[];
|
|
167
170
|
test?: TestEngines;
|
|
168
171
|
client?: ClientEngines;
|
|
169
172
|
graphql?: GraphqlEngines;
|
|
@@ -2,7 +2,7 @@ export const supportedEngines = {
|
|
|
2
2
|
html: ['html'],
|
|
3
3
|
js: ['js', 'jsx', 'ts', 'tsx'],
|
|
4
4
|
css: ['css', 'less', 'scss', 'none'],
|
|
5
|
-
api: ['rest', 'none'],
|
|
5
|
+
api: ['rest', 'rpc', 'graphql', 'none'],
|
|
6
6
|
test: ['jasmine', 'mocha', 'none'],
|
|
7
7
|
client: ['react', 'vanilla'],
|
|
8
8
|
graphql: ['apollo'],
|
|
@@ -31,6 +31,8 @@ export var CssEngines;
|
|
|
31
31
|
export var ApiEngines;
|
|
32
32
|
(function (ApiEngines) {
|
|
33
33
|
ApiEngines["REST"] = "rest";
|
|
34
|
+
ApiEngines["RPC"] = "rpc";
|
|
35
|
+
ApiEngines["GRAPHQL"] = "graphql";
|
|
34
36
|
ApiEngines["NONE"] = "none";
|
|
35
37
|
})(ApiEngines || (ApiEngines = {}));
|
|
36
38
|
export var TestEngines;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fsi.interfaces.js","sourceRoot":"","sources":["../../../../../src/tools/fsi/fsi.interfaces.ts"],"names":[],"mappings":"AAoIA,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;IAC9B,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IACpC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"fsi.interfaces.js","sourceRoot":"","sources":["../../../../../src/tools/fsi/fsi.interfaces.ts"],"names":[],"mappings":"AAoIA,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;IAC9B,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IACpC,GAAG,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC;IAClC,MAAM,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,OAAO,EAAE,CAAC,QAAQ,CAAC;IACnB,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;IAClB,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,6CAA6C;AAC7C,MAAM,CAAN,IAAY,WAEX;AAFD,WAAY,WAAW;IACrB,4BAAa,CAAA;AACf,CAAC,EAFW,WAAW,KAAX,WAAW,QAEtB;AAED,MAAM,CAAN,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,sBAAS,CAAA;IACT,wBAAW,CAAA;IACX,sBAAS,CAAA;IACT,wBAAW,CAAA;AACb,CAAC,EALW,SAAS,KAAT,SAAS,QAKpB;AAED,MAAM,CAAN,IAAY,UAKX;AALD,WAAY,UAAU;IACpB,yBAAW,CAAA;IACX,2BAAa,CAAA;IACb,2BAAa,CAAA;IACb,2BAAa,CAAA;AACf,CAAC,EALW,UAAU,KAAV,UAAU,QAKrB;AAED,MAAM,CAAN,IAAY,UAKX;AALD,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,yBAAW,CAAA;IACX,iCAAmB,CAAA;IACnB,2BAAa,CAAA;AACf,CAAC,EALW,UAAU,KAAV,UAAU,QAKrB;AAED,MAAM,CAAN,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,kCAAmB,CAAA;IACnB,8BAAe,CAAA;IACf,4BAAa,CAAA;AACf,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB;AAED,MAAM,CAAN,IAAY,aAGX;AAHD,WAAY,aAAa;IACvB,gCAAe,CAAA;IACf,oCAAmB,CAAA;AACrB,CAAC,EAHW,aAAa,KAAb,aAAa,QAGxB;AAED,MAAM,CAAN,IAAY,cAGX;AAHD,WAAY,cAAc;IACxB,+BAAa,CAAA;IACb,mCAAiB,CAAA;AACnB,CAAC,EAHW,cAAc,KAAd,cAAc,QAGzB;AAED,MAAM,CAAN,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,+BAAiB,CAAA;AACnB,CAAC,EAHW,UAAU,KAAV,UAAU,QAGrB;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,qCAAqB,CAAA;IACrB,6BAAa,CAAA;AACf,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB"}
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
# Maka CLI MCP Server
|
|
2
|
+
|
|
3
|
+
The Maka CLI includes an enhanced Model Context Protocol (MCP) server that exposes **all maka-cli capabilities** to AI agents like Claude. This allows AI assistants to discover, understand, and help you use any maka-cli command.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
Start the MCP server:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
maka ai:mcp
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The server starts on `http://localhost:3000` by default and automatically discovers all available maka-cli commands.
|
|
14
|
+
|
|
15
|
+
## Options
|
|
16
|
+
|
|
17
|
+
- `--port` - Port to listen on (default: 3000)
|
|
18
|
+
- `--host` - Host to bind to (default: localhost)
|
|
19
|
+
|
|
20
|
+
### Examples
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Start on default port
|
|
24
|
+
maka ai:mcp
|
|
25
|
+
|
|
26
|
+
# Custom port
|
|
27
|
+
maka ai:mcp --port=8080
|
|
28
|
+
|
|
29
|
+
# Bind to all network interfaces
|
|
30
|
+
maka ai:mcp --host=0.0.0.0 --port=3001
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Server Features
|
|
34
|
+
|
|
35
|
+
### Tools
|
|
36
|
+
|
|
37
|
+
The MCP server provides these tools for AI agents:
|
|
38
|
+
|
|
39
|
+
#### 1. `list-maka-commands`
|
|
40
|
+
List all available Maka CLI commands with descriptions and usage.
|
|
41
|
+
|
|
42
|
+
**Parameters:**
|
|
43
|
+
- `filter` (optional): Filter commands by name or category (e.g., "aws", "generate", "deploy")
|
|
44
|
+
|
|
45
|
+
**Example Usage:**
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"name": "list-maka-commands",
|
|
49
|
+
"arguments": {
|
|
50
|
+
"filter": "generate"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### 2. `get-command-info`
|
|
56
|
+
Get detailed information about a specific command including usage, options, examples, and description.
|
|
57
|
+
|
|
58
|
+
**Parameters:**
|
|
59
|
+
- `command` (required): Command name (e.g., "create", "generate:component", "aws:create-instance")
|
|
60
|
+
|
|
61
|
+
**Example Usage:**
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"name": "get-command-info",
|
|
65
|
+
"arguments": {
|
|
66
|
+
"command": "generate:component"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### 3. `execute-maka-command`
|
|
72
|
+
Execute Maka CLI commands with safety restrictions to prevent destructive operations.
|
|
73
|
+
|
|
74
|
+
**Parameters:**
|
|
75
|
+
- `command` (required): Full command to execute (e.g., "maka --help")
|
|
76
|
+
- `workingDirectory` (optional): Working directory for the command
|
|
77
|
+
|
|
78
|
+
**Safety Features:**
|
|
79
|
+
- Blocks destructive commands (murder, uninstall, rm, delete)
|
|
80
|
+
- 30-second timeout
|
|
81
|
+
- 10MB output buffer limit
|
|
82
|
+
|
|
83
|
+
**Example Usage:**
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"name": "execute-maka-command",
|
|
87
|
+
"arguments": {
|
|
88
|
+
"command": "maka --help"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### 4. `get-project-info`
|
|
94
|
+
Get information about the current Maka project including configuration.
|
|
95
|
+
|
|
96
|
+
**Example Usage:**
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"name": "get-project-info",
|
|
100
|
+
"arguments": {}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Resources
|
|
105
|
+
|
|
106
|
+
#### 1. `maka://commands/all`
|
|
107
|
+
Complete reference of all Maka CLI commands in JSON format.
|
|
108
|
+
|
|
109
|
+
**Format:**
|
|
110
|
+
```json
|
|
111
|
+
[
|
|
112
|
+
{
|
|
113
|
+
"name": "create",
|
|
114
|
+
"aliases": "None",
|
|
115
|
+
"shortDesc": "Create a new Meteor application",
|
|
116
|
+
"description": "...",
|
|
117
|
+
"usage": "maka create <app-name>",
|
|
118
|
+
"examples": ["maka create MyApp"],
|
|
119
|
+
"validOpts": ["..."],
|
|
120
|
+
"requiredOpts": [],
|
|
121
|
+
"experimental": false
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
#### 2. `maka://project/config`
|
|
127
|
+
Current project configuration and metadata.
|
|
128
|
+
|
|
129
|
+
#### 3. `maka://info`
|
|
130
|
+
Maka CLI version, platform, and system information.
|
|
131
|
+
|
|
132
|
+
### Prompts
|
|
133
|
+
|
|
134
|
+
Interactive conversation starters for common workflows:
|
|
135
|
+
|
|
136
|
+
#### 1. `create-component`
|
|
137
|
+
Component creation wizard with examples and best practices.
|
|
138
|
+
|
|
139
|
+
**Parameters:**
|
|
140
|
+
- `componentName` (required): Name of the component
|
|
141
|
+
- `componentType` (optional): Type (component, page, layout, template)
|
|
142
|
+
|
|
143
|
+
#### 2. `deploy-help`
|
|
144
|
+
Deployment guide for different platforms and environments.
|
|
145
|
+
|
|
146
|
+
**Parameters:**
|
|
147
|
+
- `environment` (optional): Target environment (dev, staging, production)
|
|
148
|
+
- `platform` (optional): Deployment platform (aws, docker, custom)
|
|
149
|
+
|
|
150
|
+
#### 3. `project-setup`
|
|
151
|
+
Interactive guide for setting up a new Maka project.
|
|
152
|
+
|
|
153
|
+
**Parameters:**
|
|
154
|
+
- `projectType` (optional): Project type (basic, full-stack, api)
|
|
155
|
+
|
|
156
|
+
## Protocol
|
|
157
|
+
|
|
158
|
+
The server implements the [Model Context Protocol](https://modelcontextprotocol.io) specification:
|
|
159
|
+
|
|
160
|
+
- **Transport**: Streamable HTTP (stateless mode)
|
|
161
|
+
- **Format**: Server-Sent Events (SSE)
|
|
162
|
+
- **Message Protocol**: JSON-RPC 2.0
|
|
163
|
+
- **Protocol Version**: 2024-11-05
|
|
164
|
+
|
|
165
|
+
## Endpoints
|
|
166
|
+
|
|
167
|
+
- `POST /mcp` - MCP protocol endpoint (Server-Sent Events)
|
|
168
|
+
- `GET /health` - Health check endpoint
|
|
169
|
+
|
|
170
|
+
## Testing
|
|
171
|
+
|
|
172
|
+
### Health Check
|
|
173
|
+
```bash
|
|
174
|
+
curl http://localhost:3000/health
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### List Available Tools
|
|
178
|
+
```bash
|
|
179
|
+
curl -X POST http://localhost:3000/mcp \
|
|
180
|
+
-H "Content-Type: application/json" \
|
|
181
|
+
-H "Accept: application/json, text/event-stream" \
|
|
182
|
+
-d '{
|
|
183
|
+
"jsonrpc": "2.0",
|
|
184
|
+
"id": 1,
|
|
185
|
+
"method": "tools/list",
|
|
186
|
+
"params": {}
|
|
187
|
+
}'
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Call a Tool
|
|
191
|
+
```bash
|
|
192
|
+
curl -X POST http://localhost:3000/mcp \
|
|
193
|
+
-H "Content-Type: application/json" \
|
|
194
|
+
-H "Accept: application/json, text/event-stream" \
|
|
195
|
+
-d '{
|
|
196
|
+
"jsonrpc": "2.0",
|
|
197
|
+
"id": 2,
|
|
198
|
+
"method": "tools/call",
|
|
199
|
+
"params": {
|
|
200
|
+
"name": "list-maka-commands",
|
|
201
|
+
"arguments": {
|
|
202
|
+
"filter": "aws"
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}'
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Integrating with Claude Desktop
|
|
209
|
+
|
|
210
|
+
Add this configuration to your Claude Desktop MCP settings:
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"mcpServers": {
|
|
215
|
+
"maka-cli": {
|
|
216
|
+
"command": "maka",
|
|
217
|
+
"args": ["ai:mcp", "--port=3000"],
|
|
218
|
+
"transport": "http",
|
|
219
|
+
"url": "http://localhost:3000/mcp"
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Alternatively, run the server manually and configure Claude Desktop to connect to the HTTP endpoint:
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"mcpServers": {
|
|
230
|
+
"maka-cli": {
|
|
231
|
+
"transport": "http",
|
|
232
|
+
"url": "http://localhost:3000/mcp"
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## How It Works
|
|
239
|
+
|
|
240
|
+
### Command Discovery
|
|
241
|
+
|
|
242
|
+
The MCP server automatically discovers all commands by traversing the Maka CLI command tree:
|
|
243
|
+
|
|
244
|
+
1. Starts at the root `Maka` command
|
|
245
|
+
2. Recursively explores all subcommands
|
|
246
|
+
3. Extracts metadata (name, description, usage, options, examples)
|
|
247
|
+
4. Filters out internal/hidden commands
|
|
248
|
+
5. Builds a complete command registry
|
|
249
|
+
|
|
250
|
+
This means **any new command added to maka-cli is automatically exposed** through the MCP server.
|
|
251
|
+
|
|
252
|
+
### Project Detection
|
|
253
|
+
|
|
254
|
+
The server detects if you're in a Maka project by looking for `.maka/config.json`. Project-specific information is exposed through the `get-project-info` tool and `maka://project/config` resource.
|
|
255
|
+
|
|
256
|
+
## Use Cases for AI Agents
|
|
257
|
+
|
|
258
|
+
With this MCP server, AI agents like Claude can:
|
|
259
|
+
|
|
260
|
+
1. **Discover Commands**: "What commands are available in maka-cli?"
|
|
261
|
+
2. **Get Help**: "How do I create a new component?"
|
|
262
|
+
3. **Learn Usage**: "Show me examples of the deploy command"
|
|
263
|
+
4. **Execute Commands**: "Run maka --version for me"
|
|
264
|
+
5. **Guide Workflows**: "Walk me through deploying to AWS"
|
|
265
|
+
6. **Project Context**: "What's configured in my current project?"
|
|
266
|
+
|
|
267
|
+
## Customization
|
|
268
|
+
|
|
269
|
+
### Adding Custom Tools
|
|
270
|
+
|
|
271
|
+
Edit `src/commands/ai/mcp.sub.cmd.ts` and add new tools:
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
server.tool(
|
|
275
|
+
'my-custom-tool',
|
|
276
|
+
'Description of what my tool does',
|
|
277
|
+
{
|
|
278
|
+
param1: z.string().describe('Description of parameter')
|
|
279
|
+
},
|
|
280
|
+
async ({ param1 }) => {
|
|
281
|
+
// Your tool logic here
|
|
282
|
+
return {
|
|
283
|
+
content: [
|
|
284
|
+
{
|
|
285
|
+
type: 'text',
|
|
286
|
+
text: `Result: ${param1}`
|
|
287
|
+
}
|
|
288
|
+
]
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
);
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Adding Custom Resources
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
server.resource(
|
|
298
|
+
'my-resource',
|
|
299
|
+
'maka://custom/resource',
|
|
300
|
+
{
|
|
301
|
+
mimeType: 'application/json',
|
|
302
|
+
description: 'My custom resource'
|
|
303
|
+
},
|
|
304
|
+
async () => {
|
|
305
|
+
return {
|
|
306
|
+
contents: [
|
|
307
|
+
{
|
|
308
|
+
uri: 'maka://custom/resource',
|
|
309
|
+
mimeType: 'application/json',
|
|
310
|
+
text: JSON.stringify({ data: 'value' }, null, 2)
|
|
311
|
+
}
|
|
312
|
+
]
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Adding Custom Prompts
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
server.prompt(
|
|
322
|
+
'my-workflow',
|
|
323
|
+
'Guided workflow for a specific task',
|
|
324
|
+
{
|
|
325
|
+
taskType: z.enum(['option1', 'option2']).describe('Type of task')
|
|
326
|
+
},
|
|
327
|
+
async ({ taskType }) => {
|
|
328
|
+
return {
|
|
329
|
+
messages: [
|
|
330
|
+
{
|
|
331
|
+
role: 'user',
|
|
332
|
+
content: {
|
|
333
|
+
type: 'text',
|
|
334
|
+
text: `Help me with ${taskType}`
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
role: 'assistant',
|
|
339
|
+
content: {
|
|
340
|
+
type: 'text',
|
|
341
|
+
text: `Here's how to handle ${taskType}...`
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
]
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
);
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## CORS Configuration
|
|
351
|
+
|
|
352
|
+
The server is configured with CORS enabled for all origins by default. For production:
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
app.use(cors({
|
|
356
|
+
origin: 'https://yourdomain.com', // Restrict to specific origin
|
|
357
|
+
exposedHeaders: ['Mcp-Session-Id']
|
|
358
|
+
}));
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Dependencies
|
|
362
|
+
|
|
363
|
+
- `@modelcontextprotocol/sdk` - MCP SDK
|
|
364
|
+
- `express` - HTTP server
|
|
365
|
+
- `cors` - CORS middleware
|
|
366
|
+
- `zod` - Schema validation
|
|
367
|
+
|
|
368
|
+
## Architecture
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
┌─────────────────┐
|
|
372
|
+
│ AI Agent │
|
|
373
|
+
│ (e.g. Claude) │
|
|
374
|
+
└────────┬────────┘
|
|
375
|
+
│ MCP over HTTP
|
|
376
|
+
│
|
|
377
|
+
┌────────▼────────┐
|
|
378
|
+
│ MCP Server │
|
|
379
|
+
│ (ai:mcp cmd) │
|
|
380
|
+
├─────────────────┤
|
|
381
|
+
│ • Tools │
|
|
382
|
+
│ • Resources │
|
|
383
|
+
│ • Prompts │
|
|
384
|
+
└────────┬────────┘
|
|
385
|
+
│
|
|
386
|
+
├─► Command Discovery (Maka._commands)
|
|
387
|
+
├─► Project Detection (.maka/config.json)
|
|
388
|
+
└─► Command Execution (execSync with safety)
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Resources
|
|
392
|
+
|
|
393
|
+
- [Model Context Protocol Documentation](https://modelcontextprotocol.io)
|
|
394
|
+
- [MCP SDK on GitHub](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
395
|
+
- [Claude Desktop MCP Integration](https://docs.anthropic.com/claude/docs/model-context-protocol)
|
|
396
|
+
- [Maka CLI Documentation](https://www.maka-cli.com)
|