@sota-io/mcp 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 +295 -0
- package/dist/api-client.d.ts +49 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +105 -0
- package/dist/api-client.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/deploy.d.ts +4 -0
- package/dist/tools/deploy.d.ts.map +1 -0
- package/dist/tools/deploy.js +55 -0
- package/dist/tools/deploy.js.map +1 -0
- package/dist/tools/env.d.ts +4 -0
- package/dist/tools/env.d.ts.map +1 -0
- package/dist/tools/env.js +75 -0
- package/dist/tools/env.js.map +1 -0
- package/dist/tools/logs.d.ts +4 -0
- package/dist/tools/logs.d.ts.map +1 -0
- package/dist/tools/logs.js +50 -0
- package/dist/tools/logs.js.map +1 -0
- package/dist/tools/projects.d.ts +4 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +65 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/rollback.d.ts +4 -0
- package/dist/tools/rollback.d.ts.map +1 -0
- package/dist/tools/rollback.js +33 -0
- package/dist/tools/rollback.js.map +1 -0
- package/dist/tools/status.d.ts +4 -0
- package/dist/tools/status.d.ts.map +1 -0
- package/dist/tools/status.js +63 -0
- package/dist/tools/status.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# @sota-io/mcp
|
|
2
|
+
|
|
3
|
+
MCP server for [sota.io](https://sota.io) — deploy web apps via AI agents.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@sota-io/mcp)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://nodejs.org)
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
1. Get an API key from [sota.io/dashboard/settings](https://sota.io/dashboard/settings)
|
|
12
|
+
2. [Configure your IDE](#configuration)
|
|
13
|
+
3. Ask your AI: *"Deploy my app to sota.io"*
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
**No install needed** — run directly with npx:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx -y @sota-io/mcp
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or install globally:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g @sota-io/mcp
|
|
27
|
+
sota-mcp
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Configuration
|
|
31
|
+
|
|
32
|
+
### Claude Code
|
|
33
|
+
|
|
34
|
+
**CLI method:**
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
claude mcp add sota -- npx -y @sota-io/mcp
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Then set your API key in the shell environment:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
export SOTA_API_KEY=sota_your_api_key_here
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Manual JSON** (`.claude/settings.json`):
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"sota": {
|
|
52
|
+
"command": "npx",
|
|
53
|
+
"args": ["-y", "@sota-io/mcp"],
|
|
54
|
+
"env": {
|
|
55
|
+
"SOTA_API_KEY": "sota_your_api_key_here"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Claude Desktop
|
|
63
|
+
|
|
64
|
+
Edit `claude_desktop_config.json`:
|
|
65
|
+
|
|
66
|
+
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
67
|
+
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"mcpServers": {
|
|
72
|
+
"sota": {
|
|
73
|
+
"command": "npx",
|
|
74
|
+
"args": ["-y", "@sota-io/mcp"],
|
|
75
|
+
"env": {
|
|
76
|
+
"SOTA_API_KEY": "sota_your_api_key_here"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Cursor
|
|
84
|
+
|
|
85
|
+
Create `.cursor/mcp.json` in your project root:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"mcpServers": {
|
|
90
|
+
"sota": {
|
|
91
|
+
"command": "npx",
|
|
92
|
+
"args": ["-y", "@sota-io/mcp"],
|
|
93
|
+
"env": {
|
|
94
|
+
"SOTA_API_KEY": "sota_your_api_key_here"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Windsurf
|
|
102
|
+
|
|
103
|
+
Edit `~/.codeium/windsurf/mcp_config.json`:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"mcpServers": {
|
|
108
|
+
"sota": {
|
|
109
|
+
"command": "npx",
|
|
110
|
+
"args": ["-y", "@sota-io/mcp"],
|
|
111
|
+
"env": {
|
|
112
|
+
"SOTA_API_KEY": "sota_your_api_key_here"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Tools
|
|
120
|
+
|
|
121
|
+
| Tool | Description | Parameters |
|
|
122
|
+
|------|-------------|------------|
|
|
123
|
+
| `deploy` | Deploy an app | `project_id`, `directory?` |
|
|
124
|
+
| `get-logs` | Get build/runtime logs | `project_id`, `deployment_id?` |
|
|
125
|
+
| `set-env` | Set environment variable | `project_id`, `key`, `value` |
|
|
126
|
+
| `get-env` | List environment variables | `project_id` |
|
|
127
|
+
| `rollback` | Rollback to previous deployment | `project_id` |
|
|
128
|
+
| `get-status` | Get deployment status | `project_id` |
|
|
129
|
+
| `list-projects` | List all projects | *(none)* |
|
|
130
|
+
| `create-project` | Create a new project | `name` |
|
|
131
|
+
|
|
132
|
+
### `deploy`
|
|
133
|
+
|
|
134
|
+
Deploy an application to sota.io. Creates a tar.gz archive of the specified directory and uploads it.
|
|
135
|
+
|
|
136
|
+
| Parameter | Type | Required | Description |
|
|
137
|
+
|-----------|------|----------|-------------|
|
|
138
|
+
| `project_id` | string | Yes | Project ID to deploy to |
|
|
139
|
+
| `directory` | string | No | Directory to deploy (defaults to current working directory) |
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
"Deploy my app in the current directory to sota.io"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### `get-logs`
|
|
146
|
+
|
|
147
|
+
Get build and runtime logs for a deployment. If no deployment_id is provided, returns logs for the latest deployment.
|
|
148
|
+
|
|
149
|
+
| Parameter | Type | Required | Description |
|
|
150
|
+
|-----------|------|----------|-------------|
|
|
151
|
+
| `project_id` | string | Yes | Project ID to get logs for |
|
|
152
|
+
| `deployment_id` | string | No | Specific deployment ID (defaults to latest) |
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
"Show me the build logs for my sota.io project"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### `set-env`
|
|
159
|
+
|
|
160
|
+
Set an environment variable for a project.
|
|
161
|
+
|
|
162
|
+
| Parameter | Type | Required | Description |
|
|
163
|
+
|-----------|------|----------|-------------|
|
|
164
|
+
| `project_id` | string | Yes | Project ID |
|
|
165
|
+
| `key` | string | Yes | Environment variable name (e.g., DATABASE_URL) |
|
|
166
|
+
| `value` | string | Yes | Environment variable value |
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
"Set DATABASE_URL on my project to postgres://localhost/mydb"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### `get-env`
|
|
173
|
+
|
|
174
|
+
List environment variables for a project.
|
|
175
|
+
|
|
176
|
+
| Parameter | Type | Required | Description |
|
|
177
|
+
|-----------|------|----------|-------------|
|
|
178
|
+
| `project_id` | string | Yes | Project ID |
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
"Show all environment variables for my project"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### `rollback`
|
|
185
|
+
|
|
186
|
+
Rollback a project to its previous deployment. This swaps the container image without rebuilding.
|
|
187
|
+
|
|
188
|
+
| Parameter | Type | Required | Description |
|
|
189
|
+
|-----------|------|----------|-------------|
|
|
190
|
+
| `project_id` | string | Yes | Project ID to rollback |
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
"Roll back my app to the previous version"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### `get-status`
|
|
197
|
+
|
|
198
|
+
Get the current deployment status for a project, including URL and recent deployment history.
|
|
199
|
+
|
|
200
|
+
| Parameter | Type | Required | Description |
|
|
201
|
+
|-----------|------|----------|-------------|
|
|
202
|
+
| `project_id` | string | Yes | Project ID to check status for |
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
"What's the status of my sota.io deployment?"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### `list-projects`
|
|
209
|
+
|
|
210
|
+
List all projects on your sota.io account.
|
|
211
|
+
|
|
212
|
+
*No parameters required.*
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
"List my sota.io projects"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### `create-project`
|
|
219
|
+
|
|
220
|
+
Create a new project on sota.io.
|
|
221
|
+
|
|
222
|
+
| Parameter | Type | Required | Description |
|
|
223
|
+
|-----------|------|----------|-------------|
|
|
224
|
+
| `name` | string | Yes | Name for the new project |
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
"Create a new sota.io project called my-api"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Environment Variables
|
|
231
|
+
|
|
232
|
+
| Variable | Required | Default | Description |
|
|
233
|
+
|----------|----------|---------|-------------|
|
|
234
|
+
| `SOTA_API_KEY` | Yes | — | API key with `sota_` prefix. Create at [sota.io/dashboard/settings](https://sota.io/dashboard/settings) |
|
|
235
|
+
| `SOTA_API_URL` | No | `https://api.sota.io` | API base URL |
|
|
236
|
+
|
|
237
|
+
## Troubleshooting
|
|
238
|
+
|
|
239
|
+
### "npx: command not found"
|
|
240
|
+
|
|
241
|
+
**Problem:** Your IDE doesn't inherit the shell PATH where nvm/fnm is loaded.
|
|
242
|
+
|
|
243
|
+
**Fix:** Use the absolute path to npx. Find it with:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
which npx
|
|
247
|
+
# Example output: /Users/you/.nvm/versions/node/v22.0.0/bin/npx
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Then update your MCP config to use the absolute path:
|
|
251
|
+
|
|
252
|
+
```json
|
|
253
|
+
{
|
|
254
|
+
"mcpServers": {
|
|
255
|
+
"sota": {
|
|
256
|
+
"command": "/Users/you/.nvm/versions/node/v22.0.0/bin/npx",
|
|
257
|
+
"args": ["-y", "@sota-io/mcp"],
|
|
258
|
+
"env": {
|
|
259
|
+
"SOTA_API_KEY": "sota_your_api_key_here"
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### "SOTA_API_KEY environment variable is required"
|
|
267
|
+
|
|
268
|
+
**Problem:** The API key is not set in your MCP configuration.
|
|
269
|
+
|
|
270
|
+
**Fix:** Add the `env` block to your MCP server config. Shell environment variables do **not** automatically pass to MCP servers — the `env` block in the config is required:
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"env": {
|
|
275
|
+
"SOTA_API_KEY": "sota_your_api_key_here"
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Connection refused or timeout errors
|
|
281
|
+
|
|
282
|
+
**Problem:** Network issue or wrong API URL.
|
|
283
|
+
|
|
284
|
+
**Fix:** Check your internet connection. If you're using a custom API URL, verify `SOTA_API_URL` is set correctly. The default is `https://api.sota.io`.
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
MIT
|
|
289
|
+
|
|
290
|
+
## Links
|
|
291
|
+
|
|
292
|
+
- [Website](https://sota.io)
|
|
293
|
+
- [Documentation](https://sota.io/docs/mcp)
|
|
294
|
+
- [Dashboard](https://sota.io/dashboard)
|
|
295
|
+
- [Issues](https://github.com/sota-io/mcp/issues)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the sota.io REST API.
|
|
3
|
+
* Used by MCP tools to interact with the platform.
|
|
4
|
+
*/
|
|
5
|
+
export interface Project {
|
|
6
|
+
id: string;
|
|
7
|
+
user_id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
slug: string;
|
|
10
|
+
created_at: string;
|
|
11
|
+
updated_at: string;
|
|
12
|
+
}
|
|
13
|
+
export interface Deployment {
|
|
14
|
+
id: string;
|
|
15
|
+
project_id: string;
|
|
16
|
+
status: string;
|
|
17
|
+
url?: string;
|
|
18
|
+
image_tag?: string;
|
|
19
|
+
build_method?: string;
|
|
20
|
+
framework?: string;
|
|
21
|
+
error?: string;
|
|
22
|
+
created_at: string;
|
|
23
|
+
updated_at: string;
|
|
24
|
+
}
|
|
25
|
+
export interface EnvVar {
|
|
26
|
+
id: string;
|
|
27
|
+
project_id: string;
|
|
28
|
+
key: string;
|
|
29
|
+
value?: string;
|
|
30
|
+
created_at: string;
|
|
31
|
+
updated_at: string;
|
|
32
|
+
}
|
|
33
|
+
export declare class SotaAPIClient {
|
|
34
|
+
private baseURL;
|
|
35
|
+
private apiKey;
|
|
36
|
+
constructor(baseURL: string, apiKey: string);
|
|
37
|
+
private request;
|
|
38
|
+
listProjects(): Promise<Project[]>;
|
|
39
|
+
createProject(name: string): Promise<Project>;
|
|
40
|
+
deploy(projectId: string, archiveBuffer: Buffer): Promise<Deployment>;
|
|
41
|
+
rollback(projectId: string): Promise<Deployment>;
|
|
42
|
+
getDeployments(projectId: string): Promise<Deployment[]>;
|
|
43
|
+
getLogs(projectId: string, deploymentId: string): Promise<string>;
|
|
44
|
+
setEnvVar(projectId: string, key: string, value: string): Promise<void>;
|
|
45
|
+
listEnvVars(projectId: string): Promise<EnvVar[]>;
|
|
46
|
+
deleteEnvVar(projectId: string, key: string): Promise<void>;
|
|
47
|
+
deleteProject(projectId: string): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
//# 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;AAEH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAqBD,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;YAK7B,OAAO;IAoBf,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAKlC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK7C,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiCrE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAKhD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAKxD,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBjE,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKjD,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAatD"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the sota.io REST API.
|
|
3
|
+
* Used by MCP tools to interact with the platform.
|
|
4
|
+
*/
|
|
5
|
+
export class SotaAPIClient {
|
|
6
|
+
baseURL;
|
|
7
|
+
apiKey;
|
|
8
|
+
constructor(baseURL, apiKey) {
|
|
9
|
+
this.baseURL = baseURL.replace(/\/$/, '');
|
|
10
|
+
this.apiKey = apiKey;
|
|
11
|
+
}
|
|
12
|
+
async request(method, path, body) {
|
|
13
|
+
const headers = {
|
|
14
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
15
|
+
'Content-Type': 'application/json',
|
|
16
|
+
};
|
|
17
|
+
const response = await fetch(`${this.baseURL}${path}`, {
|
|
18
|
+
method,
|
|
19
|
+
headers,
|
|
20
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
const errorBody = await response.json();
|
|
24
|
+
throw new Error(`API error: ${errorBody.error?.message || response.statusText}`);
|
|
25
|
+
}
|
|
26
|
+
return response.json();
|
|
27
|
+
}
|
|
28
|
+
async listProjects() {
|
|
29
|
+
const resp = await this.request('GET', '/v1/projects?limit=100');
|
|
30
|
+
return resp.data;
|
|
31
|
+
}
|
|
32
|
+
async createProject(name) {
|
|
33
|
+
const resp = await this.request('POST', '/v1/projects', { name });
|
|
34
|
+
return resp.data;
|
|
35
|
+
}
|
|
36
|
+
async deploy(projectId, archiveBuffer) {
|
|
37
|
+
const boundary = '----SotaMCPBoundary' + Date.now();
|
|
38
|
+
const headers = {
|
|
39
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
40
|
+
'Content-Type': `multipart/form-data; boundary=${boundary}`,
|
|
41
|
+
};
|
|
42
|
+
const bodyParts = [
|
|
43
|
+
`--${boundary}\r\n`,
|
|
44
|
+
`Content-Disposition: form-data; name="archive"; filename="archive.tar.gz"\r\n`,
|
|
45
|
+
`Content-Type: application/gzip\r\n`,
|
|
46
|
+
`\r\n`,
|
|
47
|
+
];
|
|
48
|
+
const prefix = Buffer.from(bodyParts.join(''));
|
|
49
|
+
const suffix = Buffer.from(`\r\n--${boundary}--\r\n`);
|
|
50
|
+
const body = Buffer.concat([prefix, archiveBuffer, suffix]);
|
|
51
|
+
const response = await fetch(`${this.baseURL}/v1/projects/${projectId}/deploy`, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers,
|
|
54
|
+
body,
|
|
55
|
+
});
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
const errorBody = await response.json();
|
|
58
|
+
throw new Error(`Deploy failed: ${errorBody.error?.message || response.statusText}`);
|
|
59
|
+
}
|
|
60
|
+
const resp = await response.json();
|
|
61
|
+
return resp.data;
|
|
62
|
+
}
|
|
63
|
+
async rollback(projectId) {
|
|
64
|
+
const resp = await this.request('POST', `/v1/projects/${projectId}/rollback`);
|
|
65
|
+
return resp.data;
|
|
66
|
+
}
|
|
67
|
+
async getDeployments(projectId) {
|
|
68
|
+
const resp = await this.request('GET', `/v1/projects/${projectId}/deployments`);
|
|
69
|
+
return resp.data;
|
|
70
|
+
}
|
|
71
|
+
async getLogs(projectId, deploymentId) {
|
|
72
|
+
const headers = {
|
|
73
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
74
|
+
};
|
|
75
|
+
const response = await fetch(`${this.baseURL}/v1/projects/${projectId}/deployments/${deploymentId}/logs`, { headers });
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
throw new Error(`Failed to get logs: ${response.statusText}`);
|
|
78
|
+
}
|
|
79
|
+
return response.text();
|
|
80
|
+
}
|
|
81
|
+
async setEnvVar(projectId, key, value) {
|
|
82
|
+
await this.request('POST', `/v1/projects/${projectId}/envs`, { key, value });
|
|
83
|
+
}
|
|
84
|
+
async listEnvVars(projectId) {
|
|
85
|
+
const resp = await this.request('GET', `/v1/projects/${projectId}/envs`);
|
|
86
|
+
return resp.data;
|
|
87
|
+
}
|
|
88
|
+
async deleteEnvVar(projectId, key) {
|
|
89
|
+
await this.request('DELETE', `/v1/projects/${projectId}/envs/${key}`);
|
|
90
|
+
}
|
|
91
|
+
async deleteProject(projectId) {
|
|
92
|
+
const headers = {
|
|
93
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
94
|
+
};
|
|
95
|
+
const response = await fetch(`${this.baseURL}/v1/projects/${projectId}`, {
|
|
96
|
+
method: 'DELETE',
|
|
97
|
+
headers,
|
|
98
|
+
});
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
const body = await response.json().catch(() => ({ error: { message: response.statusText } }));
|
|
101
|
+
throw new Error(`Delete failed: ${body.error?.message || response.statusText}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# 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,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* sota.io MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Exposes all sota.io platform operations as MCP tools for AI agents
|
|
6
|
+
* (Claude Code, Open CLAW, etc.)
|
|
7
|
+
*
|
|
8
|
+
* Environment variables:
|
|
9
|
+
* SOTA_API_KEY - API key for authentication (sota_... prefix)
|
|
10
|
+
* SOTA_API_URL - API base URL (default: https://api.sota.io)
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* sota.io MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Exposes all sota.io platform operations as MCP tools for AI agents
|
|
6
|
+
* (Claude Code, Open CLAW, etc.)
|
|
7
|
+
*
|
|
8
|
+
* Environment variables:
|
|
9
|
+
* SOTA_API_KEY - API key for authentication (sota_... prefix)
|
|
10
|
+
* SOTA_API_URL - API base URL (default: https://api.sota.io)
|
|
11
|
+
*/
|
|
12
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
13
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
14
|
+
import { SotaAPIClient } from './api-client.js';
|
|
15
|
+
import { registerProjectTools } from './tools/projects.js';
|
|
16
|
+
import { registerDeployTool } from './tools/deploy.js';
|
|
17
|
+
import { registerLogsTool } from './tools/logs.js';
|
|
18
|
+
import { registerEnvTools } from './tools/env.js';
|
|
19
|
+
import { registerRollbackTool } from './tools/rollback.js';
|
|
20
|
+
import { registerStatusTool } from './tools/status.js';
|
|
21
|
+
async function main() {
|
|
22
|
+
const apiKey = process.env.SOTA_API_KEY;
|
|
23
|
+
if (!apiKey) {
|
|
24
|
+
console.error('Error: SOTA_API_KEY environment variable is required');
|
|
25
|
+
console.error('Create one at: https://api.sota.io/v1/api-keys (or via sota CLI)');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const apiURL = process.env.SOTA_API_URL || 'https://api.sota.io';
|
|
29
|
+
const client = new SotaAPIClient(apiURL, apiKey);
|
|
30
|
+
const server = new McpServer({
|
|
31
|
+
name: 'sota',
|
|
32
|
+
version: '1.0.0',
|
|
33
|
+
});
|
|
34
|
+
// Register all tools
|
|
35
|
+
registerProjectTools(server, client);
|
|
36
|
+
registerDeployTool(server, client);
|
|
37
|
+
registerLogsTool(server, client);
|
|
38
|
+
registerEnvTools(server, client);
|
|
39
|
+
registerRollbackTool(server, client);
|
|
40
|
+
registerStatusTool(server, client);
|
|
41
|
+
// Start stdio transport
|
|
42
|
+
const transport = new StdioServerTransport();
|
|
43
|
+
await server.connect(transport);
|
|
44
|
+
}
|
|
45
|
+
main().catch((error) => {
|
|
46
|
+
console.error('Fatal error:', error);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;QACtE,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,qBAAqB,CAAC;IAEjE,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,qBAAqB;IACrB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEnC,wBAAwB;IACxB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/tools/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,QAwD1E"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { resolve } from 'path';
|
|
5
|
+
export function registerDeployTool(server, client) {
|
|
6
|
+
server.registerTool('deploy', {
|
|
7
|
+
description: 'Deploy an application to sota.io. Creates a tar.gz archive of the specified directory and uploads it.',
|
|
8
|
+
inputSchema: {
|
|
9
|
+
project_id: z.string().describe('Project ID to deploy to'),
|
|
10
|
+
directory: z.string().optional().describe('Directory to deploy (defaults to current working directory)'),
|
|
11
|
+
},
|
|
12
|
+
}, async ({ project_id, directory }) => {
|
|
13
|
+
const dir = directory ? resolve(directory) : process.cwd();
|
|
14
|
+
if (!existsSync(dir)) {
|
|
15
|
+
return {
|
|
16
|
+
content: [
|
|
17
|
+
{
|
|
18
|
+
type: 'text',
|
|
19
|
+
text: `Error: Directory not found: ${dir}`,
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
isError: true,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
// Create tar.gz archive using system tar (excludes common ignores)
|
|
27
|
+
const archivePath = `/tmp/sota-deploy-${Date.now()}.tar.gz`;
|
|
28
|
+
execSync(`tar -czf ${archivePath} --exclude='.git' --exclude='node_modules' --exclude='.env' --exclude='.DS_Store' -C ${dir} .`, { stdio: 'pipe' });
|
|
29
|
+
const { readFileSync, unlinkSync } = await import('fs');
|
|
30
|
+
const archiveBuffer = readFileSync(archivePath);
|
|
31
|
+
unlinkSync(archivePath);
|
|
32
|
+
const deployment = await client.deploy(project_id, archiveBuffer);
|
|
33
|
+
return {
|
|
34
|
+
content: [
|
|
35
|
+
{
|
|
36
|
+
type: 'text',
|
|
37
|
+
text: `Deployment started:\n ID: ${deployment.id}\n Status: ${deployment.status}\n URL: ${deployment.url || 'pending'}\n\nUse get-logs to check build progress.`,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
text: `Deploy failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
isError: true,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/tools/deploy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAG/B,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAqB;IACzE,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE;QAC5B,WAAW,EAAE,uGAAuG;QACpH,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YAC1D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6DAA6D,CAAC;SACzG;KACF,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAE3D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,+BAA+B,GAAG,EAAE;qBAC3C;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,mEAAmE;YACnE,MAAM,WAAW,GAAG,oBAAoB,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC;YAC5D,QAAQ,CACN,YAAY,WAAW,wFAAwF,GAAG,IAAI,EACtH,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;YAEF,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YACxD,MAAM,aAAa,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;YAChD,UAAU,CAAC,WAAW,CAAC,CAAC;YAExB,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;YAElE,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,8BAA8B,UAAU,CAAC,EAAE,eAAe,UAAU,CAAC,MAAM,YAAY,UAAU,CAAC,GAAG,IAAI,SAAS,2CAA2C;qBACpK;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,kBAAkB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACjF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/tools/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,QAwExE"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerEnvTools(server, client) {
|
|
3
|
+
server.registerTool('set-env', {
|
|
4
|
+
description: 'Set an environment variable for a project',
|
|
5
|
+
inputSchema: {
|
|
6
|
+
project_id: z.string().describe('Project ID'),
|
|
7
|
+
key: z.string().describe('Environment variable name (e.g., DATABASE_URL)'),
|
|
8
|
+
value: z.string().describe('Environment variable value'),
|
|
9
|
+
},
|
|
10
|
+
}, async ({ project_id, key, value }) => {
|
|
11
|
+
try {
|
|
12
|
+
await client.setEnvVar(project_id, key, value);
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: 'text',
|
|
17
|
+
text: `Environment variable ${key} set successfully.`,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
return {
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
type: 'text',
|
|
27
|
+
text: `Failed to set env var: ${error instanceof Error ? error.message : String(error)}`,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
isError: true,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
server.registerTool('get-env', {
|
|
35
|
+
description: 'List environment variables for a project',
|
|
36
|
+
inputSchema: {
|
|
37
|
+
project_id: z.string().describe('Project ID'),
|
|
38
|
+
},
|
|
39
|
+
}, async ({ project_id }) => {
|
|
40
|
+
try {
|
|
41
|
+
const envVars = await client.listEnvVars(project_id);
|
|
42
|
+
if (envVars.length === 0) {
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
text: 'No environment variables set.',
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const lines = envVars.map((ev) => `${ev.key}=${ev.value || '****'}`);
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: `Environment variables:\n${lines.join('\n')}`,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: 'text',
|
|
67
|
+
text: `Failed to list env vars: ${error instanceof Error ? error.message : String(error)}`,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
isError: true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/tools/env.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAqB;IACvE,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE;QAC7B,WAAW,EAAE,2CAA2C;QACxD,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;YAC7C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;YAC1E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SACzD;KACF,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,wBAAwB,GAAG,oBAAoB;qBACtD;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACzF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE;QAC7B,WAAW,EAAE,0CAA0C;QACvD,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;SAC9C;KACF,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QAC1B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,+BAA+B;yBACtC;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC;YACrE,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,2BAA2B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;qBACpD;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBAC3F;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/tools/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,QAiDxE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerLogsTool(server, client) {
|
|
3
|
+
server.registerTool('get-logs', {
|
|
4
|
+
description: 'Get build and runtime logs for a deployment. If no deployment_id is provided, returns logs for the latest deployment.',
|
|
5
|
+
inputSchema: {
|
|
6
|
+
project_id: z.string().describe('Project ID to get logs for'),
|
|
7
|
+
deployment_id: z.string().optional().describe('Specific deployment ID (optional, defaults to latest)'),
|
|
8
|
+
},
|
|
9
|
+
}, async ({ project_id, deployment_id }) => {
|
|
10
|
+
try {
|
|
11
|
+
let deployId = deployment_id;
|
|
12
|
+
if (!deployId) {
|
|
13
|
+
// Get latest deployment
|
|
14
|
+
const deployments = await client.getDeployments(project_id);
|
|
15
|
+
if (deployments.length === 0) {
|
|
16
|
+
return {
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
type: 'text',
|
|
20
|
+
text: 'No deployments found for this project.',
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
deployId = deployments[0].id;
|
|
26
|
+
}
|
|
27
|
+
const logs = await client.getLogs(project_id, deployId);
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{
|
|
31
|
+
type: 'text',
|
|
32
|
+
text: logs || 'No logs available yet.',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: 'text',
|
|
42
|
+
text: `Failed to get logs: ${error instanceof Error ? error.message : String(error)}`,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
isError: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/tools/logs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAqB;IACvE,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE;QAC9B,WAAW,EAAE,uHAAuH;QACpI,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC7D,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;SACvG;KACF,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,EAAE,EAAE;QACzC,IAAI,CAAC;YACH,IAAI,QAAQ,GAAG,aAAa,CAAC;YAE7B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,wBAAwB;gBACxB,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;gBAC5D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC7B,OAAO;wBACL,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,wCAAwC;6BAC/C;yBACF;qBACF,CAAC;gBACJ,CAAC;gBACD,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAExD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,IAAI,wBAAwB;qBACvC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,uBAAuB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACtF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,QAiE5E"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerProjectTools(server, client) {
|
|
3
|
+
server.registerTool('list-projects', {
|
|
4
|
+
description: 'List all projects on your sota.io account',
|
|
5
|
+
}, async () => {
|
|
6
|
+
const projects = await client.listProjects();
|
|
7
|
+
const lines = projects.map((p) => `${p.name} (${p.slug}) - ID: ${p.id}`);
|
|
8
|
+
return {
|
|
9
|
+
content: [
|
|
10
|
+
{
|
|
11
|
+
type: 'text',
|
|
12
|
+
text: projects.length === 0
|
|
13
|
+
? 'No projects found. Use create-project to create one.'
|
|
14
|
+
: `Projects:\n${lines.join('\n')}`,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
server.registerTool('create-project', {
|
|
20
|
+
description: 'Create a new project on sota.io',
|
|
21
|
+
inputSchema: {
|
|
22
|
+
name: z.string().describe('Name for the new project'),
|
|
23
|
+
},
|
|
24
|
+
}, async ({ name }) => {
|
|
25
|
+
const project = await client.createProject(name);
|
|
26
|
+
return {
|
|
27
|
+
content: [
|
|
28
|
+
{
|
|
29
|
+
type: 'text',
|
|
30
|
+
text: `Project created:\n Name: ${project.name}\n Slug: ${project.slug}\n ID: ${project.id}\n URL: https://${project.slug}.sota.io`,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
server.registerTool('delete-project', {
|
|
36
|
+
description: 'Delete a project and all its deployments from sota.io. This action is permanent.',
|
|
37
|
+
inputSchema: {
|
|
38
|
+
project_id: z.string().describe('Project ID to delete'),
|
|
39
|
+
},
|
|
40
|
+
}, async ({ project_id }) => {
|
|
41
|
+
try {
|
|
42
|
+
await client.deleteProject(project_id);
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
text: `Project ${project_id} deleted successfully.`,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: `Delete failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
isError: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,MAAqB;IAC3E,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE;QACnC,WAAW,EAAE,2CAA2C;KACzD,EAAE,KAAK,IAAI,EAAE;QACZ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CACxB,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,EAAE,CAC7C,CAAC;QACF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;wBACzB,CAAC,CAAC,sDAAsD;wBACxD,CAAC,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBACrC;aACF;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,gBAAgB,EAAE;QACpC,WAAW,EAAE,iCAAiC;QAC9C,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;SACtD;KACF,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACpB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,6BAA6B,OAAO,CAAC,IAAI,aAAa,OAAO,CAAC,IAAI,WAAW,OAAO,CAAC,EAAE,oBAAoB,OAAO,CAAC,IAAI,UAAU;iBACxI;aACF;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,gBAAgB,EAAE;QACpC,WAAW,EAAE,kFAAkF;QAC/F,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;SACxD;KACF,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YACvC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,WAAW,UAAU,wBAAwB;qBACpD;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,kBAAkB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACjF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/tools/rollback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,QA6B5E"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerRollbackTool(server, client) {
|
|
3
|
+
server.registerTool('rollback', {
|
|
4
|
+
description: 'Rollback a project to its previous deployment. This swaps the container image without rebuilding.',
|
|
5
|
+
inputSchema: {
|
|
6
|
+
project_id: z.string().describe('Project ID to rollback'),
|
|
7
|
+
},
|
|
8
|
+
}, async ({ project_id }) => {
|
|
9
|
+
try {
|
|
10
|
+
const deployment = await client.rollback(project_id);
|
|
11
|
+
return {
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
type: 'text',
|
|
15
|
+
text: `Rollback successful:\n Deployment ID: ${deployment.id}\n Status: ${deployment.status}\n URL: ${deployment.url || 'pending'}`,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
return {
|
|
22
|
+
content: [
|
|
23
|
+
{
|
|
24
|
+
type: 'text',
|
|
25
|
+
text: `Rollback failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
isError: true,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=rollback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.js","sourceRoot":"","sources":["../../src/tools/rollback.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,MAAqB;IAC3E,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE;QAC9B,WAAW,EAAE,mGAAmG;QAChH,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SAC1D;KACF,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QAC1B,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACrD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,0CAA0C,UAAU,CAAC,EAAE,eAAe,UAAU,CAAC,MAAM,YAAY,UAAU,CAAC,GAAG,IAAI,SAAS,EAAE;qBACvI;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,oBAAoB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACnF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/tools/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,QAgE1E"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerStatusTool(server, client) {
|
|
3
|
+
server.registerTool('get-status', {
|
|
4
|
+
description: 'Get the current deployment status for a project, including URL and recent deployment history',
|
|
5
|
+
inputSchema: {
|
|
6
|
+
project_id: z.string().describe('Project ID to check status for'),
|
|
7
|
+
},
|
|
8
|
+
}, async ({ project_id }) => {
|
|
9
|
+
try {
|
|
10
|
+
const deployments = await client.getDeployments(project_id);
|
|
11
|
+
if (deployments.length === 0) {
|
|
12
|
+
return {
|
|
13
|
+
content: [
|
|
14
|
+
{
|
|
15
|
+
type: 'text',
|
|
16
|
+
text: 'No deployments found. Use the deploy tool to deploy your app.',
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const latest = deployments[0];
|
|
22
|
+
const lines = [
|
|
23
|
+
`Current deployment:`,
|
|
24
|
+
` ID: ${latest.id}`,
|
|
25
|
+
` Status: ${latest.status}`,
|
|
26
|
+
` URL: ${latest.url || 'not available'}`,
|
|
27
|
+
` Created: ${latest.created_at}`,
|
|
28
|
+
];
|
|
29
|
+
if (latest.framework) {
|
|
30
|
+
lines.push(` Framework: ${latest.framework}`);
|
|
31
|
+
}
|
|
32
|
+
if (latest.error) {
|
|
33
|
+
lines.push(` Error: ${latest.error}`);
|
|
34
|
+
}
|
|
35
|
+
if (deployments.length > 1) {
|
|
36
|
+
lines.push('', 'Recent deployments:');
|
|
37
|
+
for (const d of deployments.slice(1, 5)) {
|
|
38
|
+
lines.push(` ${d.id.slice(0, 8)} - ${d.status} (${d.created_at})`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
content: [
|
|
43
|
+
{
|
|
44
|
+
type: 'text',
|
|
45
|
+
text: lines.join('\n'),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: `Failed to get status: ${error instanceof Error ? error.message : String(error)}`,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
isError: true,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/tools/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAqB;IACzE,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE;QAChC,WAAW,EAAE,8FAA8F;QAC3G,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;SAClE;KACF,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QAC1B,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;YAE5D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,+DAA+D;yBACtE;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC9B,MAAM,KAAK,GAAG;gBACZ,qBAAqB;gBACrB,SAAS,MAAM,CAAC,EAAE,EAAE;gBACpB,aAAa,MAAM,CAAC,MAAM,EAAE;gBAC5B,UAAU,MAAM,CAAC,GAAG,IAAI,eAAe,EAAE;gBACzC,cAAc,MAAM,CAAC,UAAU,EAAE;aAClC,CAAC;YAEF,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YACjD,CAAC;YACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACzC,CAAC;YAED,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC;gBACtC,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBACxC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;YAED,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;qBACvB;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,yBAAyB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACxF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sota-io/mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"mcpName": "io.github.sota-io/sota",
|
|
5
|
+
"description": "MCP server for sota.io - deploy web apps via AI agents",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"sota-mcp": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"start": "node dist/index.js",
|
|
17
|
+
"dev": "tsx src/index.ts",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/sota-io/mcp"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://sota.io/docs/mcp",
|
|
25
|
+
"keywords": [
|
|
26
|
+
"mcp",
|
|
27
|
+
"model-context-protocol",
|
|
28
|
+
"sota",
|
|
29
|
+
"deploy",
|
|
30
|
+
"paas",
|
|
31
|
+
"ai-agent",
|
|
32
|
+
"claude",
|
|
33
|
+
"devops"
|
|
34
|
+
],
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@modelcontextprotocol/sdk": "^1.27.0",
|
|
40
|
+
"zod": "^3.25.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"typescript": "^5.7.0",
|
|
44
|
+
"tsx": "^4.0.0",
|
|
45
|
+
"@types/node": "^22.0.0"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=20.0.0"
|
|
49
|
+
},
|
|
50
|
+
"license": "MIT"
|
|
51
|
+
}
|