@shipstatic/mcp 0.1.12 → 0.2.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 -32
  3. package/package.json +1 -1
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,128 @@ 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.dev) 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 live URL.
16
+
17
+ To add a custom domain: domains_validate → domains_set (with the deployment ID) → 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.12',
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 with its live URL, 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
+ subdomain: z.string().optional().describe('Preferred subdomain for the deployment URL (e.g. "my-site" for my-site.shipstatic.dev). If unavailable or omitted, a random name is assigned.'),
32
+ labels: z.array(z.string()).optional().describe('Labels for organizing deployments (e.g. ["production", "v1.2"]). Lowercase, 3-25 chars, allows . _ - separators.'),
23
33
  },
24
34
  }, ({ path, subdomain, labels }) => call(() => ship.deployments.upload(path, { subdomain, labels, via: 'mcp' })));
25
35
  server.registerTool('deployments_list', {
26
- description: 'List all deployments',
36
+ description: 'List all deployments with their URLs, status, and labels.',
27
37
  annotations: READ,
28
38
  }, () => call(() => ship.deployments.list()));
29
39
  server.registerTool('deployments_get', {
30
- description: 'Show deployment information',
40
+ description: 'Get deployment details including URL, status, file count, size, and labels.',
31
41
  annotations: READ,
32
42
  inputSchema: {
33
- deployment: z.string().describe('Deployment ID (e.g. "happy-cat-abc1234")'),
43
+ deployment: z.string().describe('Deployment ID (e.g. "happy-cat-abc1234"). Returned by deployments_upload or deployments_list.'),
34
44
  },
35
45
  }, ({ deployment }) => call(() => ship.deployments.get(deployment)));
36
46
  server.registerTool('deployments_set', {
37
- description: 'Set deployment labels',
47
+ description: 'Update deployment labels. Replaces all existing labels.',
38
48
  annotations: WRITE,
39
49
  inputSchema: {
40
- deployment: z.string().describe('Deployment ID'),
41
- labels: z.array(z.string()).describe('New labels for the deployment'),
50
+ deployment: z.string().describe('Deployment ID (e.g. "happy-cat-abc1234"). Use deployments_list to find IDs.'),
51
+ labels: z.array(z.string()).describe('Labels to set. Replaces all existing labels. Pass empty array to clear.'),
42
52
  },
43
53
  }, ({ deployment, labels }) => call(() => ship.deployments.set(deployment, { labels })));
44
54
  server.registerTool('deployments_remove', {
45
- description: 'Delete deployment permanently',
55
+ description: 'Permanently delete a deployment and its files. You MUST confirm with the user before calling this tool, referencing the deployment ID.',
46
56
  annotations: DESTRUCTIVE,
47
57
  inputSchema: {
48
- deployment: z.string().describe('Deployment ID to delete'),
58
+ deployment: z.string().describe('Deployment ID to delete (e.g. "happy-cat-abc1234")'),
49
59
  },
50
60
  }, ({ deployment }) => call(() => ship.deployments.remove(deployment)));
51
61
  // Domains
52
62
  server.registerTool('domains_set', {
53
- description: 'Create domain, link to deployment, or update labels',
63
+ 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
64
  annotations: WRITE,
55
65
  inputSchema: {
56
66
  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'),
67
+ deployment: z.string().optional().describe('Deployment ID to serve on this domain (e.g. "happy-cat-abc1234"). Omit to reserve the domain without linking.'),
68
+ labels: z.array(z.string()).optional().describe('Labels for organizing domains (e.g. ["production"]).'),
59
69
  },
60
70
  }, ({ domain, deployment, labels }) => call(() => ship.domains.set(domain, { deployment, labels })));
61
71
  server.registerTool('domains_list', {
62
- description: 'List all domains',
72
+ description: 'List all domains with their linked deployments and verification status.',
63
73
  annotations: READ,
64
74
  }, () => call(() => ship.domains.list()));
65
75
  server.registerTool('domains_get', {
66
- description: 'Show domain information',
76
+ description: 'Get domain details including linked deployment, verification status, and labels.',
67
77
  annotations: READ,
68
78
  inputSchema: {
69
- domain: z.string().describe('Domain name'),
79
+ domain: z.string().describe('Domain name (e.g. "www.example.com"). Use domains_list to find names.'),
70
80
  },
71
81
  }, ({ domain }) => call(() => ship.domains.get(domain)));
72
82
  server.registerTool('domains_records', {
73
- description: 'Get required DNS records for a domain',
83
+ 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
84
  annotations: READ,
75
85
  inputSchema: {
76
- domain: z.string().describe('Domain name'),
86
+ domain: z.string().describe('Domain name. Must be a domain previously created with domains_set.'),
77
87
  },
78
88
  }, ({ domain }) => call(() => ship.domains.records(domain)));
89
+ server.registerTool('domains_dns', {
90
+ description: 'Look up the DNS provider for a domain (e.g. Cloudflare, Namecheap). Helps the user know where to configure their DNS records.',
91
+ annotations: READ,
92
+ inputSchema: {
93
+ domain: z.string().describe('Domain name to look up DNS provider for (e.g. "www.example.com")'),
94
+ },
95
+ }, ({ domain }) => call(() => ship.domains.dns(domain)));
96
+ server.registerTool('domains_share', {
97
+ 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.',
98
+ annotations: READ,
99
+ inputSchema: {
100
+ domain: z.string().describe('Domain name to generate a share link for. Must be a domain previously created with domains_set.'),
101
+ },
102
+ }, ({ domain }) => call(() => ship.domains.share(domain)));
79
103
  server.registerTool('domains_validate', {
80
- description: 'Check if domain name is valid and available',
104
+ description: 'Check if a domain name is valid and available before creating it. Returns the normalized form and availability.',
81
105
  annotations: READ,
82
106
  inputSchema: {
83
- domain: z.string().describe('Domain name to validate'),
107
+ domain: z.string().describe('Domain name to check (e.g. "www.example.com"). Call before domains_set to check availability.'),
84
108
  },
85
109
  }, ({ domain }) => call(() => ship.domains.validate(domain)));
86
110
  server.registerTool('domains_verify', {
87
- description: 'Trigger DNS verification for external domain',
111
+ 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
112
  annotations: WRITE,
89
113
  inputSchema: {
90
- domain: z.string().describe('Domain name'),
114
+ domain: z.string().describe('Domain name to verify DNS for. Must be a domain previously created with domains_set.'),
91
115
  },
92
116
  }, ({ domain }) => call(() => ship.domains.verify(domain)));
93
117
  server.registerTool('domains_remove', {
94
- description: 'Delete domain permanently',
118
+ description: 'Permanently delete a domain. You MUST confirm with the user before calling this tool, referencing the domain name.',
95
119
  annotations: DESTRUCTIVE,
96
120
  inputSchema: {
97
- domain: z.string().describe('Domain name to delete'),
121
+ domain: z.string().describe('Domain name to delete (e.g. "www.example.com")'),
98
122
  },
99
123
  }, ({ domain }) => call(() => ship.domains.remove(domain)));
100
124
  // Debugging
101
125
  server.registerTool('whoami', {
102
- description: 'Show current account information',
126
+ description: 'Show authenticated account details including email, plan, and usage.',
103
127
  annotations: READ,
104
128
  }, () => call(() => ship.whoami()));
105
129
  return server;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipstatic/mcp",
3
- "version": "0.1.12",
3
+ "version": "0.2.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",