@shipstatic/mcp 1.0.0-beta.5 → 1.0.0-beta.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 CHANGED
@@ -85,7 +85,7 @@ Same config format — `npx @shipstatic/mcp`. Works with any MCP-compatible clie
85
85
 
86
86
  ## Free API key — permanent deployments
87
87
 
88
- `SHIP_TOKEN` is optional. Without it, deploys behave like the hosted endpoint (public, claim URL, 3-day expiry). With it, you get permanent deployments, the full toolset, and bigger limits.
88
+ `SHIP_TOKEN` is optional. Without it, deploys behave like the hosted endpoint (public, claim URL, expire in 3 days). With it, you get permanent deployments, the full toolset, and bigger limits.
89
89
 
90
90
  Get a free API key at [my.shipstatic.com/api-key](https://my.shipstatic.com/api-key):
91
91
 
package/dist/index.d.ts CHANGED
@@ -1,34 +1,57 @@
1
1
  /**
2
2
  * The library entry — importing this file has NO side effects.
3
3
  *
4
- * `bin.ts` is the executable; this is what a consumer imports. Today there is
5
- * one such consumer, the hosted Streamable-HTTP transport in the platform's
6
- * private `cloudflare/mcp`, and both transports are converging on the same
7
- * product: the complete toolset for authenticated callers, the anonymous
8
- * deploy for everyone else. "One product, two transports" is only true if one
9
- * of them can import the other.
4
+ * `bin.ts` is the executable; this is what a consumer imports. There are two
5
+ * such consumers: the hosted Streamable-HTTP transport in the platform's
6
+ * private `cloudflare/mcp`, and the VS Code extension
7
+ * (`integrations/vscode`), which bundles a stdio server into its `.vsix`.
8
+ * Both transports are converging on the same product the complete toolset
9
+ * for authenticated callers, the anonymous deploy for everyone else — and
10
+ * "one product, two transports" is only true if one of them can import the
11
+ * other.
10
12
  *
11
- * **The surface is exactly what a SECOND TRANSPORT needs — nothing more.**
12
- * That is the rule, and it is stricter than "curated". `createServer` and the
13
- * configured `call` are deliberately NOT here: they are stdio's own
14
- * composition, they have no consumer outside `bin.ts`, and `createServer` in
15
- * particular builds a tool whose input is a filesystem PATH — a footgun to
16
- * offer a Worker. Exporting them would make this package's API "stdio's
17
- * internals, plus some shared bits" instead of a contract.
13
+ * **The surface is exactly what a SECOND CONSUMER needs — nothing more.**
14
+ * That is the rule, and it is stricter than "curated". It read "a second
15
+ * TRANSPORT" until 1.0.0-beta.7, when the VS Code extension arrived as a
16
+ * consumer that is not a transport: it wants stdio's own composition,
17
+ * verbatim, running on the user's machine. The wording widened; the strictness
18
+ * did not.
18
19
  *
19
- * Every name below answers a question the second transport must otherwise
20
- * answer for itself, and each admission was a restatement deleted, not a
21
- * convenience added: `SERVER_NAME` and `UPLOAD_TOOL_NAME` were literals in two
22
- * repos (the first also correlates the Apps-SDK widget to the connector),
23
- * `PUBLIC_EXPIRY` was the same duration written out eight times,
24
- * `DESCRIPTION_BLOCKS` the fragments two tool descriptions genuinely share,
25
- * and `ACCOUNT_TOOL_NAMES` is what lets the hosted catalogue fence name the
26
- * fourteen without counting them again.
20
+ * Every name below answers a question a consumer must otherwise answer for
21
+ * itself, and each admission was a restatement deleted, not a convenience
22
+ * added: `SERVER_NAME` and `UPLOAD_TOOL_NAME` were literals in two repos (the
23
+ * first also correlates the Apps-SDK widget to the connector), `PUBLIC_EXPIRY`
24
+ * was the same duration written out eight times, `DESCRIPTION_BLOCKS` the
25
+ * fragments two tool descriptions genuinely share, `ACCOUNT_TOOL_NAMES` is
26
+ * what lets the hosted catalogue fence name the fourteen without counting them
27
+ * again, and `createServer` deleted three regexes in another repo's build (see
28
+ * below).
29
+ *
30
+ * **`createServer` is exported; the configured `call` is not.** The extension
31
+ * previously reached stdio's composition by REGEX-PATCHING this package's
32
+ * compiled `dist/` at bundle time — stripping `bin`'s shebang, and rewriting
33
+ * the `createRequire(import.meta.url)('../package.json')` line inside
34
+ * `server.js` to inline a version literal. Three hacks against another
35
+ * package's build output, each of which the 1.x library split broke. A
36
+ * fifteen-line entry point calling `createServer(ship, version)` replaces all
37
+ * of them, which is a restatement deleted rather than a convenience added.
38
+ * `call` stays internal because a consumer configures its own hints through
39
+ * `createCall`, and stdio's instance is not a contract anyone needs.
40
+ *
41
+ * The old reason for withholding `createServer` — that its upload tool takes a
42
+ * filesystem PATH, a footgun to offer a Worker — is still true and is now the
43
+ * CALLER's judgement rather than an absence: `cloudflare/mcp` must keep
44
+ * authoring its own upload tool, and does. An absence cannot express "correct
45
+ * for one consumer, wrong for another"; a documented rule can. What makes the
46
+ * export safe to publish at all is that `createServer` takes its `version` as
47
+ * an ARGUMENT — so exporting it adds no `node:module` to the import graph of a
48
+ * module the Workers-hosted transport loads.
27
49
  *
28
50
  * `tests/index.test.ts` fences both directions — nothing missing, nothing
29
51
  * extra — because adding an export is the quiet failure: everything published
30
52
  * becomes a breaking change to remove.
31
53
  */
32
54
  export { type CallFn, type CallOptions, createCall, type ErrorHints } from './call.js';
55
+ export { createServer } from './server.js';
33
56
  export { ACCOUNT_TOOL_NAMES, registerAccountTools } from './tools.js';
34
57
  export { ANNOTATIONS, DESCRIPTION_BLOCKS, INSTRUCTION_BLOCKS, PARAM_DESCRIPTIONS, PUBLIC_EXPIRY, SERVER_NAME, UPLOAD_TOOL_NAME, } from './vocabulary.js';
package/dist/index.js CHANGED
@@ -1,34 +1,57 @@
1
1
  /**
2
2
  * The library entry — importing this file has NO side effects.
3
3
  *
4
- * `bin.ts` is the executable; this is what a consumer imports. Today there is
5
- * one such consumer, the hosted Streamable-HTTP transport in the platform's
6
- * private `cloudflare/mcp`, and both transports are converging on the same
7
- * product: the complete toolset for authenticated callers, the anonymous
8
- * deploy for everyone else. "One product, two transports" is only true if one
9
- * of them can import the other.
4
+ * `bin.ts` is the executable; this is what a consumer imports. There are two
5
+ * such consumers: the hosted Streamable-HTTP transport in the platform's
6
+ * private `cloudflare/mcp`, and the VS Code extension
7
+ * (`integrations/vscode`), which bundles a stdio server into its `.vsix`.
8
+ * Both transports are converging on the same product the complete toolset
9
+ * for authenticated callers, the anonymous deploy for everyone else — and
10
+ * "one product, two transports" is only true if one of them can import the
11
+ * other.
10
12
  *
11
- * **The surface is exactly what a SECOND TRANSPORT needs — nothing more.**
12
- * That is the rule, and it is stricter than "curated". `createServer` and the
13
- * configured `call` are deliberately NOT here: they are stdio's own
14
- * composition, they have no consumer outside `bin.ts`, and `createServer` in
15
- * particular builds a tool whose input is a filesystem PATH — a footgun to
16
- * offer a Worker. Exporting them would make this package's API "stdio's
17
- * internals, plus some shared bits" instead of a contract.
13
+ * **The surface is exactly what a SECOND CONSUMER needs — nothing more.**
14
+ * That is the rule, and it is stricter than "curated". It read "a second
15
+ * TRANSPORT" until 1.0.0-beta.7, when the VS Code extension arrived as a
16
+ * consumer that is not a transport: it wants stdio's own composition,
17
+ * verbatim, running on the user's machine. The wording widened; the strictness
18
+ * did not.
18
19
  *
19
- * Every name below answers a question the second transport must otherwise
20
- * answer for itself, and each admission was a restatement deleted, not a
21
- * convenience added: `SERVER_NAME` and `UPLOAD_TOOL_NAME` were literals in two
22
- * repos (the first also correlates the Apps-SDK widget to the connector),
23
- * `PUBLIC_EXPIRY` was the same duration written out eight times,
24
- * `DESCRIPTION_BLOCKS` the fragments two tool descriptions genuinely share,
25
- * and `ACCOUNT_TOOL_NAMES` is what lets the hosted catalogue fence name the
26
- * fourteen without counting them again.
20
+ * Every name below answers a question a consumer must otherwise answer for
21
+ * itself, and each admission was a restatement deleted, not a convenience
22
+ * added: `SERVER_NAME` and `UPLOAD_TOOL_NAME` were literals in two repos (the
23
+ * first also correlates the Apps-SDK widget to the connector), `PUBLIC_EXPIRY`
24
+ * was the same duration written out eight times, `DESCRIPTION_BLOCKS` the
25
+ * fragments two tool descriptions genuinely share, `ACCOUNT_TOOL_NAMES` is
26
+ * what lets the hosted catalogue fence name the fourteen without counting them
27
+ * again, and `createServer` deleted three regexes in another repo's build (see
28
+ * below).
29
+ *
30
+ * **`createServer` is exported; the configured `call` is not.** The extension
31
+ * previously reached stdio's composition by REGEX-PATCHING this package's
32
+ * compiled `dist/` at bundle time — stripping `bin`'s shebang, and rewriting
33
+ * the `createRequire(import.meta.url)('../package.json')` line inside
34
+ * `server.js` to inline a version literal. Three hacks against another
35
+ * package's build output, each of which the 1.x library split broke. A
36
+ * fifteen-line entry point calling `createServer(ship, version)` replaces all
37
+ * of them, which is a restatement deleted rather than a convenience added.
38
+ * `call` stays internal because a consumer configures its own hints through
39
+ * `createCall`, and stdio's instance is not a contract anyone needs.
40
+ *
41
+ * The old reason for withholding `createServer` — that its upload tool takes a
42
+ * filesystem PATH, a footgun to offer a Worker — is still true and is now the
43
+ * CALLER's judgement rather than an absence: `cloudflare/mcp` must keep
44
+ * authoring its own upload tool, and does. An absence cannot express "correct
45
+ * for one consumer, wrong for another"; a documented rule can. What makes the
46
+ * export safe to publish at all is that `createServer` takes its `version` as
47
+ * an ARGUMENT — so exporting it adds no `node:module` to the import graph of a
48
+ * module the Workers-hosted transport loads.
27
49
  *
28
50
  * `tests/index.test.ts` fences both directions — nothing missing, nothing
29
51
  * extra — because adding an export is the quiet failure: everything published
30
52
  * becomes a breaking change to remove.
31
53
  */
32
54
  export { createCall } from './call.js';
55
+ export { createServer } from './server.js';
33
56
  export { ACCOUNT_TOOL_NAMES, registerAccountTools } from './tools.js';
34
57
  export { ANNOTATIONS, DESCRIPTION_BLOCKS, INSTRUCTION_BLOCKS, PARAM_DESCRIPTIONS, PUBLIC_EXPIRY, SERVER_NAME, UPLOAD_TOOL_NAME, } from './vocabulary.js';
package/dist/server.js CHANGED
@@ -15,7 +15,7 @@ const D = DESCRIPTION_BLOCKS;
15
15
  // around its own two.
16
16
  const INSTRUCTIONS = `${B.opening}
17
17
 
18
- To deploy: call deployments_upload with the build output directory path. ${B.liveAndPassword}
18
+ To deploy: call ${UPLOAD_TOOL_NAME} with the build output directory path. ${B.liveAndPassword}
19
19
 
20
20
  Without SHIP_TOKEN, deployments are public and expire in ${PUBLIC_EXPIRY}. ${B.claim}
21
21
 
@@ -27,6 +27,23 @@
27
27
  * Everything else should be here, and adding a shared fact anywhere else is
28
28
  * how the next year's drift starts.
29
29
  */
30
+ /**
31
+ * Two packages, and the split is a rule rather than an accident: **read a
32
+ * constant from whatever will act on it.**
33
+ *
34
+ * The label, password and idempotency-key constraints come from
35
+ * `@shipstatic/ship` because the SDK is what validates a value against them
36
+ * before it reaches the wire — describing a bound the client in the same
37
+ * process will not honour is the drift that matters, and reading both from one
38
+ * module makes it impossible. `@shipstatic/types` declares them, but ship
39
+ * bundles its own copy, so importing them from types here would let a describe
40
+ * advertise a limit the validator beside it rejects.
41
+ *
42
+ * The public-deploy lifetime is the other kind of fact. Ship never reads it —
43
+ * the API stamps it — so there is no validator to agree with, and taking it
44
+ * from the package that merely forwards it would mean a ship release every
45
+ * time the platform's own vocabulary grows.
46
+ */
30
47
  /**
31
48
  * The server name every transport reports in `serverInfo`.
32
49
  *
@@ -46,18 +63,25 @@ export declare const UPLOAD_TOOL_NAME = "deployments_upload";
46
63
  /**
47
64
  * How long an anonymous deployment lives, in the words an agent reads.
48
65
  *
49
- * **The fact is owned by `cloudflare/api` (`DEPLOYMENT.PUBLIC_TTL`), which
50
- * `@shipstatic/types` does not yet export** so this is a restatement, and it
51
- * is deliberately the ONLY one. It previously appeared in eight places across
52
- * the two servers and the widget; a TTL change had to find all eight. When
53
- * types exports the constant, this line becomes a derivation and nothing above
54
- * it moves.
66
+ * **Derived, since `@shipstatic/types@2.5.0-beta.19`.** It was a restatement
67
+ * until then, and deliberately the only one the duration had appeared in
68
+ * eight places across the two servers and the widget, so a TTL change had to
69
+ * find all eight. Both halves of the fix landed together: types declares the
70
+ * number and `cloudflare/api` imports it back, because exporting without the
71
+ * import-back would have given the fact two owners instead of ending the
72
+ * duplication.
55
73
  *
56
74
  * A phrase rather than a number because every consumer is prose: the value has
57
- * to carry its own unit, and `PUBLIC_TTL / 86400` interpolated at eight sites
58
- * would restate the unit eight times instead of the number.
75
+ * to carry its own unit, and dividing by 86400 at eight sites would restate the
76
+ * unit eight times instead of the number.
77
+ *
78
+ * The unit stays literal, and that is the one assumption here: this reads
79
+ * correctly while the TTL is a whole number of days, which it has always been.
80
+ * A TTL of hours would need the prose reviewed anyway — the widget's own
81
+ * `formatExpires` speaks in days and hours too — so the honest failure is a
82
+ * sentence someone must rewrite, not a number that silently rounds.
59
83
  */
60
- export declare const PUBLIC_EXPIRY = "3 days";
84
+ export declare const PUBLIC_EXPIRY: string;
61
85
  /**
62
86
  * MCP tool annotations by kind of operation. An agent reads these to decide
63
87
  * whether it may call speculatively (`readOnlyHint`), whether a retry is free
@@ -28,6 +28,24 @@
28
28
  * how the next year's drift starts.
29
29
  */
30
30
  import { IDEMPOTENCY_KEY_CONSTRAINTS, LABEL_CONSTRAINTS, PASSWORD_CONSTRAINTS, } from '@shipstatic/ship';
31
+ import { PUBLIC_DEPLOYMENT_TTL_SECONDS } from '@shipstatic/types';
32
+ /**
33
+ * Two packages, and the split is a rule rather than an accident: **read a
34
+ * constant from whatever will act on it.**
35
+ *
36
+ * The label, password and idempotency-key constraints come from
37
+ * `@shipstatic/ship` because the SDK is what validates a value against them
38
+ * before it reaches the wire — describing a bound the client in the same
39
+ * process will not honour is the drift that matters, and reading both from one
40
+ * module makes it impossible. `@shipstatic/types` declares them, but ship
41
+ * bundles its own copy, so importing them from types here would let a describe
42
+ * advertise a limit the validator beside it rejects.
43
+ *
44
+ * The public-deploy lifetime is the other kind of fact. Ship never reads it —
45
+ * the API stamps it — so there is no validator to agree with, and taking it
46
+ * from the package that merely forwards it would mean a ship release every
47
+ * time the platform's own vocabulary grows.
48
+ */
31
49
  /**
32
50
  * The server name every transport reports in `serverInfo`.
33
51
  *
@@ -47,18 +65,25 @@ export const UPLOAD_TOOL_NAME = 'deployments_upload';
47
65
  /**
48
66
  * How long an anonymous deployment lives, in the words an agent reads.
49
67
  *
50
- * **The fact is owned by `cloudflare/api` (`DEPLOYMENT.PUBLIC_TTL`), which
51
- * `@shipstatic/types` does not yet export** so this is a restatement, and it
52
- * is deliberately the ONLY one. It previously appeared in eight places across
53
- * the two servers and the widget; a TTL change had to find all eight. When
54
- * types exports the constant, this line becomes a derivation and nothing above
55
- * it moves.
68
+ * **Derived, since `@shipstatic/types@2.5.0-beta.19`.** It was a restatement
69
+ * until then, and deliberately the only one the duration had appeared in
70
+ * eight places across the two servers and the widget, so a TTL change had to
71
+ * find all eight. Both halves of the fix landed together: types declares the
72
+ * number and `cloudflare/api` imports it back, because exporting without the
73
+ * import-back would have given the fact two owners instead of ending the
74
+ * duplication.
56
75
  *
57
76
  * A phrase rather than a number because every consumer is prose: the value has
58
- * to carry its own unit, and `PUBLIC_TTL / 86400` interpolated at eight sites
59
- * would restate the unit eight times instead of the number.
77
+ * to carry its own unit, and dividing by 86400 at eight sites would restate the
78
+ * unit eight times instead of the number.
79
+ *
80
+ * The unit stays literal, and that is the one assumption here: this reads
81
+ * correctly while the TTL is a whole number of days, which it has always been.
82
+ * A TTL of hours would need the prose reviewed anyway — the widget's own
83
+ * `formatExpires` speaks in days and hours too — so the honest failure is a
84
+ * sentence someone must rewrite, not a number that silently rounds.
60
85
  */
61
- export const PUBLIC_EXPIRY = '3 days';
86
+ export const PUBLIC_EXPIRY = `${PUBLIC_DEPLOYMENT_TTL_SECONDS / 86_400} days`;
62
87
  const OPEN_WORLD = { openWorldHint: true };
63
88
  /**
64
89
  * MCP tool annotations by kind of operation. An agent reads these to decide
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipstatic/mcp",
3
- "version": "1.0.0-beta.5",
3
+ "version": "1.0.0-beta.7",
4
4
  "mcpName": "com.shipstatic/mcp",
5
5
  "description": "ShipStatic MCP — deploy static websites from AI agents. Full toolset incl. custom domains. Free hosted endpoint at mcp.shipstatic.com — no install.",
6
6
  "type": "module",
@@ -64,11 +64,11 @@
64
64
  "dependencies": {
65
65
  "@modelcontextprotocol/sdk": "^1.30.0",
66
66
  "@shipstatic/ship": "2.0.0-beta.15",
67
+ "@shipstatic/types": "2.5.0-beta.20",
67
68
  "zod": "^4.4.3"
68
69
  },
69
70
  "devDependencies": {
70
71
  "@biomejs/biome": "2.5.5",
71
- "@shipstatic/types": "2.5.0-beta.18",
72
72
  "@types/node": "^25.9.5",
73
73
  "@vitest/coverage-v8": "4.1.10",
74
74
  "typescript": "^6.0.3",