@apicircle/mcp-server 1.0.6 → 1.0.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 +14 -13
- package/dist/bin/mcp-server.cjs +470 -272
- package/dist/bin/mcp-server.cjs.map +1 -1
- package/dist/index.cjs +456 -265
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +458 -261
- package/dist/index.js.map +1 -1
- package/package.json +28 -4
package/dist/index.js
CHANGED
|
@@ -6,10 +6,34 @@ import { z } from "zod";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@apicircle/mcp-server",
|
|
9
|
-
version: "1.0.
|
|
9
|
+
version: "1.0.7",
|
|
10
10
|
private: false,
|
|
11
11
|
type: "module",
|
|
12
12
|
description: "Model Context Protocol server exposing API Circle Studio's workspace as a tool catalog. Used by Claude Desktop, ChatGPT, Cursor, GitHub Copilot, and any other MCP-compatible AI client.",
|
|
13
|
+
keywords: [
|
|
14
|
+
"apicircle",
|
|
15
|
+
"api",
|
|
16
|
+
"api-circle",
|
|
17
|
+
"mcp",
|
|
18
|
+
"mcp-server",
|
|
19
|
+
"model-context-protocol",
|
|
20
|
+
"ai",
|
|
21
|
+
"llm",
|
|
22
|
+
"agent",
|
|
23
|
+
"tool-catalog",
|
|
24
|
+
"claude",
|
|
25
|
+
"claude-desktop",
|
|
26
|
+
"chatgpt",
|
|
27
|
+
"cursor",
|
|
28
|
+
"copilot",
|
|
29
|
+
"continue",
|
|
30
|
+
"cline",
|
|
31
|
+
"zed",
|
|
32
|
+
"windsurf",
|
|
33
|
+
"openapi",
|
|
34
|
+
"postman",
|
|
35
|
+
"api-tools"
|
|
36
|
+
],
|
|
13
37
|
license: "SEE LICENSE IN LICENSE",
|
|
14
38
|
repository: {
|
|
15
39
|
type: "git",
|
|
@@ -534,6 +558,7 @@ var workspaceListTool = {
|
|
|
534
558
|
// src/tools/crud.ts
|
|
535
559
|
import { z as z5 } from "zod";
|
|
536
560
|
import { generateId as generateId2 } from "@apicircle/shared";
|
|
561
|
+
import { parseApicircleEnvironmentDoc } from "@apicircle/core";
|
|
537
562
|
var HTTP_METHOD = z5.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
538
563
|
var requestCreateTool = {
|
|
539
564
|
name: "request.create",
|
|
@@ -778,55 +803,136 @@ var environmentSetPriorityTool = {
|
|
|
778
803
|
};
|
|
779
804
|
var environmentExportTool = {
|
|
780
805
|
name: "environment.export",
|
|
781
|
-
description: "Serialize an environment to a portable JSON string. Encrypted variables
|
|
806
|
+
description: "Serialize an environment to a portable JSON string (envelope v2). Encrypted variables now carry their ciphertext, slot label, and per-slot salt \u2014 the destination decrypts with its local slot value at request-execute time, matching the Git push/pull contract. The plaintext slot value never leaves the device, but the ciphertext does. v1 envelopes (no ciphertext) still parse on import for back-compat.",
|
|
782
807
|
inputSchema: z5.object({ name: z5.string() }),
|
|
783
808
|
async handler(input, ctx) {
|
|
784
809
|
const state = await ctx.workspace.read();
|
|
785
810
|
const env = state.synced.environments.items[input.name];
|
|
786
811
|
if (!env) return { ok: false, error: "environment not found" };
|
|
787
812
|
const payload = {
|
|
788
|
-
apicircleEnvironment:
|
|
813
|
+
apicircleEnvironment: 2,
|
|
789
814
|
name: env.name,
|
|
790
|
-
variables: env.variables.map(
|
|
791
|
-
(v
|
|
792
|
-
|
|
815
|
+
variables: env.variables.map((v) => {
|
|
816
|
+
if (v.encrypted && v.secretKeyId) {
|
|
817
|
+
const slot = state.synced.secretKeys?.[v.secretKeyId];
|
|
818
|
+
const label = slot?.label ?? v.key;
|
|
819
|
+
const value = typeof v.value === "string" && v.value.startsWith("enc:") ? v.value : "";
|
|
820
|
+
return {
|
|
821
|
+
key: v.key,
|
|
822
|
+
encrypted: true,
|
|
823
|
+
value,
|
|
824
|
+
secretKeyId: v.secretKeyId,
|
|
825
|
+
secret: { label, salt: slot?.salt ?? null }
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
return { key: v.key, value: v.value, encrypted: false };
|
|
829
|
+
})
|
|
793
830
|
};
|
|
794
831
|
return { ok: true, json: JSON.stringify(payload, null, 2) };
|
|
795
832
|
}
|
|
796
833
|
};
|
|
797
834
|
var environmentImportTool = {
|
|
798
835
|
name: "environment.import",
|
|
799
|
-
description: "Import an environment from the JSON shape produced by `environment.export`.
|
|
836
|
+
description: "Import an environment from the JSON shape produced by `environment.export`. v2 envelopes carry the row ciphertext + per-slot salt, so the destination decrypts at request-execute time with its local slot value (same model as Git push/pull); when no destination slot matches the source's salt, a new slot is minted via `secretKey.upsert` and surfaced in `mintedSlots` so the caller can provide values via `secret.addLocal`. v1 envelopes carry only metadata, so unmatched rows come back as `pendingBindings` for the caller to prompt-and-bind via `secret.addLocal` + `environment.bindSecret`. Pass `overwrite: true` to replace a same-name destination env.",
|
|
800
837
|
inputSchema: z5.object({
|
|
801
838
|
json: z5.string().min(1),
|
|
802
839
|
overwrite: z5.boolean().default(false)
|
|
803
840
|
}),
|
|
804
841
|
async handler(input, ctx) {
|
|
805
|
-
let
|
|
842
|
+
let raw;
|
|
806
843
|
try {
|
|
807
|
-
|
|
844
|
+
raw = JSON.parse(input.json);
|
|
808
845
|
} catch {
|
|
809
846
|
return { ok: false, error: "invalid JSON" };
|
|
810
847
|
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
848
|
+
let parsed;
|
|
849
|
+
try {
|
|
850
|
+
parsed = parseApicircleEnvironmentDoc(raw);
|
|
851
|
+
} catch (err) {
|
|
852
|
+
return {
|
|
853
|
+
ok: false,
|
|
854
|
+
error: err instanceof Error ? err.message : "unsupported export shape"
|
|
855
|
+
};
|
|
814
856
|
}
|
|
815
857
|
const state = await ctx.workspace.read();
|
|
816
|
-
if (state.synced.environments.items[
|
|
858
|
+
if (state.synced.environments.items[parsed.name] && !input.overwrite) {
|
|
817
859
|
return {
|
|
818
860
|
ok: false,
|
|
819
861
|
error: "environment already exists; pass overwrite:true"
|
|
820
862
|
};
|
|
821
863
|
}
|
|
822
|
-
const
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
864
|
+
const destSlots = state.synced.secretKeys ?? {};
|
|
865
|
+
const labelToSlotId = /* @__PURE__ */ new Map();
|
|
866
|
+
for (const slot of Object.values(destSlots)) {
|
|
867
|
+
if (!labelToSlotId.has(slot.label)) labelToSlotId.set(slot.label, slot.id);
|
|
868
|
+
}
|
|
869
|
+
const resolvedVariables = [];
|
|
870
|
+
const pendingBindings = [];
|
|
871
|
+
const mintedSlots = [];
|
|
872
|
+
const knownDestIds = new Set(Object.keys(destSlots));
|
|
873
|
+
let hintCursor = 0;
|
|
874
|
+
for (const v of parsed.variables) {
|
|
875
|
+
if (!v.encrypted) {
|
|
876
|
+
resolvedVariables.push(v);
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
879
|
+
const hint = parsed.encryptedBindingHints[hintCursor];
|
|
880
|
+
hintCursor += 1;
|
|
881
|
+
if (hint && hint.ciphertext && hint.salt) {
|
|
882
|
+
if (hint.originSecretKeyId && destSlots[hint.originSecretKeyId]?.salt === hint.salt) {
|
|
883
|
+
resolvedVariables.push({ ...v, secretKeyId: hint.originSecretKeyId });
|
|
884
|
+
continue;
|
|
885
|
+
}
|
|
886
|
+
const labelMatch = labelToSlotId.get(hint.label);
|
|
887
|
+
if (labelMatch && destSlots[labelMatch]?.salt === hint.salt) {
|
|
888
|
+
resolvedVariables.push({ ...v, secretKeyId: labelMatch });
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
const mintedId = hint.originSecretKeyId && !knownDestIds.has(hint.originSecretKeyId) ? hint.originSecretKeyId : generateId2();
|
|
892
|
+
knownDestIds.add(mintedId);
|
|
893
|
+
if (!labelToSlotId.has(hint.label)) labelToSlotId.set(hint.label, mintedId);
|
|
894
|
+
mintedSlots.push({
|
|
895
|
+
id: mintedId,
|
|
896
|
+
label: hint.label,
|
|
897
|
+
salt: hint.salt,
|
|
898
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
899
|
+
});
|
|
900
|
+
resolvedVariables.push({ ...v, secretKeyId: mintedId });
|
|
901
|
+
continue;
|
|
902
|
+
}
|
|
903
|
+
if (hint?.originSecretKeyId && destSlots[hint.originSecretKeyId]) {
|
|
904
|
+
resolvedVariables.push({ ...v, secretKeyId: hint.originSecretKeyId });
|
|
905
|
+
continue;
|
|
906
|
+
}
|
|
907
|
+
if (hint?.label) {
|
|
908
|
+
const matchId = labelToSlotId.get(hint.label);
|
|
909
|
+
if (matchId) {
|
|
910
|
+
resolvedVariables.push({ ...v, secretKeyId: matchId });
|
|
911
|
+
continue;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
resolvedVariables.push(v);
|
|
915
|
+
if (hint) {
|
|
916
|
+
pendingBindings.push({
|
|
917
|
+
varKey: hint.varKey,
|
|
918
|
+
label: hint.label,
|
|
919
|
+
labelFromFallback: hint.labelFromFallback
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
for (const meta of mintedSlots) {
|
|
924
|
+
await ctx.workspace.apply({ kind: "secretKey.upsert", meta });
|
|
925
|
+
}
|
|
926
|
+
const env = { name: parsed.name, variables: resolvedVariables };
|
|
828
927
|
const out = await ctx.workspace.apply({ kind: "environment.upsert", environment: env });
|
|
829
|
-
return {
|
|
928
|
+
return {
|
|
929
|
+
ok: true,
|
|
930
|
+
name: env.name,
|
|
931
|
+
changedIds: out.changedIds,
|
|
932
|
+
pendingBindings,
|
|
933
|
+
mintedSlots: mintedSlots.map((s) => ({ id: s.id, label: s.label })),
|
|
934
|
+
warnings: parsed.warnings
|
|
935
|
+
};
|
|
830
936
|
}
|
|
831
937
|
};
|
|
832
938
|
var PLAN_STEP = z5.object({
|
|
@@ -1157,17 +1263,106 @@ var workspaceWriteTool = {
|
|
|
1157
1263
|
}
|
|
1158
1264
|
};
|
|
1159
1265
|
|
|
1160
|
-
// src/tools/
|
|
1266
|
+
// src/tools/folderExchange.ts
|
|
1161
1267
|
import { z as z6 } from "zod";
|
|
1268
|
+
import {
|
|
1269
|
+
collectFolderExport,
|
|
1270
|
+
parseApicircleFolderExport,
|
|
1271
|
+
redactFolderExportCredentials,
|
|
1272
|
+
serializeFolderExport,
|
|
1273
|
+
suggestFolderExportFilename
|
|
1274
|
+
} from "@apicircle/core";
|
|
1275
|
+
var folderExportJsonTool = {
|
|
1276
|
+
name: "folder.export_json",
|
|
1277
|
+
description: "Export an existing folder (and its subtree) to the API Circle exchange JSON format. Embeds JSON Schema + GraphQL dependencies inline. Auth credentials are redacted by default \u2014 pass `includeCredentialIds` to keep specific fields verbatim (the report from `collectFolderExport` enumerates the available ids).",
|
|
1278
|
+
inputSchema: z6.object({
|
|
1279
|
+
folderId: z6.string().min(1, "folderId is required"),
|
|
1280
|
+
/**
|
|
1281
|
+
* Subset of credential ids to KEEP in the output. Anything not in
|
|
1282
|
+
* this list (and every detected credential when this is empty)
|
|
1283
|
+
* gets blanked. Use the report-side ids surfaced by the export
|
|
1284
|
+
* report (`<scope>:<ownerId>.<authType>.<field>`).
|
|
1285
|
+
*/
|
|
1286
|
+
includeCredentialIds: z6.array(z6.string()).optional()
|
|
1287
|
+
}),
|
|
1288
|
+
async handler(input, ctx) {
|
|
1289
|
+
const state = await ctx.workspace.read();
|
|
1290
|
+
const collected = collectFolderExport({
|
|
1291
|
+
synced: state.synced,
|
|
1292
|
+
folderId: input.folderId
|
|
1293
|
+
});
|
|
1294
|
+
if (!collected) {
|
|
1295
|
+
return {
|
|
1296
|
+
error: "folder_not_found",
|
|
1297
|
+
message: `No folder with id "${input.folderId}" exists in the active workspace.`
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
const includeIds = new Set(input.includeCredentialIds ?? []);
|
|
1301
|
+
const redacted = redactFolderExportCredentials(collected.envelope, includeIds);
|
|
1302
|
+
return {
|
|
1303
|
+
envelope: redacted,
|
|
1304
|
+
json: serializeFolderExport(redacted),
|
|
1305
|
+
filename: suggestFolderExportFilename(redacted),
|
|
1306
|
+
report: collected.report
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
};
|
|
1310
|
+
var folderImportJsonTool = {
|
|
1311
|
+
name: "folder.import_json",
|
|
1312
|
+
description: "Import an `apicircle.folder/v1` envelope into the active workspace. Folder + request ids are reminted, dependency references are remapped, and JSON Schema / GraphQL definitions that match an existing global asset (by name + content) are reused.",
|
|
1313
|
+
inputSchema: z6.object({
|
|
1314
|
+
/** Either a JSON string or the already-parsed envelope object. */
|
|
1315
|
+
json: z6.string().min(1).optional(),
|
|
1316
|
+
envelope: z6.record(z6.unknown()).optional(),
|
|
1317
|
+
parentFolderId: z6.string().nullable().optional()
|
|
1318
|
+
}),
|
|
1319
|
+
async handler(input, ctx) {
|
|
1320
|
+
if (!input.json && !input.envelope) {
|
|
1321
|
+
return {
|
|
1322
|
+
error: "invalid_input",
|
|
1323
|
+
message: "Pass either `json` (string) or `envelope` (object)."
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
const text = input.json !== void 0 ? input.json : JSON.stringify(input.envelope);
|
|
1327
|
+
let parsed;
|
|
1328
|
+
try {
|
|
1329
|
+
parsed = parseApicircleFolderExport(text);
|
|
1330
|
+
} catch (err) {
|
|
1331
|
+
return {
|
|
1332
|
+
error: "invalid_envelope",
|
|
1333
|
+
message: err instanceof Error ? err.message : String(err)
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
const out = await ctx.workspace.apply({
|
|
1337
|
+
kind: "folder.import_apicircle",
|
|
1338
|
+
parsed,
|
|
1339
|
+
parentFolderId: input.parentFolderId ?? null
|
|
1340
|
+
});
|
|
1341
|
+
return {
|
|
1342
|
+
rootFolderId: parsed.rootFolder.id,
|
|
1343
|
+
rootFolderName: parsed.rootFolder.name,
|
|
1344
|
+
counts: {
|
|
1345
|
+
folders: parsed.subfolders.length + 1,
|
|
1346
|
+
requests: parsed.requests.length
|
|
1347
|
+
},
|
|
1348
|
+
filesRequiringReattachment: parsed.dependencies.files.map((f) => f.id),
|
|
1349
|
+
warnings: parsed.warnings,
|
|
1350
|
+
changedIds: out.changedIds
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
};
|
|
1354
|
+
|
|
1355
|
+
// src/tools/history.ts
|
|
1356
|
+
import { z as z7 } from "zod";
|
|
1162
1357
|
var historyListRunsTool = {
|
|
1163
1358
|
name: "history.list_runs",
|
|
1164
1359
|
description: "List request-run history rows in reverse-chronological order. Filter by `requestId`, `ok` (success/failure), or `since`/`until` ISO timestamps. `limit` caps the result set; default 100.",
|
|
1165
|
-
inputSchema:
|
|
1166
|
-
requestId:
|
|
1167
|
-
ok:
|
|
1168
|
-
since:
|
|
1169
|
-
until:
|
|
1170
|
-
limit:
|
|
1360
|
+
inputSchema: z7.object({
|
|
1361
|
+
requestId: z7.string().optional(),
|
|
1362
|
+
ok: z7.boolean().optional(),
|
|
1363
|
+
since: z7.string().optional(),
|
|
1364
|
+
until: z7.string().optional(),
|
|
1365
|
+
limit: z7.number().int().positive().max(500).default(100)
|
|
1171
1366
|
}),
|
|
1172
1367
|
async handler(input, ctx) {
|
|
1173
1368
|
const state = await ctx.workspace.read();
|
|
@@ -1201,7 +1396,7 @@ var historyListRunsTool = {
|
|
|
1201
1396
|
var historyGetRunTool = {
|
|
1202
1397
|
name: "history.get_run",
|
|
1203
1398
|
description: "Fetch a single history row in full (headers, body preview, assertion results).",
|
|
1204
|
-
inputSchema:
|
|
1399
|
+
inputSchema: z7.object({ id: z7.string() }),
|
|
1205
1400
|
async handler(input, ctx) {
|
|
1206
1401
|
const state = await ctx.workspace.read();
|
|
1207
1402
|
const run = state.local.history.requestRuns.find((r) => r.id === input.id);
|
|
@@ -1212,7 +1407,7 @@ var historyGetRunTool = {
|
|
|
1212
1407
|
var historyDeleteRunTool = {
|
|
1213
1408
|
name: "history.delete_run",
|
|
1214
1409
|
description: "Delete a single request-run row by id.",
|
|
1215
|
-
inputSchema:
|
|
1410
|
+
inputSchema: z7.object({ id: z7.string() }),
|
|
1216
1411
|
async handler(input, ctx) {
|
|
1217
1412
|
const out = await ctx.workspace.apply({ kind: "history.delete_run", runId: input.id });
|
|
1218
1413
|
return { deleted: out.changedIds.length, changedIds: out.changedIds };
|
|
@@ -1221,8 +1416,8 @@ var historyDeleteRunTool = {
|
|
|
1221
1416
|
var historyPurgeTool = {
|
|
1222
1417
|
name: "history.purge_by_age",
|
|
1223
1418
|
description: "Drop every request-run + plan-run older than `olderThanDays` days. Pass 0 to clear all history.",
|
|
1224
|
-
inputSchema:
|
|
1225
|
-
olderThanDays:
|
|
1419
|
+
inputSchema: z7.object({
|
|
1420
|
+
olderThanDays: z7.number().nonnegative()
|
|
1226
1421
|
}),
|
|
1227
1422
|
async handler(input, ctx) {
|
|
1228
1423
|
const olderThanMs = input.olderThanDays * 24 * 60 * 60 * 1e3;
|
|
@@ -1232,15 +1427,15 @@ var historyPurgeTool = {
|
|
|
1232
1427
|
};
|
|
1233
1428
|
|
|
1234
1429
|
// src/tools/codebase.ts
|
|
1235
|
-
import { z as
|
|
1430
|
+
import { z as z8 } from "zod";
|
|
1236
1431
|
var HTTP_METHODS = ["get", "post", "put", "patch", "delete", "options", "head"];
|
|
1237
1432
|
var codebaseExtractCollectionTool = {
|
|
1238
1433
|
name: "codebase.extract_collection",
|
|
1239
1434
|
description: "Scan source code for HTTP route definitions (Express, FastAPI, NestJS, Spring) and return candidate requests for the user to confirm before import.",
|
|
1240
|
-
inputSchema:
|
|
1241
|
-
source:
|
|
1435
|
+
inputSchema: z8.object({
|
|
1436
|
+
source: z8.string().min(1),
|
|
1242
1437
|
/** Hint to limit which framework patterns to apply. Empty = try all. */
|
|
1243
|
-
frameworks:
|
|
1438
|
+
frameworks: z8.array(z8.enum(["express", "fastapi", "nest", "spring"])).default([])
|
|
1244
1439
|
}),
|
|
1245
1440
|
async handler(input) {
|
|
1246
1441
|
const enabled = new Set(
|
|
@@ -1321,18 +1516,18 @@ var codebaseExtractCollectionTool = {
|
|
|
1321
1516
|
};
|
|
1322
1517
|
|
|
1323
1518
|
// src/tools/prompt.ts
|
|
1324
|
-
import { z as
|
|
1519
|
+
import { z as z9 } from "zod";
|
|
1325
1520
|
import { generateId as generateId3, makeDefaultMockResponse, makeDefaultRequestSchema } from "@apicircle/shared";
|
|
1326
1521
|
var promptCreateEnvironmentTool = {
|
|
1327
1522
|
name: "prompt.create_environment",
|
|
1328
1523
|
description: "Create a new environment from an LLM-shaped JSON envelope. The model produces { name, variables: [{ key, value, encrypted }] }; this tool validates and persists it.",
|
|
1329
|
-
inputSchema:
|
|
1330
|
-
name:
|
|
1331
|
-
variables:
|
|
1332
|
-
|
|
1333
|
-
key:
|
|
1334
|
-
value:
|
|
1335
|
-
encrypted:
|
|
1524
|
+
inputSchema: z9.object({
|
|
1525
|
+
name: z9.string(),
|
|
1526
|
+
variables: z9.array(
|
|
1527
|
+
z9.object({
|
|
1528
|
+
key: z9.string(),
|
|
1529
|
+
value: z9.string(),
|
|
1530
|
+
encrypted: z9.boolean().default(false)
|
|
1336
1531
|
})
|
|
1337
1532
|
)
|
|
1338
1533
|
}),
|
|
@@ -1345,13 +1540,13 @@ var promptCreateEnvironmentTool = {
|
|
|
1345
1540
|
var promptCreateAssertionTool = {
|
|
1346
1541
|
name: "prompt.create_assertion",
|
|
1347
1542
|
description: 'Add an assertion to a request from an LLM-shaped JSON envelope. Useful when the user asks "assert that the response status is 200 and body.id matches".',
|
|
1348
|
-
inputSchema:
|
|
1349
|
-
requestId:
|
|
1350
|
-
assertion:
|
|
1351
|
-
kind:
|
|
1352
|
-
op:
|
|
1353
|
-
target:
|
|
1354
|
-
expected:
|
|
1543
|
+
inputSchema: z9.object({
|
|
1544
|
+
requestId: z9.string(),
|
|
1545
|
+
assertion: z9.object({
|
|
1546
|
+
kind: z9.enum(["status", "header", "json-path", "duration"]),
|
|
1547
|
+
op: z9.enum(["equals", "not-equals", "contains", "lt", "gt", "matches"]),
|
|
1548
|
+
target: z9.string().optional(),
|
|
1549
|
+
expected: z9.union([z9.string(), z9.number()])
|
|
1355
1550
|
})
|
|
1356
1551
|
}),
|
|
1357
1552
|
async handler(input, ctx) {
|
|
@@ -1370,10 +1565,10 @@ var promptCreateAssertionTool = {
|
|
|
1370
1565
|
var promptCreatePlanTool = {
|
|
1371
1566
|
name: "prompt.create_plan",
|
|
1372
1567
|
description: "Create an execution plan from an LLM-shaped JSON envelope. The model produces { name, stepRequestIds: [...] } and the tool validates that each id exists in the workspace before persisting.",
|
|
1373
|
-
inputSchema:
|
|
1374
|
-
name:
|
|
1375
|
-
stepRequestIds:
|
|
1376
|
-
envPriorityOrder:
|
|
1568
|
+
inputSchema: z9.object({
|
|
1569
|
+
name: z9.string(),
|
|
1570
|
+
stepRequestIds: z9.array(z9.string()).default([]),
|
|
1571
|
+
envPriorityOrder: z9.array(z9.string()).default([])
|
|
1377
1572
|
}),
|
|
1378
1573
|
async handler(input, ctx) {
|
|
1379
1574
|
const state = await ctx.workspace.read();
|
|
@@ -1402,51 +1597,51 @@ var promptCreatePlanTool = {
|
|
|
1402
1597
|
return { ok: true, id, changedIds: out.changedIds };
|
|
1403
1598
|
}
|
|
1404
1599
|
};
|
|
1405
|
-
var HTTP_METHOD2 =
|
|
1406
|
-
var HEADER_OR_QUERY =
|
|
1407
|
-
key:
|
|
1408
|
-
value:
|
|
1409
|
-
enabled:
|
|
1600
|
+
var HTTP_METHOD2 = z9.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
1601
|
+
var HEADER_OR_QUERY = z9.object({
|
|
1602
|
+
key: z9.string(),
|
|
1603
|
+
value: z9.string(),
|
|
1604
|
+
enabled: z9.boolean().default(true)
|
|
1410
1605
|
});
|
|
1411
|
-
var REQUEST_BODY =
|
|
1412
|
-
type:
|
|
1413
|
-
content:
|
|
1414
|
-
variables:
|
|
1606
|
+
var REQUEST_BODY = z9.object({
|
|
1607
|
+
type: z9.enum(["none", "json", "text", "xml", "graphql", "urlencoded"]).default("none"),
|
|
1608
|
+
content: z9.string().default(""),
|
|
1609
|
+
variables: z9.string().optional()
|
|
1415
1610
|
});
|
|
1416
|
-
var PROMPT_AUTH =
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
type:
|
|
1422
|
-
username:
|
|
1423
|
-
password:
|
|
1611
|
+
var PROMPT_AUTH = z9.discriminatedUnion("type", [
|
|
1612
|
+
z9.object({ type: z9.literal("none") }),
|
|
1613
|
+
z9.object({ type: z9.literal("inherit") }),
|
|
1614
|
+
z9.object({ type: z9.literal("bearer"), token: z9.string().default("") }),
|
|
1615
|
+
z9.object({
|
|
1616
|
+
type: z9.literal("basic"),
|
|
1617
|
+
username: z9.string().default(""),
|
|
1618
|
+
password: z9.string().default("")
|
|
1424
1619
|
}),
|
|
1425
|
-
|
|
1426
|
-
type:
|
|
1427
|
-
key:
|
|
1428
|
-
value:
|
|
1429
|
-
addTo:
|
|
1620
|
+
z9.object({
|
|
1621
|
+
type: z9.literal("api-key"),
|
|
1622
|
+
key: z9.string().default(""),
|
|
1623
|
+
value: z9.string().default(""),
|
|
1624
|
+
addTo: z9.enum(["header", "query", "cookie"]).default("header")
|
|
1430
1625
|
}),
|
|
1431
|
-
|
|
1432
|
-
type:
|
|
1433
|
-
key:
|
|
1434
|
-
value:
|
|
1626
|
+
z9.object({
|
|
1627
|
+
type: z9.literal("custom-header"),
|
|
1628
|
+
key: z9.string().default(""),
|
|
1629
|
+
value: z9.string().default("")
|
|
1435
1630
|
})
|
|
1436
1631
|
]);
|
|
1437
|
-
var PROMPT_ASSERTION =
|
|
1438
|
-
kind:
|
|
1439
|
-
op:
|
|
1440
|
-
target:
|
|
1441
|
-
expected:
|
|
1632
|
+
var PROMPT_ASSERTION = z9.object({
|
|
1633
|
+
kind: z9.enum(["status", "header", "json-path", "duration"]),
|
|
1634
|
+
op: z9.enum(["equals", "not-equals", "contains", "lt", "gt", "matches"]),
|
|
1635
|
+
target: z9.string().optional(),
|
|
1636
|
+
expected: z9.union([z9.string(), z9.number()])
|
|
1442
1637
|
});
|
|
1443
|
-
var ENDPOINT_RESPONSE =
|
|
1444
|
-
status:
|
|
1445
|
-
jsonBody:
|
|
1446
|
-
contentType:
|
|
1638
|
+
var ENDPOINT_RESPONSE = z9.object({
|
|
1639
|
+
status: z9.number().int().min(100).max(599).default(200),
|
|
1640
|
+
jsonBody: z9.string().default("{}"),
|
|
1641
|
+
contentType: z9.string().default("application/json")
|
|
1447
1642
|
});
|
|
1448
|
-
var VALIDATION_RULE_NL =
|
|
1449
|
-
kind:
|
|
1643
|
+
var VALIDATION_RULE_NL = z9.object({
|
|
1644
|
+
kind: z9.enum([
|
|
1450
1645
|
"header-required",
|
|
1451
1646
|
"header-equals",
|
|
1452
1647
|
"header-matches",
|
|
@@ -1457,50 +1652,50 @@ var VALIDATION_RULE_NL = z8.object({
|
|
|
1457
1652
|
"body-required",
|
|
1458
1653
|
"content-type-equals"
|
|
1459
1654
|
]),
|
|
1460
|
-
target:
|
|
1461
|
-
expected:
|
|
1462
|
-
message:
|
|
1463
|
-
enabled:
|
|
1464
|
-
failResponse:
|
|
1465
|
-
status:
|
|
1466
|
-
jsonBody:
|
|
1655
|
+
target: z9.string().default(""),
|
|
1656
|
+
expected: z9.string().optional(),
|
|
1657
|
+
message: z9.string().optional(),
|
|
1658
|
+
enabled: z9.boolean().default(true),
|
|
1659
|
+
failResponse: z9.object({
|
|
1660
|
+
status: z9.number().int().min(100).max(599).default(400),
|
|
1661
|
+
jsonBody: z9.string().default('{"error":"validation failed"}')
|
|
1467
1662
|
}).default({})
|
|
1468
1663
|
});
|
|
1469
|
-
var CONDITION_CLAUSE_NL =
|
|
1470
|
-
scope:
|
|
1471
|
-
target:
|
|
1472
|
-
op:
|
|
1473
|
-
value:
|
|
1664
|
+
var CONDITION_CLAUSE_NL = z9.object({
|
|
1665
|
+
scope: z9.enum(["query", "pathParam", "header", "cookie", "body-json-path"]),
|
|
1666
|
+
target: z9.string(),
|
|
1667
|
+
op: z9.enum(["equals", "not-equals", "matches", "gt", "lt", "gte", "lte", "present", "absent"]),
|
|
1668
|
+
value: z9.string().optional()
|
|
1474
1669
|
});
|
|
1475
|
-
var RESPONSE_RULE_NL =
|
|
1476
|
-
name:
|
|
1477
|
-
enabled:
|
|
1478
|
-
when:
|
|
1479
|
-
response:
|
|
1480
|
-
status:
|
|
1481
|
-
jsonBody:
|
|
1670
|
+
var RESPONSE_RULE_NL = z9.object({
|
|
1671
|
+
name: z9.string(),
|
|
1672
|
+
enabled: z9.boolean().default(true),
|
|
1673
|
+
when: z9.array(CONDITION_CLAUSE_NL).default([]),
|
|
1674
|
+
response: z9.object({
|
|
1675
|
+
status: z9.number().int().min(100).max(599).default(200),
|
|
1676
|
+
jsonBody: z9.string().default("{}")
|
|
1482
1677
|
}).default({})
|
|
1483
1678
|
});
|
|
1484
|
-
var MULTIPLIER_NL =
|
|
1485
|
-
name:
|
|
1486
|
-
source:
|
|
1487
|
-
kind:
|
|
1488
|
-
key:
|
|
1679
|
+
var MULTIPLIER_NL = z9.object({
|
|
1680
|
+
name: z9.string().optional(),
|
|
1681
|
+
source: z9.object({
|
|
1682
|
+
kind: z9.enum(["query", "pathParam", "header", "body-json-path"]),
|
|
1683
|
+
key: z9.string()
|
|
1489
1684
|
}),
|
|
1490
|
-
targetJsonPath:
|
|
1491
|
-
defaultCount:
|
|
1492
|
-
min:
|
|
1493
|
-
max:
|
|
1685
|
+
targetJsonPath: z9.string(),
|
|
1686
|
+
defaultCount: z9.number().int().nonnegative().default(0),
|
|
1687
|
+
min: z9.number().int().nonnegative().optional(),
|
|
1688
|
+
max: z9.number().int().nonnegative().optional()
|
|
1494
1689
|
});
|
|
1495
|
-
var ENDPOINT_INPUT =
|
|
1690
|
+
var ENDPOINT_INPUT = z9.object({
|
|
1496
1691
|
method: HTTP_METHOD2,
|
|
1497
|
-
pathPattern:
|
|
1498
|
-
name:
|
|
1499
|
-
description:
|
|
1692
|
+
pathPattern: z9.string().min(1),
|
|
1693
|
+
name: z9.string().optional(),
|
|
1694
|
+
description: z9.string().optional(),
|
|
1500
1695
|
response: ENDPOINT_RESPONSE.optional(),
|
|
1501
|
-
validationRules:
|
|
1502
|
-
responseRules:
|
|
1503
|
-
multipliers:
|
|
1696
|
+
validationRules: z9.array(VALIDATION_RULE_NL).default([]),
|
|
1697
|
+
responseRules: z9.array(RESPONSE_RULE_NL).default([]),
|
|
1698
|
+
multipliers: z9.array(MULTIPLIER_NL).default([])
|
|
1504
1699
|
});
|
|
1505
1700
|
function buildRequestBody(input) {
|
|
1506
1701
|
if (!input) return { type: "none", content: "" };
|
|
@@ -1593,17 +1788,17 @@ function patchEndpoint(mock, endpointId, patcher) {
|
|
|
1593
1788
|
var promptCreateRequestTool = {
|
|
1594
1789
|
name: "prompt.create_request",
|
|
1595
1790
|
description: "Create a fully-shaped request from an LLM-shaped JSON envelope: method, url, headers, query params, body, auth, and inline assertions. The model produces a flat object; this tool generates the request id, normalizes auth (defaults to `inherit` so folder auth wins), and persists.",
|
|
1596
|
-
inputSchema:
|
|
1597
|
-
name:
|
|
1791
|
+
inputSchema: z9.object({
|
|
1792
|
+
name: z9.string().default("New request"),
|
|
1598
1793
|
method: HTTP_METHOD2.default("GET"),
|
|
1599
|
-
url:
|
|
1600
|
-
folderId:
|
|
1601
|
-
headers:
|
|
1602
|
-
queryParams:
|
|
1603
|
-
pathParams:
|
|
1794
|
+
url: z9.string().default(""),
|
|
1795
|
+
folderId: z9.string().nullable().optional(),
|
|
1796
|
+
headers: z9.array(HEADER_OR_QUERY).default([]),
|
|
1797
|
+
queryParams: z9.array(HEADER_OR_QUERY).default([]),
|
|
1798
|
+
pathParams: z9.record(z9.string(), z9.string()).optional(),
|
|
1604
1799
|
body: REQUEST_BODY.optional(),
|
|
1605
1800
|
auth: PROMPT_AUTH.optional(),
|
|
1606
|
-
assertions:
|
|
1801
|
+
assertions: z9.array(PROMPT_ASSERTION).default([])
|
|
1607
1802
|
}),
|
|
1608
1803
|
async handler(input, ctx) {
|
|
1609
1804
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1633,19 +1828,19 @@ var promptCreateRequestTool = {
|
|
|
1633
1828
|
var promptUpdateRequestTool = {
|
|
1634
1829
|
name: "prompt.update_request",
|
|
1635
1830
|
description: "Patch an existing request from an LLM-shaped JSON envelope. Provided fields replace the existing values; omitted fields are left untouched. Arrays (headers, queryParams, assertions) are full replacements when supplied. Returns `{ ok: false, error }` when the id does not resolve.",
|
|
1636
|
-
inputSchema:
|
|
1637
|
-
id:
|
|
1638
|
-
patch:
|
|
1639
|
-
name:
|
|
1831
|
+
inputSchema: z9.object({
|
|
1832
|
+
id: z9.string(),
|
|
1833
|
+
patch: z9.object({
|
|
1834
|
+
name: z9.string().optional(),
|
|
1640
1835
|
method: HTTP_METHOD2.optional(),
|
|
1641
|
-
url:
|
|
1642
|
-
folderId:
|
|
1643
|
-
headers:
|
|
1644
|
-
queryParams:
|
|
1645
|
-
pathParams:
|
|
1836
|
+
url: z9.string().optional(),
|
|
1837
|
+
folderId: z9.string().nullable().optional(),
|
|
1838
|
+
headers: z9.array(HEADER_OR_QUERY).optional(),
|
|
1839
|
+
queryParams: z9.array(HEADER_OR_QUERY).optional(),
|
|
1840
|
+
pathParams: z9.record(z9.string(), z9.string()).optional(),
|
|
1646
1841
|
body: REQUEST_BODY.optional(),
|
|
1647
1842
|
auth: PROMPT_AUTH.optional(),
|
|
1648
|
-
assertions:
|
|
1843
|
+
assertions: z9.array(PROMPT_ASSERTION).optional()
|
|
1649
1844
|
}).strict()
|
|
1650
1845
|
}),
|
|
1651
1846
|
async handler(input, ctx) {
|
|
@@ -1673,17 +1868,17 @@ var promptUpdateRequestTool = {
|
|
|
1673
1868
|
return { ok: true, changedIds: out.changedIds };
|
|
1674
1869
|
}
|
|
1675
1870
|
};
|
|
1676
|
-
var FOLDER_TREE_NODE =
|
|
1677
|
-
() =>
|
|
1678
|
-
name:
|
|
1679
|
-
children:
|
|
1871
|
+
var FOLDER_TREE_NODE = z9.lazy(
|
|
1872
|
+
() => z9.object({
|
|
1873
|
+
name: z9.string(),
|
|
1874
|
+
children: z9.array(FOLDER_TREE_NODE).optional()
|
|
1680
1875
|
})
|
|
1681
1876
|
);
|
|
1682
1877
|
var promptCreateFolderTreeTool = {
|
|
1683
1878
|
name: "prompt.create_folder_tree",
|
|
1684
1879
|
description: "Create a recursive folder hierarchy from an LLM-shaped JSON envelope. The model produces `{ parentId?, tree: { name, children?: [...] } }` and this tool walks the tree, generating ids and persisting one folder per node. Returns the list of created ids in pre-order.",
|
|
1685
|
-
inputSchema:
|
|
1686
|
-
parentId:
|
|
1880
|
+
inputSchema: z9.object({
|
|
1881
|
+
parentId: z9.string().nullable().optional(),
|
|
1687
1882
|
tree: FOLDER_TREE_NODE
|
|
1688
1883
|
}),
|
|
1689
1884
|
async handler(input, ctx) {
|
|
@@ -1709,9 +1904,9 @@ var promptCreateFolderTreeTool = {
|
|
|
1709
1904
|
var promptAddPlanStepsTool = {
|
|
1710
1905
|
name: "prompt.add_plan_steps",
|
|
1711
1906
|
description: "Append one or more steps to an existing execution plan from an LLM-shaped JSON envelope. The model produces `{ planId, requestIds: [...] }`; each id is validated against the workspace before any step is appended. Order in the input list is preserved.",
|
|
1712
|
-
inputSchema:
|
|
1713
|
-
planId:
|
|
1714
|
-
requestIds:
|
|
1907
|
+
inputSchema: z9.object({
|
|
1908
|
+
planId: z9.string(),
|
|
1909
|
+
requestIds: z9.array(z9.string()).min(1)
|
|
1715
1910
|
}),
|
|
1716
1911
|
async handler(input, ctx) {
|
|
1717
1912
|
const state = await ctx.workspace.read();
|
|
@@ -1741,9 +1936,9 @@ var promptAddPlanStepsTool = {
|
|
|
1741
1936
|
var promptSetPlanVariablesTool = {
|
|
1742
1937
|
name: "prompt.set_plan_variables",
|
|
1743
1938
|
description: "Replace the plan-scoped variables on an execution plan from an LLM-shaped JSON envelope. The model produces `{ planId, variables: [{ key, value }] }`. Empty array clears all plan variables.",
|
|
1744
|
-
inputSchema:
|
|
1745
|
-
planId:
|
|
1746
|
-
variables:
|
|
1939
|
+
inputSchema: z9.object({
|
|
1940
|
+
planId: z9.string(),
|
|
1941
|
+
variables: z9.array(z9.object({ key: z9.string(), value: z9.string() }))
|
|
1747
1942
|
}),
|
|
1748
1943
|
async handler(input, ctx) {
|
|
1749
1944
|
const state = await ctx.workspace.read();
|
|
@@ -1759,10 +1954,10 @@ var promptSetPlanVariablesTool = {
|
|
|
1759
1954
|
var promptCreateMockServerTool = {
|
|
1760
1955
|
name: "prompt.create_mock_server",
|
|
1761
1956
|
description: "Create a manual-mode mock server with optional inline endpoints from an LLM-shaped JSON envelope. The model produces `{ name, defaultPort?, endpoints: [{ method, pathPattern, name?, response?, validationRules?, responseRules?, multipliers? }] }`; this tool generates ids for the server and every endpoint / rule, then persists in one shot.",
|
|
1762
|
-
inputSchema:
|
|
1763
|
-
name:
|
|
1764
|
-
defaultPort:
|
|
1765
|
-
endpoints:
|
|
1957
|
+
inputSchema: z9.object({
|
|
1958
|
+
name: z9.string().min(1),
|
|
1959
|
+
defaultPort: z9.number().int().positive().nullable().optional(),
|
|
1960
|
+
endpoints: z9.array(ENDPOINT_INPUT).default([])
|
|
1766
1961
|
}),
|
|
1767
1962
|
async handler(input, ctx) {
|
|
1768
1963
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1789,16 +1984,16 @@ var promptCreateMockServerTool = {
|
|
|
1789
1984
|
var promptAddMockEndpointTool = {
|
|
1790
1985
|
name: "prompt.add_mock_endpoint",
|
|
1791
1986
|
description: "Append a new endpoint (with optional inline validation rules, response rules, and multipliers) to an existing mock server from an LLM-shaped JSON envelope. All ids are auto-generated; the existing endpoints stay in place.",
|
|
1792
|
-
inputSchema:
|
|
1793
|
-
mockId:
|
|
1987
|
+
inputSchema: z9.object({
|
|
1988
|
+
mockId: z9.string(),
|
|
1794
1989
|
method: HTTP_METHOD2,
|
|
1795
|
-
pathPattern:
|
|
1796
|
-
name:
|
|
1797
|
-
description:
|
|
1990
|
+
pathPattern: z9.string().min(1),
|
|
1991
|
+
name: z9.string().optional(),
|
|
1992
|
+
description: z9.string().optional(),
|
|
1798
1993
|
response: ENDPOINT_RESPONSE.optional(),
|
|
1799
|
-
validationRules:
|
|
1800
|
-
responseRules:
|
|
1801
|
-
multipliers:
|
|
1994
|
+
validationRules: z9.array(VALIDATION_RULE_NL).default([]),
|
|
1995
|
+
responseRules: z9.array(RESPONSE_RULE_NL).default([]),
|
|
1996
|
+
multipliers: z9.array(MULTIPLIER_NL).default([])
|
|
1802
1997
|
}),
|
|
1803
1998
|
async handler(input, ctx) {
|
|
1804
1999
|
const state = await ctx.workspace.read();
|
|
@@ -1820,10 +2015,10 @@ var promptAddMockEndpointTool = {
|
|
|
1820
2015
|
var promptSetEndpointValidationRulesTool = {
|
|
1821
2016
|
name: "prompt.set_endpoint_validation_rules",
|
|
1822
2017
|
description: "Replace an endpoint's validation rules with an LLM-shaped list. Every rule gets a fresh id; the existing rules are dropped. Empty array clears all validation rules.",
|
|
1823
|
-
inputSchema:
|
|
1824
|
-
mockId:
|
|
1825
|
-
endpointId:
|
|
1826
|
-
rules:
|
|
2018
|
+
inputSchema: z9.object({
|
|
2019
|
+
mockId: z9.string(),
|
|
2020
|
+
endpointId: z9.string(),
|
|
2021
|
+
rules: z9.array(VALIDATION_RULE_NL)
|
|
1827
2022
|
}),
|
|
1828
2023
|
async handler(input, ctx) {
|
|
1829
2024
|
const state = await ctx.workspace.read();
|
|
@@ -1854,10 +2049,10 @@ var promptSetEndpointValidationRulesTool = {
|
|
|
1854
2049
|
var promptSetEndpointResponseRulesTool = {
|
|
1855
2050
|
name: "prompt.set_endpoint_response_rules",
|
|
1856
2051
|
description: "Replace an endpoint's conditional response rules with an LLM-shaped list. Rules fire in order, first match wins. Every rule + clause gets a fresh id. Empty array falls back to defaultResponse.",
|
|
1857
|
-
inputSchema:
|
|
1858
|
-
mockId:
|
|
1859
|
-
endpointId:
|
|
1860
|
-
rules:
|
|
2052
|
+
inputSchema: z9.object({
|
|
2053
|
+
mockId: z9.string(),
|
|
2054
|
+
endpointId: z9.string(),
|
|
2055
|
+
rules: z9.array(RESPONSE_RULE_NL)
|
|
1861
2056
|
}),
|
|
1862
2057
|
async handler(input, ctx) {
|
|
1863
2058
|
const state = await ctx.workspace.read();
|
|
@@ -1892,10 +2087,10 @@ var promptSetEndpointResponseRulesTool = {
|
|
|
1892
2087
|
var promptSetEndpointMultipliersTool = {
|
|
1893
2088
|
name: "prompt.set_endpoint_multipliers",
|
|
1894
2089
|
description: "Replace the response multipliers on an endpoint's defaultResponse with an LLM-shaped list. Multipliers expand an array at `targetJsonPath` to a count derived from a request value. Every multiplier gets a fresh id. Empty array clears all multipliers.",
|
|
1895
|
-
inputSchema:
|
|
1896
|
-
mockId:
|
|
1897
|
-
endpointId:
|
|
1898
|
-
multipliers:
|
|
2090
|
+
inputSchema: z9.object({
|
|
2091
|
+
mockId: z9.string(),
|
|
2092
|
+
endpointId: z9.string(),
|
|
2093
|
+
multipliers: z9.array(MULTIPLIER_NL)
|
|
1899
2094
|
}),
|
|
1900
2095
|
async handler(input, ctx) {
|
|
1901
2096
|
const state = await ctx.workspace.read();
|
|
@@ -1924,7 +2119,7 @@ var promptSetEndpointMultipliersTool = {
|
|
|
1924
2119
|
};
|
|
1925
2120
|
|
|
1926
2121
|
// src/tools/mocks.ts
|
|
1927
|
-
import { z as
|
|
2122
|
+
import { z as z10 } from "zod";
|
|
1928
2123
|
import { generateId as generateId4, makeDefaultMockResponse as makeDefaultMockResponse2, makeDefaultRequestSchema as makeDefaultRequestSchema2 } from "@apicircle/shared";
|
|
1929
2124
|
import { parseSourceToEndpoints } from "@apicircle/mock-server-core";
|
|
1930
2125
|
async function ingestSource(source, name) {
|
|
@@ -1947,10 +2142,10 @@ async function ingestSource(source, name) {
|
|
|
1947
2142
|
var mockCreateFromOpenApiTool = {
|
|
1948
2143
|
name: "mock.create_from_openapi",
|
|
1949
2144
|
description: "Create a mock server from an OpenAPI / Swagger spec (YAML or JSON).",
|
|
1950
|
-
inputSchema:
|
|
1951
|
-
name:
|
|
1952
|
-
spec:
|
|
1953
|
-
format:
|
|
2145
|
+
inputSchema: z10.object({
|
|
2146
|
+
name: z10.string(),
|
|
2147
|
+
spec: z10.string().min(1),
|
|
2148
|
+
format: z10.enum(["json", "yaml"]).default("json")
|
|
1954
2149
|
}),
|
|
1955
2150
|
async handler(input, ctx) {
|
|
1956
2151
|
const { mock, warnings } = await ingestSource(
|
|
@@ -1969,7 +2164,7 @@ var mockCreateFromOpenApiTool = {
|
|
|
1969
2164
|
var mockCreateFromPostmanTool = {
|
|
1970
2165
|
name: "mock.create_from_postman",
|
|
1971
2166
|
description: "Create a mock server from a Postman v2/v2.1 collection.",
|
|
1972
|
-
inputSchema:
|
|
2167
|
+
inputSchema: z10.object({ name: z10.string(), collection: z10.string().min(1) }),
|
|
1973
2168
|
async handler(input, ctx) {
|
|
1974
2169
|
const { mock, warnings } = await ingestSource(
|
|
1975
2170
|
{ kind: "postman", collection: input.collection },
|
|
@@ -1987,7 +2182,7 @@ var mockCreateFromPostmanTool = {
|
|
|
1987
2182
|
var mockCreateFromInsomniaTool = {
|
|
1988
2183
|
name: "mock.create_from_insomnia",
|
|
1989
2184
|
description: "Create a mock server from an Insomnia v4 export.",
|
|
1990
|
-
inputSchema:
|
|
2185
|
+
inputSchema: z10.object({ name: z10.string(), export: z10.string().min(1) }),
|
|
1991
2186
|
async handler(input, ctx) {
|
|
1992
2187
|
const { mock, warnings } = await ingestSource(
|
|
1993
2188
|
{ kind: "insomnia", export: input.export },
|
|
@@ -2005,7 +2200,7 @@ var mockCreateFromInsomniaTool = {
|
|
|
2005
2200
|
var mockImportPostmanMockCollectionTool = {
|
|
2006
2201
|
name: "mock.import_postman_mock_collection",
|
|
2007
2202
|
description: "Import a Postman Mock Collection (collections previously hosted on Postman's mock service). Same parser as a regular Postman collection but marked as a mock import.",
|
|
2008
|
-
inputSchema:
|
|
2203
|
+
inputSchema: z10.object({ name: z10.string(), collection: z10.string().min(1) }),
|
|
2009
2204
|
async handler(input, ctx) {
|
|
2010
2205
|
const { mock, warnings } = await ingestSource(
|
|
2011
2206
|
{ kind: "postman", collection: input.collection },
|
|
@@ -2023,7 +2218,7 @@ var mockImportPostmanMockCollectionTool = {
|
|
|
2023
2218
|
var mockListTool = {
|
|
2024
2219
|
name: "mock.list",
|
|
2025
2220
|
description: "List all mock servers in the workspace plus their runtime status (running / stopped, port).",
|
|
2026
|
-
inputSchema:
|
|
2221
|
+
inputSchema: z10.object({}),
|
|
2027
2222
|
async handler(_input, ctx) {
|
|
2028
2223
|
const state = await ctx.workspace.read();
|
|
2029
2224
|
const running = await ctx.mock.list();
|
|
@@ -2045,9 +2240,9 @@ var mockListTool = {
|
|
|
2045
2240
|
var mockStartTool = {
|
|
2046
2241
|
name: "mock.start",
|
|
2047
2242
|
description: "Start a mock server by id. Returns the bound port. Errors if the mock is already running or the requested port is in use.",
|
|
2048
|
-
inputSchema:
|
|
2049
|
-
id:
|
|
2050
|
-
port:
|
|
2243
|
+
inputSchema: z10.object({
|
|
2244
|
+
id: z10.string(),
|
|
2245
|
+
port: z10.number().int().positive().optional()
|
|
2051
2246
|
}),
|
|
2052
2247
|
async handler(input, ctx) {
|
|
2053
2248
|
const state = await ctx.workspace.read();
|
|
@@ -2064,7 +2259,7 @@ var mockStartTool = {
|
|
|
2064
2259
|
var mockStopTool = {
|
|
2065
2260
|
name: "mock.stop",
|
|
2066
2261
|
description: "Stop a running mock server by id (no-op if not running).",
|
|
2067
|
-
inputSchema:
|
|
2262
|
+
inputSchema: z10.object({ id: z10.string() }),
|
|
2068
2263
|
async handler(input, ctx) {
|
|
2069
2264
|
try {
|
|
2070
2265
|
await ctx.mock.stop(input.id);
|
|
@@ -2077,7 +2272,7 @@ var mockStopTool = {
|
|
|
2077
2272
|
var mockDeleteTool = {
|
|
2078
2273
|
name: "mock.delete",
|
|
2079
2274
|
description: "Delete a mock server definition. Stops it first if it's running.",
|
|
2080
|
-
inputSchema:
|
|
2275
|
+
inputSchema: z10.object({ id: z10.string() }),
|
|
2081
2276
|
async handler(input, ctx) {
|
|
2082
2277
|
try {
|
|
2083
2278
|
await ctx.mock.stop(input.id);
|
|
@@ -2087,13 +2282,13 @@ var mockDeleteTool = {
|
|
|
2087
2282
|
return { ok: true, changedIds: out.changedIds };
|
|
2088
2283
|
}
|
|
2089
2284
|
};
|
|
2090
|
-
var HTTP_METHOD3 =
|
|
2285
|
+
var HTTP_METHOD3 = z10.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
2091
2286
|
var mockCreateManualTool = {
|
|
2092
2287
|
name: "mock.create_manual",
|
|
2093
2288
|
description: "Create an empty manual-mode mock server. Use `mock.add_endpoint` afterward to populate it. CORS defaults to off (same-origin only); enable + list explicit origins via `mock.update_cors` if cross-origin access is needed.",
|
|
2094
|
-
inputSchema:
|
|
2095
|
-
name:
|
|
2096
|
-
defaultPort:
|
|
2289
|
+
inputSchema: z10.object({
|
|
2290
|
+
name: z10.string().min(1),
|
|
2291
|
+
defaultPort: z10.number().int().positive().nullable().optional()
|
|
2097
2292
|
}),
|
|
2098
2293
|
async handler(input, ctx) {
|
|
2099
2294
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -2116,7 +2311,7 @@ var mockCreateManualTool = {
|
|
|
2116
2311
|
var mockListEndpointsTool = {
|
|
2117
2312
|
name: "mock.list_endpoints",
|
|
2118
2313
|
description: "List endpoints for a mock server (id, method, path, name).",
|
|
2119
|
-
inputSchema:
|
|
2314
|
+
inputSchema: z10.object({ mockId: z10.string() }),
|
|
2120
2315
|
async handler(input, ctx) {
|
|
2121
2316
|
const state = await ctx.workspace.read();
|
|
2122
2317
|
const mock = state.synced.mockServers[input.mockId];
|
|
@@ -2135,10 +2330,10 @@ var mockListEndpointsTool = {
|
|
|
2135
2330
|
};
|
|
2136
2331
|
}
|
|
2137
2332
|
};
|
|
2138
|
-
var ENDPOINT_RESPONSE2 =
|
|
2139
|
-
status:
|
|
2140
|
-
jsonBody:
|
|
2141
|
-
contentType:
|
|
2333
|
+
var ENDPOINT_RESPONSE2 = z10.object({
|
|
2334
|
+
status: z10.number().int().min(100).max(599).default(200),
|
|
2335
|
+
jsonBody: z10.string().default("{}"),
|
|
2336
|
+
contentType: z10.string().default("application/json")
|
|
2142
2337
|
});
|
|
2143
2338
|
function buildDefaultEndpoint(args) {
|
|
2144
2339
|
const response = args.response ?? {
|
|
@@ -2167,12 +2362,12 @@ function buildDefaultEndpoint(args) {
|
|
|
2167
2362
|
var mockAddEndpointTool = {
|
|
2168
2363
|
name: "mock.add_endpoint",
|
|
2169
2364
|
description: "Append a new endpoint to a mock server. Defaults to a 200 JSON response of `{}`. Returns the new endpoint id.",
|
|
2170
|
-
inputSchema:
|
|
2171
|
-
mockId:
|
|
2365
|
+
inputSchema: z10.object({
|
|
2366
|
+
mockId: z10.string(),
|
|
2172
2367
|
method: HTTP_METHOD3,
|
|
2173
|
-
pathPattern:
|
|
2174
|
-
name:
|
|
2175
|
-
description:
|
|
2368
|
+
pathPattern: z10.string().min(1),
|
|
2369
|
+
name: z10.string().optional(),
|
|
2370
|
+
description: z10.string().optional(),
|
|
2176
2371
|
response: ENDPOINT_RESPONSE2.optional()
|
|
2177
2372
|
}),
|
|
2178
2373
|
async handler(input, ctx) {
|
|
@@ -2195,13 +2390,13 @@ var mockAddEndpointTool = {
|
|
|
2195
2390
|
var mockUpdateEndpointTool = {
|
|
2196
2391
|
name: "mock.update_endpoint",
|
|
2197
2392
|
description: "Patch fields on a single mock endpoint (method, pathPattern, name, description, defaultResponse status / contentType / json body). Pass only the fields you want to change.",
|
|
2198
|
-
inputSchema:
|
|
2199
|
-
mockId:
|
|
2200
|
-
endpointId:
|
|
2393
|
+
inputSchema: z10.object({
|
|
2394
|
+
mockId: z10.string(),
|
|
2395
|
+
endpointId: z10.string(),
|
|
2201
2396
|
method: HTTP_METHOD3.optional(),
|
|
2202
|
-
pathPattern:
|
|
2203
|
-
name:
|
|
2204
|
-
description:
|
|
2397
|
+
pathPattern: z10.string().optional(),
|
|
2398
|
+
name: z10.string().optional(),
|
|
2399
|
+
description: z10.string().optional(),
|
|
2205
2400
|
response: ENDPOINT_RESPONSE2.partial().optional()
|
|
2206
2401
|
}),
|
|
2207
2402
|
async handler(input, ctx) {
|
|
@@ -2242,7 +2437,7 @@ var mockUpdateEndpointTool = {
|
|
|
2242
2437
|
var mockDeleteEndpointTool = {
|
|
2243
2438
|
name: "mock.delete_endpoint",
|
|
2244
2439
|
description: "Remove an endpoint from a mock server.",
|
|
2245
|
-
inputSchema:
|
|
2440
|
+
inputSchema: z10.object({ mockId: z10.string(), endpointId: z10.string() }),
|
|
2246
2441
|
async handler(input, ctx) {
|
|
2247
2442
|
const state = await ctx.workspace.read();
|
|
2248
2443
|
const mock = state.synced.mockServers[input.mockId];
|
|
@@ -2262,9 +2457,9 @@ var mockDeleteEndpointTool = {
|
|
|
2262
2457
|
return { ok: true, changedIds: out.changedIds };
|
|
2263
2458
|
}
|
|
2264
2459
|
};
|
|
2265
|
-
var VALIDATION_RULE =
|
|
2266
|
-
id:
|
|
2267
|
-
kind:
|
|
2460
|
+
var VALIDATION_RULE = z10.object({
|
|
2461
|
+
id: z10.string().optional(),
|
|
2462
|
+
kind: z10.enum([
|
|
2268
2463
|
"header-required",
|
|
2269
2464
|
"header-equals",
|
|
2270
2465
|
"header-matches",
|
|
@@ -2275,43 +2470,43 @@ var VALIDATION_RULE = z9.object({
|
|
|
2275
2470
|
"body-required",
|
|
2276
2471
|
"content-type-equals"
|
|
2277
2472
|
]),
|
|
2278
|
-
target:
|
|
2279
|
-
expected:
|
|
2280
|
-
message:
|
|
2281
|
-
enabled:
|
|
2282
|
-
failResponse:
|
|
2283
|
-
status:
|
|
2284
|
-
jsonBody:
|
|
2473
|
+
target: z10.string().default(""),
|
|
2474
|
+
expected: z10.string().optional(),
|
|
2475
|
+
message: z10.string().optional(),
|
|
2476
|
+
enabled: z10.boolean().default(true),
|
|
2477
|
+
failResponse: z10.object({
|
|
2478
|
+
status: z10.number().int().min(100).max(599).default(400),
|
|
2479
|
+
jsonBody: z10.string().default('{"error":"validation failed"}')
|
|
2285
2480
|
}).default({})
|
|
2286
2481
|
});
|
|
2287
|
-
var CONDITION_CLAUSE =
|
|
2288
|
-
id:
|
|
2289
|
-
scope:
|
|
2290
|
-
target:
|
|
2291
|
-
op:
|
|
2292
|
-
value:
|
|
2482
|
+
var CONDITION_CLAUSE = z10.object({
|
|
2483
|
+
id: z10.string().optional(),
|
|
2484
|
+
scope: z10.enum(["query", "pathParam", "header", "cookie", "body-json-path"]),
|
|
2485
|
+
target: z10.string(),
|
|
2486
|
+
op: z10.enum(["equals", "not-equals", "matches", "gt", "lt", "gte", "lte", "present", "absent"]),
|
|
2487
|
+
value: z10.string().optional()
|
|
2293
2488
|
});
|
|
2294
|
-
var RESPONSE_RULE =
|
|
2295
|
-
id:
|
|
2296
|
-
name:
|
|
2297
|
-
enabled:
|
|
2298
|
-
when:
|
|
2299
|
-
response:
|
|
2300
|
-
status:
|
|
2301
|
-
jsonBody:
|
|
2489
|
+
var RESPONSE_RULE = z10.object({
|
|
2490
|
+
id: z10.string().optional(),
|
|
2491
|
+
name: z10.string(),
|
|
2492
|
+
enabled: z10.boolean().default(true),
|
|
2493
|
+
when: z10.array(CONDITION_CLAUSE).default([]),
|
|
2494
|
+
response: z10.object({
|
|
2495
|
+
status: z10.number().int().min(100).max(599).default(200),
|
|
2496
|
+
jsonBody: z10.string().default("{}")
|
|
2302
2497
|
}).default({})
|
|
2303
2498
|
});
|
|
2304
|
-
var MULTIPLIER =
|
|
2305
|
-
id:
|
|
2306
|
-
name:
|
|
2307
|
-
source:
|
|
2308
|
-
kind:
|
|
2309
|
-
key:
|
|
2499
|
+
var MULTIPLIER = z10.object({
|
|
2500
|
+
id: z10.string().optional(),
|
|
2501
|
+
name: z10.string().optional(),
|
|
2502
|
+
source: z10.object({
|
|
2503
|
+
kind: z10.enum(["query", "pathParam", "header", "body-json-path"]),
|
|
2504
|
+
key: z10.string()
|
|
2310
2505
|
}),
|
|
2311
|
-
targetJsonPath:
|
|
2312
|
-
defaultCount:
|
|
2313
|
-
min:
|
|
2314
|
-
max:
|
|
2506
|
+
targetJsonPath: z10.string(),
|
|
2507
|
+
defaultCount: z10.number().int().nonnegative().default(0),
|
|
2508
|
+
min: z10.number().int().nonnegative().optional(),
|
|
2509
|
+
max: z10.number().int().nonnegative().optional()
|
|
2315
2510
|
});
|
|
2316
2511
|
function defaultJsonResponseConfig(args) {
|
|
2317
2512
|
return {
|
|
@@ -2336,10 +2531,10 @@ function patchEndpoint2(mock, endpointId, patcher) {
|
|
|
2336
2531
|
var mockSetValidationRulesTool = {
|
|
2337
2532
|
name: "mock.set_validation_rules",
|
|
2338
2533
|
description: "Replace an endpoint's validation rules. Rules without an `id` get a fresh one; existing rules can keep theirs to preserve client-side selection state. Empty array clears all rules.",
|
|
2339
|
-
inputSchema:
|
|
2340
|
-
mockId:
|
|
2341
|
-
endpointId:
|
|
2342
|
-
rules:
|
|
2534
|
+
inputSchema: z10.object({
|
|
2535
|
+
mockId: z10.string(),
|
|
2536
|
+
endpointId: z10.string(),
|
|
2537
|
+
rules: z10.array(VALIDATION_RULE)
|
|
2343
2538
|
}),
|
|
2344
2539
|
async handler(input, ctx) {
|
|
2345
2540
|
const state = await ctx.workspace.read();
|
|
@@ -2366,10 +2561,10 @@ var mockSetValidationRulesTool = {
|
|
|
2366
2561
|
var mockSetResponseRulesTool = {
|
|
2367
2562
|
name: "mock.set_response_rules",
|
|
2368
2563
|
description: "Replace an endpoint's conditional response rules. Rules fire in order; the first whose every clause matches wins. Disabled rules are skipped. Empty array falls back to defaultResponse.",
|
|
2369
|
-
inputSchema:
|
|
2370
|
-
mockId:
|
|
2371
|
-
endpointId:
|
|
2372
|
-
rules:
|
|
2564
|
+
inputSchema: z10.object({
|
|
2565
|
+
mockId: z10.string(),
|
|
2566
|
+
endpointId: z10.string(),
|
|
2567
|
+
rules: z10.array(RESPONSE_RULE)
|
|
2373
2568
|
}),
|
|
2374
2569
|
async handler(input, ctx) {
|
|
2375
2570
|
const state = await ctx.workspace.read();
|
|
@@ -2400,10 +2595,10 @@ var mockSetResponseRulesTool = {
|
|
|
2400
2595
|
var mockSetMultipliersTool = {
|
|
2401
2596
|
name: "mock.set_multipliers",
|
|
2402
2597
|
description: "Replace the response multipliers on an endpoint's defaultResponse. Multipliers expand an array at `targetJsonPath` to a count derived from a request value. Empty array clears all multipliers.",
|
|
2403
|
-
inputSchema:
|
|
2404
|
-
mockId:
|
|
2405
|
-
endpointId:
|
|
2406
|
-
multipliers:
|
|
2598
|
+
inputSchema: z10.object({
|
|
2599
|
+
mockId: z10.string(),
|
|
2600
|
+
endpointId: z10.string(),
|
|
2601
|
+
multipliers: z10.array(MULTIPLIER)
|
|
2407
2602
|
}),
|
|
2408
2603
|
async handler(input, ctx) {
|
|
2409
2604
|
const state = await ctx.workspace.read();
|
|
@@ -2450,6 +2645,8 @@ var TOOL_REGISTRY = [
|
|
|
2450
2645
|
folderReadTool,
|
|
2451
2646
|
folderUpdateTool,
|
|
2452
2647
|
folderDeleteTool,
|
|
2648
|
+
folderExportJsonTool,
|
|
2649
|
+
folderImportJsonTool,
|
|
2453
2650
|
environmentCreateTool,
|
|
2454
2651
|
environmentReadTool,
|
|
2455
2652
|
environmentUpdateTool,
|