@shipstatic/mcp 0.4.5 → 0.4.7
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 +9 -7
- package/dist/call.js +10 -2
- package/dist/index.js +3 -2
- package/dist/server.js +14 -10
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -52,9 +52,11 @@ Same config format — `npx @shipstatic/mcp` via stdio. Works with any MCP-compa
|
|
|
52
52
|
|
|
53
53
|
Ask your AI agent to deploy a site. No API key, no sign-up, no configuration.
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Your site is live instantly on `*.shipstatic.com`.
|
|
56
56
|
|
|
57
|
-
Deployments without an API key are public and expire in 3 days.
|
|
57
|
+
Deployments without an API key are public and expire in 3 days. The response includes a **claim URL** — always show it to the user so they can keep the site permanently.
|
|
58
|
+
|
|
59
|
+
Want a private site? Ask your agent to set a password when deploying — visitors will be prompted to unlock before viewing, on the deployment URL and on any custom domains pointing at it.
|
|
58
60
|
|
|
59
61
|
## All Tools — Free API Key
|
|
60
62
|
|
|
@@ -68,9 +70,9 @@ claude mcp add shipstatic -e SHIP_API_KEY=ship-... -- npx @shipstatic/mcp
|
|
|
68
70
|
|
|
69
71
|
| Tool | Description |
|
|
70
72
|
|------|-------------|
|
|
71
|
-
| `deployments_upload` | Publish files and get a live URL instantly |
|
|
72
|
-
| `deployments_list` | List all
|
|
73
|
-
| `deployments_get` | Get details
|
|
73
|
+
| `deployments_upload` | Publish files and get a live URL instantly, optionally protected by a password |
|
|
74
|
+
| `deployments_list` | List all deployments with their URLs, status, and labels |
|
|
75
|
+
| `deployments_get` | Get deployment details including URL, status, file count, size, and labels |
|
|
74
76
|
| `deployments_set` | Update the labels on a deployment for organization and filtering |
|
|
75
77
|
| `deployments_remove` | Permanently remove a deployment and all its files |
|
|
76
78
|
|
|
@@ -79,8 +81,8 @@ claude mcp add shipstatic -e SHIP_API_KEY=ship-... -- npx @shipstatic/mcp
|
|
|
79
81
|
| Tool | Description |
|
|
80
82
|
|------|-------------|
|
|
81
83
|
| `domains_set` | Connect a custom domain to your site, switch deployments, or update labels |
|
|
82
|
-
| `domains_list` | List all
|
|
83
|
-
| `domains_get` | Get details
|
|
84
|
+
| `domains_list` | List all domains with their linked deployments and verification status |
|
|
85
|
+
| `domains_get` | Get domain details including linked deployment, verification status, and labels |
|
|
84
86
|
| `domains_records` | Get the DNS records you need to configure at your DNS provider |
|
|
85
87
|
| `domains_dns` | Look up which DNS provider hosts a domain (e.g. Cloudflare, Namecheap) |
|
|
86
88
|
| `domains_share` | Get a shareable link so someone else can see the required DNS records |
|
package/dist/call.js
CHANGED
|
@@ -14,11 +14,11 @@ export async function call(fn) {
|
|
|
14
14
|
function handleError(error) {
|
|
15
15
|
if (isShipError(error)) {
|
|
16
16
|
let message = error.message;
|
|
17
|
-
if (error.isType(ErrorType.Authentication)
|
|
17
|
+
if (error.isType(ErrorType.Authentication)) {
|
|
18
18
|
message += '\n\nHint: Set a free SHIP_API_KEY environment variable in your MCP server configuration.';
|
|
19
19
|
}
|
|
20
20
|
if (error.isType(ErrorType.Validation) && error.details) {
|
|
21
|
-
message += `\n\nDetails: ${
|
|
21
|
+
message += `\n\nDetails: ${safeStringify(error.details)}`;
|
|
22
22
|
}
|
|
23
23
|
return {
|
|
24
24
|
content: [{ type: 'text', text: message }],
|
|
@@ -31,3 +31,11 @@ function handleError(error) {
|
|
|
31
31
|
isError: true,
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
+
function safeStringify(value) {
|
|
35
|
+
try {
|
|
36
|
+
return JSON.stringify(value);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return String(value);
|
|
40
|
+
}
|
|
41
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import Ship from '@shipstatic/ship';
|
|
4
4
|
import { createServer } from './server.js';
|
|
5
|
-
const apiKey = process.env.SHIP_API_KEY;
|
|
6
5
|
async function main() {
|
|
7
|
-
|
|
6
|
+
// SHIP_API_KEY is optional — without it, deployments are public (3-day expiry).
|
|
7
|
+
// The SDK coerces empty strings to undefined, so we can pass through directly.
|
|
8
|
+
const ship = new Ship({ apiKey: process.env.SHIP_API_KEY });
|
|
8
9
|
const server = createServer(ship);
|
|
9
10
|
const transport = new StdioServerTransport();
|
|
10
11
|
await server.connect(transport);
|
package/dist/server.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import { LABEL_CONSTRAINTS, PASSWORD_CONSTRAINTS } from '@shipstatic/ship';
|
|
1
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
2
4
|
import { z } from 'zod';
|
|
3
5
|
import { call } from './call.js';
|
|
6
|
+
const { version } = createRequire(import.meta.url)('../package.json');
|
|
4
7
|
const OPEN_WORLD = { openWorldHint: true };
|
|
5
8
|
const READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, ...OPEN_WORLD };
|
|
6
|
-
const CREATE = { destructiveHint: false, ...OPEN_WORLD };
|
|
7
|
-
const WRITE = { destructiveHint: false, idempotentHint: true, ...OPEN_WORLD };
|
|
8
|
-
const DESTRUCTIVE = { destructiveHint: true, idempotentHint: true, ...OPEN_WORLD };
|
|
9
|
+
const CREATE = { readOnlyHint: false, destructiveHint: false, ...OPEN_WORLD };
|
|
10
|
+
const WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, ...OPEN_WORLD };
|
|
11
|
+
const DESTRUCTIVE = { readOnlyHint: false, destructiveHint: true, idempotentHint: true, ...OPEN_WORLD };
|
|
9
12
|
const INSTRUCTIONS = `ShipStatic deploys static websites instantly. No account required.
|
|
10
13
|
|
|
11
|
-
To deploy: call deployments_upload with the build output directory path. The site is live immediately.
|
|
14
|
+
To deploy: call deployments_upload with the build output directory path. The site is live immediately. To make the site private, pass \`password\` — visitors must unlock before viewing, including on any custom domains pointing at it.
|
|
12
15
|
|
|
13
16
|
Without SHIP_API_KEY, deployments are public and expire in 3 days. The response includes a claim URL — always show the deployment URL and the claim URL to the user so they can keep the site permanently.
|
|
14
17
|
|
|
@@ -22,25 +25,26 @@ To add a custom domain: domains_validate → domains_set → domains_records (sh
|
|
|
22
25
|
export function createServer(ship) {
|
|
23
26
|
const server = new McpServer({
|
|
24
27
|
name: 'shipstatic',
|
|
25
|
-
version
|
|
28
|
+
version,
|
|
26
29
|
}, {
|
|
27
30
|
instructions: INSTRUCTIONS,
|
|
28
31
|
});
|
|
29
32
|
// Deployments
|
|
30
33
|
server.registerTool('deployments_upload', {
|
|
31
|
-
description: 'Deploy a static site instantly. No account or API key required. Returns the live URL, file count, and size. Without SHIP_API_KEY, the response includes a claim URL (site expires in 3 days) — always show both the deployment URL and claim URL to the user.',
|
|
34
|
+
description: 'Deploy a static site instantly. No account or API key required. Returns the live URL, file count, and size. Without SHIP_API_KEY, the response includes a claim URL (site expires in 3 days) — always show both the deployment URL and claim URL to the user. To make the site private, pass `password`; always show the password to the user if you set one.',
|
|
32
35
|
annotations: CREATE,
|
|
33
36
|
inputSchema: {
|
|
34
37
|
path: z.string().describe('Absolute path to the build output directory to deploy (e.g. "/Users/me/project/dist")'),
|
|
35
|
-
labels: z.array(z.string()).optional().describe(
|
|
38
|
+
labels: z.array(z.string()).optional().describe(`Labels for organizing deployments (e.g. ["production", "v1.2"]). Lowercase, ${LABEL_CONSTRAINTS.MIN_LENGTH}-${LABEL_CONSTRAINTS.MAX_LENGTH} chars, allows . _ - separators.`),
|
|
39
|
+
password: z.string().optional().describe(`Optional password to gate the deployment behind an unlock prompt (${PASSWORD_CONSTRAINTS.MIN_LENGTH}–${PASSWORD_CONSTRAINTS.MAX_LENGTH} characters; whitespace significant). Visitors must enter this password before viewing the site, including on any custom domains pointing at it.`),
|
|
36
40
|
},
|
|
37
|
-
}, ({ path, labels }) => call(() => ship.deployments.upload(path, { labels, via: 'mcp' })));
|
|
41
|
+
}, ({ path, labels, password }) => call(() => ship.deployments.upload(path, { labels, password, via: 'mcp' })));
|
|
38
42
|
server.registerTool('deployments_list', {
|
|
39
|
-
description: 'List all deployments with their URLs, status, and
|
|
43
|
+
description: 'List all deployments with their URLs, status, labels, and password protection state.',
|
|
40
44
|
annotations: READ,
|
|
41
45
|
}, () => call(() => ship.deployments.list()));
|
|
42
46
|
server.registerTool('deployments_get', {
|
|
43
|
-
description: 'Get deployment details including URL, status, file count, size, and
|
|
47
|
+
description: 'Get deployment details including URL, status, file count, size, labels, and password protection state.',
|
|
44
48
|
annotations: READ,
|
|
45
49
|
inputSchema: {
|
|
46
50
|
deployment: z.string().describe('Deployment hostname (e.g. "happy-cat-abc1234.shipstatic.com"). Returned by deployments_upload or deployments_list.'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipstatic/mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"mcpName": "com.shipstatic/mcp",
|
|
5
5
|
"description": "Free, no account needed — deploy static websites, landing pages, and prototypes instantly from AI agents",
|
|
6
6
|
"type": "module",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"license": "MIT",
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
48
|
-
"@shipstatic/ship": "^0.
|
|
48
|
+
"@shipstatic/ship": "^0.9.1",
|
|
49
49
|
"zod": "^4.3.6"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@shipstatic/types": "^0.
|
|
52
|
+
"@shipstatic/types": "^0.9.1",
|
|
53
53
|
"@types/node": "^25.6.0",
|
|
54
54
|
"husky": "^9.1.7",
|
|
55
55
|
"typescript": "^6.0.2",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build": "tsc",
|
|
60
60
|
"clean": "rm -rf dist",
|
|
61
|
-
"test": "vitest"
|
|
61
|
+
"test": "vitest",
|
|
62
|
+
"typecheck": "tsc --noEmit -p tsconfig.test.json"
|
|
62
63
|
}
|
|
63
64
|
}
|