@typeship-ax/mcp 0.9.1 → 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.
- package/AGENTS.md +10 -4
- package/README.md +16 -5
- package/api.json +6055 -645
- package/api.md +5225 -567
- package/dist/core/http.d.ts +3 -2
- package/dist/core/http.d.ts.map +1 -1
- package/dist/core/http.js +18 -6
- package/dist/errors.d.ts +17 -10
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +24 -15
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/mcp-protocol.d.ts +10 -6
- package/dist/mcp-protocol.d.ts.map +1 -1
- package/dist/mcp-protocol.js +108 -37
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +36 -17
- package/dist/ops.d.ts +4 -0
- package/dist/ops.d.ts.map +1 -1
- package/dist/ops.js +45 -31
- package/dist/resources/account.d.ts +4 -4
- package/dist/resources/account.d.ts.map +1 -1
- package/dist/resources/account.js +10 -5
- package/dist/resources/api-keys.d.ts +40 -14
- package/dist/resources/api-keys.d.ts.map +1 -1
- package/dist/resources/api-keys.js +45 -13
- package/dist/resources/definition-revisions.d.ts +35 -18
- package/dist/resources/definition-revisions.d.ts.map +1 -1
- package/dist/resources/definition-revisions.js +43 -15
- package/dist/resources/definitions.d.ts +21 -6
- package/dist/resources/definitions.d.ts.map +1 -1
- package/dist/resources/definitions.js +16 -3
- package/dist/resources/generate.d.ts +44 -15
- package/dist/resources/generate.d.ts.map +1 -1
- package/dist/resources/generate.js +55 -13
- package/dist/resources/generations.d.ts +14 -6
- package/dist/resources/generations.d.ts.map +1 -1
- package/dist/resources/generations.js +26 -5
- package/dist/resources/projects.d.ts +106 -53
- package/dist/resources/projects.d.ts.map +1 -1
- package/dist/resources/projects.js +78 -31
- package/dist/resources/targets.d.ts +285 -22
- package/dist/resources/targets.d.ts.map +1 -1
- package/dist/resources/targets.js +408 -10
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +138 -73
- package/dist/types.d.ts +2162 -134
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +99 -2
- package/package.json +3 -3
- package/server.json +3 -3
- package/src/core/http.ts +17 -6
- package/src/errors.ts +25 -15
- package/src/index.ts +9 -5
- package/src/mcp-protocol.ts +93 -36
- package/src/mcp.ts +32 -15
- package/src/ops.ts +49 -31
- package/src/resources/account.ts +11 -4
- package/src/resources/api-keys.ts +84 -13
- package/src/resources/definition-revisions.ts +74 -16
- package/src/resources/definitions.ts +28 -4
- package/src/resources/generate.ts +78 -13
- package/src/resources/generations.ts +31 -4
- package/src/resources/projects.ts +141 -39
- package/src/resources/targets.ts +756 -13
- package/src/schemas.ts +138 -73
- package/src/types.ts +2372 -189
package/dist/mcp-protocol.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
//
|
|
176
|
-
//
|
|
218
|
+
// Only the wire envelope differs. Tool execution and authorization below
|
|
219
|
+
// remain shared with modern clients.
|
|
177
220
|
if (request.method === "initialize") {
|
|
178
|
-
|
|
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
|
|
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
|
|
1010
|
-
|
|
1011
|
-
|
|
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
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
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) =>
|
|
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;
|
|
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
|
|
4
|
-
//
|
|
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.
|
|
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
|
|
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 +
|
|
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
|
-
|
|
177
|
-
|
|
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
|
-
|
|
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;
|
|
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
|
-
//
|
|
453
|
-
|
|
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
|
|
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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"}
|