otoinstall-mcp-server 1.0.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/README.md +278 -0
- package/dist/api-client.d.ts +41 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +107 -0
- package/dist/api-client.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +306 -0
- package/dist/index.js.map +1 -0
- package/dist/zip-utils.d.ts +10 -0
- package/dist/zip-utils.d.ts.map +1 -0
- package/dist/zip-utils.js +57 -0
- package/dist/zip-utils.js.map +1 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# 🚀 @otoinstall/mcp-server
|
|
2
|
+
|
|
3
|
+
**Deploy projects from any AI tool with a single command.**
|
|
4
|
+
|
|
5
|
+
Works with **Claude Desktop**, **Cursor**, **Windsurf**, **Cline**, **Continue**, **Zed**, **Roo Code**, **Amazon Q**, and any MCP-compatible AI assistant.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
### 1. Get Your API Key
|
|
12
|
+
|
|
13
|
+
Sign up at [otoinstall.com](https://otoinstall.com) → Dashboard → **API Keys** → Create Key
|
|
14
|
+
|
|
15
|
+
### 2. Configure Your AI Tool
|
|
16
|
+
|
|
17
|
+
Choose your tool below and add the configuration:
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🤖 Claude Desktop
|
|
22
|
+
|
|
23
|
+
Edit `claude_desktop_config.json`:
|
|
24
|
+
|
|
25
|
+
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
26
|
+
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"mcpServers": {
|
|
31
|
+
"otoinstall": {
|
|
32
|
+
"command": "npx",
|
|
33
|
+
"args": ["-y", "@otoinstall/mcp-server"],
|
|
34
|
+
"env": {
|
|
35
|
+
"OTOINSTALL_API_KEY": "oi_live_your_key_here",
|
|
36
|
+
"OTOINSTALL_BASE_URL": "https://otoinstall.com"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 🖱️ Cursor
|
|
46
|
+
|
|
47
|
+
Settings → **MCP Servers** → Add:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"mcpServers": {
|
|
52
|
+
"otoinstall": {
|
|
53
|
+
"command": "npx",
|
|
54
|
+
"args": ["-y", "@otoinstall/mcp-server"],
|
|
55
|
+
"env": {
|
|
56
|
+
"OTOINSTALL_API_KEY": "oi_live_your_key_here"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Or via `.cursor/mcp.json` in your project root.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 🏄 Windsurf
|
|
68
|
+
|
|
69
|
+
Settings → **MCP** → Add server:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"otoinstall": {
|
|
75
|
+
"command": "npx",
|
|
76
|
+
"args": ["-y", "@otoinstall/mcp-server"],
|
|
77
|
+
"env": {
|
|
78
|
+
"OTOINSTALL_API_KEY": "oi_live_your_key_here"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 🔌 Cline (VS Code Extension)
|
|
88
|
+
|
|
89
|
+
Cline settings → **MCP Servers** → Add:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"otoinstall": {
|
|
95
|
+
"command": "npx",
|
|
96
|
+
"args": ["-y", "@otoinstall/mcp-server"],
|
|
97
|
+
"env": {
|
|
98
|
+
"OTOINSTALL_API_KEY": "oi_live_your_key_here"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## ➡️ Continue (VS Code / JetBrains)
|
|
108
|
+
|
|
109
|
+
Edit `~/.continue/config.json`:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"experimental": {
|
|
114
|
+
"modelContextProtocolServers": [
|
|
115
|
+
{
|
|
116
|
+
"transport": {
|
|
117
|
+
"type": "stdio",
|
|
118
|
+
"command": "npx",
|
|
119
|
+
"args": ["-y", "@otoinstall/mcp-server"],
|
|
120
|
+
"env": {
|
|
121
|
+
"OTOINSTALL_API_KEY": "oi_live_your_key_here"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## ⚡ Zed
|
|
133
|
+
|
|
134
|
+
Edit `~/.config/zed/settings.json`:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"context_servers": {
|
|
139
|
+
"otoinstall": {
|
|
140
|
+
"command": {
|
|
141
|
+
"path": "npx",
|
|
142
|
+
"args": ["-y", "@otoinstall/mcp-server"],
|
|
143
|
+
"env": {
|
|
144
|
+
"OTOINSTALL_API_KEY": "oi_live_your_key_here"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 🦘 Roo Code
|
|
155
|
+
|
|
156
|
+
`.roo/mcp.json`:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"mcpServers": {
|
|
161
|
+
"otoinstall": {
|
|
162
|
+
"command": "npx",
|
|
163
|
+
"args": ["-y", "@otoinstall/mcp-server"],
|
|
164
|
+
"env": {
|
|
165
|
+
"OTOINSTALL_API_KEY": "oi_live_your_key_here"
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## 🔧 Antigravity (Google Gemini)
|
|
175
|
+
|
|
176
|
+
Add to your MCP configuration:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"mcpServers": {
|
|
181
|
+
"otoinstall": {
|
|
182
|
+
"command": "npx",
|
|
183
|
+
"args": ["-y", "@otoinstall/mcp-server"],
|
|
184
|
+
"env": {
|
|
185
|
+
"OTOINSTALL_API_KEY": "oi_live_your_key_here"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 🏗️ Any MCP-Compatible Tool
|
|
195
|
+
|
|
196
|
+
The universal configuration pattern:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"command": "npx",
|
|
201
|
+
"args": ["-y", "@otoinstall/mcp-server"],
|
|
202
|
+
"env": {
|
|
203
|
+
"OTOINSTALL_API_KEY": "oi_live_your_key_here",
|
|
204
|
+
"OTOINSTALL_BASE_URL": "https://otoinstall.com"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 🛠️ Available Tools
|
|
212
|
+
|
|
213
|
+
| Tool | Description |
|
|
214
|
+
|---|---|
|
|
215
|
+
| `deploy_project` | Zip & deploy a project directory to a live server |
|
|
216
|
+
| `deploy_zip` | Deploy an existing ZIP file |
|
|
217
|
+
| `check_deploy_status` | Check deployment progress and status |
|
|
218
|
+
| `get_deploy_logs` | View detailed deployment logs |
|
|
219
|
+
| `list_projects` | List all your deployments |
|
|
220
|
+
| `list_servers` | List configured server credentials |
|
|
221
|
+
| `whoami` | Check API key owner and permissions |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 💬 Usage Examples
|
|
226
|
+
|
|
227
|
+
### Deploy from Claude
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
You: "Deploy this project to my server"
|
|
231
|
+
Claude: I'll deploy the project. First, let me check your servers.
|
|
232
|
+
[calls list_servers]
|
|
233
|
+
You have 1 server: [ID: 1] MyVPS — sftp://user@myserver.com
|
|
234
|
+
[calls deploy_project with directory and credential_id=1]
|
|
235
|
+
✅ Deployment started! Deploy ID: 01HYJ3R8KQFG...
|
|
236
|
+
[calls check_deploy_status]
|
|
237
|
+
🎉 Deployment completed! Your site is live at https://mysite.com
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Deploy from Cursor
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
You: "Publish this to production"
|
|
244
|
+
Cursor: [calls deploy_project]
|
|
245
|
+
✅ Your project has been deployed!
|
|
246
|
+
🌐 Live at: https://yourproject.com
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 🔐 Environment Variables
|
|
252
|
+
|
|
253
|
+
| Variable | Required | Default | Description |
|
|
254
|
+
|---|---|---|---|
|
|
255
|
+
| `OTOINSTALL_API_KEY` | ✅ | — | Your OtoInstall API key |
|
|
256
|
+
| `OTOINSTALL_BASE_URL` | ❌ | `https://otoinstall.com` | API base URL |
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 📦 Local Development
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
git clone https://github.com/otoinstall/mcp-server
|
|
264
|
+
cd mcp-server
|
|
265
|
+
npm install
|
|
266
|
+
npm run build
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Test with MCP Inspector:
|
|
270
|
+
```bash
|
|
271
|
+
npx @modelcontextprotocol/inspector node dist/index.js
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## License
|
|
277
|
+
|
|
278
|
+
MIT © OtoInstall
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OtoInstall API Client
|
|
3
|
+
* Handles all HTTP communication with the OtoInstall REST API.
|
|
4
|
+
*/
|
|
5
|
+
export declare class OtoInstallClient {
|
|
6
|
+
private apiKey;
|
|
7
|
+
private baseUrl;
|
|
8
|
+
constructor(apiKey: string, baseUrl: string);
|
|
9
|
+
private get headers();
|
|
10
|
+
private request;
|
|
11
|
+
/**
|
|
12
|
+
* Deploy a ZIP file
|
|
13
|
+
*/
|
|
14
|
+
deploy(zipPath: string, options: {
|
|
15
|
+
credential_id: number;
|
|
16
|
+
remote_path?: string;
|
|
17
|
+
target_url?: string;
|
|
18
|
+
project_type?: string;
|
|
19
|
+
}): Promise<any>;
|
|
20
|
+
/**
|
|
21
|
+
* Get deployment status
|
|
22
|
+
*/
|
|
23
|
+
getDeployStatus(deployId: string): Promise<any>;
|
|
24
|
+
/**
|
|
25
|
+
* Get deployment logs
|
|
26
|
+
*/
|
|
27
|
+
getDeployLogs(deployId: string): Promise<any>;
|
|
28
|
+
/**
|
|
29
|
+
* List projects/deployments
|
|
30
|
+
*/
|
|
31
|
+
listProjects(status?: string, perPage?: number): Promise<any>;
|
|
32
|
+
/**
|
|
33
|
+
* List server credentials
|
|
34
|
+
*/
|
|
35
|
+
listCredentials(): Promise<any>;
|
|
36
|
+
/**
|
|
37
|
+
* Get current user info
|
|
38
|
+
*/
|
|
39
|
+
me(): Promise<any>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAK3C,OAAO,KAAK,OAAO,GAKlB;YAEa,OAAO;IA0BrB;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;QACrC,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,OAAO,CAAC,GAAG,CAAC;IA+BhB;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIrD;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAInD;;OAEG;IACG,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAOvE;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC;IAIrC;;OAEG;IACG,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC;CAGzB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OtoInstall API Client
|
|
3
|
+
* Handles all HTTP communication with the OtoInstall REST API.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync } from "fs";
|
|
6
|
+
import { basename } from "path";
|
|
7
|
+
export class OtoInstallClient {
|
|
8
|
+
apiKey;
|
|
9
|
+
baseUrl;
|
|
10
|
+
constructor(apiKey, baseUrl) {
|
|
11
|
+
this.apiKey = apiKey;
|
|
12
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
13
|
+
}
|
|
14
|
+
get headers() {
|
|
15
|
+
return {
|
|
16
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
17
|
+
Accept: "application/json",
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async request(method, endpoint, body) {
|
|
21
|
+
const url = `${this.baseUrl}/api/v1${endpoint}`;
|
|
22
|
+
const opts = {
|
|
23
|
+
method,
|
|
24
|
+
headers: this.headers,
|
|
25
|
+
};
|
|
26
|
+
if (body && !(body instanceof FormData)) {
|
|
27
|
+
opts.headers["Content-Type"] = "application/json";
|
|
28
|
+
opts.body = JSON.stringify(body);
|
|
29
|
+
}
|
|
30
|
+
else if (body instanceof FormData) {
|
|
31
|
+
opts.body = body;
|
|
32
|
+
}
|
|
33
|
+
const response = await fetch(url, opts);
|
|
34
|
+
const data = await response.json();
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
const msg = data?.error?.message ?? `HTTP ${response.status}`;
|
|
37
|
+
throw new Error(msg);
|
|
38
|
+
}
|
|
39
|
+
return data;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Deploy a ZIP file
|
|
43
|
+
*/
|
|
44
|
+
async deploy(zipPath, options) {
|
|
45
|
+
const fileBuffer = readFileSync(zipPath);
|
|
46
|
+
const fileName = basename(zipPath);
|
|
47
|
+
const fileBlob = new Blob([fileBuffer], { type: "application/zip" });
|
|
48
|
+
const form = new FormData();
|
|
49
|
+
form.append("file", fileBlob, fileName);
|
|
50
|
+
form.append("credential_id", String(options.credential_id));
|
|
51
|
+
if (options.remote_path)
|
|
52
|
+
form.append("remote_path", options.remote_path);
|
|
53
|
+
if (options.target_url)
|
|
54
|
+
form.append("target_url", options.target_url);
|
|
55
|
+
if (options.project_type)
|
|
56
|
+
form.append("project_type", options.project_type);
|
|
57
|
+
const url = `${this.baseUrl}/api/v1/deploy`;
|
|
58
|
+
const response = await fetch(url, {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: {
|
|
61
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
62
|
+
Accept: "application/json",
|
|
63
|
+
},
|
|
64
|
+
body: form,
|
|
65
|
+
});
|
|
66
|
+
const data = await response.json();
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
throw new Error(data?.error?.message ?? `HTTP ${response.status}`);
|
|
69
|
+
}
|
|
70
|
+
return data;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get deployment status
|
|
74
|
+
*/
|
|
75
|
+
async getDeployStatus(deployId) {
|
|
76
|
+
return this.request("GET", `/deploy/${deployId}/status`);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get deployment logs
|
|
80
|
+
*/
|
|
81
|
+
async getDeployLogs(deployId) {
|
|
82
|
+
return this.request("GET", `/deploy/${deployId}/logs`);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* List projects/deployments
|
|
86
|
+
*/
|
|
87
|
+
async listProjects(status, perPage = 10) {
|
|
88
|
+
const params = new URLSearchParams();
|
|
89
|
+
if (status)
|
|
90
|
+
params.set("status", status);
|
|
91
|
+
params.set("per_page", String(perPage));
|
|
92
|
+
return this.request("GET", `/projects?${params.toString()}`);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* List server credentials
|
|
96
|
+
*/
|
|
97
|
+
async listCredentials() {
|
|
98
|
+
return this.request("GET", "/credentials");
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get current user info
|
|
102
|
+
*/
|
|
103
|
+
async me() {
|
|
104
|
+
return this.request("GET", "/me");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* OtoInstall MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Deploy projects directly from any MCP-compatible AI tool:
|
|
6
|
+
* Claude Desktop, Cursor, Windsurf, Cline, Continue, Zed, and more.
|
|
7
|
+
*
|
|
8
|
+
* Setup: Set OTOINSTALL_API_KEY and optionally OTOINSTALL_BASE_URL env vars.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* OtoInstall MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Deploy projects directly from any MCP-compatible AI tool:
|
|
6
|
+
* Claude Desktop, Cursor, Windsurf, Cline, Continue, Zed, and more.
|
|
7
|
+
*
|
|
8
|
+
* Setup: Set OTOINSTALL_API_KEY and optionally OTOINSTALL_BASE_URL env vars.
|
|
9
|
+
*/
|
|
10
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { OtoInstallClient } from "./api-client.js";
|
|
14
|
+
import { zipDirectory } from "./zip-utils.js";
|
|
15
|
+
import { existsSync } from "fs";
|
|
16
|
+
import { resolve, basename } from "path";
|
|
17
|
+
// ─── Configuration ───
|
|
18
|
+
const API_KEY = process.env.OTOINSTALL_API_KEY ?? "";
|
|
19
|
+
const BASE_URL = process.env.OTOINSTALL_BASE_URL ?? "https://otoinstall.com";
|
|
20
|
+
if (!API_KEY) {
|
|
21
|
+
console.error("❌ OTOINSTALL_API_KEY environment variable is required.");
|
|
22
|
+
console.error(" Get your key at: https://otoinstall.com/account/api-keys");
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const client = new OtoInstallClient(API_KEY, BASE_URL);
|
|
26
|
+
// ─── MCP Server ───
|
|
27
|
+
const server = new McpServer({
|
|
28
|
+
name: "otoinstall",
|
|
29
|
+
version: "1.0.0",
|
|
30
|
+
});
|
|
31
|
+
// ════════════════════════════════════════════════════════════════
|
|
32
|
+
// TOOL 1: deploy_project
|
|
33
|
+
// ════════════════════════════════════════════════════════════════
|
|
34
|
+
server.tool("deploy_project", "Deploy a project to a live server. Zips the specified directory and uploads it to OtoInstall for automated security scanning, auto-fixing, and deployment via FTP/SFTP/SSH.", {
|
|
35
|
+
directory: z.string().describe("Absolute path to the project directory to deploy"),
|
|
36
|
+
credential_id: z.number().describe("Server credential ID to deploy to (use list_servers to find IDs)"),
|
|
37
|
+
remote_path: z.string().optional().describe("Remote path on the server (optional, uses credential default)"),
|
|
38
|
+
target_url: z.string().optional().describe("Expected URL of the deployed site (optional)"),
|
|
39
|
+
project_type: z.enum(["auto", "laravel", "wordpress", "react", "vue", "nextjs", "html", "php"]).optional().describe("Project type hint (default: auto-detect)"),
|
|
40
|
+
}, async ({ directory, credential_id, remote_path, target_url, project_type }) => {
|
|
41
|
+
try {
|
|
42
|
+
// Validate directory exists
|
|
43
|
+
const absDir = resolve(directory);
|
|
44
|
+
if (!existsSync(absDir)) {
|
|
45
|
+
return { content: [{ type: "text", text: `❌ Directory not found: ${absDir}` }] };
|
|
46
|
+
}
|
|
47
|
+
// Zip the directory
|
|
48
|
+
const zipPath = await zipDirectory(absDir);
|
|
49
|
+
const zipName = `${basename(absDir)}.zip`;
|
|
50
|
+
// Deploy via API
|
|
51
|
+
const result = await client.deploy(zipPath, {
|
|
52
|
+
credential_id,
|
|
53
|
+
remote_path,
|
|
54
|
+
target_url,
|
|
55
|
+
project_type: project_type ?? "auto",
|
|
56
|
+
});
|
|
57
|
+
// Clean up temp zip
|
|
58
|
+
try {
|
|
59
|
+
(await import("fs")).unlinkSync(zipPath);
|
|
60
|
+
}
|
|
61
|
+
catch { }
|
|
62
|
+
return {
|
|
63
|
+
content: [{
|
|
64
|
+
type: "text",
|
|
65
|
+
text: [
|
|
66
|
+
`✅ Deployment started!`,
|
|
67
|
+
``,
|
|
68
|
+
`📦 Deploy ID: ${result.deploy_id}`,
|
|
69
|
+
`📊 Status: ${result.status}`,
|
|
70
|
+
`🔗 Status URL: ${result.links?.status ?? "N/A"}`,
|
|
71
|
+
`🌐 Web Dashboard: ${result.links?.web ?? "N/A"}`,
|
|
72
|
+
``,
|
|
73
|
+
`Use check_deploy_status with deploy_id "${result.deploy_id}" to monitor progress.`,
|
|
74
|
+
].join("\n"),
|
|
75
|
+
}],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return {
|
|
80
|
+
content: [{ type: "text", text: `❌ Deploy failed: ${error.message}` }],
|
|
81
|
+
isError: true,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
// ════════════════════════════════════════════════════════════════
|
|
86
|
+
// TOOL 2: deploy_zip
|
|
87
|
+
// ════════════════════════════════════════════════════════════════
|
|
88
|
+
server.tool("deploy_zip", "Deploy an existing ZIP file to a live server via OtoInstall. Use this when you already have a ZIP file ready.", {
|
|
89
|
+
zip_path: z.string().describe("Absolute path to the ZIP file to deploy"),
|
|
90
|
+
credential_id: z.number().describe("Server credential ID to deploy to"),
|
|
91
|
+
remote_path: z.string().optional().describe("Remote path on the server"),
|
|
92
|
+
target_url: z.string().optional().describe("Expected URL of the deployed site"),
|
|
93
|
+
project_type: z.enum(["auto", "laravel", "wordpress", "react", "vue", "nextjs", "html", "php"]).optional().describe("Project type hint"),
|
|
94
|
+
}, async ({ zip_path, credential_id, remote_path, target_url, project_type }) => {
|
|
95
|
+
try {
|
|
96
|
+
const absPath = resolve(zip_path);
|
|
97
|
+
if (!existsSync(absPath)) {
|
|
98
|
+
return { content: [{ type: "text", text: `❌ ZIP file not found: ${absPath}` }] };
|
|
99
|
+
}
|
|
100
|
+
const result = await client.deploy(absPath, {
|
|
101
|
+
credential_id,
|
|
102
|
+
remote_path,
|
|
103
|
+
target_url,
|
|
104
|
+
project_type: project_type ?? "auto",
|
|
105
|
+
});
|
|
106
|
+
return {
|
|
107
|
+
content: [{
|
|
108
|
+
type: "text",
|
|
109
|
+
text: [
|
|
110
|
+
`✅ Deployment started from ZIP!`,
|
|
111
|
+
``,
|
|
112
|
+
`📦 Deploy ID: ${result.deploy_id}`,
|
|
113
|
+
`📊 Status: ${result.status}`,
|
|
114
|
+
`🔗 Track: ${result.links?.status ?? "N/A"}`,
|
|
115
|
+
].join("\n"),
|
|
116
|
+
}],
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
return {
|
|
121
|
+
content: [{ type: "text", text: `❌ Deploy failed: ${error.message}` }],
|
|
122
|
+
isError: true,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
// ════════════════════════════════════════════════════════════════
|
|
127
|
+
// TOOL 3: check_deploy_status
|
|
128
|
+
// ════════════════════════════════════════════════════════════════
|
|
129
|
+
server.tool("check_deploy_status", "Check the current status of a deployment. Returns progress percentage, current phase, and any errors.", {
|
|
130
|
+
deploy_id: z.string().describe("The deployment ULID returned from deploy_project or deploy_zip"),
|
|
131
|
+
}, async ({ deploy_id }) => {
|
|
132
|
+
try {
|
|
133
|
+
const status = await client.getDeployStatus(deploy_id);
|
|
134
|
+
const statusEmoji = {
|
|
135
|
+
queued: "⏳", scanning: "🔍", detecting: "🔎",
|
|
136
|
+
compatibility_check: "🧪", fixing: "🔧",
|
|
137
|
+
local_testing: "🧪", deploying: "🚀",
|
|
138
|
+
verifying: "✅", completed: "🎉",
|
|
139
|
+
scan_failed: "❌", fix_failed: "❌",
|
|
140
|
+
deploy_failed: "❌", local_test_failed: "❌",
|
|
141
|
+
awaiting_user: "⏸️",
|
|
142
|
+
};
|
|
143
|
+
const emoji = statusEmoji[status.status] ?? "📊";
|
|
144
|
+
let text = [
|
|
145
|
+
`${emoji} Deployment Status`,
|
|
146
|
+
``,
|
|
147
|
+
`📦 Deploy ID: ${status.deploy_id}`,
|
|
148
|
+
`📊 Status: ${status.status}`,
|
|
149
|
+
`📈 Progress: ${status.progress}%`,
|
|
150
|
+
];
|
|
151
|
+
if (status.project_type)
|
|
152
|
+
text.push(`📁 Type: ${status.project_type}`);
|
|
153
|
+
if (status.target_url)
|
|
154
|
+
text.push(`🌐 URL: ${status.target_url}`);
|
|
155
|
+
if (status.security_score !== null && status.security_score !== undefined) {
|
|
156
|
+
text.push(`🛡️ Security Score: ${status.security_score}/100`);
|
|
157
|
+
}
|
|
158
|
+
if (status.started_at)
|
|
159
|
+
text.push(`⏱️ Started: ${status.started_at}`);
|
|
160
|
+
if (status.completed_at)
|
|
161
|
+
text.push(`✅ Completed: ${status.completed_at}`);
|
|
162
|
+
if (status.error)
|
|
163
|
+
text.push(`\n❌ Error: ${status.error}`);
|
|
164
|
+
return { content: [{ type: "text", text: text.join("\n") }] };
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
return {
|
|
168
|
+
content: [{ type: "text", text: `❌ Failed to check status: ${error.message}` }],
|
|
169
|
+
isError: true,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
// ════════════════════════════════════════════════════════════════
|
|
174
|
+
// TOOL 4: get_deploy_logs
|
|
175
|
+
// ════════════════════════════════════════════════════════════════
|
|
176
|
+
server.tool("get_deploy_logs", "Retrieve the detailed deployment logs for a specific deployment.", {
|
|
177
|
+
deploy_id: z.string().describe("The deployment ULID"),
|
|
178
|
+
}, async ({ deploy_id }) => {
|
|
179
|
+
try {
|
|
180
|
+
const data = await client.getDeployLogs(deploy_id);
|
|
181
|
+
if (!data.logs || data.logs.length === 0) {
|
|
182
|
+
return { content: [{ type: "text", text: `📋 No logs yet for deployment ${deploy_id}.` }] };
|
|
183
|
+
}
|
|
184
|
+
const logText = data.logs.map((log) => {
|
|
185
|
+
const levelEmoji = {
|
|
186
|
+
info: "ℹ️", warning: "⚠️", error: "❌", success: "✅", debug: "🔍"
|
|
187
|
+
};
|
|
188
|
+
return `${levelEmoji[log.level] ?? "•"} [${log.time}] ${log.message}`;
|
|
189
|
+
}).join("\n");
|
|
190
|
+
return {
|
|
191
|
+
content: [{ type: "text", text: `📋 Deployment Logs (${deploy_id}):\n\n${logText}` }],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
return {
|
|
196
|
+
content: [{ type: "text", text: `❌ Failed to get logs: ${error.message}` }],
|
|
197
|
+
isError: true,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
// ════════════════════════════════════════════════════════════════
|
|
202
|
+
// TOOL 5: list_projects
|
|
203
|
+
// ════════════════════════════════════════════════════════════════
|
|
204
|
+
server.tool("list_projects", "List all deployments (projects) for the current user. Shows status, progress, and URLs.", {
|
|
205
|
+
status: z.string().optional().describe("Filter by status: queued, scanning, deploying, completed, etc."),
|
|
206
|
+
per_page: z.number().optional().describe("Results per page (default: 10)"),
|
|
207
|
+
}, async ({ status, per_page }) => {
|
|
208
|
+
try {
|
|
209
|
+
const data = await client.listProjects(status, per_page ?? 10);
|
|
210
|
+
if (!data.data || data.data.length === 0) {
|
|
211
|
+
return { content: [{ type: "text", text: "📭 No deployments found." }] };
|
|
212
|
+
}
|
|
213
|
+
const projectList = data.data.map((p) => {
|
|
214
|
+
return [
|
|
215
|
+
`• ${p.filename} (${p.deploy_id})`,
|
|
216
|
+
` Status: ${p.status} | Progress: ${p.progress}%`,
|
|
217
|
+
p.target_url ? ` URL: ${p.target_url}` : null,
|
|
218
|
+
` Created: ${p.created_at}`,
|
|
219
|
+
].filter(Boolean).join("\n");
|
|
220
|
+
}).join("\n\n");
|
|
221
|
+
return {
|
|
222
|
+
content: [{
|
|
223
|
+
type: "text",
|
|
224
|
+
text: `📦 Deployments (${data.pagination.total} total):\n\n${projectList}`,
|
|
225
|
+
}],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
return {
|
|
230
|
+
content: [{ type: "text", text: `❌ Failed to list projects: ${error.message}` }],
|
|
231
|
+
isError: true,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
// ════════════════════════════════════════════════════════════════
|
|
236
|
+
// TOOL 6: list_servers
|
|
237
|
+
// ════════════════════════════════════════════════════════════════
|
|
238
|
+
server.tool("list_servers", "List all configured server credentials. Returns server IDs needed for deploy_project.", {}, async () => {
|
|
239
|
+
try {
|
|
240
|
+
const data = await client.listCredentials();
|
|
241
|
+
if (!data.data || data.data.length === 0) {
|
|
242
|
+
return {
|
|
243
|
+
content: [{
|
|
244
|
+
type: "text",
|
|
245
|
+
text: "📭 No servers configured. Add servers at your OtoInstall dashboard.",
|
|
246
|
+
}],
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
const serverList = data.data.map((s) => {
|
|
250
|
+
return `• [ID: ${s.id}] ${s.label} — ${s.protocol}://${s.username}@${s.host}:${s.port}${s.remote_path ?? ""}`;
|
|
251
|
+
}).join("\n");
|
|
252
|
+
return {
|
|
253
|
+
content: [{
|
|
254
|
+
type: "text",
|
|
255
|
+
text: `🖥️ Configured Servers:\n\n${serverList}\n\nUse the ID number with deploy_project's credential_id parameter.`,
|
|
256
|
+
}],
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
return {
|
|
261
|
+
content: [{ type: "text", text: `❌ Failed to list servers: ${error.message}` }],
|
|
262
|
+
isError: true,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
// ════════════════════════════════════════════════════════════════
|
|
267
|
+
// TOOL 7: whoami
|
|
268
|
+
// ════════════════════════════════════════════════════════════════
|
|
269
|
+
server.tool("whoami", "Check the current API key owner and permissions.", {}, async () => {
|
|
270
|
+
try {
|
|
271
|
+
const data = await client.me();
|
|
272
|
+
return {
|
|
273
|
+
content: [{
|
|
274
|
+
type: "text",
|
|
275
|
+
text: [
|
|
276
|
+
`👤 OtoInstall Account`,
|
|
277
|
+
``,
|
|
278
|
+
`Name: ${data.user.name}`,
|
|
279
|
+
`Email: ${data.user.email}`,
|
|
280
|
+
``,
|
|
281
|
+
`🔑 API Key: ${data.api_key.prefix}`,
|
|
282
|
+
`📋 Scopes: ${data.api_key.scopes.join(", ")}`,
|
|
283
|
+
`📊 Rate Limit: ${data.api_key.rate_limit}/hour`,
|
|
284
|
+
data.api_key.last_used ? `⏱️ Last Used: ${data.api_key.last_used}` : null,
|
|
285
|
+
].filter(Boolean).join("\n"),
|
|
286
|
+
}],
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
return {
|
|
291
|
+
content: [{ type: "text", text: `❌ Auth failed: ${error.message}` }],
|
|
292
|
+
isError: true,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
// ─── Start Server ───
|
|
297
|
+
async function main() {
|
|
298
|
+
const transport = new StdioServerTransport();
|
|
299
|
+
await server.connect(transport);
|
|
300
|
+
console.error("🚀 OtoInstall MCP Server running (stdio transport)");
|
|
301
|
+
}
|
|
302
|
+
main().catch((error) => {
|
|
303
|
+
console.error("Fatal error:", error);
|
|
304
|
+
process.exit(1);
|
|
305
|
+
});
|
|
306
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZIP Utilities
|
|
3
|
+
* Creates ZIP archives from directories for deployment.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Zip a directory and return the path to the temporary ZIP file.
|
|
7
|
+
* Excludes common non-deployable files (node_modules, .git, etc.)
|
|
8
|
+
*/
|
|
9
|
+
export declare function zipDirectory(dirPath: string): Promise<string>;
|
|
10
|
+
//# sourceMappingURL=zip-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip-utils.d.ts","sourceRoot":"","sources":["../src/zip-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+CnE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZIP Utilities
|
|
3
|
+
* Creates ZIP archives from directories for deployment.
|
|
4
|
+
*/
|
|
5
|
+
import archiver from "archiver";
|
|
6
|
+
import { createWriteStream, mkdtempSync } from "fs";
|
|
7
|
+
import { tmpdir } from "os";
|
|
8
|
+
import { join, basename } from "path";
|
|
9
|
+
/**
|
|
10
|
+
* Zip a directory and return the path to the temporary ZIP file.
|
|
11
|
+
* Excludes common non-deployable files (node_modules, .git, etc.)
|
|
12
|
+
*/
|
|
13
|
+
export async function zipDirectory(dirPath) {
|
|
14
|
+
const tempDir = mkdtempSync(join(tmpdir(), "otoinstall-"));
|
|
15
|
+
const zipPath = join(tempDir, `${basename(dirPath)}.zip`);
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const output = createWriteStream(zipPath);
|
|
18
|
+
const archive = archiver("zip", { zlib: { level: 6 } });
|
|
19
|
+
output.on("close", () => resolve(zipPath));
|
|
20
|
+
archive.on("error", (err) => reject(err));
|
|
21
|
+
archive.on("warning", (err) => {
|
|
22
|
+
if (err.code !== "ENOENT")
|
|
23
|
+
reject(err);
|
|
24
|
+
});
|
|
25
|
+
archive.pipe(output);
|
|
26
|
+
// Add directory contents, excluding heavy/unnecessary files
|
|
27
|
+
archive.glob("**/*", {
|
|
28
|
+
cwd: dirPath,
|
|
29
|
+
dot: true,
|
|
30
|
+
ignore: [
|
|
31
|
+
"node_modules/**",
|
|
32
|
+
".git/**",
|
|
33
|
+
".svn/**",
|
|
34
|
+
".hg/**",
|
|
35
|
+
".DS_Store",
|
|
36
|
+
"Thumbs.db",
|
|
37
|
+
"*.log",
|
|
38
|
+
".env.local",
|
|
39
|
+
".env.*.local",
|
|
40
|
+
"vendor/**",
|
|
41
|
+
"__pycache__/**",
|
|
42
|
+
"*.pyc",
|
|
43
|
+
".next/**",
|
|
44
|
+
"dist/**",
|
|
45
|
+
"build/**",
|
|
46
|
+
".cache/**",
|
|
47
|
+
"coverage/**",
|
|
48
|
+
".idea/**",
|
|
49
|
+
".vscode/**",
|
|
50
|
+
"*.swp",
|
|
51
|
+
"*.swo",
|
|
52
|
+
],
|
|
53
|
+
});
|
|
54
|
+
archive.finalize();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=zip-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip-utils.js","sourceRoot":"","sources":["../src/zip-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEtC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe;IAChD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1D,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAExD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3C,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;YAC5B,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAErB,4DAA4D;QAC5D,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE;YACnB,GAAG,EAAE,OAAO;YACZ,GAAG,EAAE,IAAI;YACT,MAAM,EAAE;gBACN,iBAAiB;gBACjB,SAAS;gBACT,SAAS;gBACT,QAAQ;gBACR,WAAW;gBACX,WAAW;gBACX,OAAO;gBACP,YAAY;gBACZ,cAAc;gBACd,WAAW;gBACX,gBAAgB;gBAChB,OAAO;gBACP,UAAU;gBACV,SAAS;gBACT,UAAU;gBACV,WAAW;gBACX,aAAa;gBACb,UAAU;gBACV,YAAY;gBACZ,OAAO;gBACP,OAAO;aACR;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,QAAQ,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "otoinstall-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OtoInstall MCP Server — Deploy projects from Claude, Cursor, Windsurf, Cline, Zed, and any MCP-compatible AI tool",
|
|
5
|
+
"keywords": ["mcp", "otoinstall", "deploy", "claude", "cursor", "windsurf", "cline", "ai-tools", "vibecoding"],
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "OtoInstall <hello@otoinstall.com>",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/ovkdigital/otoinstall-tools.git",
|
|
11
|
+
"directory": "packages/mcp-server"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://otoinstall.com",
|
|
14
|
+
"bugs": "https://github.com/ovkdigital/otoinstall/issues",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"bin": {
|
|
17
|
+
"otoinstall-mcp": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
|
+
"files": ["dist", "README.md"],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"dev": "tsc --watch",
|
|
24
|
+
"start": "node dist/index.js",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
29
|
+
"archiver": "^7.0.1",
|
|
30
|
+
"node-fetch": "^3.3.2",
|
|
31
|
+
"form-data": "^4.0.1",
|
|
32
|
+
"zod": "^3.23.8"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/archiver": "^6.0.3",
|
|
36
|
+
"@types/node": "^22.10.0",
|
|
37
|
+
"typescript": "^5.7.0"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.0.0"
|
|
41
|
+
}
|
|
42
|
+
}
|