@apicircle/mcp-server 1.0.0 → 1.0.2
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/LICENSE +110 -110
- package/README.md +197 -25
- package/dist/bin/mcp-server.cjs +606 -352
- package/dist/bin/mcp-server.cjs.map +1 -1
- package/dist/index.cjs +577 -350
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -1
- package/dist/index.d.ts +88 -1
- package/dist/index.js +580 -350
- package/dist/index.js.map +1 -1
- package/package.json +33 -26
package/dist/index.cjs
CHANGED
|
@@ -24,7 +24,10 @@ __export(index_exports, {
|
|
|
24
24
|
InMemoryWorkspaceProvider: () => InMemoryWorkspaceProvider,
|
|
25
25
|
InProcessMockController: () => InProcessMockController,
|
|
26
26
|
McpHost: () => McpHost,
|
|
27
|
+
MultiWorkspaceProvider: () => MultiWorkspaceProvider,
|
|
28
|
+
SingleWorkspaceAdapter: () => SingleWorkspaceAdapter,
|
|
27
29
|
TOOL_REGISTRY: () => TOOL_REGISTRY,
|
|
30
|
+
WorkspaceNotFoundError: () => WorkspaceNotFoundError,
|
|
28
31
|
createMcpServer: () => createMcpServer,
|
|
29
32
|
getTool: () => getTool
|
|
30
33
|
});
|
|
@@ -462,18 +465,37 @@ function renderRust(req) {
|
|
|
462
465
|
return lines.join("\n");
|
|
463
466
|
}
|
|
464
467
|
|
|
465
|
-
// src/tools/
|
|
468
|
+
// src/tools/workspaceList.ts
|
|
466
469
|
var import_zod4 = require("zod");
|
|
470
|
+
var workspaceListTool = {
|
|
471
|
+
name: "workspace.list",
|
|
472
|
+
description: "List every workspace registered with this server, including which one is currently active. Returns id, display name, last-opened timestamp, and a per-workspace summary (request count, environment count, mock-server count, plan count). Use this BEFORE drilling into a specific workspace via other tools \u2014 pass the resulting `id` as `workspaceId` to `workspace.read` or related reads when you want to scope to a non-active workspace.",
|
|
473
|
+
inputSchema: import_zod4.z.object({}),
|
|
474
|
+
async handler(_input, ctx) {
|
|
475
|
+
const summaries = await ctx.workspaces.list();
|
|
476
|
+
return {
|
|
477
|
+
activeWorkspaceId: ctx.workspaces.activeId(),
|
|
478
|
+
workspaceCount: summaries.length,
|
|
479
|
+
workspaces: summaries,
|
|
480
|
+
// Plain-text hint the AI surfaces when telling the user. Cheap to
|
|
481
|
+
// generate here and saves round-trips on disambiguation prompts.
|
|
482
|
+
hint: summaries.length === 0 ? "No workspaces are registered yet. The user should open the desktop app once or run `apicircle workspaces create <name>` from the terminal." : summaries.length === 1 ? `Only one workspace ("${summaries[0].name}") is registered \u2014 most tools will default to it without a workspaceId.` : `Multiple workspaces are registered. Pass the desired \`id\` as \`workspaceId\` to other tools to scope reads/writes to that workspace; the active one ("${summaries.find((w) => w.isActive)?.name ?? "(none)"}") is used by default.`
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
// src/tools/crud.ts
|
|
488
|
+
var import_zod5 = require("zod");
|
|
467
489
|
var import_shared2 = require("@apicircle/shared");
|
|
468
|
-
var HTTP_METHOD =
|
|
490
|
+
var HTTP_METHOD = import_zod5.z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
469
491
|
var requestCreateTool = {
|
|
470
492
|
name: "request.create",
|
|
471
493
|
description: "Create a new request from explicit fields and persist it.",
|
|
472
|
-
inputSchema:
|
|
473
|
-
name:
|
|
494
|
+
inputSchema: import_zod5.z.object({
|
|
495
|
+
name: import_zod5.z.string().default("New request"),
|
|
474
496
|
method: HTTP_METHOD.default("GET"),
|
|
475
|
-
url:
|
|
476
|
-
folderId:
|
|
497
|
+
url: import_zod5.z.string().default(""),
|
|
498
|
+
folderId: import_zod5.z.string().nullable().optional()
|
|
477
499
|
}),
|
|
478
500
|
async handler(input, ctx) {
|
|
479
501
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -502,7 +524,7 @@ var requestCreateTool = {
|
|
|
502
524
|
var requestReadTool = {
|
|
503
525
|
name: "request.read",
|
|
504
526
|
description: "Read a request by id, or list summaries (id, name, method, url) when no id is provided.",
|
|
505
|
-
inputSchema:
|
|
527
|
+
inputSchema: import_zod5.z.object({ id: import_zod5.z.string().optional() }),
|
|
506
528
|
async handler(input, ctx) {
|
|
507
529
|
const state = await ctx.workspace.read();
|
|
508
530
|
if (input.id) {
|
|
@@ -523,13 +545,13 @@ var requestReadTool = {
|
|
|
523
545
|
var requestUpdateTool = {
|
|
524
546
|
name: "request.update",
|
|
525
547
|
description: "Patch fields on an existing request.",
|
|
526
|
-
inputSchema:
|
|
527
|
-
id:
|
|
528
|
-
patch:
|
|
529
|
-
name:
|
|
548
|
+
inputSchema: import_zod5.z.object({
|
|
549
|
+
id: import_zod5.z.string(),
|
|
550
|
+
patch: import_zod5.z.object({
|
|
551
|
+
name: import_zod5.z.string().optional(),
|
|
530
552
|
method: HTTP_METHOD.optional(),
|
|
531
|
-
url:
|
|
532
|
-
folderId:
|
|
553
|
+
url: import_zod5.z.string().optional(),
|
|
554
|
+
folderId: import_zod5.z.string().nullable().optional()
|
|
533
555
|
}).strict()
|
|
534
556
|
}),
|
|
535
557
|
async handler(input, ctx) {
|
|
@@ -544,7 +566,7 @@ var requestUpdateTool = {
|
|
|
544
566
|
var requestDeleteTool = {
|
|
545
567
|
name: "request.delete",
|
|
546
568
|
description: "Delete a request by id.",
|
|
547
|
-
inputSchema:
|
|
569
|
+
inputSchema: import_zod5.z.object({ id: import_zod5.z.string() }),
|
|
548
570
|
async handler(input, ctx) {
|
|
549
571
|
const out = await ctx.workspace.apply({ kind: "request.delete", id: input.id });
|
|
550
572
|
return { changedIds: out.changedIds };
|
|
@@ -553,9 +575,9 @@ var requestDeleteTool = {
|
|
|
553
575
|
var folderCreateTool = {
|
|
554
576
|
name: "folder.create",
|
|
555
577
|
description: "Create a folder under an optional parent folder.",
|
|
556
|
-
inputSchema:
|
|
557
|
-
name:
|
|
558
|
-
parentId:
|
|
578
|
+
inputSchema: import_zod5.z.object({
|
|
579
|
+
name: import_zod5.z.string().default("New folder"),
|
|
580
|
+
parentId: import_zod5.z.string().nullable().optional()
|
|
559
581
|
}),
|
|
560
582
|
async handler(input, ctx) {
|
|
561
583
|
const folder = {
|
|
@@ -570,7 +592,7 @@ var folderCreateTool = {
|
|
|
570
592
|
var folderReadTool = {
|
|
571
593
|
name: "folder.read",
|
|
572
594
|
description: "Read a folder by id, or list all folders when no id is provided.",
|
|
573
|
-
inputSchema:
|
|
595
|
+
inputSchema: import_zod5.z.object({ id: import_zod5.z.string().optional() }),
|
|
574
596
|
async handler(input, ctx) {
|
|
575
597
|
const state = await ctx.workspace.read();
|
|
576
598
|
if (input.id) {
|
|
@@ -586,9 +608,9 @@ var folderReadTool = {
|
|
|
586
608
|
var folderUpdateTool = {
|
|
587
609
|
name: "folder.update",
|
|
588
610
|
description: "Move a folder to a new parent (or to root with parentId: null).",
|
|
589
|
-
inputSchema:
|
|
590
|
-
id:
|
|
591
|
-
parentId:
|
|
611
|
+
inputSchema: import_zod5.z.object({
|
|
612
|
+
id: import_zod5.z.string(),
|
|
613
|
+
parentId: import_zod5.z.string().nullable()
|
|
592
614
|
}),
|
|
593
615
|
async handler(input, ctx) {
|
|
594
616
|
const out = await ctx.workspace.apply({
|
|
@@ -602,23 +624,23 @@ var folderUpdateTool = {
|
|
|
602
624
|
var folderDeleteTool = {
|
|
603
625
|
name: "folder.delete",
|
|
604
626
|
description: "Delete a folder. Direct children (sub-folders + requests) are reparented to the deleted folder's parent.",
|
|
605
|
-
inputSchema:
|
|
627
|
+
inputSchema: import_zod5.z.object({ id: import_zod5.z.string() }),
|
|
606
628
|
async handler(input, ctx) {
|
|
607
629
|
const out = await ctx.workspace.apply({ kind: "folder.delete", id: input.id });
|
|
608
630
|
return { changedIds: out.changedIds };
|
|
609
631
|
}
|
|
610
632
|
};
|
|
611
|
-
var VARIABLE =
|
|
612
|
-
key:
|
|
613
|
-
value:
|
|
614
|
-
encrypted:
|
|
633
|
+
var VARIABLE = import_zod5.z.object({
|
|
634
|
+
key: import_zod5.z.string(),
|
|
635
|
+
value: import_zod5.z.string(),
|
|
636
|
+
encrypted: import_zod5.z.boolean().default(false)
|
|
615
637
|
});
|
|
616
638
|
var environmentCreateTool = {
|
|
617
639
|
name: "environment.create",
|
|
618
640
|
description: "Create a new environment (or upsert one with the same name).",
|
|
619
|
-
inputSchema:
|
|
620
|
-
name:
|
|
621
|
-
variables:
|
|
641
|
+
inputSchema: import_zod5.z.object({
|
|
642
|
+
name: import_zod5.z.string(),
|
|
643
|
+
variables: import_zod5.z.array(VARIABLE).default([])
|
|
622
644
|
}),
|
|
623
645
|
async handler(input, ctx) {
|
|
624
646
|
const env = { name: input.name, variables: input.variables };
|
|
@@ -629,7 +651,7 @@ var environmentCreateTool = {
|
|
|
629
651
|
var environmentReadTool = {
|
|
630
652
|
name: "environment.read",
|
|
631
653
|
description: "Read environments \u2014 pass `name` for one, or omit for the full list.",
|
|
632
|
-
inputSchema:
|
|
654
|
+
inputSchema: import_zod5.z.object({ name: import_zod5.z.string().optional() }),
|
|
633
655
|
async handler(input, ctx) {
|
|
634
656
|
const state = await ctx.workspace.read();
|
|
635
657
|
if (input.name) {
|
|
@@ -646,9 +668,9 @@ var environmentReadTool = {
|
|
|
646
668
|
var environmentUpdateTool = {
|
|
647
669
|
name: "environment.update",
|
|
648
670
|
description: "Replace the variables list of an environment.",
|
|
649
|
-
inputSchema:
|
|
650
|
-
name:
|
|
651
|
-
variables:
|
|
671
|
+
inputSchema: import_zod5.z.object({
|
|
672
|
+
name: import_zod5.z.string(),
|
|
673
|
+
variables: import_zod5.z.array(VARIABLE)
|
|
652
674
|
}),
|
|
653
675
|
async handler(input, ctx) {
|
|
654
676
|
const out = await ctx.workspace.apply({
|
|
@@ -661,7 +683,7 @@ var environmentUpdateTool = {
|
|
|
661
683
|
var environmentDeleteTool = {
|
|
662
684
|
name: "environment.delete",
|
|
663
685
|
description: "Delete an environment by name.",
|
|
664
|
-
inputSchema:
|
|
686
|
+
inputSchema: import_zod5.z.object({ name: import_zod5.z.string() }),
|
|
665
687
|
async handler(input, ctx) {
|
|
666
688
|
const out = await ctx.workspace.apply({ kind: "environment.delete", name: input.name });
|
|
667
689
|
return { changedIds: out.changedIds };
|
|
@@ -670,7 +692,7 @@ var environmentDeleteTool = {
|
|
|
670
692
|
var environmentSetActiveTool = {
|
|
671
693
|
name: "environment.set_active",
|
|
672
694
|
description: "Set (or clear) the active environment. Pass `name: null` to deactivate the current environment.",
|
|
673
|
-
inputSchema:
|
|
695
|
+
inputSchema: import_zod5.z.object({ name: import_zod5.z.string().nullable() }),
|
|
674
696
|
async handler(input, ctx) {
|
|
675
697
|
const out = await ctx.workspace.apply({
|
|
676
698
|
kind: "environment.setActive",
|
|
@@ -682,18 +704,18 @@ var environmentSetActiveTool = {
|
|
|
682
704
|
var environmentSetPriorityTool = {
|
|
683
705
|
name: "environment.set_priority",
|
|
684
706
|
description: 'Replace the global environment priority order (highest priority first). Strings are interpreted as local env names. To target a linked env, pass `{ kind: "linked", linkedWorkspaceId, envName }` instead.',
|
|
685
|
-
inputSchema:
|
|
686
|
-
order:
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
kind:
|
|
691
|
-
name:
|
|
707
|
+
inputSchema: import_zod5.z.object({
|
|
708
|
+
order: import_zod5.z.array(
|
|
709
|
+
import_zod5.z.union([
|
|
710
|
+
import_zod5.z.string(),
|
|
711
|
+
import_zod5.z.object({
|
|
712
|
+
kind: import_zod5.z.literal("local"),
|
|
713
|
+
name: import_zod5.z.string()
|
|
692
714
|
}),
|
|
693
|
-
|
|
694
|
-
kind:
|
|
695
|
-
linkedWorkspaceId:
|
|
696
|
-
envName:
|
|
715
|
+
import_zod5.z.object({
|
|
716
|
+
kind: import_zod5.z.literal("linked"),
|
|
717
|
+
linkedWorkspaceId: import_zod5.z.string(),
|
|
718
|
+
envName: import_zod5.z.string()
|
|
697
719
|
})
|
|
698
720
|
])
|
|
699
721
|
)
|
|
@@ -710,7 +732,7 @@ var environmentSetPriorityTool = {
|
|
|
710
732
|
var environmentExportTool = {
|
|
711
733
|
name: "environment.export",
|
|
712
734
|
description: "Serialize an environment to a portable JSON string. Encrypted variables drop their value (only `secretKeyId` survives) so the export can be safely pasted elsewhere \u2014 re-attach secrets locally on the receiving side.",
|
|
713
|
-
inputSchema:
|
|
735
|
+
inputSchema: import_zod5.z.object({ name: import_zod5.z.string() }),
|
|
714
736
|
async handler(input, ctx) {
|
|
715
737
|
const state = await ctx.workspace.read();
|
|
716
738
|
const env = state.synced.environments.items[input.name];
|
|
@@ -728,9 +750,9 @@ var environmentExportTool = {
|
|
|
728
750
|
var environmentImportTool = {
|
|
729
751
|
name: "environment.import",
|
|
730
752
|
description: "Import an environment from the JSON shape produced by `environment.export`. When a target with the same name exists, pass `overwrite: true` to replace it, otherwise the import is rejected.",
|
|
731
|
-
inputSchema:
|
|
732
|
-
json:
|
|
733
|
-
overwrite:
|
|
753
|
+
inputSchema: import_zod5.z.object({
|
|
754
|
+
json: import_zod5.z.string().min(1),
|
|
755
|
+
overwrite: import_zod5.z.boolean().default(false)
|
|
734
756
|
}),
|
|
735
757
|
async handler(input, ctx) {
|
|
736
758
|
let parsed;
|
|
@@ -760,17 +782,17 @@ var environmentImportTool = {
|
|
|
760
782
|
return { ok: true, name: env.name, changedIds: out.changedIds };
|
|
761
783
|
}
|
|
762
784
|
};
|
|
763
|
-
var PLAN_STEP =
|
|
764
|
-
requestId:
|
|
765
|
-
linkedWorkspaceId:
|
|
785
|
+
var PLAN_STEP = import_zod5.z.object({
|
|
786
|
+
requestId: import_zod5.z.string(),
|
|
787
|
+
linkedWorkspaceId: import_zod5.z.string().optional()
|
|
766
788
|
});
|
|
767
789
|
var planCreateTool = {
|
|
768
790
|
name: "plan.create",
|
|
769
791
|
description: "Create a new execution plan (sequence of request steps).",
|
|
770
|
-
inputSchema:
|
|
771
|
-
name:
|
|
772
|
-
steps:
|
|
773
|
-
envPriorityOrder:
|
|
792
|
+
inputSchema: import_zod5.z.object({
|
|
793
|
+
name: import_zod5.z.string().default("New plan"),
|
|
794
|
+
steps: import_zod5.z.array(PLAN_STEP).default([]),
|
|
795
|
+
envPriorityOrder: import_zod5.z.array(import_zod5.z.string()).default([])
|
|
774
796
|
}),
|
|
775
797
|
async handler(input, ctx) {
|
|
776
798
|
const id = (0, import_shared2.generateId)();
|
|
@@ -790,7 +812,7 @@ var planCreateTool = {
|
|
|
790
812
|
var planReadTool = {
|
|
791
813
|
name: "plan.read",
|
|
792
814
|
description: "Read a plan by id, or list all plans when no id is provided.",
|
|
793
|
-
inputSchema:
|
|
815
|
+
inputSchema: import_zod5.z.object({ id: import_zod5.z.string().optional() }),
|
|
794
816
|
async handler(input, ctx) {
|
|
795
817
|
const state = await ctx.workspace.read();
|
|
796
818
|
if (input.id) {
|
|
@@ -806,12 +828,12 @@ var planReadTool = {
|
|
|
806
828
|
var planUpdateTool = {
|
|
807
829
|
name: "plan.update",
|
|
808
830
|
description: "Patch fields on an existing plan.",
|
|
809
|
-
inputSchema:
|
|
810
|
-
id:
|
|
811
|
-
patch:
|
|
812
|
-
name:
|
|
813
|
-
steps:
|
|
814
|
-
envPriorityOrder:
|
|
831
|
+
inputSchema: import_zod5.z.object({
|
|
832
|
+
id: import_zod5.z.string(),
|
|
833
|
+
patch: import_zod5.z.object({
|
|
834
|
+
name: import_zod5.z.string().optional(),
|
|
835
|
+
steps: import_zod5.z.array(PLAN_STEP).optional(),
|
|
836
|
+
envPriorityOrder: import_zod5.z.array(import_zod5.z.string()).optional()
|
|
815
837
|
}).strict()
|
|
816
838
|
}),
|
|
817
839
|
async handler(input, ctx) {
|
|
@@ -832,7 +854,7 @@ var planUpdateTool = {
|
|
|
832
854
|
var planDeleteTool = {
|
|
833
855
|
name: "plan.delete",
|
|
834
856
|
description: "Delete a plan by id. Drops history rows referencing this plan.",
|
|
835
|
-
inputSchema:
|
|
857
|
+
inputSchema: import_zod5.z.object({ id: import_zod5.z.string() }),
|
|
836
858
|
async handler(input, ctx) {
|
|
837
859
|
const out = await ctx.workspace.apply({ kind: "plan.delete", id: input.id });
|
|
838
860
|
return { changedIds: out.changedIds };
|
|
@@ -841,11 +863,11 @@ var planDeleteTool = {
|
|
|
841
863
|
var planAddStepTool = {
|
|
842
864
|
name: "plan.add_step",
|
|
843
865
|
description: "Append a step to an execution plan. Optional `position` (0-based) inserts at that index instead.",
|
|
844
|
-
inputSchema:
|
|
845
|
-
planId:
|
|
846
|
-
requestId:
|
|
847
|
-
linkedWorkspaceId:
|
|
848
|
-
position:
|
|
866
|
+
inputSchema: import_zod5.z.object({
|
|
867
|
+
planId: import_zod5.z.string(),
|
|
868
|
+
requestId: import_zod5.z.string(),
|
|
869
|
+
linkedWorkspaceId: import_zod5.z.string().optional(),
|
|
870
|
+
position: import_zod5.z.number().int().nonnegative().optional()
|
|
849
871
|
}),
|
|
850
872
|
async handler(input, ctx) {
|
|
851
873
|
const state = await ctx.workspace.read();
|
|
@@ -871,9 +893,9 @@ var planAddStepTool = {
|
|
|
871
893
|
var planRemoveStepTool = {
|
|
872
894
|
name: "plan.remove_step",
|
|
873
895
|
description: "Remove a step from a plan by 0-based index.",
|
|
874
|
-
inputSchema:
|
|
875
|
-
planId:
|
|
876
|
-
index:
|
|
896
|
+
inputSchema: import_zod5.z.object({
|
|
897
|
+
planId: import_zod5.z.string(),
|
|
898
|
+
index: import_zod5.z.number().int().nonnegative()
|
|
877
899
|
}),
|
|
878
900
|
async handler(input, ctx) {
|
|
879
901
|
const state = await ctx.workspace.read();
|
|
@@ -893,9 +915,9 @@ var planRemoveStepTool = {
|
|
|
893
915
|
var planReorderStepsTool = {
|
|
894
916
|
name: "plan.reorder_steps",
|
|
895
917
|
description: "Replace the plan steps with a new permutation. The supplied indices must reference valid current step indices.",
|
|
896
|
-
inputSchema:
|
|
897
|
-
planId:
|
|
898
|
-
order:
|
|
918
|
+
inputSchema: import_zod5.z.object({
|
|
919
|
+
planId: import_zod5.z.string(),
|
|
920
|
+
order: import_zod5.z.array(import_zod5.z.number().int().nonnegative())
|
|
899
921
|
}),
|
|
900
922
|
async handler(input, ctx) {
|
|
901
923
|
const state = await ctx.workspace.read();
|
|
@@ -917,13 +939,13 @@ var planReorderStepsTool = {
|
|
|
917
939
|
return { ok: true, changedIds: out.changedIds };
|
|
918
940
|
}
|
|
919
941
|
};
|
|
920
|
-
var PLAN_VARIABLE =
|
|
942
|
+
var PLAN_VARIABLE = import_zod5.z.object({ key: import_zod5.z.string(), value: import_zod5.z.string() });
|
|
921
943
|
var planSetVariablesTool = {
|
|
922
944
|
name: "plan.set_variables",
|
|
923
945
|
description: "Replace the plan-scoped variables. These live highest-priority during plan runs (above environment vars, below context vars).",
|
|
924
|
-
inputSchema:
|
|
925
|
-
planId:
|
|
926
|
-
variables:
|
|
946
|
+
inputSchema: import_zod5.z.object({
|
|
947
|
+
planId: import_zod5.z.string(),
|
|
948
|
+
variables: import_zod5.z.array(PLAN_VARIABLE)
|
|
927
949
|
}),
|
|
928
950
|
async handler(input, ctx) {
|
|
929
951
|
const state = await ctx.workspace.read();
|
|
@@ -939,9 +961,9 @@ var planSetVariablesTool = {
|
|
|
939
961
|
var planRunTool = {
|
|
940
962
|
name: "plan.run",
|
|
941
963
|
description: "Run a plan headlessly (server-side). Currently returns a not-implemented marker \u2014 full execution requires the Desktop or browser runtime which the MCP host does not own. The Desktop integration overrides this tool with a real runner.",
|
|
942
|
-
inputSchema:
|
|
943
|
-
id:
|
|
944
|
-
withAssertions:
|
|
964
|
+
inputSchema: import_zod5.z.object({
|
|
965
|
+
id: import_zod5.z.string(),
|
|
966
|
+
withAssertions: import_zod5.z.boolean().default(true)
|
|
945
967
|
}),
|
|
946
968
|
async handler(input, ctx) {
|
|
947
969
|
const state = await ctx.workspace.read();
|
|
@@ -955,18 +977,18 @@ var planRunTool = {
|
|
|
955
977
|
};
|
|
956
978
|
}
|
|
957
979
|
};
|
|
958
|
-
var ASSERTION =
|
|
959
|
-
id:
|
|
960
|
-
kind:
|
|
961
|
-
op:
|
|
962
|
-
target:
|
|
963
|
-
expected:
|
|
980
|
+
var ASSERTION = import_zod5.z.object({
|
|
981
|
+
id: import_zod5.z.string().optional(),
|
|
982
|
+
kind: import_zod5.z.enum(["status", "header", "json-path", "duration"]),
|
|
983
|
+
op: import_zod5.z.enum(["equals", "not-equals", "contains", "lt", "gt", "matches"]),
|
|
984
|
+
target: import_zod5.z.string().optional(),
|
|
985
|
+
expected: import_zod5.z.union([import_zod5.z.string(), import_zod5.z.number()])
|
|
964
986
|
});
|
|
965
987
|
var assertionCreateTool = {
|
|
966
988
|
name: "assertion.create",
|
|
967
989
|
description: "Add an assertion to a request.",
|
|
968
|
-
inputSchema:
|
|
969
|
-
requestId:
|
|
990
|
+
inputSchema: import_zod5.z.object({
|
|
991
|
+
requestId: import_zod5.z.string(),
|
|
970
992
|
assertion: ASSERTION
|
|
971
993
|
}),
|
|
972
994
|
async handler(input, ctx) {
|
|
@@ -985,9 +1007,9 @@ var assertionCreateTool = {
|
|
|
985
1007
|
var assertionReadTool = {
|
|
986
1008
|
name: "assertion.read",
|
|
987
1009
|
description: "List assertions for a request, or fetch a single assertion by id.",
|
|
988
|
-
inputSchema:
|
|
989
|
-
requestId:
|
|
990
|
-
assertionId:
|
|
1010
|
+
inputSchema: import_zod5.z.object({
|
|
1011
|
+
requestId: import_zod5.z.string(),
|
|
1012
|
+
assertionId: import_zod5.z.string().optional()
|
|
991
1013
|
}),
|
|
992
1014
|
async handler(input, ctx) {
|
|
993
1015
|
const state = await ctx.workspace.read();
|
|
@@ -1003,8 +1025,8 @@ var assertionReadTool = {
|
|
|
1003
1025
|
var assertionUpdateTool = {
|
|
1004
1026
|
name: "assertion.update",
|
|
1005
1027
|
description: "Replace an existing assertion (matched by `assertion.id`).",
|
|
1006
|
-
inputSchema:
|
|
1007
|
-
requestId:
|
|
1028
|
+
inputSchema: import_zod5.z.object({
|
|
1029
|
+
requestId: import_zod5.z.string(),
|
|
1008
1030
|
assertion: ASSERTION.required({ id: true })
|
|
1009
1031
|
}),
|
|
1010
1032
|
async handler(input, ctx) {
|
|
@@ -1019,9 +1041,9 @@ var assertionUpdateTool = {
|
|
|
1019
1041
|
var assertionDeleteTool = {
|
|
1020
1042
|
name: "assertion.delete",
|
|
1021
1043
|
description: "Remove an assertion from a request.",
|
|
1022
|
-
inputSchema:
|
|
1023
|
-
requestId:
|
|
1024
|
-
assertionId:
|
|
1044
|
+
inputSchema: import_zod5.z.object({
|
|
1045
|
+
requestId: import_zod5.z.string(),
|
|
1046
|
+
assertionId: import_zod5.z.string()
|
|
1025
1047
|
}),
|
|
1026
1048
|
async handler(input, ctx) {
|
|
1027
1049
|
const out = await ctx.workspace.apply({
|
|
@@ -1034,21 +1056,53 @@ var assertionDeleteTool = {
|
|
|
1034
1056
|
};
|
|
1035
1057
|
var workspaceReadTool = {
|
|
1036
1058
|
name: "workspace.read",
|
|
1037
|
-
description:
|
|
1038
|
-
inputSchema:
|
|
1039
|
-
|
|
1040
|
-
|
|
1059
|
+
description: 'Return the full `{ synced, local }` workspace pair. Pass `workspaceId` to scope to a specific workspace when multiple are registered (call `workspace.list` first to discover ids). When omitted and multiple workspaces exist, the response is a structured "multiple workspaces found" envelope listing each summary so the AI can clarify before drilling in. Use sparingly \u2014 entity-specific tools are more efficient for small reads.',
|
|
1060
|
+
inputSchema: import_zod5.z.object({
|
|
1061
|
+
workspaceId: import_zod5.z.string().min(1).max(256).optional().describe(
|
|
1062
|
+
'Optional workspace id (from `workspace.list`). Omit to read the active workspace; the tool will switch to the "multiple workspaces" envelope when ambiguous.'
|
|
1063
|
+
)
|
|
1064
|
+
}),
|
|
1065
|
+
async handler(input, ctx) {
|
|
1066
|
+
if (input.workspaceId) {
|
|
1067
|
+
const provider = ctx.workspaces.for(input.workspaceId);
|
|
1068
|
+
const state2 = await provider.read();
|
|
1069
|
+
return {
|
|
1070
|
+
kind: "single",
|
|
1071
|
+
workspaceId: state2.synced.workspaceId,
|
|
1072
|
+
synced: state2.synced,
|
|
1073
|
+
local: state2.local
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
const summaries = await ctx.workspaces.list();
|
|
1077
|
+
if (summaries.length > 1) {
|
|
1078
|
+
return {
|
|
1079
|
+
kind: "multiple-workspaces",
|
|
1080
|
+
activeWorkspaceId: ctx.workspaces.activeId(),
|
|
1081
|
+
workspaceCount: summaries.length,
|
|
1082
|
+
workspaces: summaries,
|
|
1083
|
+
hint: `Found ${summaries.length} workspaces. Re-call \`workspace.read\` with \`workspaceId\` set to the desired entry, or call entity-specific tools (which default to the active workspace) when scoping to one workspace is acceptable.`
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
const state = await ctx.workspace.read();
|
|
1087
|
+
return {
|
|
1088
|
+
kind: "single",
|
|
1089
|
+
workspaceId: state.synced.workspaceId,
|
|
1090
|
+
synced: state.synced,
|
|
1091
|
+
local: state.local
|
|
1092
|
+
};
|
|
1041
1093
|
}
|
|
1042
1094
|
};
|
|
1043
1095
|
var workspaceWriteTool = {
|
|
1044
1096
|
name: "workspace.write",
|
|
1045
|
-
description: "Bulk-replace the workspace. Pass `synced` and/or `local` to overwrite either side. Mutating tools are preferred \u2014 this is for full-doc imports/exports.",
|
|
1046
|
-
inputSchema:
|
|
1047
|
-
|
|
1048
|
-
|
|
1097
|
+
description: "Bulk-replace the workspace. Pass `synced` and/or `local` to overwrite either side. Use `workspaceId` to target a non-active workspace (omit to write the active one). Mutating tools are preferred \u2014 this is for full-doc imports/exports.",
|
|
1098
|
+
inputSchema: import_zod5.z.object({
|
|
1099
|
+
workspaceId: import_zod5.z.string().min(1).max(256).optional().describe("Optional workspace id; omit to write the active workspace."),
|
|
1100
|
+
synced: import_zod5.z.unknown().optional(),
|
|
1101
|
+
local: import_zod5.z.unknown().optional()
|
|
1049
1102
|
}),
|
|
1050
1103
|
async handler(input, ctx) {
|
|
1051
|
-
const
|
|
1104
|
+
const provider = input.workspaceId ? ctx.workspaces.for(input.workspaceId) : ctx.workspace;
|
|
1105
|
+
const next = await provider.write({
|
|
1052
1106
|
synced: input.synced,
|
|
1053
1107
|
local: input.local
|
|
1054
1108
|
});
|
|
@@ -1057,16 +1111,16 @@ var workspaceWriteTool = {
|
|
|
1057
1111
|
};
|
|
1058
1112
|
|
|
1059
1113
|
// src/tools/history.ts
|
|
1060
|
-
var
|
|
1114
|
+
var import_zod6 = require("zod");
|
|
1061
1115
|
var historyListRunsTool = {
|
|
1062
1116
|
name: "history.list_runs",
|
|
1063
1117
|
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.",
|
|
1064
|
-
inputSchema:
|
|
1065
|
-
requestId:
|
|
1066
|
-
ok:
|
|
1067
|
-
since:
|
|
1068
|
-
until:
|
|
1069
|
-
limit:
|
|
1118
|
+
inputSchema: import_zod6.z.object({
|
|
1119
|
+
requestId: import_zod6.z.string().optional(),
|
|
1120
|
+
ok: import_zod6.z.boolean().optional(),
|
|
1121
|
+
since: import_zod6.z.string().optional(),
|
|
1122
|
+
until: import_zod6.z.string().optional(),
|
|
1123
|
+
limit: import_zod6.z.number().int().positive().max(500).default(100)
|
|
1070
1124
|
}),
|
|
1071
1125
|
async handler(input, ctx) {
|
|
1072
1126
|
const state = await ctx.workspace.read();
|
|
@@ -1100,7 +1154,7 @@ var historyListRunsTool = {
|
|
|
1100
1154
|
var historyGetRunTool = {
|
|
1101
1155
|
name: "history.get_run",
|
|
1102
1156
|
description: "Fetch a single history row in full (headers, body preview, assertion results).",
|
|
1103
|
-
inputSchema:
|
|
1157
|
+
inputSchema: import_zod6.z.object({ id: import_zod6.z.string() }),
|
|
1104
1158
|
async handler(input, ctx) {
|
|
1105
1159
|
const state = await ctx.workspace.read();
|
|
1106
1160
|
const run = state.local.history.requestRuns.find((r) => r.id === input.id);
|
|
@@ -1111,7 +1165,7 @@ var historyGetRunTool = {
|
|
|
1111
1165
|
var historyDeleteRunTool = {
|
|
1112
1166
|
name: "history.delete_run",
|
|
1113
1167
|
description: "Delete a single request-run row by id.",
|
|
1114
|
-
inputSchema:
|
|
1168
|
+
inputSchema: import_zod6.z.object({ id: import_zod6.z.string() }),
|
|
1115
1169
|
async handler(input, ctx) {
|
|
1116
1170
|
const out = await ctx.workspace.apply({ kind: "history.delete_run", runId: input.id });
|
|
1117
1171
|
return { deleted: out.changedIds.length, changedIds: out.changedIds };
|
|
@@ -1120,8 +1174,8 @@ var historyDeleteRunTool = {
|
|
|
1120
1174
|
var historyPurgeTool = {
|
|
1121
1175
|
name: "history.purge_by_age",
|
|
1122
1176
|
description: "Drop every request-run + plan-run older than `olderThanDays` days. Pass 0 to clear all history.",
|
|
1123
|
-
inputSchema:
|
|
1124
|
-
olderThanDays:
|
|
1177
|
+
inputSchema: import_zod6.z.object({
|
|
1178
|
+
olderThanDays: import_zod6.z.number().nonnegative()
|
|
1125
1179
|
}),
|
|
1126
1180
|
async handler(input, ctx) {
|
|
1127
1181
|
const olderThanMs = input.olderThanDays * 24 * 60 * 60 * 1e3;
|
|
@@ -1131,15 +1185,15 @@ var historyPurgeTool = {
|
|
|
1131
1185
|
};
|
|
1132
1186
|
|
|
1133
1187
|
// src/tools/codebase.ts
|
|
1134
|
-
var
|
|
1188
|
+
var import_zod7 = require("zod");
|
|
1135
1189
|
var HTTP_METHODS = ["get", "post", "put", "patch", "delete", "options", "head"];
|
|
1136
1190
|
var codebaseExtractCollectionTool = {
|
|
1137
1191
|
name: "codebase.extract_collection",
|
|
1138
1192
|
description: "Scan source code for HTTP route definitions (Express, FastAPI, NestJS, Spring) and return candidate requests for the user to confirm before import.",
|
|
1139
|
-
inputSchema:
|
|
1140
|
-
source:
|
|
1193
|
+
inputSchema: import_zod7.z.object({
|
|
1194
|
+
source: import_zod7.z.string().min(1),
|
|
1141
1195
|
/** Hint to limit which framework patterns to apply. Empty = try all. */
|
|
1142
|
-
frameworks:
|
|
1196
|
+
frameworks: import_zod7.z.array(import_zod7.z.enum(["express", "fastapi", "nest", "spring"])).default([])
|
|
1143
1197
|
}),
|
|
1144
1198
|
async handler(input) {
|
|
1145
1199
|
const enabled = new Set(
|
|
@@ -1220,18 +1274,18 @@ var codebaseExtractCollectionTool = {
|
|
|
1220
1274
|
};
|
|
1221
1275
|
|
|
1222
1276
|
// src/tools/prompt.ts
|
|
1223
|
-
var
|
|
1277
|
+
var import_zod8 = require("zod");
|
|
1224
1278
|
var import_shared3 = require("@apicircle/shared");
|
|
1225
1279
|
var promptCreateEnvironmentTool = {
|
|
1226
1280
|
name: "prompt.create_environment",
|
|
1227
1281
|
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.",
|
|
1228
|
-
inputSchema:
|
|
1229
|
-
name:
|
|
1230
|
-
variables:
|
|
1231
|
-
|
|
1232
|
-
key:
|
|
1233
|
-
value:
|
|
1234
|
-
encrypted:
|
|
1282
|
+
inputSchema: import_zod8.z.object({
|
|
1283
|
+
name: import_zod8.z.string(),
|
|
1284
|
+
variables: import_zod8.z.array(
|
|
1285
|
+
import_zod8.z.object({
|
|
1286
|
+
key: import_zod8.z.string(),
|
|
1287
|
+
value: import_zod8.z.string(),
|
|
1288
|
+
encrypted: import_zod8.z.boolean().default(false)
|
|
1235
1289
|
})
|
|
1236
1290
|
)
|
|
1237
1291
|
}),
|
|
@@ -1244,13 +1298,13 @@ var promptCreateEnvironmentTool = {
|
|
|
1244
1298
|
var promptCreateAssertionTool = {
|
|
1245
1299
|
name: "prompt.create_assertion",
|
|
1246
1300
|
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".',
|
|
1247
|
-
inputSchema:
|
|
1248
|
-
requestId:
|
|
1249
|
-
assertion:
|
|
1250
|
-
kind:
|
|
1251
|
-
op:
|
|
1252
|
-
target:
|
|
1253
|
-
expected:
|
|
1301
|
+
inputSchema: import_zod8.z.object({
|
|
1302
|
+
requestId: import_zod8.z.string(),
|
|
1303
|
+
assertion: import_zod8.z.object({
|
|
1304
|
+
kind: import_zod8.z.enum(["status", "header", "json-path", "duration"]),
|
|
1305
|
+
op: import_zod8.z.enum(["equals", "not-equals", "contains", "lt", "gt", "matches"]),
|
|
1306
|
+
target: import_zod8.z.string().optional(),
|
|
1307
|
+
expected: import_zod8.z.union([import_zod8.z.string(), import_zod8.z.number()])
|
|
1254
1308
|
})
|
|
1255
1309
|
}),
|
|
1256
1310
|
async handler(input, ctx) {
|
|
@@ -1269,10 +1323,10 @@ var promptCreateAssertionTool = {
|
|
|
1269
1323
|
var promptCreatePlanTool = {
|
|
1270
1324
|
name: "prompt.create_plan",
|
|
1271
1325
|
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.",
|
|
1272
|
-
inputSchema:
|
|
1273
|
-
name:
|
|
1274
|
-
stepRequestIds:
|
|
1275
|
-
envPriorityOrder:
|
|
1326
|
+
inputSchema: import_zod8.z.object({
|
|
1327
|
+
name: import_zod8.z.string(),
|
|
1328
|
+
stepRequestIds: import_zod8.z.array(import_zod8.z.string()).default([]),
|
|
1329
|
+
envPriorityOrder: import_zod8.z.array(import_zod8.z.string()).default([])
|
|
1276
1330
|
}),
|
|
1277
1331
|
async handler(input, ctx) {
|
|
1278
1332
|
const state = await ctx.workspace.read();
|
|
@@ -1301,51 +1355,51 @@ var promptCreatePlanTool = {
|
|
|
1301
1355
|
return { ok: true, id, changedIds: out.changedIds };
|
|
1302
1356
|
}
|
|
1303
1357
|
};
|
|
1304
|
-
var HTTP_METHOD2 =
|
|
1305
|
-
var HEADER_OR_QUERY =
|
|
1306
|
-
key:
|
|
1307
|
-
value:
|
|
1308
|
-
enabled:
|
|
1358
|
+
var HTTP_METHOD2 = import_zod8.z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
1359
|
+
var HEADER_OR_QUERY = import_zod8.z.object({
|
|
1360
|
+
key: import_zod8.z.string(),
|
|
1361
|
+
value: import_zod8.z.string(),
|
|
1362
|
+
enabled: import_zod8.z.boolean().default(true)
|
|
1309
1363
|
});
|
|
1310
|
-
var REQUEST_BODY =
|
|
1311
|
-
type:
|
|
1312
|
-
content:
|
|
1313
|
-
variables:
|
|
1364
|
+
var REQUEST_BODY = import_zod8.z.object({
|
|
1365
|
+
type: import_zod8.z.enum(["none", "json", "text", "xml", "graphql", "urlencoded"]).default("none"),
|
|
1366
|
+
content: import_zod8.z.string().default(""),
|
|
1367
|
+
variables: import_zod8.z.string().optional()
|
|
1314
1368
|
});
|
|
1315
|
-
var PROMPT_AUTH =
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
type:
|
|
1321
|
-
username:
|
|
1322
|
-
password:
|
|
1369
|
+
var PROMPT_AUTH = import_zod8.z.discriminatedUnion("type", [
|
|
1370
|
+
import_zod8.z.object({ type: import_zod8.z.literal("none") }),
|
|
1371
|
+
import_zod8.z.object({ type: import_zod8.z.literal("inherit") }),
|
|
1372
|
+
import_zod8.z.object({ type: import_zod8.z.literal("bearer"), token: import_zod8.z.string().default("") }),
|
|
1373
|
+
import_zod8.z.object({
|
|
1374
|
+
type: import_zod8.z.literal("basic"),
|
|
1375
|
+
username: import_zod8.z.string().default(""),
|
|
1376
|
+
password: import_zod8.z.string().default("")
|
|
1323
1377
|
}),
|
|
1324
|
-
|
|
1325
|
-
type:
|
|
1326
|
-
key:
|
|
1327
|
-
value:
|
|
1328
|
-
addTo:
|
|
1378
|
+
import_zod8.z.object({
|
|
1379
|
+
type: import_zod8.z.literal("api-key"),
|
|
1380
|
+
key: import_zod8.z.string().default(""),
|
|
1381
|
+
value: import_zod8.z.string().default(""),
|
|
1382
|
+
addTo: import_zod8.z.enum(["header", "query", "cookie"]).default("header")
|
|
1329
1383
|
}),
|
|
1330
|
-
|
|
1331
|
-
type:
|
|
1332
|
-
key:
|
|
1333
|
-
value:
|
|
1384
|
+
import_zod8.z.object({
|
|
1385
|
+
type: import_zod8.z.literal("custom-header"),
|
|
1386
|
+
key: import_zod8.z.string().default(""),
|
|
1387
|
+
value: import_zod8.z.string().default("")
|
|
1334
1388
|
})
|
|
1335
1389
|
]);
|
|
1336
|
-
var PROMPT_ASSERTION =
|
|
1337
|
-
kind:
|
|
1338
|
-
op:
|
|
1339
|
-
target:
|
|
1340
|
-
expected:
|
|
1390
|
+
var PROMPT_ASSERTION = import_zod8.z.object({
|
|
1391
|
+
kind: import_zod8.z.enum(["status", "header", "json-path", "duration"]),
|
|
1392
|
+
op: import_zod8.z.enum(["equals", "not-equals", "contains", "lt", "gt", "matches"]),
|
|
1393
|
+
target: import_zod8.z.string().optional(),
|
|
1394
|
+
expected: import_zod8.z.union([import_zod8.z.string(), import_zod8.z.number()])
|
|
1341
1395
|
});
|
|
1342
|
-
var ENDPOINT_RESPONSE =
|
|
1343
|
-
status:
|
|
1344
|
-
jsonBody:
|
|
1345
|
-
contentType:
|
|
1396
|
+
var ENDPOINT_RESPONSE = import_zod8.z.object({
|
|
1397
|
+
status: import_zod8.z.number().int().min(100).max(599).default(200),
|
|
1398
|
+
jsonBody: import_zod8.z.string().default("{}"),
|
|
1399
|
+
contentType: import_zod8.z.string().default("application/json")
|
|
1346
1400
|
});
|
|
1347
|
-
var VALIDATION_RULE_NL =
|
|
1348
|
-
kind:
|
|
1401
|
+
var VALIDATION_RULE_NL = import_zod8.z.object({
|
|
1402
|
+
kind: import_zod8.z.enum([
|
|
1349
1403
|
"header-required",
|
|
1350
1404
|
"header-equals",
|
|
1351
1405
|
"header-matches",
|
|
@@ -1356,50 +1410,50 @@ var VALIDATION_RULE_NL = import_zod7.z.object({
|
|
|
1356
1410
|
"body-required",
|
|
1357
1411
|
"content-type-equals"
|
|
1358
1412
|
]),
|
|
1359
|
-
target:
|
|
1360
|
-
expected:
|
|
1361
|
-
message:
|
|
1362
|
-
enabled:
|
|
1363
|
-
failResponse:
|
|
1364
|
-
status:
|
|
1365
|
-
jsonBody:
|
|
1413
|
+
target: import_zod8.z.string().default(""),
|
|
1414
|
+
expected: import_zod8.z.string().optional(),
|
|
1415
|
+
message: import_zod8.z.string().optional(),
|
|
1416
|
+
enabled: import_zod8.z.boolean().default(true),
|
|
1417
|
+
failResponse: import_zod8.z.object({
|
|
1418
|
+
status: import_zod8.z.number().int().min(100).max(599).default(400),
|
|
1419
|
+
jsonBody: import_zod8.z.string().default('{"error":"validation failed"}')
|
|
1366
1420
|
}).default({})
|
|
1367
1421
|
});
|
|
1368
|
-
var CONDITION_CLAUSE_NL =
|
|
1369
|
-
scope:
|
|
1370
|
-
target:
|
|
1371
|
-
op:
|
|
1372
|
-
value:
|
|
1422
|
+
var CONDITION_CLAUSE_NL = import_zod8.z.object({
|
|
1423
|
+
scope: import_zod8.z.enum(["query", "pathParam", "header", "cookie", "body-json-path"]),
|
|
1424
|
+
target: import_zod8.z.string(),
|
|
1425
|
+
op: import_zod8.z.enum(["equals", "not-equals", "matches", "gt", "lt", "gte", "lte", "present", "absent"]),
|
|
1426
|
+
value: import_zod8.z.string().optional()
|
|
1373
1427
|
});
|
|
1374
|
-
var RESPONSE_RULE_NL =
|
|
1375
|
-
name:
|
|
1376
|
-
enabled:
|
|
1377
|
-
when:
|
|
1378
|
-
response:
|
|
1379
|
-
status:
|
|
1380
|
-
jsonBody:
|
|
1428
|
+
var RESPONSE_RULE_NL = import_zod8.z.object({
|
|
1429
|
+
name: import_zod8.z.string(),
|
|
1430
|
+
enabled: import_zod8.z.boolean().default(true),
|
|
1431
|
+
when: import_zod8.z.array(CONDITION_CLAUSE_NL).default([]),
|
|
1432
|
+
response: import_zod8.z.object({
|
|
1433
|
+
status: import_zod8.z.number().int().min(100).max(599).default(200),
|
|
1434
|
+
jsonBody: import_zod8.z.string().default("{}")
|
|
1381
1435
|
}).default({})
|
|
1382
1436
|
});
|
|
1383
|
-
var MULTIPLIER_NL =
|
|
1384
|
-
name:
|
|
1385
|
-
source:
|
|
1386
|
-
kind:
|
|
1387
|
-
key:
|
|
1437
|
+
var MULTIPLIER_NL = import_zod8.z.object({
|
|
1438
|
+
name: import_zod8.z.string().optional(),
|
|
1439
|
+
source: import_zod8.z.object({
|
|
1440
|
+
kind: import_zod8.z.enum(["query", "pathParam", "header", "body-json-path"]),
|
|
1441
|
+
key: import_zod8.z.string()
|
|
1388
1442
|
}),
|
|
1389
|
-
targetJsonPath:
|
|
1390
|
-
defaultCount:
|
|
1391
|
-
min:
|
|
1392
|
-
max:
|
|
1443
|
+
targetJsonPath: import_zod8.z.string(),
|
|
1444
|
+
defaultCount: import_zod8.z.number().int().nonnegative().default(0),
|
|
1445
|
+
min: import_zod8.z.number().int().nonnegative().optional(),
|
|
1446
|
+
max: import_zod8.z.number().int().nonnegative().optional()
|
|
1393
1447
|
});
|
|
1394
|
-
var ENDPOINT_INPUT =
|
|
1448
|
+
var ENDPOINT_INPUT = import_zod8.z.object({
|
|
1395
1449
|
method: HTTP_METHOD2,
|
|
1396
|
-
pathPattern:
|
|
1397
|
-
name:
|
|
1398
|
-
description:
|
|
1450
|
+
pathPattern: import_zod8.z.string().min(1),
|
|
1451
|
+
name: import_zod8.z.string().optional(),
|
|
1452
|
+
description: import_zod8.z.string().optional(),
|
|
1399
1453
|
response: ENDPOINT_RESPONSE.optional(),
|
|
1400
|
-
validationRules:
|
|
1401
|
-
responseRules:
|
|
1402
|
-
multipliers:
|
|
1454
|
+
validationRules: import_zod8.z.array(VALIDATION_RULE_NL).default([]),
|
|
1455
|
+
responseRules: import_zod8.z.array(RESPONSE_RULE_NL).default([]),
|
|
1456
|
+
multipliers: import_zod8.z.array(MULTIPLIER_NL).default([])
|
|
1403
1457
|
});
|
|
1404
1458
|
function buildRequestBody(input) {
|
|
1405
1459
|
if (!input) return { type: "none", content: "" };
|
|
@@ -1492,17 +1546,17 @@ function patchEndpoint(mock, endpointId, patcher) {
|
|
|
1492
1546
|
var promptCreateRequestTool = {
|
|
1493
1547
|
name: "prompt.create_request",
|
|
1494
1548
|
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.",
|
|
1495
|
-
inputSchema:
|
|
1496
|
-
name:
|
|
1549
|
+
inputSchema: import_zod8.z.object({
|
|
1550
|
+
name: import_zod8.z.string().default("New request"),
|
|
1497
1551
|
method: HTTP_METHOD2.default("GET"),
|
|
1498
|
-
url:
|
|
1499
|
-
folderId:
|
|
1500
|
-
headers:
|
|
1501
|
-
queryParams:
|
|
1502
|
-
pathParams:
|
|
1552
|
+
url: import_zod8.z.string().default(""),
|
|
1553
|
+
folderId: import_zod8.z.string().nullable().optional(),
|
|
1554
|
+
headers: import_zod8.z.array(HEADER_OR_QUERY).default([]),
|
|
1555
|
+
queryParams: import_zod8.z.array(HEADER_OR_QUERY).default([]),
|
|
1556
|
+
pathParams: import_zod8.z.record(import_zod8.z.string(), import_zod8.z.string()).optional(),
|
|
1503
1557
|
body: REQUEST_BODY.optional(),
|
|
1504
1558
|
auth: PROMPT_AUTH.optional(),
|
|
1505
|
-
assertions:
|
|
1559
|
+
assertions: import_zod8.z.array(PROMPT_ASSERTION).default([])
|
|
1506
1560
|
}),
|
|
1507
1561
|
async handler(input, ctx) {
|
|
1508
1562
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1532,19 +1586,19 @@ var promptCreateRequestTool = {
|
|
|
1532
1586
|
var promptUpdateRequestTool = {
|
|
1533
1587
|
name: "prompt.update_request",
|
|
1534
1588
|
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.",
|
|
1535
|
-
inputSchema:
|
|
1536
|
-
id:
|
|
1537
|
-
patch:
|
|
1538
|
-
name:
|
|
1589
|
+
inputSchema: import_zod8.z.object({
|
|
1590
|
+
id: import_zod8.z.string(),
|
|
1591
|
+
patch: import_zod8.z.object({
|
|
1592
|
+
name: import_zod8.z.string().optional(),
|
|
1539
1593
|
method: HTTP_METHOD2.optional(),
|
|
1540
|
-
url:
|
|
1541
|
-
folderId:
|
|
1542
|
-
headers:
|
|
1543
|
-
queryParams:
|
|
1544
|
-
pathParams:
|
|
1594
|
+
url: import_zod8.z.string().optional(),
|
|
1595
|
+
folderId: import_zod8.z.string().nullable().optional(),
|
|
1596
|
+
headers: import_zod8.z.array(HEADER_OR_QUERY).optional(),
|
|
1597
|
+
queryParams: import_zod8.z.array(HEADER_OR_QUERY).optional(),
|
|
1598
|
+
pathParams: import_zod8.z.record(import_zod8.z.string(), import_zod8.z.string()).optional(),
|
|
1545
1599
|
body: REQUEST_BODY.optional(),
|
|
1546
1600
|
auth: PROMPT_AUTH.optional(),
|
|
1547
|
-
assertions:
|
|
1601
|
+
assertions: import_zod8.z.array(PROMPT_ASSERTION).optional()
|
|
1548
1602
|
}).strict()
|
|
1549
1603
|
}),
|
|
1550
1604
|
async handler(input, ctx) {
|
|
@@ -1572,17 +1626,17 @@ var promptUpdateRequestTool = {
|
|
|
1572
1626
|
return { ok: true, changedIds: out.changedIds };
|
|
1573
1627
|
}
|
|
1574
1628
|
};
|
|
1575
|
-
var FOLDER_TREE_NODE =
|
|
1576
|
-
() =>
|
|
1577
|
-
name:
|
|
1578
|
-
children:
|
|
1629
|
+
var FOLDER_TREE_NODE = import_zod8.z.lazy(
|
|
1630
|
+
() => import_zod8.z.object({
|
|
1631
|
+
name: import_zod8.z.string(),
|
|
1632
|
+
children: import_zod8.z.array(FOLDER_TREE_NODE).optional()
|
|
1579
1633
|
})
|
|
1580
1634
|
);
|
|
1581
1635
|
var promptCreateFolderTreeTool = {
|
|
1582
1636
|
name: "prompt.create_folder_tree",
|
|
1583
1637
|
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.",
|
|
1584
|
-
inputSchema:
|
|
1585
|
-
parentId:
|
|
1638
|
+
inputSchema: import_zod8.z.object({
|
|
1639
|
+
parentId: import_zod8.z.string().nullable().optional(),
|
|
1586
1640
|
tree: FOLDER_TREE_NODE
|
|
1587
1641
|
}),
|
|
1588
1642
|
async handler(input, ctx) {
|
|
@@ -1608,9 +1662,9 @@ var promptCreateFolderTreeTool = {
|
|
|
1608
1662
|
var promptAddPlanStepsTool = {
|
|
1609
1663
|
name: "prompt.add_plan_steps",
|
|
1610
1664
|
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.",
|
|
1611
|
-
inputSchema:
|
|
1612
|
-
planId:
|
|
1613
|
-
requestIds:
|
|
1665
|
+
inputSchema: import_zod8.z.object({
|
|
1666
|
+
planId: import_zod8.z.string(),
|
|
1667
|
+
requestIds: import_zod8.z.array(import_zod8.z.string()).min(1)
|
|
1614
1668
|
}),
|
|
1615
1669
|
async handler(input, ctx) {
|
|
1616
1670
|
const state = await ctx.workspace.read();
|
|
@@ -1640,9 +1694,9 @@ var promptAddPlanStepsTool = {
|
|
|
1640
1694
|
var promptSetPlanVariablesTool = {
|
|
1641
1695
|
name: "prompt.set_plan_variables",
|
|
1642
1696
|
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.",
|
|
1643
|
-
inputSchema:
|
|
1644
|
-
planId:
|
|
1645
|
-
variables:
|
|
1697
|
+
inputSchema: import_zod8.z.object({
|
|
1698
|
+
planId: import_zod8.z.string(),
|
|
1699
|
+
variables: import_zod8.z.array(import_zod8.z.object({ key: import_zod8.z.string(), value: import_zod8.z.string() }))
|
|
1646
1700
|
}),
|
|
1647
1701
|
async handler(input, ctx) {
|
|
1648
1702
|
const state = await ctx.workspace.read();
|
|
@@ -1658,10 +1712,10 @@ var promptSetPlanVariablesTool = {
|
|
|
1658
1712
|
var promptCreateMockServerTool = {
|
|
1659
1713
|
name: "prompt.create_mock_server",
|
|
1660
1714
|
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.",
|
|
1661
|
-
inputSchema:
|
|
1662
|
-
name:
|
|
1663
|
-
defaultPort:
|
|
1664
|
-
endpoints:
|
|
1715
|
+
inputSchema: import_zod8.z.object({
|
|
1716
|
+
name: import_zod8.z.string().min(1),
|
|
1717
|
+
defaultPort: import_zod8.z.number().int().positive().nullable().optional(),
|
|
1718
|
+
endpoints: import_zod8.z.array(ENDPOINT_INPUT).default([])
|
|
1665
1719
|
}),
|
|
1666
1720
|
async handler(input, ctx) {
|
|
1667
1721
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1688,16 +1742,16 @@ var promptCreateMockServerTool = {
|
|
|
1688
1742
|
var promptAddMockEndpointTool = {
|
|
1689
1743
|
name: "prompt.add_mock_endpoint",
|
|
1690
1744
|
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.",
|
|
1691
|
-
inputSchema:
|
|
1692
|
-
mockId:
|
|
1745
|
+
inputSchema: import_zod8.z.object({
|
|
1746
|
+
mockId: import_zod8.z.string(),
|
|
1693
1747
|
method: HTTP_METHOD2,
|
|
1694
|
-
pathPattern:
|
|
1695
|
-
name:
|
|
1696
|
-
description:
|
|
1748
|
+
pathPattern: import_zod8.z.string().min(1),
|
|
1749
|
+
name: import_zod8.z.string().optional(),
|
|
1750
|
+
description: import_zod8.z.string().optional(),
|
|
1697
1751
|
response: ENDPOINT_RESPONSE.optional(),
|
|
1698
|
-
validationRules:
|
|
1699
|
-
responseRules:
|
|
1700
|
-
multipliers:
|
|
1752
|
+
validationRules: import_zod8.z.array(VALIDATION_RULE_NL).default([]),
|
|
1753
|
+
responseRules: import_zod8.z.array(RESPONSE_RULE_NL).default([]),
|
|
1754
|
+
multipliers: import_zod8.z.array(MULTIPLIER_NL).default([])
|
|
1701
1755
|
}),
|
|
1702
1756
|
async handler(input, ctx) {
|
|
1703
1757
|
const state = await ctx.workspace.read();
|
|
@@ -1719,10 +1773,10 @@ var promptAddMockEndpointTool = {
|
|
|
1719
1773
|
var promptSetEndpointValidationRulesTool = {
|
|
1720
1774
|
name: "prompt.set_endpoint_validation_rules",
|
|
1721
1775
|
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.",
|
|
1722
|
-
inputSchema:
|
|
1723
|
-
mockId:
|
|
1724
|
-
endpointId:
|
|
1725
|
-
rules:
|
|
1776
|
+
inputSchema: import_zod8.z.object({
|
|
1777
|
+
mockId: import_zod8.z.string(),
|
|
1778
|
+
endpointId: import_zod8.z.string(),
|
|
1779
|
+
rules: import_zod8.z.array(VALIDATION_RULE_NL)
|
|
1726
1780
|
}),
|
|
1727
1781
|
async handler(input, ctx) {
|
|
1728
1782
|
const state = await ctx.workspace.read();
|
|
@@ -1753,10 +1807,10 @@ var promptSetEndpointValidationRulesTool = {
|
|
|
1753
1807
|
var promptSetEndpointResponseRulesTool = {
|
|
1754
1808
|
name: "prompt.set_endpoint_response_rules",
|
|
1755
1809
|
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.",
|
|
1756
|
-
inputSchema:
|
|
1757
|
-
mockId:
|
|
1758
|
-
endpointId:
|
|
1759
|
-
rules:
|
|
1810
|
+
inputSchema: import_zod8.z.object({
|
|
1811
|
+
mockId: import_zod8.z.string(),
|
|
1812
|
+
endpointId: import_zod8.z.string(),
|
|
1813
|
+
rules: import_zod8.z.array(RESPONSE_RULE_NL)
|
|
1760
1814
|
}),
|
|
1761
1815
|
async handler(input, ctx) {
|
|
1762
1816
|
const state = await ctx.workspace.read();
|
|
@@ -1791,10 +1845,10 @@ var promptSetEndpointResponseRulesTool = {
|
|
|
1791
1845
|
var promptSetEndpointMultipliersTool = {
|
|
1792
1846
|
name: "prompt.set_endpoint_multipliers",
|
|
1793
1847
|
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.",
|
|
1794
|
-
inputSchema:
|
|
1795
|
-
mockId:
|
|
1796
|
-
endpointId:
|
|
1797
|
-
multipliers:
|
|
1848
|
+
inputSchema: import_zod8.z.object({
|
|
1849
|
+
mockId: import_zod8.z.string(),
|
|
1850
|
+
endpointId: import_zod8.z.string(),
|
|
1851
|
+
multipliers: import_zod8.z.array(MULTIPLIER_NL)
|
|
1798
1852
|
}),
|
|
1799
1853
|
async handler(input, ctx) {
|
|
1800
1854
|
const state = await ctx.workspace.read();
|
|
@@ -1823,7 +1877,7 @@ var promptSetEndpointMultipliersTool = {
|
|
|
1823
1877
|
};
|
|
1824
1878
|
|
|
1825
1879
|
// src/tools/mocks.ts
|
|
1826
|
-
var
|
|
1880
|
+
var import_zod9 = require("zod");
|
|
1827
1881
|
var import_shared4 = require("@apicircle/shared");
|
|
1828
1882
|
var import_mock_server_core2 = require("@apicircle/mock-server-core");
|
|
1829
1883
|
async function ingestSource(source, name) {
|
|
@@ -1846,10 +1900,10 @@ async function ingestSource(source, name) {
|
|
|
1846
1900
|
var mockCreateFromOpenApiTool = {
|
|
1847
1901
|
name: "mock.create_from_openapi",
|
|
1848
1902
|
description: "Create a mock server from an OpenAPI / Swagger spec (YAML or JSON).",
|
|
1849
|
-
inputSchema:
|
|
1850
|
-
name:
|
|
1851
|
-
spec:
|
|
1852
|
-
format:
|
|
1903
|
+
inputSchema: import_zod9.z.object({
|
|
1904
|
+
name: import_zod9.z.string(),
|
|
1905
|
+
spec: import_zod9.z.string().min(1),
|
|
1906
|
+
format: import_zod9.z.enum(["json", "yaml"]).default("json")
|
|
1853
1907
|
}),
|
|
1854
1908
|
async handler(input, ctx) {
|
|
1855
1909
|
const { mock, warnings } = await ingestSource(
|
|
@@ -1868,7 +1922,7 @@ var mockCreateFromOpenApiTool = {
|
|
|
1868
1922
|
var mockCreateFromPostmanTool = {
|
|
1869
1923
|
name: "mock.create_from_postman",
|
|
1870
1924
|
description: "Create a mock server from a Postman v2/v2.1 collection.",
|
|
1871
|
-
inputSchema:
|
|
1925
|
+
inputSchema: import_zod9.z.object({ name: import_zod9.z.string(), collection: import_zod9.z.string().min(1) }),
|
|
1872
1926
|
async handler(input, ctx) {
|
|
1873
1927
|
const { mock, warnings } = await ingestSource(
|
|
1874
1928
|
{ kind: "postman", collection: input.collection },
|
|
@@ -1886,7 +1940,7 @@ var mockCreateFromPostmanTool = {
|
|
|
1886
1940
|
var mockCreateFromInsomniaTool = {
|
|
1887
1941
|
name: "mock.create_from_insomnia",
|
|
1888
1942
|
description: "Create a mock server from an Insomnia v4 export.",
|
|
1889
|
-
inputSchema:
|
|
1943
|
+
inputSchema: import_zod9.z.object({ name: import_zod9.z.string(), export: import_zod9.z.string().min(1) }),
|
|
1890
1944
|
async handler(input, ctx) {
|
|
1891
1945
|
const { mock, warnings } = await ingestSource(
|
|
1892
1946
|
{ kind: "insomnia", export: input.export },
|
|
@@ -1904,7 +1958,7 @@ var mockCreateFromInsomniaTool = {
|
|
|
1904
1958
|
var mockImportPostmanMockCollectionTool = {
|
|
1905
1959
|
name: "mock.import_postman_mock_collection",
|
|
1906
1960
|
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.",
|
|
1907
|
-
inputSchema:
|
|
1961
|
+
inputSchema: import_zod9.z.object({ name: import_zod9.z.string(), collection: import_zod9.z.string().min(1) }),
|
|
1908
1962
|
async handler(input, ctx) {
|
|
1909
1963
|
const { mock, warnings } = await ingestSource(
|
|
1910
1964
|
{ kind: "postman", collection: input.collection },
|
|
@@ -1922,7 +1976,7 @@ var mockImportPostmanMockCollectionTool = {
|
|
|
1922
1976
|
var mockListTool = {
|
|
1923
1977
|
name: "mock.list",
|
|
1924
1978
|
description: "List all mock servers in the workspace plus their runtime status (running / stopped, port).",
|
|
1925
|
-
inputSchema:
|
|
1979
|
+
inputSchema: import_zod9.z.object({}),
|
|
1926
1980
|
async handler(_input, ctx) {
|
|
1927
1981
|
const state = await ctx.workspace.read();
|
|
1928
1982
|
const running = await ctx.mock.list();
|
|
@@ -1944,9 +1998,9 @@ var mockListTool = {
|
|
|
1944
1998
|
var mockStartTool = {
|
|
1945
1999
|
name: "mock.start",
|
|
1946
2000
|
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.",
|
|
1947
|
-
inputSchema:
|
|
1948
|
-
id:
|
|
1949
|
-
port:
|
|
2001
|
+
inputSchema: import_zod9.z.object({
|
|
2002
|
+
id: import_zod9.z.string(),
|
|
2003
|
+
port: import_zod9.z.number().int().positive().optional()
|
|
1950
2004
|
}),
|
|
1951
2005
|
async handler(input, ctx) {
|
|
1952
2006
|
const state = await ctx.workspace.read();
|
|
@@ -1963,7 +2017,7 @@ var mockStartTool = {
|
|
|
1963
2017
|
var mockStopTool = {
|
|
1964
2018
|
name: "mock.stop",
|
|
1965
2019
|
description: "Stop a running mock server by id (no-op if not running).",
|
|
1966
|
-
inputSchema:
|
|
2020
|
+
inputSchema: import_zod9.z.object({ id: import_zod9.z.string() }),
|
|
1967
2021
|
async handler(input, ctx) {
|
|
1968
2022
|
try {
|
|
1969
2023
|
await ctx.mock.stop(input.id);
|
|
@@ -1976,7 +2030,7 @@ var mockStopTool = {
|
|
|
1976
2030
|
var mockDeleteTool = {
|
|
1977
2031
|
name: "mock.delete",
|
|
1978
2032
|
description: "Delete a mock server definition. Stops it first if it's running.",
|
|
1979
|
-
inputSchema:
|
|
2033
|
+
inputSchema: import_zod9.z.object({ id: import_zod9.z.string() }),
|
|
1980
2034
|
async handler(input, ctx) {
|
|
1981
2035
|
try {
|
|
1982
2036
|
await ctx.mock.stop(input.id);
|
|
@@ -1986,13 +2040,13 @@ var mockDeleteTool = {
|
|
|
1986
2040
|
return { ok: true, changedIds: out.changedIds };
|
|
1987
2041
|
}
|
|
1988
2042
|
};
|
|
1989
|
-
var HTTP_METHOD3 =
|
|
2043
|
+
var HTTP_METHOD3 = import_zod9.z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
1990
2044
|
var mockCreateManualTool = {
|
|
1991
2045
|
name: "mock.create_manual",
|
|
1992
2046
|
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.",
|
|
1993
|
-
inputSchema:
|
|
1994
|
-
name:
|
|
1995
|
-
defaultPort:
|
|
2047
|
+
inputSchema: import_zod9.z.object({
|
|
2048
|
+
name: import_zod9.z.string().min(1),
|
|
2049
|
+
defaultPort: import_zod9.z.number().int().positive().nullable().optional()
|
|
1996
2050
|
}),
|
|
1997
2051
|
async handler(input, ctx) {
|
|
1998
2052
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -2015,7 +2069,7 @@ var mockCreateManualTool = {
|
|
|
2015
2069
|
var mockListEndpointsTool = {
|
|
2016
2070
|
name: "mock.list_endpoints",
|
|
2017
2071
|
description: "List endpoints for a mock server (id, method, path, name).",
|
|
2018
|
-
inputSchema:
|
|
2072
|
+
inputSchema: import_zod9.z.object({ mockId: import_zod9.z.string() }),
|
|
2019
2073
|
async handler(input, ctx) {
|
|
2020
2074
|
const state = await ctx.workspace.read();
|
|
2021
2075
|
const mock = state.synced.mockServers[input.mockId];
|
|
@@ -2034,10 +2088,10 @@ var mockListEndpointsTool = {
|
|
|
2034
2088
|
};
|
|
2035
2089
|
}
|
|
2036
2090
|
};
|
|
2037
|
-
var ENDPOINT_RESPONSE2 =
|
|
2038
|
-
status:
|
|
2039
|
-
jsonBody:
|
|
2040
|
-
contentType:
|
|
2091
|
+
var ENDPOINT_RESPONSE2 = import_zod9.z.object({
|
|
2092
|
+
status: import_zod9.z.number().int().min(100).max(599).default(200),
|
|
2093
|
+
jsonBody: import_zod9.z.string().default("{}"),
|
|
2094
|
+
contentType: import_zod9.z.string().default("application/json")
|
|
2041
2095
|
});
|
|
2042
2096
|
function buildDefaultEndpoint(args) {
|
|
2043
2097
|
const response = args.response ?? {
|
|
@@ -2066,12 +2120,12 @@ function buildDefaultEndpoint(args) {
|
|
|
2066
2120
|
var mockAddEndpointTool = {
|
|
2067
2121
|
name: "mock.add_endpoint",
|
|
2068
2122
|
description: "Append a new endpoint to a mock server. Defaults to a 200 JSON response of `{}`. Returns the new endpoint id.",
|
|
2069
|
-
inputSchema:
|
|
2070
|
-
mockId:
|
|
2123
|
+
inputSchema: import_zod9.z.object({
|
|
2124
|
+
mockId: import_zod9.z.string(),
|
|
2071
2125
|
method: HTTP_METHOD3,
|
|
2072
|
-
pathPattern:
|
|
2073
|
-
name:
|
|
2074
|
-
description:
|
|
2126
|
+
pathPattern: import_zod9.z.string().min(1),
|
|
2127
|
+
name: import_zod9.z.string().optional(),
|
|
2128
|
+
description: import_zod9.z.string().optional(),
|
|
2075
2129
|
response: ENDPOINT_RESPONSE2.optional()
|
|
2076
2130
|
}),
|
|
2077
2131
|
async handler(input, ctx) {
|
|
@@ -2094,13 +2148,13 @@ var mockAddEndpointTool = {
|
|
|
2094
2148
|
var mockUpdateEndpointTool = {
|
|
2095
2149
|
name: "mock.update_endpoint",
|
|
2096
2150
|
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.",
|
|
2097
|
-
inputSchema:
|
|
2098
|
-
mockId:
|
|
2099
|
-
endpointId:
|
|
2151
|
+
inputSchema: import_zod9.z.object({
|
|
2152
|
+
mockId: import_zod9.z.string(),
|
|
2153
|
+
endpointId: import_zod9.z.string(),
|
|
2100
2154
|
method: HTTP_METHOD3.optional(),
|
|
2101
|
-
pathPattern:
|
|
2102
|
-
name:
|
|
2103
|
-
description:
|
|
2155
|
+
pathPattern: import_zod9.z.string().optional(),
|
|
2156
|
+
name: import_zod9.z.string().optional(),
|
|
2157
|
+
description: import_zod9.z.string().optional(),
|
|
2104
2158
|
response: ENDPOINT_RESPONSE2.partial().optional()
|
|
2105
2159
|
}),
|
|
2106
2160
|
async handler(input, ctx) {
|
|
@@ -2141,7 +2195,7 @@ var mockUpdateEndpointTool = {
|
|
|
2141
2195
|
var mockDeleteEndpointTool = {
|
|
2142
2196
|
name: "mock.delete_endpoint",
|
|
2143
2197
|
description: "Remove an endpoint from a mock server.",
|
|
2144
|
-
inputSchema:
|
|
2198
|
+
inputSchema: import_zod9.z.object({ mockId: import_zod9.z.string(), endpointId: import_zod9.z.string() }),
|
|
2145
2199
|
async handler(input, ctx) {
|
|
2146
2200
|
const state = await ctx.workspace.read();
|
|
2147
2201
|
const mock = state.synced.mockServers[input.mockId];
|
|
@@ -2161,9 +2215,9 @@ var mockDeleteEndpointTool = {
|
|
|
2161
2215
|
return { ok: true, changedIds: out.changedIds };
|
|
2162
2216
|
}
|
|
2163
2217
|
};
|
|
2164
|
-
var VALIDATION_RULE =
|
|
2165
|
-
id:
|
|
2166
|
-
kind:
|
|
2218
|
+
var VALIDATION_RULE = import_zod9.z.object({
|
|
2219
|
+
id: import_zod9.z.string().optional(),
|
|
2220
|
+
kind: import_zod9.z.enum([
|
|
2167
2221
|
"header-required",
|
|
2168
2222
|
"header-equals",
|
|
2169
2223
|
"header-matches",
|
|
@@ -2174,43 +2228,43 @@ var VALIDATION_RULE = import_zod8.z.object({
|
|
|
2174
2228
|
"body-required",
|
|
2175
2229
|
"content-type-equals"
|
|
2176
2230
|
]),
|
|
2177
|
-
target:
|
|
2178
|
-
expected:
|
|
2179
|
-
message:
|
|
2180
|
-
enabled:
|
|
2181
|
-
failResponse:
|
|
2182
|
-
status:
|
|
2183
|
-
jsonBody:
|
|
2231
|
+
target: import_zod9.z.string().default(""),
|
|
2232
|
+
expected: import_zod9.z.string().optional(),
|
|
2233
|
+
message: import_zod9.z.string().optional(),
|
|
2234
|
+
enabled: import_zod9.z.boolean().default(true),
|
|
2235
|
+
failResponse: import_zod9.z.object({
|
|
2236
|
+
status: import_zod9.z.number().int().min(100).max(599).default(400),
|
|
2237
|
+
jsonBody: import_zod9.z.string().default('{"error":"validation failed"}')
|
|
2184
2238
|
}).default({})
|
|
2185
2239
|
});
|
|
2186
|
-
var CONDITION_CLAUSE =
|
|
2187
|
-
id:
|
|
2188
|
-
scope:
|
|
2189
|
-
target:
|
|
2190
|
-
op:
|
|
2191
|
-
value:
|
|
2240
|
+
var CONDITION_CLAUSE = import_zod9.z.object({
|
|
2241
|
+
id: import_zod9.z.string().optional(),
|
|
2242
|
+
scope: import_zod9.z.enum(["query", "pathParam", "header", "cookie", "body-json-path"]),
|
|
2243
|
+
target: import_zod9.z.string(),
|
|
2244
|
+
op: import_zod9.z.enum(["equals", "not-equals", "matches", "gt", "lt", "gte", "lte", "present", "absent"]),
|
|
2245
|
+
value: import_zod9.z.string().optional()
|
|
2192
2246
|
});
|
|
2193
|
-
var RESPONSE_RULE =
|
|
2194
|
-
id:
|
|
2195
|
-
name:
|
|
2196
|
-
enabled:
|
|
2197
|
-
when:
|
|
2198
|
-
response:
|
|
2199
|
-
status:
|
|
2200
|
-
jsonBody:
|
|
2247
|
+
var RESPONSE_RULE = import_zod9.z.object({
|
|
2248
|
+
id: import_zod9.z.string().optional(),
|
|
2249
|
+
name: import_zod9.z.string(),
|
|
2250
|
+
enabled: import_zod9.z.boolean().default(true),
|
|
2251
|
+
when: import_zod9.z.array(CONDITION_CLAUSE).default([]),
|
|
2252
|
+
response: import_zod9.z.object({
|
|
2253
|
+
status: import_zod9.z.number().int().min(100).max(599).default(200),
|
|
2254
|
+
jsonBody: import_zod9.z.string().default("{}")
|
|
2201
2255
|
}).default({})
|
|
2202
2256
|
});
|
|
2203
|
-
var MULTIPLIER =
|
|
2204
|
-
id:
|
|
2205
|
-
name:
|
|
2206
|
-
source:
|
|
2207
|
-
kind:
|
|
2208
|
-
key:
|
|
2257
|
+
var MULTIPLIER = import_zod9.z.object({
|
|
2258
|
+
id: import_zod9.z.string().optional(),
|
|
2259
|
+
name: import_zod9.z.string().optional(),
|
|
2260
|
+
source: import_zod9.z.object({
|
|
2261
|
+
kind: import_zod9.z.enum(["query", "pathParam", "header", "body-json-path"]),
|
|
2262
|
+
key: import_zod9.z.string()
|
|
2209
2263
|
}),
|
|
2210
|
-
targetJsonPath:
|
|
2211
|
-
defaultCount:
|
|
2212
|
-
min:
|
|
2213
|
-
max:
|
|
2264
|
+
targetJsonPath: import_zod9.z.string(),
|
|
2265
|
+
defaultCount: import_zod9.z.number().int().nonnegative().default(0),
|
|
2266
|
+
min: import_zod9.z.number().int().nonnegative().optional(),
|
|
2267
|
+
max: import_zod9.z.number().int().nonnegative().optional()
|
|
2214
2268
|
});
|
|
2215
2269
|
function defaultJsonResponseConfig(args) {
|
|
2216
2270
|
return {
|
|
@@ -2235,10 +2289,10 @@ function patchEndpoint2(mock, endpointId, patcher) {
|
|
|
2235
2289
|
var mockSetValidationRulesTool = {
|
|
2236
2290
|
name: "mock.set_validation_rules",
|
|
2237
2291
|
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.",
|
|
2238
|
-
inputSchema:
|
|
2239
|
-
mockId:
|
|
2240
|
-
endpointId:
|
|
2241
|
-
rules:
|
|
2292
|
+
inputSchema: import_zod9.z.object({
|
|
2293
|
+
mockId: import_zod9.z.string(),
|
|
2294
|
+
endpointId: import_zod9.z.string(),
|
|
2295
|
+
rules: import_zod9.z.array(VALIDATION_RULE)
|
|
2242
2296
|
}),
|
|
2243
2297
|
async handler(input, ctx) {
|
|
2244
2298
|
const state = await ctx.workspace.read();
|
|
@@ -2265,10 +2319,10 @@ var mockSetValidationRulesTool = {
|
|
|
2265
2319
|
var mockSetResponseRulesTool = {
|
|
2266
2320
|
name: "mock.set_response_rules",
|
|
2267
2321
|
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.",
|
|
2268
|
-
inputSchema:
|
|
2269
|
-
mockId:
|
|
2270
|
-
endpointId:
|
|
2271
|
-
rules:
|
|
2322
|
+
inputSchema: import_zod9.z.object({
|
|
2323
|
+
mockId: import_zod9.z.string(),
|
|
2324
|
+
endpointId: import_zod9.z.string(),
|
|
2325
|
+
rules: import_zod9.z.array(RESPONSE_RULE)
|
|
2272
2326
|
}),
|
|
2273
2327
|
async handler(input, ctx) {
|
|
2274
2328
|
const state = await ctx.workspace.read();
|
|
@@ -2299,10 +2353,10 @@ var mockSetResponseRulesTool = {
|
|
|
2299
2353
|
var mockSetMultipliersTool = {
|
|
2300
2354
|
name: "mock.set_multipliers",
|
|
2301
2355
|
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.",
|
|
2302
|
-
inputSchema:
|
|
2303
|
-
mockId:
|
|
2304
|
-
endpointId:
|
|
2305
|
-
multipliers:
|
|
2356
|
+
inputSchema: import_zod9.z.object({
|
|
2357
|
+
mockId: import_zod9.z.string(),
|
|
2358
|
+
endpointId: import_zod9.z.string(),
|
|
2359
|
+
multipliers: import_zod9.z.array(MULTIPLIER)
|
|
2306
2360
|
}),
|
|
2307
2361
|
async handler(input, ctx) {
|
|
2308
2362
|
const state = await ctx.workspace.read();
|
|
@@ -2338,6 +2392,7 @@ var TOOL_REGISTRY = [
|
|
|
2338
2392
|
importInsomniaTool,
|
|
2339
2393
|
importHarTool,
|
|
2340
2394
|
generateCodeTool,
|
|
2395
|
+
workspaceListTool,
|
|
2341
2396
|
workspaceReadTool,
|
|
2342
2397
|
workspaceWriteTool,
|
|
2343
2398
|
requestCreateTool,
|
|
@@ -2408,6 +2463,63 @@ function getTool(name) {
|
|
|
2408
2463
|
return TOOL_REGISTRY.find((t) => t.name === name);
|
|
2409
2464
|
}
|
|
2410
2465
|
|
|
2466
|
+
// src/providers/Workspaces.ts
|
|
2467
|
+
var SingleWorkspaceAdapter = class {
|
|
2468
|
+
constructor(provider, workspaceId, displayName = "Workspace") {
|
|
2469
|
+
this.provider = provider;
|
|
2470
|
+
this.workspaceId = workspaceId;
|
|
2471
|
+
this.displayName = displayName;
|
|
2472
|
+
}
|
|
2473
|
+
provider;
|
|
2474
|
+
workspaceId;
|
|
2475
|
+
displayName;
|
|
2476
|
+
async list() {
|
|
2477
|
+
const state = await this.provider.read();
|
|
2478
|
+
const id = state.synced.workspaceId;
|
|
2479
|
+
this.workspaceId = id;
|
|
2480
|
+
return [
|
|
2481
|
+
{
|
|
2482
|
+
id,
|
|
2483
|
+
name: this.displayName,
|
|
2484
|
+
isActive: true,
|
|
2485
|
+
createdAt: state.synced.meta.createdAt,
|
|
2486
|
+
lastOpenedAt: state.synced.meta.updatedAt,
|
|
2487
|
+
counts: {
|
|
2488
|
+
requests: Object.keys(state.synced.collections.requests).length,
|
|
2489
|
+
folders: Object.keys(state.synced.collections.folders).length,
|
|
2490
|
+
environments: Object.keys(state.synced.environments.items).length,
|
|
2491
|
+
mockServers: Object.keys(state.synced.mockServers ?? {}).length,
|
|
2492
|
+
plans: Object.keys(state.synced.executionPlans ?? {}).length
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
];
|
|
2496
|
+
}
|
|
2497
|
+
for(workspaceId) {
|
|
2498
|
+
if (this.workspaceId && workspaceId !== this.workspaceId) {
|
|
2499
|
+
throw new WorkspaceNotFoundError(workspaceId);
|
|
2500
|
+
}
|
|
2501
|
+
return this.provider;
|
|
2502
|
+
}
|
|
2503
|
+
activeId() {
|
|
2504
|
+
return this.workspaceId;
|
|
2505
|
+
}
|
|
2506
|
+
setActive(workspaceId) {
|
|
2507
|
+
if (this.workspaceId && workspaceId !== this.workspaceId) {
|
|
2508
|
+
throw new WorkspaceNotFoundError(workspaceId);
|
|
2509
|
+
}
|
|
2510
|
+
return Promise.resolve();
|
|
2511
|
+
}
|
|
2512
|
+
};
|
|
2513
|
+
var WorkspaceNotFoundError = class extends Error {
|
|
2514
|
+
code = "workspace-not-found";
|
|
2515
|
+
workspaceId;
|
|
2516
|
+
constructor(workspaceId) {
|
|
2517
|
+
super(`No workspace with id "${workspaceId}" is available on this server.`);
|
|
2518
|
+
this.name = "WorkspaceNotFoundError";
|
|
2519
|
+
this.workspaceId = workspaceId;
|
|
2520
|
+
}
|
|
2521
|
+
};
|
|
2522
|
+
|
|
2411
2523
|
// src/providers/InMemoryWorkspaceProvider.ts
|
|
2412
2524
|
var import_core2 = require("@apicircle/core");
|
|
2413
2525
|
var InMemoryWorkspaceProvider = class {
|
|
@@ -2468,6 +2580,109 @@ var FileBackedWorkspaceProvider = class {
|
|
|
2468
2580
|
}
|
|
2469
2581
|
};
|
|
2470
2582
|
|
|
2583
|
+
// src/providers/MultiWorkspaceProvider.ts
|
|
2584
|
+
var import_registry = require("@apicircle/core/workspace/registry");
|
|
2585
|
+
var MultiWorkspaceProvider = class {
|
|
2586
|
+
constructor(registryRoot) {
|
|
2587
|
+
this.registryRoot = registryRoot;
|
|
2588
|
+
}
|
|
2589
|
+
registryRoot;
|
|
2590
|
+
active = null;
|
|
2591
|
+
activeWorkspaceId = null;
|
|
2592
|
+
/**
|
|
2593
|
+
* Hydrate the active provider from disk. Must be called once before the
|
|
2594
|
+
* MCP host boots so `ctx.workspace.read()` doesn't race the first
|
|
2595
|
+
* registry-load. Returns the registry the boot can log.
|
|
2596
|
+
*/
|
|
2597
|
+
async init() {
|
|
2598
|
+
const registry = await (0, import_registry.loadRegistry)(this.registryRoot) ?? {
|
|
2599
|
+
schemaVersion: 1,
|
|
2600
|
+
activeWorkspaceId: null,
|
|
2601
|
+
workspaces: []
|
|
2602
|
+
};
|
|
2603
|
+
if (registry.activeWorkspaceId) {
|
|
2604
|
+
this.activeWorkspaceId = registry.activeWorkspaceId;
|
|
2605
|
+
this.active = new FileBackedWorkspaceProvider(
|
|
2606
|
+
(0, import_registry.workspaceDirFor)(this.registryRoot, registry.activeWorkspaceId)
|
|
2607
|
+
);
|
|
2608
|
+
}
|
|
2609
|
+
return registry;
|
|
2610
|
+
}
|
|
2611
|
+
/** The provider tool handlers see as `ctx.workspace`. */
|
|
2612
|
+
activeProvider() {
|
|
2613
|
+
if (!this.active) {
|
|
2614
|
+
throw new Error(
|
|
2615
|
+
"No active workspace. Open the desktop app at least once, or run `apicircle workspaces create <name>`."
|
|
2616
|
+
);
|
|
2617
|
+
}
|
|
2618
|
+
return this.active;
|
|
2619
|
+
}
|
|
2620
|
+
// ─── Workspaces interface ──────────────────────────────────────────────────
|
|
2621
|
+
async list() {
|
|
2622
|
+
const registry = await (0, import_registry.loadRegistry)(this.registryRoot) ?? {
|
|
2623
|
+
schemaVersion: 1,
|
|
2624
|
+
activeWorkspaceId: null,
|
|
2625
|
+
workspaces: []
|
|
2626
|
+
};
|
|
2627
|
+
const out = [];
|
|
2628
|
+
for (const entry of registry.workspaces) {
|
|
2629
|
+
let counts = null;
|
|
2630
|
+
try {
|
|
2631
|
+
const state = await (0, import_registry.loadWorkspaceById)(this.registryRoot, entry.id);
|
|
2632
|
+
if (state) {
|
|
2633
|
+
counts = {
|
|
2634
|
+
requests: Object.keys(state.synced.collections.requests).length,
|
|
2635
|
+
folders: Object.keys(state.synced.collections.folders).length,
|
|
2636
|
+
environments: Object.keys(state.synced.environments.items).length,
|
|
2637
|
+
mockServers: Object.keys(state.synced.mockServers ?? {}).length,
|
|
2638
|
+
plans: Object.keys(state.synced.executionPlans ?? {}).length
|
|
2639
|
+
};
|
|
2640
|
+
}
|
|
2641
|
+
} catch {
|
|
2642
|
+
counts = null;
|
|
2643
|
+
}
|
|
2644
|
+
out.push({
|
|
2645
|
+
id: entry.id,
|
|
2646
|
+
name: entry.name,
|
|
2647
|
+
isActive: entry.id === registry.activeWorkspaceId,
|
|
2648
|
+
createdAt: entry.createdAt,
|
|
2649
|
+
lastOpenedAt: entry.lastOpenedAt,
|
|
2650
|
+
counts
|
|
2651
|
+
});
|
|
2652
|
+
}
|
|
2653
|
+
return out;
|
|
2654
|
+
}
|
|
2655
|
+
for(workspaceId) {
|
|
2656
|
+
return new FileBackedWorkspaceProvider((0, import_registry.workspaceDirFor)(this.registryRoot, workspaceId));
|
|
2657
|
+
}
|
|
2658
|
+
activeId() {
|
|
2659
|
+
return this.activeWorkspaceId;
|
|
2660
|
+
}
|
|
2661
|
+
async setActive(workspaceId) {
|
|
2662
|
+
const registry = await (0, import_registry.loadRegistry)(this.registryRoot);
|
|
2663
|
+
if (!registry || !registry.workspaces.some((w) => w.id === workspaceId)) {
|
|
2664
|
+
throw new WorkspaceNotFoundError(workspaceId);
|
|
2665
|
+
}
|
|
2666
|
+
const next = await (0, import_registry.setActiveWorkspace)(this.registryRoot, workspaceId);
|
|
2667
|
+
void next;
|
|
2668
|
+
this.activeWorkspaceId = workspaceId;
|
|
2669
|
+
this.active = new FileBackedWorkspaceProvider((0, import_registry.workspaceDirFor)(this.registryRoot, workspaceId));
|
|
2670
|
+
}
|
|
2671
|
+
/**
|
|
2672
|
+
* Idempotent registry write — used by tests / tools that need to
|
|
2673
|
+
* persist registry updates that didn't go through `setActive`.
|
|
2674
|
+
*/
|
|
2675
|
+
async writeRegistry(registry) {
|
|
2676
|
+
await (0, import_registry.saveRegistry)(this.registryRoot, registry);
|
|
2677
|
+
this.activeWorkspaceId = registry.activeWorkspaceId;
|
|
2678
|
+
if (registry.activeWorkspaceId) {
|
|
2679
|
+
this.active = new FileBackedWorkspaceProvider(
|
|
2680
|
+
(0, import_registry.workspaceDirFor)(this.registryRoot, registry.activeWorkspaceId)
|
|
2681
|
+
);
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
};
|
|
2685
|
+
|
|
2471
2686
|
// src/providers/InProcessMockController.ts
|
|
2472
2687
|
var import_mock_server_core3 = require("@apicircle/mock-server-core");
|
|
2473
2688
|
var InProcessMockController = class {
|
|
@@ -2508,10 +2723,19 @@ var InProcessMockController = class {
|
|
|
2508
2723
|
|
|
2509
2724
|
// src/index.ts
|
|
2510
2725
|
function createMcpServer(options) {
|
|
2726
|
+
const workspaces = options.workspaces ?? new SingleWorkspaceAdapter(
|
|
2727
|
+
options.workspace,
|
|
2728
|
+
null
|
|
2729
|
+
/* discovered on first list() */
|
|
2730
|
+
);
|
|
2511
2731
|
return new McpHost({
|
|
2512
2732
|
serverInfo: options.serverInfo,
|
|
2513
2733
|
tools: options.tools ?? TOOL_REGISTRY,
|
|
2514
|
-
context: {
|
|
2734
|
+
context: {
|
|
2735
|
+
workspace: options.workspace,
|
|
2736
|
+
workspaces,
|
|
2737
|
+
mock: options.mock
|
|
2738
|
+
}
|
|
2515
2739
|
});
|
|
2516
2740
|
}
|
|
2517
2741
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -2520,7 +2744,10 @@ function createMcpServer(options) {
|
|
|
2520
2744
|
InMemoryWorkspaceProvider,
|
|
2521
2745
|
InProcessMockController,
|
|
2522
2746
|
McpHost,
|
|
2747
|
+
MultiWorkspaceProvider,
|
|
2748
|
+
SingleWorkspaceAdapter,
|
|
2523
2749
|
TOOL_REGISTRY,
|
|
2750
|
+
WorkspaceNotFoundError,
|
|
2524
2751
|
createMcpServer,
|
|
2525
2752
|
getTool
|
|
2526
2753
|
});
|