@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 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
+ [![npm](https://img.shields.io/npm/v/@sota-io/mcp)](https://www.npmjs.com/package/@sota-io/mcp)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+ [![Node](https://img.shields.io/badge/node-%3E%3D20-green)](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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"}
@@ -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,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { SotaAPIClient } from '../api-client.js';
3
+ export declare function registerDeployTool(server: McpServer, client: SotaAPIClient): void;
4
+ //# sourceMappingURL=deploy.d.ts.map
@@ -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,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { SotaAPIClient } from '../api-client.js';
3
+ export declare function registerEnvTools(server: McpServer, client: SotaAPIClient): void;
4
+ //# sourceMappingURL=env.d.ts.map
@@ -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,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { SotaAPIClient } from '../api-client.js';
3
+ export declare function registerLogsTool(server: McpServer, client: SotaAPIClient): void;
4
+ //# sourceMappingURL=logs.d.ts.map
@@ -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,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { SotaAPIClient } from '../api-client.js';
3
+ export declare function registerProjectTools(server: McpServer, client: SotaAPIClient): void;
4
+ //# sourceMappingURL=projects.d.ts.map
@@ -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,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { SotaAPIClient } from '../api-client.js';
3
+ export declare function registerRollbackTool(server: McpServer, client: SotaAPIClient): void;
4
+ //# sourceMappingURL=rollback.d.ts.map
@@ -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,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { SotaAPIClient } from '../api-client.js';
3
+ export declare function registerStatusTool(server: McpServer, client: SotaAPIClient): void;
4
+ //# sourceMappingURL=status.d.ts.map
@@ -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
+ }