mlgym-deploy 3.3.41 → 3.3.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/ADD_TO_CURSOR_SETTINGS.json +1 -1
- package/ADD_TO_CURSOR_SETTINGS.json.example +28 -0
- package/CHANGELOG-v3.3.42.md +707 -0
- package/Dockerfile +7 -0
- package/README.md +35 -0
- package/claude-desktop-config.json +1 -1
- package/claude-desktop-config.json.example +8 -0
- package/cursor-config.json +1 -1
- package/cursor-config.json.example +13 -0
- package/docs/CURSOR_SETUP.md +204 -0
- package/index.js +263 -5
- package/mcp.json.example +13 -0
- package/package.json +11 -3
- package/tests/README.md +7 -2
- package/tests/TEST_RESULTS.md +518 -0
- package/tests/archived/README.md +71 -0
- package/{deploy-hello-world.sh → tests/archived/deploy-hello-world.sh} +9 -6
- package/tests/deploy_dollie_test.sh +203 -0
- package/tests/misc/check-sdk-version.js +50 -0
- package/tests/mlgym_auth_login_test.sh +13 -9
- package/tests/mlgym_deploy_logs_test.sh +339 -0
- package/tests/mlgym_deploy_test.sh +341 -0
- package/tests/mlgym_status_test.sh +281 -0
- package/tests/mlgym_user_create_test.sh +35 -29
- package/tests/run-all-tests.sh +135 -41
- package/CURSOR_SETUP.md +0 -119
- package/index.js.backup-atomic +0 -1358
- /package/{DEBUG.md → docs/DEBUG.md} +0 -0
- /package/{SECURITY-UPDATE-v2.4.0.md → tests/archived/SECURITY-UPDATE-v2.4.0.md} +0 -0
- /package/{cursor-integration.js → tests/archived/cursor-integration.js} +0 -0
- /package/tests/{mlgym_auth_logout_test.sh → archived/mlgym_auth_logout_test.sh} +0 -0
- /package/tests/{mlgym_deployments_test.sh → archived/mlgym_deployments_test.sh} +0 -0
- /package/tests/{mlgym_project_init_test.sh → archived/mlgym_project_init_test.sh} +0 -0
- /package/tests/{mlgym_projects_get_test.sh → archived/mlgym_projects_get_test.sh} +0 -0
- /package/tests/{mlgym_projects_list_test.sh → archived/mlgym_projects_list_test.sh} +0 -0
package/README.md
CHANGED
|
@@ -32,12 +32,47 @@ Configure in your MCP client settings:
|
|
|
32
32
|
|
|
33
33
|
## Configuration
|
|
34
34
|
|
|
35
|
+
### For Published Package (Production)
|
|
36
|
+
|
|
35
37
|
Set the backend URL via environment variable:
|
|
36
38
|
|
|
37
39
|
```bash
|
|
38
40
|
export MLGYM_BACKEND_URL=https://backend.eu.ezb.net
|
|
39
41
|
```
|
|
40
42
|
|
|
43
|
+
### For Local Development
|
|
44
|
+
|
|
45
|
+
When developing locally, you'll need to configure the MCP server with absolute paths. Configuration files are user-specific and not tracked in git.
|
|
46
|
+
|
|
47
|
+
1. **Copy example files** to create your local config:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cp cursor-config.json.example cursor-config.json
|
|
51
|
+
cp mcp.json.example mcp.json
|
|
52
|
+
cp claude-desktop-config.json.example claude-desktop-config.json
|
|
53
|
+
cp ADD_TO_CURSOR_SETTINGS.json.example ADD_TO_CURSOR_SETTINGS.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
2. **Update the path** in your config file with your absolute path:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"gitlab-backend": {
|
|
62
|
+
"command": "node",
|
|
63
|
+
"args": ["/your/absolute/path/to/gitlab_backend/mcp-server/index.js"],
|
|
64
|
+
"env": {
|
|
65
|
+
"GITLAB_BACKEND_URL": "https://backend.eu.ezb.net",
|
|
66
|
+
"GITLAB_URL": "https://git.mlgym.io",
|
|
67
|
+
"COOLIFY_URL": "https://coolify.eu.ezb.net"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Note:** Absolute paths are required because the IDE launches the MCP server from its own working directory, not the project directory. Relative paths won't work.
|
|
75
|
+
|
|
41
76
|
## License
|
|
42
77
|
|
|
43
78
|
MIT
|
package/cursor-config.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"mcp.servers": {
|
|
3
3
|
"gitlab-backend": {
|
|
4
4
|
"command": "node",
|
|
5
|
-
"args": ["/home/
|
|
5
|
+
"args": ["/home/sreedhar/Work/Projects/mlgym/gitlab_backend/mcp-server/index.js"],
|
|
6
6
|
"env": {
|
|
7
7
|
"GITLAB_BACKEND_URL": "https://backend.eu.ezb.net",
|
|
8
8
|
"GITLAB_URL": "https://git.mlgym.io",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcp.servers": {
|
|
3
|
+
"gitlab-backend": {
|
|
4
|
+
"command": "node",
|
|
5
|
+
"args": ["/path/to/your/gitlab_backend/mcp-server/index.js"],
|
|
6
|
+
"env": {
|
|
7
|
+
"GITLAB_BACKEND_URL": "https://backend.eu.ezb.net",
|
|
8
|
+
"GITLAB_URL": "https://git.mlgym.io",
|
|
9
|
+
"COOLIFY_URL": "https://coolify.eu.ezb.net"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# MCP Setup Guide for Cursor IDE
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
✅ Node.js installed
|
|
5
|
+
✅ MCP dependencies installed (already done)
|
|
6
|
+
✅ Cursor IDE with MCP support
|
|
7
|
+
|
|
8
|
+
## Setup Instructions
|
|
9
|
+
|
|
10
|
+
### 1. Configure MCP in Cursor
|
|
11
|
+
|
|
12
|
+
Open Cursor Settings (Cmd/Ctrl+,) and add the MCP server configuration:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"mcp.servers": {
|
|
17
|
+
"mlgym-deploy": {
|
|
18
|
+
"command": "node",
|
|
19
|
+
"args": ["${workspaceFolder}/mcp-server/index.js"],
|
|
20
|
+
"env": {
|
|
21
|
+
"GITLAB_BACKEND_URL": "https://backend.eu.ezb.net",
|
|
22
|
+
"GITLAB_URL": "https://git.mlgym.io",
|
|
23
|
+
"COOLIFY_URL": "https://coolify.eu.ezb.net"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. Using MCP Tools in Cursor
|
|
31
|
+
|
|
32
|
+
Once MCP is configured, you can use these commands directly in Cursor chat:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
@mcp mlgym_user_create - Create a new user account
|
|
36
|
+
@mcp mlgym_auth_login - Login with existing credentials
|
|
37
|
+
@mcp mlgym_deploy - Deploy a project (recommended)
|
|
38
|
+
@mcp mlgym_status - Check deployment status
|
|
39
|
+
@mcp mlgym_deploy_logs - View deployment logs
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. MCP Tool Details
|
|
43
|
+
|
|
44
|
+
#### mlgym_user_create
|
|
45
|
+
Creates a complete user account with:
|
|
46
|
+
- GitLab account
|
|
47
|
+
- Coolify account
|
|
48
|
+
- SSH key generation and registration
|
|
49
|
+
- Authentication token storage
|
|
50
|
+
|
|
51
|
+
**Parameters:**
|
|
52
|
+
- `email` (required): User email address
|
|
53
|
+
- `name` (required): User full name
|
|
54
|
+
- `password` (required): User password (min 8 characters)
|
|
55
|
+
- `accept_terms` (required): Must be `true`
|
|
56
|
+
|
|
57
|
+
**Example:**
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"email": "user@example.com",
|
|
61
|
+
"name": "John Doe",
|
|
62
|
+
"password": "SecurePass123!",
|
|
63
|
+
"accept_terms": true
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
#### mlgym_auth_login
|
|
68
|
+
Login with existing user credentials to get authentication token.
|
|
69
|
+
|
|
70
|
+
**Parameters:**
|
|
71
|
+
- `email` (required): Email address
|
|
72
|
+
- `password` (required): Password
|
|
73
|
+
|
|
74
|
+
**Example:**
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"email": "user@example.com",
|
|
78
|
+
"password": "SecurePass123!"
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### mlgym_deploy (RECOMMENDED)
|
|
83
|
+
Complete deployment workflow in one call. Automatically authenticates (uses cached token if available), analyzes project, creates GitLab repo, and deploys to Coolify.
|
|
84
|
+
|
|
85
|
+
**Parameters:**
|
|
86
|
+
- `project_name` (required): Project name (lowercase alphanumeric with hyphens, e.g., "my-app")
|
|
87
|
+
- `project_description` (required): Brief project description (min 10 characters)
|
|
88
|
+
- `email` (optional): Email for authentication (if not already authenticated)
|
|
89
|
+
- `password` (optional): Password (if not already authenticated)
|
|
90
|
+
- `hostname` (optional): Custom hostname
|
|
91
|
+
- `local_path` (optional): Local project directory path (defaults to current directory)
|
|
92
|
+
- `project_type` (optional): Override auto-detected type (nodejs, python, static, go)
|
|
93
|
+
- `framework` (optional): Override auto-detected framework (nextjs, express, react, vue, flask, fastapi, html)
|
|
94
|
+
|
|
95
|
+
**Example:**
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"project_name": "my-awesome-app",
|
|
99
|
+
"project_description": "A simple Node.js application",
|
|
100
|
+
"email": "user@example.com",
|
|
101
|
+
"password": "SecurePass123!",
|
|
102
|
+
"local_path": "."
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Other Available Tools
|
|
107
|
+
|
|
108
|
+
- **mlgym_status**: Check deployment status and project configuration
|
|
109
|
+
- **mlgym_deploy_logs**: View deployment logs (requires project_name)
|
|
110
|
+
- **mlgym_set_env_vars**: Set environment variables for deployment
|
|
111
|
+
- **mlgym_set_health_check**: Configure health check endpoints
|
|
112
|
+
- **mlgym_set_domain**: Set custom domain for deployment
|
|
113
|
+
- **mlgym_set_deployment_commands**: Configure build/start commands
|
|
114
|
+
- **mlgym_deploy_manual**: Manual deployment trigger
|
|
115
|
+
- **mlgym_set_options**: Configure deployment options
|
|
116
|
+
- **mlgym_rollback**: Rollback to previous deployment
|
|
117
|
+
- **mlgym_help**: Get help on available tools
|
|
118
|
+
|
|
119
|
+
### 4. Typical Workflow
|
|
120
|
+
|
|
121
|
+
#### First-time User
|
|
122
|
+
1. Create account: `@mcp mlgym_user_create`
|
|
123
|
+
2. Deploy project: `@mcp mlgym_deploy` (includes authentication)
|
|
124
|
+
|
|
125
|
+
#### Existing User
|
|
126
|
+
1. Login: `@mcp mlgym_auth_login` (or use credentials in mlgym_deploy)
|
|
127
|
+
2. Deploy project: `@mcp mlgym_deploy`
|
|
128
|
+
3. Check status: `@mcp mlgym_status`
|
|
129
|
+
4. View logs: `@mcp mlgym_deploy_logs`
|
|
130
|
+
|
|
131
|
+
### 5. Testing MCP Connection
|
|
132
|
+
|
|
133
|
+
Test that MCP is working:
|
|
134
|
+
```bash
|
|
135
|
+
# Test the MCP server directly
|
|
136
|
+
node mcp-server/index.js
|
|
137
|
+
|
|
138
|
+
# Should output the MCP protocol initialization message
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 6. Authentication
|
|
142
|
+
|
|
143
|
+
MCP stores authentication tokens in `~/.mlgym/mcp_config.json` automatically after:
|
|
144
|
+
- First user creation (`mlgym_user_create`)
|
|
145
|
+
- Successful login (`mlgym_auth_login`)
|
|
146
|
+
- Successful deployment with credentials (`mlgym_deploy`)
|
|
147
|
+
|
|
148
|
+
### 7. Troubleshooting
|
|
149
|
+
|
|
150
|
+
If MCP tools don't appear in Cursor:
|
|
151
|
+
1. Restart Cursor after configuration
|
|
152
|
+
2. Check the MCP server is accessible:
|
|
153
|
+
```bash
|
|
154
|
+
node mcp-server/index.js
|
|
155
|
+
```
|
|
156
|
+
3. Verify settings in Cursor preferences (look for "mcp.servers")
|
|
157
|
+
4. Check Cursor logs for MCP errors (View → Output → MCP)
|
|
158
|
+
5. Ensure you're using Cursor with MCP support (latest version)
|
|
159
|
+
|
|
160
|
+
### 8. Debug Mode
|
|
161
|
+
|
|
162
|
+
Debug logging is enabled by default. To see detailed output:
|
|
163
|
+
```bash
|
|
164
|
+
# Start Cursor from terminal to see MCP logs
|
|
165
|
+
cd ~/your-project
|
|
166
|
+
cursor .
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
See [DEBUG.md](./DEBUG.md) for more details on debug logging.
|
|
170
|
+
|
|
171
|
+
## Environment Variables
|
|
172
|
+
|
|
173
|
+
The MCP server uses these production endpoints:
|
|
174
|
+
- **Backend**: https://backend.eu.ezb.net
|
|
175
|
+
- **GitLab**: https://git.mlgym.io
|
|
176
|
+
- **Coolify**: https://coolify.eu.ezb.net
|
|
177
|
+
|
|
178
|
+
These are pre-configured in the MCP server configuration.
|
|
179
|
+
|
|
180
|
+
## Quick Test
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# In Cursor terminal, test user creation
|
|
184
|
+
echo '{
|
|
185
|
+
"jsonrpc": "2.0",
|
|
186
|
+
"method": "tools/call",
|
|
187
|
+
"params": {
|
|
188
|
+
"name": "mlgym_user_create",
|
|
189
|
+
"arguments": {
|
|
190
|
+
"email": "test@example.com",
|
|
191
|
+
"name": "Test User",
|
|
192
|
+
"password": "TestPass123!",
|
|
193
|
+
"accept_terms": true
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
"id": 1
|
|
197
|
+
}' | node mcp-server/index.js
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Additional Resources
|
|
201
|
+
|
|
202
|
+
- [Debug Guide](./DEBUG.md) - Enable and configure debug logging
|
|
203
|
+
- [Test Results](../tests/TEST_RESULTS.md) - Current test coverage and results
|
|
204
|
+
- Production Backend: https://backend.eu.ezb.net
|
package/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import crypto from 'crypto';
|
|
|
18
18
|
const execAsync = promisify(exec);
|
|
19
19
|
|
|
20
20
|
// Current version of this MCP server - INCREMENT FOR WORKFLOW FIXES
|
|
21
|
-
const CURRENT_VERSION = '3.3.
|
|
21
|
+
const CURRENT_VERSION = '3.3.43'; // Add embedded contact info (operations@stratus5.com) and hide infrastructure URLs from help
|
|
22
22
|
const PACKAGE_NAME = 'mlgym-deploy';
|
|
23
23
|
|
|
24
24
|
// Debug logging configuration - ENABLED BY DEFAULT
|
|
@@ -90,7 +90,13 @@ const CONFIG = {
|
|
|
90
90
|
backend_url: process.env.MLGYM_API_ENDPOINT || 'https://backend.eu.ezb.net',
|
|
91
91
|
gitlab_url: 'https://git.mlgym.io',
|
|
92
92
|
coolify_url: 'https://coolify.eu.ezb.net',
|
|
93
|
-
config_file: path.join(os.homedir(), '.mlgym', 'mcp_config.json')
|
|
93
|
+
config_file: path.join(os.homedir(), '.mlgym', 'mcp_config.json'),
|
|
94
|
+
|
|
95
|
+
// Contact information (user-facing)
|
|
96
|
+
contact: {
|
|
97
|
+
support_email: 'operations@stratus5.com',
|
|
98
|
+
docs_url: 'https://mlgym.info'
|
|
99
|
+
}
|
|
94
100
|
};
|
|
95
101
|
|
|
96
102
|
// Helper to load/save authentication
|
|
@@ -3434,6 +3440,205 @@ async function deployProject(args) {
|
|
|
3434
3440
|
}
|
|
3435
3441
|
}
|
|
3436
3442
|
|
|
3443
|
+
// ============================================================================
|
|
3444
|
+
// DOLLIE DEPLOYMENT - Next.js Dev Containers with SSH
|
|
3445
|
+
// ============================================================================
|
|
3446
|
+
async function deployDollie(args) {
|
|
3447
|
+
const {
|
|
3448
|
+
project_name,
|
|
3449
|
+
project_description,
|
|
3450
|
+
git_repo_url,
|
|
3451
|
+
git_branch = '',
|
|
3452
|
+
git_token = '',
|
|
3453
|
+
app_port = 3000,
|
|
3454
|
+
email,
|
|
3455
|
+
password
|
|
3456
|
+
} = args;
|
|
3457
|
+
|
|
3458
|
+
log.info('MCP >>> Starting Dollie deployment workflow');
|
|
3459
|
+
log.debug('MCP >>> Arguments:', { project_name, git_repo_url, git_branch, app_port });
|
|
3460
|
+
|
|
3461
|
+
try {
|
|
3462
|
+
// Step 1: Authenticate
|
|
3463
|
+
log.info('MCP >>> STEP 1: Authenticating...');
|
|
3464
|
+
const auth = await loadAuth();
|
|
3465
|
+
|
|
3466
|
+
// If not authenticated and credentials provided, authenticate
|
|
3467
|
+
if (!auth.token && email && password) {
|
|
3468
|
+
const loginResult = await apiRequest('POST', '/api/v1/auth/login', {
|
|
3469
|
+
email,
|
|
3470
|
+
password
|
|
3471
|
+
}, false);
|
|
3472
|
+
|
|
3473
|
+
if (!loginResult.success || !loginResult.data.token) {
|
|
3474
|
+
return {
|
|
3475
|
+
content: [{
|
|
3476
|
+
type: 'text',
|
|
3477
|
+
text: JSON.stringify({
|
|
3478
|
+
status: 'error',
|
|
3479
|
+
message: 'Authentication failed',
|
|
3480
|
+
error: loginResult.error || 'Invalid credentials',
|
|
3481
|
+
next_steps: [
|
|
3482
|
+
'Provide valid email and password',
|
|
3483
|
+
'Or ensure you are already logged in'
|
|
3484
|
+
]
|
|
3485
|
+
}, null, 2)
|
|
3486
|
+
}]
|
|
3487
|
+
};
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
await saveAuth(email, loginResult.data.token);
|
|
3491
|
+
log.success('MCP >>> STEP 1: Authentication successful');
|
|
3492
|
+
} else if (!auth.token) {
|
|
3493
|
+
return {
|
|
3494
|
+
content: [{
|
|
3495
|
+
type: 'text',
|
|
3496
|
+
text: JSON.stringify({
|
|
3497
|
+
status: 'error',
|
|
3498
|
+
message: 'Authentication required',
|
|
3499
|
+
error: 'No authentication token found and no credentials provided',
|
|
3500
|
+
next_steps: [
|
|
3501
|
+
'Provide email and password in the request',
|
|
3502
|
+
'Or use mlgym_auth_login first'
|
|
3503
|
+
]
|
|
3504
|
+
}, null, 2)
|
|
3505
|
+
}]
|
|
3506
|
+
};
|
|
3507
|
+
} else {
|
|
3508
|
+
log.success('MCP >>> STEP 1: Using existing authentication');
|
|
3509
|
+
}
|
|
3510
|
+
|
|
3511
|
+
// Step 2: Get current user info
|
|
3512
|
+
log.info('MCP >>> STEP 2: Getting user information...');
|
|
3513
|
+
const userResult = await apiRequest('GET', '/api/v1/user', null, true);
|
|
3514
|
+
|
|
3515
|
+
if (!userResult.success) {
|
|
3516
|
+
return {
|
|
3517
|
+
content: [{
|
|
3518
|
+
type: 'text',
|
|
3519
|
+
text: JSON.stringify({
|
|
3520
|
+
status: 'error',
|
|
3521
|
+
message: 'Failed to get user information',
|
|
3522
|
+
error: userResult.error
|
|
3523
|
+
}, null, 2)
|
|
3524
|
+
}]
|
|
3525
|
+
};
|
|
3526
|
+
}
|
|
3527
|
+
|
|
3528
|
+
log.success('MCP >>> STEP 2: User information retrieved');
|
|
3529
|
+
|
|
3530
|
+
// Step 3: Generate SSH password
|
|
3531
|
+
log.info('MCP >>> STEP 3: Generating SSH password...');
|
|
3532
|
+
const sshPassword = generateRandomPassword();
|
|
3533
|
+
log.success('MCP >>> STEP 3: SSH password generated');
|
|
3534
|
+
|
|
3535
|
+
// Step 4: Prepare environment variables
|
|
3536
|
+
log.info('MCP >>> STEP 4: Preparing environment variables...');
|
|
3537
|
+
const environmentVariables = {
|
|
3538
|
+
GIT_REPO_URL: git_repo_url,
|
|
3539
|
+
GIT_BRANCH: git_branch,
|
|
3540
|
+
GIT_TOKEN: git_token,
|
|
3541
|
+
SSH_PASSWORD: sshPassword,
|
|
3542
|
+
S5_USERNAME: 'developer',
|
|
3543
|
+
APP_PORT: app_port.toString(),
|
|
3544
|
+
SSH_PORT: '22'
|
|
3545
|
+
};
|
|
3546
|
+
log.success('MCP >>> STEP 4: Environment variables prepared');
|
|
3547
|
+
log.debug('MCP >>> Environment variables:', Object.keys(environmentVariables));
|
|
3548
|
+
|
|
3549
|
+
// Step 5: Create Coolify resource with docker-image
|
|
3550
|
+
log.info('MCP >>> STEP 5: Creating Coolify deployment...');
|
|
3551
|
+
const createResult = await apiRequest('POST', '/api/v1/projects', {
|
|
3552
|
+
name: project_name,
|
|
3553
|
+
description: project_description,
|
|
3554
|
+
repository: '', // Not needed for docker-image deployments
|
|
3555
|
+
branch: '',
|
|
3556
|
+
build_pack: 'docker-image',
|
|
3557
|
+
docker_image: 'code.stratus5.com:5050/dollie/dollie/nextjs-dev:latest',
|
|
3558
|
+
environment_variables: environmentVariables,
|
|
3559
|
+
ports_exposes: app_port.toString()
|
|
3560
|
+
}, true);
|
|
3561
|
+
|
|
3562
|
+
if (!createResult.success) {
|
|
3563
|
+
return {
|
|
3564
|
+
content: [{
|
|
3565
|
+
type: 'text',
|
|
3566
|
+
text: JSON.stringify({
|
|
3567
|
+
status: 'error',
|
|
3568
|
+
message: 'Failed to create Dollie deployment',
|
|
3569
|
+
error: createResult.error,
|
|
3570
|
+
step: 'create_coolify_resource'
|
|
3571
|
+
}, null, 2)
|
|
3572
|
+
}]
|
|
3573
|
+
};
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
log.success('MCP >>> STEP 5: Coolify deployment created');
|
|
3577
|
+
|
|
3578
|
+
// Step 6: Extract deployment details
|
|
3579
|
+
const deployment = createResult.data;
|
|
3580
|
+
const appUuid = deployment.coolify_uuid;
|
|
3581
|
+
const appUrl = deployment.url;
|
|
3582
|
+
|
|
3583
|
+
// Parse URL to extract hostname
|
|
3584
|
+
const urlObj = new URL(appUrl);
|
|
3585
|
+
const hostname = urlObj.hostname;
|
|
3586
|
+
|
|
3587
|
+
// Determine SSH port based on node (typically 2201 for all nodes)
|
|
3588
|
+
const sshPort = 2201;
|
|
3589
|
+
|
|
3590
|
+
log.success('MCP >>> Dollie deployment completed successfully');
|
|
3591
|
+
|
|
3592
|
+
return {
|
|
3593
|
+
content: [{
|
|
3594
|
+
type: 'text',
|
|
3595
|
+
text: JSON.stringify({
|
|
3596
|
+
success: true,
|
|
3597
|
+
deployment: {
|
|
3598
|
+
url: appUrl,
|
|
3599
|
+
ssh: {
|
|
3600
|
+
host: hostname,
|
|
3601
|
+
port: sshPort,
|
|
3602
|
+
username: 'developer',
|
|
3603
|
+
password: sshPassword
|
|
3604
|
+
},
|
|
3605
|
+
status: 'deploying',
|
|
3606
|
+
coolify_uuid: appUuid,
|
|
3607
|
+
project_name: project_name,
|
|
3608
|
+
git_repo: git_repo_url,
|
|
3609
|
+
git_branch: git_branch || 'default',
|
|
3610
|
+
app_port: app_port
|
|
3611
|
+
},
|
|
3612
|
+
next_steps: [
|
|
3613
|
+
`Container is deploying at ${appUrl}`,
|
|
3614
|
+
`SSH access: ssh developer@${hostname} -p ${sshPort}`,
|
|
3615
|
+
`Password: ${sshPassword}`,
|
|
3616
|
+
'The container will:',
|
|
3617
|
+
' 1. Clone your git repository',
|
|
3618
|
+
' 2. Install dependencies (npm/yarn/pnpm)',
|
|
3619
|
+
' 3. Start Next.js dev server',
|
|
3620
|
+
' 4. Enable SSH access',
|
|
3621
|
+
'Wait 2-3 minutes for deployment to complete'
|
|
3622
|
+
]
|
|
3623
|
+
}, null, 2)
|
|
3624
|
+
}]
|
|
3625
|
+
};
|
|
3626
|
+
|
|
3627
|
+
} catch (error) {
|
|
3628
|
+
log.error('MCP >>> Dollie deployment failed:', error.message);
|
|
3629
|
+
return {
|
|
3630
|
+
content: [{
|
|
3631
|
+
type: 'text',
|
|
3632
|
+
text: JSON.stringify({
|
|
3633
|
+
status: 'error',
|
|
3634
|
+
message: 'Dollie deployment failed',
|
|
3635
|
+
error: error.message
|
|
3636
|
+
}, null, 2)
|
|
3637
|
+
}]
|
|
3638
|
+
};
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
|
|
3437
3642
|
// ============================================================================
|
|
3438
3643
|
// SIMPLIFIED STATUS CHECK
|
|
3439
3644
|
// ============================================================================
|
|
@@ -4420,8 +4625,7 @@ Examples show both what users say AND the tool call that gets executed.
|
|
|
4420
4625
|
💡 Most parameters are optional with sensible defaults
|
|
4421
4626
|
|
|
4422
4627
|
📚 Documentation: https://mlgym.info
|
|
4423
|
-
|
|
4424
|
-
📊 Dashboard: https://platform.mlgym.info
|
|
4628
|
+
📧 Support: operations@stratus5.com
|
|
4425
4629
|
`;
|
|
4426
4630
|
|
|
4427
4631
|
return {
|
|
@@ -4767,6 +4971,55 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
4767
4971
|
}
|
|
4768
4972
|
}
|
|
4769
4973
|
},
|
|
4974
|
+
{
|
|
4975
|
+
name: 'deploy_dollie',
|
|
4976
|
+
description: 'Deploy a Next.js development container with SSH access for AI-assisted development. Uses the Dollie base image which clones your git repository and runs the dev server. Supports any public git repo or private repos with token authentication.',
|
|
4977
|
+
inputSchema: {
|
|
4978
|
+
type: 'object',
|
|
4979
|
+
properties: {
|
|
4980
|
+
project_name: {
|
|
4981
|
+
type: 'string',
|
|
4982
|
+
description: 'Project name (lowercase alphanumeric with hyphens, e.g., "my-nextjs-app")',
|
|
4983
|
+
pattern: '^[a-z0-9][a-z0-9-]*[a-z0-9]$',
|
|
4984
|
+
minLength: 3
|
|
4985
|
+
},
|
|
4986
|
+
project_description: {
|
|
4987
|
+
type: 'string',
|
|
4988
|
+
description: 'Brief project description (min 10 characters)',
|
|
4989
|
+
minLength: 10
|
|
4990
|
+
},
|
|
4991
|
+
git_repo_url: {
|
|
4992
|
+
type: 'string',
|
|
4993
|
+
description: 'Git repository URL (https://github.com/user/repo.git)',
|
|
4994
|
+
pattern: '^https://.*\\.git$'
|
|
4995
|
+
},
|
|
4996
|
+
git_branch: {
|
|
4997
|
+
type: 'string',
|
|
4998
|
+
description: 'Branch to clone (optional, defaults to repo\'s default branch)'
|
|
4999
|
+
},
|
|
5000
|
+
git_token: {
|
|
5001
|
+
type: 'string',
|
|
5002
|
+
description: 'OAuth token for private repos (optional)'
|
|
5003
|
+
},
|
|
5004
|
+
app_port: {
|
|
5005
|
+
type: 'number',
|
|
5006
|
+
description: 'Next.js port inside container (optional, default: 3000)',
|
|
5007
|
+
default: 3000
|
|
5008
|
+
},
|
|
5009
|
+
email: {
|
|
5010
|
+
type: 'string',
|
|
5011
|
+
description: 'Email for authentication (optional if already authenticated)',
|
|
5012
|
+
pattern: '^[^@]+@[^@]+\\.[^@]+$'
|
|
5013
|
+
},
|
|
5014
|
+
password: {
|
|
5015
|
+
type: 'string',
|
|
5016
|
+
description: 'Password (optional if already authenticated, min 8 characters)',
|
|
5017
|
+
minLength: 8
|
|
5018
|
+
}
|
|
5019
|
+
},
|
|
5020
|
+
required: ['project_name', 'project_description', 'git_repo_url']
|
|
5021
|
+
}
|
|
5022
|
+
},
|
|
4770
5023
|
{
|
|
4771
5024
|
name: 'mlgym_help',
|
|
4772
5025
|
description: 'Display all available MLGym tools with descriptions and usage examples. Use this to discover what operations you can perform.',
|
|
@@ -4902,13 +5155,18 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
4902
5155
|
result = await rollback(args);
|
|
4903
5156
|
break;
|
|
4904
5157
|
|
|
5158
|
+
case 'deploy_dollie':
|
|
5159
|
+
log.info(`Deploying Dollie development container...`);
|
|
5160
|
+
result = await deployDollie(args);
|
|
5161
|
+
break;
|
|
5162
|
+
|
|
4905
5163
|
case 'mlgym_help':
|
|
4906
5164
|
log.info(`Showing help...`);
|
|
4907
5165
|
result = await showHelp(args);
|
|
4908
5166
|
break;
|
|
4909
5167
|
|
|
4910
5168
|
default:
|
|
4911
|
-
throw new Error(`Unknown tool: ${name}. Available tools: mlgym_deploy, mlgym_status, mlgym_deploy_logs, mlgym_user_create, mlgym_auth_login, mlgym_set_env_vars, mlgym_set_health_check, mlgym_set_domain, mlgym_set_deployment_commands, mlgym_deploy_manual, mlgym_set_options, mlgym_rollback`);
|
|
5169
|
+
throw new Error(`Unknown tool: ${name}. Available tools: mlgym_deploy, mlgym_status, mlgym_deploy_logs, deploy_dollie, mlgym_user_create, mlgym_auth_login, mlgym_set_env_vars, mlgym_set_health_check, mlgym_set_domain, mlgym_set_deployment_commands, mlgym_deploy_manual, mlgym_set_options, mlgym_rollback`);
|
|
4912
5170
|
}
|
|
4913
5171
|
|
|
4914
5172
|
const duration = Date.now() - startTime;
|
package/mcp.json.example
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"gitlab-backend": {
|
|
4
|
+
"command": "node",
|
|
5
|
+
"args": ["/path/to/your/gitlab_backend/mcp-server/index.js"],
|
|
6
|
+
"env": {
|
|
7
|
+
"GITLAB_BACKEND_URL": "https://backend.eu.ezb.net",
|
|
8
|
+
"GITLAB_URL": "https://git.mlgym.io",
|
|
9
|
+
"COOLIFY_URL": "https://coolify.eu.ezb.net"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mlgym-deploy",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.43",
|
|
4
4
|
"description": "MCP server for MLGym - Complete deployment management: deploy, configure, monitor, and rollback applications",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,13 +20,17 @@
|
|
|
20
20
|
],
|
|
21
21
|
"author": "MLGym Team",
|
|
22
22
|
"license": "MIT",
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18.0.0"
|
|
25
|
+
},
|
|
23
26
|
"repository": {
|
|
24
27
|
"type": "git",
|
|
25
28
|
"url": "git@code.stratus5.com:chka/gitlab_backend.git"
|
|
26
29
|
},
|
|
27
30
|
"dependencies": {
|
|
28
|
-
"@modelcontextprotocol/sdk": "^
|
|
29
|
-
"axios": "^1.6.0"
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
32
|
+
"axios": "^1.6.0",
|
|
33
|
+
"package": "*"
|
|
30
34
|
},
|
|
31
35
|
"mcp": {
|
|
32
36
|
"name": "MLGym Deploy",
|
|
@@ -80,6 +84,10 @@
|
|
|
80
84
|
"name": "mlgym_rollback",
|
|
81
85
|
"description": "Rollback to previous deployment"
|
|
82
86
|
},
|
|
87
|
+
{
|
|
88
|
+
"name": "deploy_dollie",
|
|
89
|
+
"description": "Deploy Next.js development container with SSH access using pre-built Dollie image"
|
|
90
|
+
},
|
|
83
91
|
{
|
|
84
92
|
"name": "mlgym_help",
|
|
85
93
|
"description": "Display all available tools with descriptions and usage examples"
|
package/tests/README.md
CHANGED
|
@@ -13,7 +13,8 @@ tests/
|
|
|
13
13
|
├── mlgym_auth_logout_test.sh # ✅ 8 tests (auth_logout)
|
|
14
14
|
├── mlgym_project_init_test.sh # ✅ 6 tests (project_init)
|
|
15
15
|
├── mlgym_projects_list_test.sh # ✅ 6 tests (projects_list)
|
|
16
|
-
|
|
16
|
+
├── mlgym_projects_get_test.sh # ✅ 7 tests (projects_get)
|
|
17
|
+
└── deploy_dollie_test.sh # ✅ 20 tests (deploy_dollie)
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
## Running Tests
|
|
@@ -32,7 +33,7 @@ cd mcp-server
|
|
|
32
33
|
|
|
33
34
|
## Test Coverage
|
|
34
35
|
|
|
35
|
-
### Completed (
|
|
36
|
+
### Completed (7 functions, 82 total tests)
|
|
36
37
|
- ✅ **mlgym_auth_login** (15 tests)
|
|
37
38
|
- Valid/invalid credentials, SQL injection, XSS, buffer overflow, token storage
|
|
38
39
|
- ✅ **mlgym_user_create** (20 tests)
|
|
@@ -45,6 +46,10 @@ cd mcp-server
|
|
|
45
46
|
- List projects, user isolation, response format
|
|
46
47
|
- ✅ **mlgym_projects_get** (7 tests)
|
|
47
48
|
- Get project details, validation, non-existent projects
|
|
49
|
+
- ✅ **deploy_dollie** (20 tests)
|
|
50
|
+
- Authentication, deployment workflow, public repos, custom ports/branches
|
|
51
|
+
- Required fields, validation, security (SQL injection, XSS, buffer overflow)
|
|
52
|
+
- Response format, SSH password strength
|
|
48
53
|
|
|
49
54
|
### Remaining (37 functions)
|
|
50
55
|
See TODO.md for priority order and testing plan.
|