@shipstatic/mcp 0.1.13 → 0.3.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.
Files changed (3) hide show
  1. package/README.md +17 -15
  2. package/dist/server.js +56 -33
  3. package/package.json +5 -5
package/README.md CHANGED
@@ -44,29 +44,31 @@ Get your API key at [my.shipstatic.com](https://my.shipstatic.com).
44
44
 
45
45
  | Tool | Description |
46
46
  |------|-------------|
47
- | `deployments_upload` | Upload deployment from directory |
48
- | `deployments_list` | List all deployments |
49
- | `deployments_get` | Show deployment information |
50
- | `deployments_set` | Set deployment labels |
51
- | `deployments_remove` | Delete deployment permanently |
47
+ | `deployments_upload` | Deploy a static site by uploading files from a directory |
48
+ | `deployments_list` | List all deployments with their URLs, status, and labels |
49
+ | `deployments_get` | Get deployment details including URL, status, file count, size, and labels |
50
+ | `deployments_set` | Update deployment labels |
51
+ | `deployments_remove` | Permanently delete a deployment and its files |
52
52
 
53
53
  ### Domains
54
54
 
55
55
  | Tool | Description |
56
56
  |------|-------------|
57
- | `domains_set` | Create domain, link to deployment, or update labels |
58
- | `domains_list` | List all domains |
59
- | `domains_get` | Show domain information |
60
- | `domains_records` | Get required DNS records for a domain |
61
- | `domains_validate` | Check if domain name is valid and available |
62
- | `domains_verify` | Trigger DNS verification for external domain |
63
- | `domains_remove` | Delete domain permanently |
64
-
65
- ### Debugging
57
+ | `domains_set` | Create or update a custom domain |
58
+ | `domains_list` | List all domains with their linked deployments and verification status |
59
+ | `domains_get` | Get domain details including linked deployment, verification status, and labels |
60
+ | `domains_records` | Get the DNS records the user needs to configure at their DNS provider |
61
+ | `domains_dns` | Look up the DNS provider for a domain |
62
+ | `domains_share` | Get a shareable DNS setup hash for a domain |
63
+ | `domains_validate` | Check if a domain name is valid and available |
64
+ | `domains_verify` | Trigger DNS verification for a custom domain |
65
+ | `domains_remove` | Permanently delete a domain |
66
+
67
+ ### Account
66
68
 
67
69
  | Tool | Description |
68
70
  |------|-------------|
69
- | `whoami` | Show current account information |
71
+ | `whoami` | Show authenticated account details including email, plan, and usage |
70
72
 
71
73
  ## Registry
72
74
 
package/dist/server.js CHANGED
@@ -2,104 +2,127 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { z } from 'zod';
3
3
  import { call } from './call.js';
4
4
  const OPEN_WORLD = { openWorldHint: true };
5
- const READ = { readOnlyHint: true, idempotentHint: true, ...OPEN_WORLD };
6
- const WRITE = { idempotentHint: true, ...OPEN_WORLD };
5
+ 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 };
7
8
  const DESTRUCTIVE = { destructiveHint: true, idempotentHint: true, ...OPEN_WORLD };
9
+ const INSTRUCTIONS = `ShipStatic hosts static websites.
10
+
11
+ Concepts:
12
+ - Deployment: an immutable set of uploaded files. Every deployment gets a permanent URL (e.g. happy-cat-abc1234.shipstatic.com) immediately — no domain setup needed.
13
+ - Domain: a custom domain (e.g. www.example.com) that points to a deployment. Optional. Only subdomains are supported (www.example.com, blog.example.com) — not apex domains (example.com).
14
+
15
+ To deploy a site: call deployments_upload with the absolute path to the build output directory. The response includes the deployment hostname.
16
+
17
+ To add a custom domain: domains_validate → domains_set (with the deployment) → domains_records (show the DNS records to the user) → user configures DNS → domains_verify.`;
8
18
  export function createServer(ship) {
9
19
  const server = new McpServer({
10
20
  name: 'shipstatic',
11
- version: '0.1.13',
21
+ version: '0.2.0',
12
22
  }, {
13
- instructions: 'Deploy a static site to ShipStatic and link it to your domain. To deploy, call deployments_upload with the path to your build output directory. To set up a custom domain, first call domains_validate to check the name, then domains_set to link it to a deployment, then domains_records to get the required DNS records. After DNS is configured, call domains_verify to trigger verification.',
23
+ instructions: INSTRUCTIONS,
14
24
  });
15
25
  // Deployments
16
26
  server.registerTool('deployments_upload', {
17
- description: 'Upload deployment from directory',
18
- annotations: OPEN_WORLD,
27
+ description: 'Deploy a static site by uploading files from a directory. Returns the deployment details including hostname, file count, and size.',
28
+ annotations: CREATE,
19
29
  inputSchema: {
20
- path: z.string().describe('Absolute path to directory or file to deploy'),
21
- subdomain: z.string().optional().describe('Suggested subdomain'),
22
- labels: z.array(z.string()).optional().describe('Labels'),
30
+ path: z.string().describe('Absolute path to the build output directory to deploy (e.g. "/Users/me/project/dist")'),
31
+ labels: z.array(z.string()).optional().describe('Labels for organizing deployments (e.g. ["production", "v1.2"]). Lowercase, 3-25 chars, allows . _ - separators.'),
23
32
  },
24
- }, ({ path, subdomain, labels }) => call(() => ship.deployments.upload(path, { subdomain, labels, via: 'mcp' })));
33
+ }, ({ path, labels }) => call(() => ship.deployments.upload(path, { labels, via: 'mcp' })));
25
34
  server.registerTool('deployments_list', {
26
- description: 'List all deployments',
35
+ description: 'List all deployments with their hostnames, status, and labels.',
27
36
  annotations: READ,
28
37
  }, () => call(() => ship.deployments.list()));
29
38
  server.registerTool('deployments_get', {
30
- description: 'Show deployment information',
39
+ description: 'Get deployment details including status, file count, size, and labels.',
31
40
  annotations: READ,
32
41
  inputSchema: {
33
- deployment: z.string().describe('Deployment ID (e.g. "happy-cat-abc1234")'),
42
+ deployment: z.string().describe('Deployment hostname (e.g. "happy-cat-abc1234.shipstatic.com"). Returned by deployments_upload or deployments_list.'),
34
43
  },
35
44
  }, ({ deployment }) => call(() => ship.deployments.get(deployment)));
36
45
  server.registerTool('deployments_set', {
37
- description: 'Set deployment labels',
46
+ description: 'Update deployment labels. Replaces all existing labels.',
38
47
  annotations: WRITE,
39
48
  inputSchema: {
40
- deployment: z.string().describe('Deployment ID'),
41
- labels: z.array(z.string()).describe('New labels for the deployment'),
49
+ deployment: z.string().describe('Deployment hostname (e.g. "happy-cat-abc1234.shipstatic.com"). Use deployments_list to find deployments.'),
50
+ labels: z.array(z.string()).describe('Labels to set. Replaces all existing labels. Pass empty array to clear.'),
42
51
  },
43
52
  }, ({ deployment, labels }) => call(() => ship.deployments.set(deployment, { labels })));
44
53
  server.registerTool('deployments_remove', {
45
- description: 'Delete deployment permanently',
54
+ description: 'Permanently delete a deployment and its files. You MUST confirm with the user before calling this tool, referencing the deployment.',
46
55
  annotations: DESTRUCTIVE,
47
56
  inputSchema: {
48
- deployment: z.string().describe('Deployment ID to delete'),
57
+ deployment: z.string().describe('Deployment hostname to delete (e.g. "happy-cat-abc1234.shipstatic.com")'),
49
58
  },
50
59
  }, ({ deployment }) => call(() => ship.deployments.remove(deployment)));
51
60
  // Domains
52
61
  server.registerTool('domains_set', {
53
- description: 'Create domain, link to deployment, or update labels',
62
+ description: 'Create or update a custom domain. Can reserve a name (omit deployment), link it to a deployment, switch deployments, or update labels. After creating, call domains_records and show the DNS records to the user.',
54
63
  annotations: WRITE,
55
64
  inputSchema: {
56
65
  domain: z.string().describe('Domain name (e.g. "www.example.com" or "blog.example.com")'),
57
- deployment: z.string().optional().describe('Deployment ID to link to this domain'),
58
- labels: z.array(z.string()).optional().describe('Labels'),
66
+ deployment: z.string().optional().describe('Deployment to serve on this domain (e.g. "happy-cat-abc1234.shipstatic.com"). Omit to reserve the domain without linking.'),
67
+ labels: z.array(z.string()).optional().describe('Labels for organizing domains (e.g. ["production"]).'),
59
68
  },
60
69
  }, ({ domain, deployment, labels }) => call(() => ship.domains.set(domain, { deployment, labels })));
61
70
  server.registerTool('domains_list', {
62
- description: 'List all domains',
71
+ description: 'List all domains with their linked deployments and verification status.',
63
72
  annotations: READ,
64
73
  }, () => call(() => ship.domains.list()));
65
74
  server.registerTool('domains_get', {
66
- description: 'Show domain information',
75
+ description: 'Get domain details including linked deployment, verification status, and labels.',
67
76
  annotations: READ,
68
77
  inputSchema: {
69
- domain: z.string().describe('Domain name'),
78
+ domain: z.string().describe('Domain name (e.g. "www.example.com"). Use domains_list to find names.'),
70
79
  },
71
80
  }, ({ domain }) => call(() => ship.domains.get(domain)));
72
81
  server.registerTool('domains_records', {
73
- description: 'Get required DNS records for a domain',
82
+ description: 'Get the DNS records the user needs to configure at their DNS provider. Call after domains_set. You MUST show the returned records to the user.',
74
83
  annotations: READ,
75
84
  inputSchema: {
76
- domain: z.string().describe('Domain name'),
85
+ domain: z.string().describe('Domain name. Must be a domain previously created with domains_set.'),
77
86
  },
78
87
  }, ({ domain }) => call(() => ship.domains.records(domain)));
88
+ server.registerTool('domains_dns', {
89
+ description: 'Look up the DNS provider for a domain (e.g. Cloudflare, Namecheap). Helps the user know where to configure their DNS records.',
90
+ annotations: READ,
91
+ inputSchema: {
92
+ domain: z.string().describe('Domain name to look up DNS provider for (e.g. "www.example.com")'),
93
+ },
94
+ }, ({ domain }) => call(() => ship.domains.dns(domain)));
95
+ server.registerTool('domains_share', {
96
+ description: 'Get a shareable DNS setup hash for a domain. The hash can be shared with the user so they can view the required DNS records without needing an API key.',
97
+ annotations: READ,
98
+ inputSchema: {
99
+ domain: z.string().describe('Domain name to generate a share link for. Must be a domain previously created with domains_set.'),
100
+ },
101
+ }, ({ domain }) => call(() => ship.domains.share(domain)));
79
102
  server.registerTool('domains_validate', {
80
- description: 'Check if domain name is valid and available',
103
+ description: 'Check if a domain name is valid and available before creating it. Returns the normalized form and availability.',
81
104
  annotations: READ,
82
105
  inputSchema: {
83
- domain: z.string().describe('Domain name to validate'),
106
+ domain: z.string().describe('Domain name to check (e.g. "www.example.com"). Call before domains_set to check availability.'),
84
107
  },
85
108
  }, ({ domain }) => call(() => ship.domains.validate(domain)));
86
109
  server.registerTool('domains_verify', {
87
- description: 'Trigger DNS verification for external domain',
110
+ description: 'Trigger DNS verification for a custom domain. Call after the user has configured DNS records from domains_records. Verification is asynchronous — the domain status updates once DNS propagates.',
88
111
  annotations: WRITE,
89
112
  inputSchema: {
90
- domain: z.string().describe('Domain name'),
113
+ domain: z.string().describe('Domain name to verify DNS for. Must be a domain previously created with domains_set.'),
91
114
  },
92
115
  }, ({ domain }) => call(() => ship.domains.verify(domain)));
93
116
  server.registerTool('domains_remove', {
94
- description: 'Delete domain permanently',
117
+ description: 'Permanently delete a domain. You MUST confirm with the user before calling this tool, referencing the domain name.',
95
118
  annotations: DESTRUCTIVE,
96
119
  inputSchema: {
97
- domain: z.string().describe('Domain name to delete'),
120
+ domain: z.string().describe('Domain name to delete (e.g. "www.example.com")'),
98
121
  },
99
122
  }, ({ domain }) => call(() => ship.domains.remove(domain)));
100
123
  // Debugging
101
124
  server.registerTool('whoami', {
102
- description: 'Show current account information',
125
+ description: 'Show authenticated account details including email, plan, and usage.',
103
126
  annotations: READ,
104
127
  }, () => call(() => ship.whoami()));
105
128
  return server;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipstatic/mcp",
3
- "version": "0.1.13",
3
+ "version": "0.3.0",
4
4
  "mcpName": "com.shipstatic/mcp",
5
5
  "description": "MCP server for ShipStatic — deploy and manage static sites from AI agents",
6
6
  "type": "module",
@@ -41,13 +41,13 @@
41
41
  "author": "ShipStatic",
42
42
  "license": "MIT",
43
43
  "dependencies": {
44
- "@modelcontextprotocol/sdk": "^1.27.0",
45
- "@shipstatic/ship": "^0.7.18",
44
+ "@modelcontextprotocol/sdk": "^1.28.0",
45
+ "@shipstatic/ship": "^0.8.1",
46
46
  "zod": "^4.3.6"
47
47
  },
48
48
  "devDependencies": {
49
- "@shipstatic/types": "^0.7.1",
50
- "@types/node": "^20.0.0",
49
+ "@shipstatic/types": "^0.8.1",
50
+ "@types/node": "^20.19.37",
51
51
  "husky": "^9.1.7",
52
52
  "typescript": "^5.9.3",
53
53
  "vitest": "^3.2.4"