@typeship-ax/mcp 0.10.0 → 0.19.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 (68) hide show
  1. package/AGENTS.md +10 -4
  2. package/README.md +16 -5
  3. package/api.json +4539 -616
  4. package/api.md +3827 -673
  5. package/dist/core/http.d.ts +3 -2
  6. package/dist/core/http.d.ts.map +1 -1
  7. package/dist/core/http.js +18 -6
  8. package/dist/errors.d.ts +17 -10
  9. package/dist/errors.d.ts.map +1 -1
  10. package/dist/errors.js +24 -15
  11. package/dist/index.d.ts +7 -3
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +9 -5
  14. package/dist/mcp-protocol.d.ts +10 -6
  15. package/dist/mcp-protocol.d.ts.map +1 -1
  16. package/dist/mcp-protocol.js +108 -37
  17. package/dist/mcp.d.ts.map +1 -1
  18. package/dist/mcp.js +36 -17
  19. package/dist/ops.d.ts +4 -0
  20. package/dist/ops.d.ts.map +1 -1
  21. package/dist/ops.js +45 -35
  22. package/dist/resources/account.d.ts +4 -4
  23. package/dist/resources/account.d.ts.map +1 -1
  24. package/dist/resources/account.js +10 -5
  25. package/dist/resources/api-keys.d.ts +40 -14
  26. package/dist/resources/api-keys.d.ts.map +1 -1
  27. package/dist/resources/api-keys.js +45 -13
  28. package/dist/resources/definition-revisions.d.ts +35 -18
  29. package/dist/resources/definition-revisions.d.ts.map +1 -1
  30. package/dist/resources/definition-revisions.js +43 -15
  31. package/dist/resources/definitions.d.ts +21 -6
  32. package/dist/resources/definitions.d.ts.map +1 -1
  33. package/dist/resources/definitions.js +16 -3
  34. package/dist/resources/generate.d.ts +44 -15
  35. package/dist/resources/generate.d.ts.map +1 -1
  36. package/dist/resources/generate.js +55 -13
  37. package/dist/resources/generations.d.ts +14 -6
  38. package/dist/resources/generations.d.ts.map +1 -1
  39. package/dist/resources/generations.js +26 -5
  40. package/dist/resources/projects.d.ts +106 -53
  41. package/dist/resources/projects.d.ts.map +1 -1
  42. package/dist/resources/projects.js +78 -31
  43. package/dist/resources/targets.d.ts +240 -40
  44. package/dist/resources/targets.d.ts.map +1 -1
  45. package/dist/resources/targets.js +307 -21
  46. package/dist/schemas.d.ts.map +1 -1
  47. package/dist/schemas.js +130 -78
  48. package/dist/types.d.ts +1969 -154
  49. package/dist/types.d.ts.map +1 -1
  50. package/dist/types.js +87 -3
  51. package/package.json +3 -3
  52. package/server.json +3 -3
  53. package/src/core/http.ts +17 -6
  54. package/src/errors.ts +25 -15
  55. package/src/index.ts +9 -5
  56. package/src/mcp-protocol.ts +93 -36
  57. package/src/mcp.ts +32 -15
  58. package/src/ops.ts +49 -35
  59. package/src/resources/account.ts +11 -4
  60. package/src/resources/api-keys.ts +84 -13
  61. package/src/resources/definition-revisions.ts +74 -16
  62. package/src/resources/definitions.ts +28 -4
  63. package/src/resources/generate.ts +78 -13
  64. package/src/resources/generations.ts +31 -4
  65. package/src/resources/projects.ts +141 -39
  66. package/src/resources/targets.ts +561 -27
  67. package/src/schemas.ts +130 -78
  68. package/src/types.ts +2105 -154
@@ -1,5 +1,6 @@
1
1
  /**
2
- * MCP 2026-07-28 for a tools-only server. Generated by typeship — https://typeship.dev
2
+ * MCP tools server with a 2025-11-25 handshake adapter and a 2026-07-28 core.
3
+ * Generated by typeship — https://typeship.dev
3
4
  *
4
5
  * The protocol layer shared by the MCP server in every generated package and
5
6
  * by typeship's hosted endpoint: JSON-RPC shape checks, the per-request _meta
@@ -17,10 +18,9 @@
17
18
  import { dateKindOf, relativeDate } from "./dates.js";
18
19
  import { docsReadTarget, resolveDocsContentUrl, searchConnectedGuides } from "./docs.js";
19
20
  export const MCP_PROTOCOL_VERSION = "2026-07-28";
20
- /** Revisions served. Legacy (initialize-handshake) revisions are not; an
21
- * initialize request gets an error naming this list, as the spec asks of
22
- * modern-only servers. */
23
- export const SUPPORTED_PROTOCOL_VERSIONS = [MCP_PROTOCOL_VERSION];
21
+ export const LEGACY_PROTOCOL_VERSION = "2025-11-25";
22
+ /** The modern model and the supported initialize-handshake wire revision. */
23
+ export const SUPPORTED_PROTOCOL_VERSIONS = [MCP_PROTOCOL_VERSION, LEGACY_PROTOCOL_VERSION];
24
24
  export const META_VERSION = "io.modelcontextprotocol/protocolVersion";
25
25
  export const META_CLIENT_CAPS = "io.modelcontextprotocol/clientCapabilities";
26
26
  export const META_SERVER_INFO = "io.modelcontextprotocol/serverInfo";
@@ -98,7 +98,7 @@ export function checkRequestMeta(request) {
98
98
  if (typeof version !== "string") {
99
99
  return rpcError(request.id, -32602, "Invalid params: params._meta[\"" + META_VERSION + "\"] is required on every request (MCP " + MCP_PROTOCOL_VERSION + ").", 400);
100
100
  }
101
- if (!SUPPORTED_PROTOCOL_VERSIONS.includes(version)) {
101
+ if (version !== MCP_PROTOCOL_VERSION) {
102
102
  return rpcError(request.id, -32022, "Unsupported protocol version", 400, { supported: SUPPORTED_PROTOCOL_VERSIONS, requested: version });
103
103
  }
104
104
  if (caps === null || typeof caps !== "object" || Array.isArray(caps)) {
@@ -127,6 +127,17 @@ export function checkRequestHeaders(headers, message) {
127
127
  const id = message.id;
128
128
  const version = headers.get("mcp-protocol-version");
129
129
  const bodyVersion = message.params?._meta?.[META_VERSION];
130
+ if (version !== null && !SUPPORTED_PROTOCOL_VERSIONS.includes(version))
131
+ return rpcError(id, -32022, "Unsupported protocol version", 400, { supported: SUPPORTED_PROTOCOL_VERSIONS, requested: version });
132
+ if (message.method === "initialize" || version === LEGACY_PROTOCOL_VERSION) {
133
+ if (bodyVersion !== undefined || headers.get("mcp-method") !== null || headers.get("mcp-name") !== null) {
134
+ return rpcError(id, -32020, "Header mismatch: initialize-handshake requests cannot carry modern protocol metadata or routing headers.", 400);
135
+ }
136
+ if (version !== null && version !== LEGACY_PROTOCOL_VERSION) {
137
+ return rpcError(id, -32022, "Unsupported initialize-handshake protocol version", 400, { supported: [LEGACY_PROTOCOL_VERSION], requested: version });
138
+ }
139
+ return null;
140
+ }
130
141
  if (version === null)
131
142
  return rpcError(id, -32020, "Header mismatch: MCP-Protocol-Version header is required", 400);
132
143
  if (typeof bodyVersion === "string" && version !== bodyVersion) {
@@ -157,7 +168,39 @@ export function takeCancelled(id) {
157
168
  return (typeof id === "string" || typeof id === "number") && cancelled.delete(id);
158
169
  }
159
170
  // ---- dispatch ------------------------------------------------------------------
160
- export async function handleRpc(server, incoming) {
171
+ /** One stdio process owns its handshake state. HTTP instead carries the
172
+ * negotiated revision on each request and never needs a server session. */
173
+ export function createStdioRpcHandler(server) {
174
+ let version;
175
+ let initialized = false;
176
+ let initializing = false;
177
+ return async (incoming) => {
178
+ const request = asJsonRpc(incoming);
179
+ if (isRpcOutcome(request))
180
+ return request;
181
+ if (request.method === "initialize") {
182
+ if (version || initializing)
183
+ return rpcError(request.id, -32600, "This connection has already selected its MCP protocol.", 400, { supported: SUPPORTED_PROTOCOL_VERSIONS });
184
+ initializing = true;
185
+ const result = await handleRpc(server, request);
186
+ initializing = false;
187
+ if (result.status === 200)
188
+ version = LEGACY_PROTOCOL_VERSION;
189
+ return result;
190
+ }
191
+ if (version === LEGACY_PROTOCOL_VERSION) {
192
+ if (request.method === "notifications/initialized" && request.id === undefined)
193
+ initialized = true;
194
+ if (!initialized && request.id !== undefined && request.method !== "ping")
195
+ return rpcError(request.id, -32600, "Send notifications/initialized before calling MCP methods.", 400);
196
+ }
197
+ else if (request.params?._meta?.[META_VERSION] === MCP_PROTOCOL_VERSION) {
198
+ version = MCP_PROTOCOL_VERSION;
199
+ }
200
+ return handleRpc(server, request, version);
201
+ };
202
+ }
203
+ export async function handleRpc(server, incoming, protocolVersion) {
161
204
  const parsed = asJsonRpc(incoming);
162
205
  if (isRpcOutcome(parsed))
163
206
  return parsed;
@@ -172,20 +215,46 @@ export async function handleRpc(server, incoming) {
172
215
  }
173
216
  return { message: null, status: 202 };
174
217
  }
175
- // Legacy clients open with initialize; name what we do speak so their one
176
- // visible error is actionable (spec: modern-only servers SHOULD do this).
218
+ // Only the wire envelope differs. Tool execution and authorization below
219
+ // remain shared with modern clients.
177
220
  if (request.method === "initialize") {
178
- return rpcError(id, -32601, "This server speaks MCP " + SUPPORTED_PROTOCOL_VERSIONS.join(", ") + " only (stateless, no initialize handshake). Upgrade the client, or send requests with params._meta[\"" + META_VERSION + "\"].", 400, { supported: SUPPORTED_PROTOCOL_VERSIONS });
221
+ const params = request.params;
222
+ if (params?._meta?.[META_VERSION] !== undefined)
223
+ return rpcError(id, -32602, "initialize cannot carry modern protocol metadata.", 400);
224
+ const info = params?.clientInfo;
225
+ if (!params || typeof params.protocolVersion !== "string" || !params.capabilities || typeof params.capabilities !== "object" || Array.isArray(params.capabilities) ||
226
+ !info || typeof info !== "object" || Array.isArray(info) || typeof info.name !== "string" || typeof info.version !== "string") {
227
+ return rpcError(id, -32602, "initialize requires protocolVersion, capabilities, and clientInfo with name and version.", 400);
228
+ }
229
+ if (params.protocolVersion !== LEGACY_PROTOCOL_VERSION)
230
+ return rpcError(id, -32022, "Unsupported initialize-handshake protocol version", 400, { supported: [LEGACY_PROTOCOL_VERSION], requested: params.protocolVersion });
231
+ return { status: 200, message: { jsonrpc: "2.0", id, result: {
232
+ protocolVersion: LEGACY_PROTOCOL_VERSION,
233
+ capabilities: { tools: {} },
234
+ serverInfo: server.serverInfo,
235
+ ...(server.instructions ? { instructions: server.instructions } : {}),
236
+ } } };
237
+ }
238
+ const legacy = protocolVersion === LEGACY_PROTOCOL_VERSION;
239
+ if (legacy) {
240
+ const meta = request.params?._meta;
241
+ if (meta?.[META_VERSION] !== undefined || meta?.[META_CLIENT_CAPS] !== undefined || request.params?.inputResponses !== undefined || request.method === "server/discover") {
242
+ return rpcError(id, -32602, "Modern protocol metadata and methods cannot be used on an initialize-handshake connection.", 400);
243
+ }
244
+ }
245
+ else {
246
+ const meta = checkRequestMeta(request);
247
+ if ("status" in meta)
248
+ return meta;
179
249
  }
180
- const meta = checkRequestMeta(request);
181
- if ("status" in meta)
182
- return meta;
183
250
  const complete = (result) => ({
184
- message: { jsonrpc: "2.0", id, result: { resultType: "complete", ...result, _meta: { [META_SERVER_INFO]: server.serverInfo } } },
251
+ message: { jsonrpc: "2.0", id, result: legacy ? result : { resultType: "complete", ...result, _meta: { [META_SERVER_INFO]: server.serverInfo } } },
185
252
  status: 200,
186
253
  });
187
254
  const cacheScope = server.cacheScope ?? "public";
188
255
  switch (request.method) {
256
+ case "ping":
257
+ return legacy ? complete({}) : rpcError(id, -32601, "Method not found: ping", 404);
189
258
  case "server/discover":
190
259
  return complete({
191
260
  supportedVersions: SUPPORTED_PROTOCOL_VERSIONS,
@@ -195,7 +264,7 @@ export async function handleRpc(server, incoming) {
195
264
  cacheScope,
196
265
  });
197
266
  case "tools/list":
198
- return complete({ tools: server.listTools(), ttlMs: server.toolsTtlMs, cacheScope });
267
+ return complete({ tools: server.listTools(), ...(!legacy ? { ttlMs: server.toolsTtlMs, cacheScope } : {}) });
199
268
  case "tools/call": {
200
269
  const name = request.params?.name;
201
270
  if (typeof name !== "string")
@@ -229,7 +298,7 @@ export async function handleRpc(server, incoming) {
229
298
  catch (error) {
230
299
  if (!(error instanceof McpAccountLinkRequired))
231
300
  throw error;
232
- const caps = (request.params?._meta)[META_CLIENT_CAPS];
301
+ const caps = legacy ? {} : (request.params?._meta)[META_CLIENT_CAPS];
233
302
  const urlMode = caps.elicitation?.url;
234
303
  if (urlMode === null || typeof urlMode !== "object" || Array.isArray(urlMode)) {
235
304
  const unsupported = textError("Connect your API account using an MCP client that supports browser account-linking prompts (URL-mode elicitation), then retry.", "ACCOUNT_LINK_REQUIRED");
@@ -997,7 +1066,8 @@ export function argumentsError(op, issues) {
997
1066
  }
998
1067
  // ---- results: projection, size cap, envelopes ------------------------------------
999
1068
  /** Keep only `paths` of a value: arrays item by item, objects by dotted
1000
- * path; scalars untouched. Same rule as the CLI's --fields. */
1069
+ * path, including paths through arrays (`items.id` keeps each item's id);
1070
+ * scalars untouched. Same rule as the CLI's --fields. */
1001
1071
  export function projectFields(value, paths) {
1002
1072
  if (paths === null)
1003
1073
  return value;
@@ -1005,26 +1075,25 @@ export function projectFields(value, paths) {
1005
1075
  return value.map((v) => projectFields(v, paths));
1006
1076
  if (value === null || typeof value !== "object")
1007
1077
  return value;
1078
+ const groups = new Map();
1079
+ for (const [key, ...rest] of paths) {
1080
+ if (key === undefined)
1081
+ continue;
1082
+ const group = groups.get(key);
1083
+ if (group)
1084
+ group.push(rest);
1085
+ else
1086
+ groups.set(key, [rest]);
1087
+ }
1008
1088
  const out = {};
1009
- for (const path of paths) {
1010
- let cursor = value;
1011
- for (const key of path) {
1012
- if (cursor === null || typeof cursor !== "object" || Array.isArray(cursor)) {
1013
- cursor = undefined;
1014
- break;
1015
- }
1016
- cursor = cursor[key];
1017
- }
1018
- if (cursor === undefined)
1089
+ for (const [key, rests] of groups) {
1090
+ const child = value[key];
1091
+ if (child === undefined)
1019
1092
  continue;
1020
- let target = out;
1021
- for (const key of path.slice(0, -1)) {
1022
- const next = target[key];
1023
- if (next === undefined || next === null || typeof next !== "object" || Array.isArray(next))
1024
- target[key] = {};
1025
- target = target[key];
1026
- }
1027
- target[path[path.length - 1]] = cursor;
1093
+ if (rests.some((rest) => rest.length === 0))
1094
+ out[key] = child;
1095
+ else if (child !== null && typeof child === "object")
1096
+ out[key] = projectFields(child, rests);
1028
1097
  }
1029
1098
  return out;
1030
1099
  }
@@ -1102,7 +1171,9 @@ export function pageOutcome(items, nextPage, options = {}) {
1102
1171
  return { text: JSON.stringify(structured), isError: false, structured };
1103
1172
  }
1104
1173
  /** Placeholder for a value cut from an oversized object result. */
1105
- const omittedMarker = (key, chars) => "[omitted: " + chars.toLocaleString("en-US") + " characters. Pass fields=[\"" + key + "\"] to fetch this key alone.]";
1174
+ const omittedMarker = (key, chars, maxChars) => chars > maxChars
1175
+ ? "[omitted: " + chars.toLocaleString("en-US") + " characters, more than the cap on its own. Pass fields with dotted paths inside it, such as [\"" + key + ".id\"], or request a smaller page.]"
1176
+ : "[omitted: " + chars.toLocaleString("en-US") + " characters. Pass fields=[\"" + key + "\"] to fetch this key alone.]";
1106
1177
  export function dataOutcome(data, options = {}) {
1107
1178
  const fields = options.fields ?? null;
1108
1179
  const maxChars = options.maxChars ?? DEFAULT_MAX_RESULT_CHARS;
@@ -1143,7 +1214,7 @@ export function dataOutcome(data, options = {}) {
1143
1214
  out[e.key] = e.v;
1144
1215
  out.truncated = {
1145
1216
  omitted_keys: [...cut.keys()],
1146
- omitted: Object.fromEntries([...cut].map(([key, chars]) => [key, omittedMarker(key, chars)])),
1217
+ omitted: Object.fromEntries([...cut].map(([key, chars]) => [key, omittedMarker(key, chars, maxChars)])),
1147
1218
  reason: "The result is " + text.length.toLocaleString("en-US") + " characters; results are capped at " + maxChars.toLocaleString("en-US") + ".",
1148
1219
  next_steps: [fieldsHint(false)],
1149
1220
  };
package/dist/mcp.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":";AAuBA,OAAO,EAAoC,KAAK,aAAa,EAAmB,MAAM,YAAY,CAAC;AAcnG,OAAO,EAA8C,KAAK,6BAA6B,EAAE,KAAK,kCAAkC,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACpL,YAAY,EAAE,6BAA6B,EAAE,kCAAkC,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC9H,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AA4U3D,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,6BAA6B,CAAC;IAC9C;kFAC8E;IAC9E,aAAa,CAAC,EAAE,kCAAkC,CAAC;IACnD;;;;iFAI6E;IAC7E,cAAc,CAAC,SAAS,EAAE,YAAY,GAAG,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACjF;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAMjG;AAED;+EAC+E;AAC/E,wBAAsB,UAAU,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAErE"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":";AAuBA,OAAO,EAAoC,KAAK,aAAa,EAAmB,MAAM,YAAY,CAAC;AAcnG,OAAO,EAA8C,KAAK,6BAA6B,EAAE,KAAK,kCAAkC,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACpL,YAAY,EAAE,6BAA6B,EAAE,kCAAkC,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC9H,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AA6V3D,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,6BAA6B,CAAC;IAC9C;kFAC8E;IAC9E,aAAa,CAAC,EAAE,kCAAkC,CAAC;IACnD;;;;iFAI6E;IAC7E,cAAc,CAAC,SAAS,EAAE,YAAY,GAAG,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACjF;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAMjG;AAED;+EAC+E;AAC/E,wBAAsB,UAAU,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAErE"}
package/dist/mcp.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // typeship — MCP server. Generated by typeship — https://typeship.dev
3
- // Speaks MCP 2026-07-28 (stateless: per-request _meta, server/discover; no
4
- // initialize handshake, no sessions); the protocol layer and tool surface
3
+ // Speaks MCP 2026-07-28 and accepts the 2025-11-25 initialize handshake.
4
+ // HTTP is stateless (no sessions); the protocol layer and tool surface
5
5
  // live in ./mcp-protocol.js, shared with typeship's hosted endpoint. Two
6
6
  // transports, zero dependencies:
7
7
  // node mcp.js stdio (newline-delimited JSON-RPC 2.0)
@@ -22,7 +22,7 @@ import { basename, join } from "node:path";
22
22
  import { fileURLToPath } from "node:url";
23
23
  import { TypeshipClient, formatDebugEvent } from "./index.js";
24
24
  import { GLOBALS, OMITTED_OPS, OPS, buildArgs } from "./ops.js";
25
- import { DEFAULT_MAX_RESULT_CHARS, SUPPORTED_PROTOCOL_VERSIONS, McpAccountLinkRequired, argumentsError, asJsonRpc, binaryOutcome, callSharedTool, checkRequestHeaders, dataOutcome, errorOutcome, handleRpc, isRpcOutcome, pageOutcome, parseIncludeList, prepareCall, resolveReferences, serverInstructions, takeCancelled, textError, toolDefinitions, visibleOps, } from "./mcp-protocol.js";
25
+ import { DEFAULT_MAX_RESULT_CHARS, SUPPORTED_PROTOCOL_VERSIONS, McpAccountLinkRequired, argumentsError, asJsonRpc, binaryOutcome, callSharedTool, checkRequestHeaders, createStdioRpcHandler, dataOutcome, errorOutcome, handleRpc, isRpcOutcome, pageOutcome, parseIncludeList, prepareCall, resolveReferences, serverInstructions, takeCancelled, textError, toolDefinitions, visibleOps, } from "./mcp-protocol.js";
26
26
  import { fetchDocsText } from "./docs.js";
27
27
  import { assertCredentialDestination, assertStoredIdentity } from "./oauth-session.js";
28
28
  import { createCredentialStore } from "./credential-storage.js";
@@ -33,14 +33,14 @@ export { McpAccountLinkRequired } from "./mcp-protocol.js";
33
33
  const BIN = "typeship";
34
34
  const PKG_NAME = "@typeship-ax/mcp";
35
35
  const SERVER_NAME = "typeship-mcp";
36
- const SERVER_VERSION = "0.10.0";
36
+ const SERVER_VERSION = "0.19.0";
37
37
  /** The MCP client's announced name (clientInfo in request _meta), for the User-Agent. */
38
38
  let MCP_CLIENT_NAME = null;
39
39
  function noteClientInfo(message) {
40
40
  const meta = message?.params?._meta;
41
41
  const name = meta?.["io.modelcontextprotocol/clientInfo"]?.name;
42
- if (typeof name === "string" && name && name !== MCP_CLIENT_NAME) {
43
- MCP_CLIENT_NAME = name.slice(0, 60);
42
+ if (typeof name === "string" && name) {
43
+ MCP_CLIENT_NAME = name.replace(/[\s;()]+/g, "_").slice(0, 60);
44
44
  }
45
45
  }
46
46
  const DEFAULT_BASE_URL = "https://typeship.dev/api/v1";
@@ -144,7 +144,7 @@ function makeClient(op) {
144
144
  options.debug = (event) => process.stderr.write(formatDebugEvent(BIN + "-mcp", event) + "\n");
145
145
  }
146
146
  // The local MCP server identifies itself (surface + the client it serves, when announced).
147
- options.defaultHeaders = { "User-Agent": PKG_NAME + "-mcp/" + SERVER_VERSION + " (typeship" + (MCP_CLIENT_NAME ? "; client=" + MCP_CLIENT_NAME : "") + ")" };
147
+ options.defaultHeaders = { "User-Agent": PKG_NAME + "-mcp/" + SERVER_VERSION + (MCP_CLIENT_NAME ? " (client=" + MCP_CLIENT_NAME + ")" : "") };
148
148
  // Keep the SDK's machine-token cache while re-evaluating local configuration.
149
149
  const key = createHash("sha256").update(JSON.stringify([options, config, profile?.name, stored?.oauth?.sessionId, null, process.env["TYPESHIP_DEBUG"]])).digest("hex");
150
150
  if (clientInstance && clientKey === key)
@@ -173,8 +173,9 @@ async function callOperationRaw(op, rawArgs, remote, client) {
173
173
  const { args, fields, maxChars } = prepared.call;
174
174
  const values = {};
175
175
  for (const p of op.params) {
176
- if (args[p.name] !== undefined)
177
- values[p.name] = args[p.name];
176
+ const argument = p.kind === "header" && p.name === "If-Match" ? "if_match" : p.name;
177
+ if (args[argument] !== undefined)
178
+ values[p.name] = args[argument];
178
179
  }
179
180
  // File arguments are local paths on this machine; unreadable ones are
180
181
  // argument errors, reported before anything is sent.
@@ -211,9 +212,21 @@ async function callOperationRaw(op, rawArgs, remote, client) {
211
212
  const shape = { fields, maxChars, pagination: op.pagination, args };
212
213
  try {
213
214
  const target = client[op.resource];
214
- const result = await target[op.method](...callArgs);
215
+ let result = await target[op.method](...callArgs);
215
216
  if (!result.ok)
216
217
  return errorOutcome(result.error, errorContext);
218
+ if (op.httpMethod === "POST" && op.path === "/projects/{project_id}/generations") {
219
+ const batch = result.data;
220
+ const generations = client.generations;
221
+ const completed = [];
222
+ for (const generation of batch.data) {
223
+ const waited = await generations.wait(generation.id);
224
+ if (!waited.ok)
225
+ return errorOutcome(waited.error, errorContext);
226
+ completed.push(waited.data);
227
+ }
228
+ result = { ...result, data: { ...batch, data: completed } };
229
+ }
217
230
  if (op.paginated) {
218
231
  const page = result.data;
219
232
  return pageOutcome(page.items, page.nextPageParams(), { ...shape, requestId: page.response.requestId });
@@ -281,7 +294,13 @@ const LOCAL_CREDENTIALS = LOCAL_PROCESS && !ARGV.includes("--http");
281
294
  * only on a local server (mcpExposed), writes are out under --read-only,
282
295
  * and --tools narrows to a subset. A hidden operation is unknown to
283
296
  * tools/call and execute alike. */
284
- const MCP_OPS = visibleOps(OPS, { readOnly: READ_ONLY, include: INCLUDE, uploads: LOCAL_PROCESS });
297
+ const MCP_OPS = visibleOps(OPS, { readOnly: READ_ONLY, include: INCLUDE, uploads: LOCAL_PROCESS }).map((op) => {
298
+ const properties = op.inputSchema.properties;
299
+ if (!properties || !Object.hasOwn(properties, "If-Match"))
300
+ return op;
301
+ const { ["If-Match"]: ifMatch, ...rest } = properties;
302
+ return { ...op, inputSchema: { ...op.inputSchema, properties: { ...rest, if_match: ifMatch } } };
303
+ });
285
304
  const HIDDEN_WRITES = READ_ONLY ? visibleOps(OPS, { include: INCLUDE, uploads: LOCAL_PROCESS }).length - MCP_OPS.length : 0;
286
305
  const HAS_UPLOADS = MCP_OPS.some((op) => op.bodyKind === "multipart" || op.bodyKind === "binary");
287
306
  /** A local file as an upload part (multipart field or raw body). */
@@ -408,7 +427,7 @@ async function authorizedHttp(request, authorizer, credentialsFor, apiBaseUrl) {
408
427
  return json(404, { error: "Unknown MCP endpoint." });
409
428
  if (request.method !== "POST") {
410
429
  // GET streams, DELETE (session end) and Mcp-Session-Id belong to earlier
411
- // revisions; the spec asks modern-only servers to answer 405.
430
+ // revisions; this stateless transport answers 405 instead.
412
431
  return json(405, { error: "POST JSON-RPC messages to this endpoint (MCP " + SUPPORTED_PROTOCOL_VERSIONS[0] + ", stateless)." }, { Allow: "POST, OPTIONS" });
413
432
  }
414
433
  let principal;
@@ -449,9 +468,8 @@ async function authorizedHttp(request, authorizer, credentialsFor, apiBaseUrl) {
449
468
  const parsed = asJsonRpc(incoming);
450
469
  if (isRpcOutcome(parsed))
451
470
  return json(parsed.status, parsed.message);
452
- // Header/body agreement is checked for requests; the spec defines no
453
- // header requirements for notification POSTs.
454
- if (parsed.id !== undefined && parsed.id !== null && parsed.method !== "initialize") {
471
+ // Validate the selected wire revision before dispatching a request.
472
+ if (parsed.id !== undefined && parsed.id !== null) {
455
473
  const mismatch = checkRequestHeaders(request.headers, parsed);
456
474
  if (mismatch)
457
475
  return json(mismatch.status, mismatch.message);
@@ -459,7 +477,7 @@ async function authorizedHttp(request, authorizer, credentialsFor, apiBaseUrl) {
459
477
  noteClientInfo(parsed);
460
478
  let outcome;
461
479
  try {
462
- outcome = await handleRpc(serverFor(remote), parsed);
480
+ outcome = await handleRpc(serverFor(remote), parsed, request.headers.get("mcp-protocol-version"));
463
481
  }
464
482
  catch (e) {
465
483
  return json(500, { jsonrpc: "2.0", id: parsed.id ?? null, error: { code: -32603, message: "Internal error" } });
@@ -505,6 +523,7 @@ async function startStdio() {
505
523
  const rl = createInterface({ input: process.stdin });
506
524
  const write = (message) => process.stdout.write(JSON.stringify(message) + "\n");
507
525
  const server = serverFor();
526
+ const dispatch = createStdioRpcHandler(server);
508
527
  rl.on("line", (line) => {
509
528
  const trimmed = line.trim();
510
529
  if (trimmed === "")
@@ -519,7 +538,7 @@ async function startStdio() {
519
538
  }
520
539
  const id = incoming !== null && typeof incoming === "object" && !Array.isArray(incoming) ? incoming.id : undefined;
521
540
  noteClientInfo(incoming);
522
- void handleRpc(server, incoming)
541
+ void dispatch(incoming)
523
542
  .then((outcome) => {
524
543
  if (outcome.message === null)
525
544
  return;
package/dist/ops.d.ts CHANGED
@@ -12,6 +12,8 @@ export interface ParamSpec {
12
12
  * value — JSON if it parses, else the raw text. */
13
13
  type: "string" | "number" | "boolean" | "array" | "object" | "json" | "file";
14
14
  required: boolean;
15
+ /** A JSON body flag accepts the literal null as JSON null. */
16
+ nullable?: boolean;
15
17
  enum?: string[];
16
18
  /** Element type of an "array" param: what each repeated/comma value coerces to. */
17
19
  items?: {
@@ -107,6 +109,8 @@ export interface OpSpec {
107
109
  /** What the tool returns (JSON Schema 2020-12), when the spec documents
108
110
  * a success body; paginated tools describe { items, hasMore, nextPage }. */
109
111
  outputSchema?: Record<string, unknown>;
112
+ /** File array used by CLI --out, independent of the agent schema budget. */
113
+ fileBundleProperty?: string;
110
114
  }
111
115
  export declare const OPS: OpSpec[];
112
116
  /** Operations present in the API Definition but omitted by this
package/dist/ops.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../src/ops.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../src/ops.ts"],"names":[],"mappings":"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"}