@lexq/cli 0.1.59 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3317,8 +3317,8 @@ import dedent17 from "dedent";
3317
3317
  import { readFileSync as readFileSync3 } from "fs";
3318
3318
  import { dirname, join as join2 } from "path";
3319
3319
  import { fileURLToPath } from "url";
3320
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3321
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3320
+ import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
3321
+ import { McpServer } from "@modelcontextprotocol/server";
3322
3322
 
3323
3323
  // src/mcp/tools/_shared.ts
3324
3324
  function createCallApiFromConfig() {
@@ -3402,27 +3402,28 @@ function formatUnregisteredFactWarning(meta) {
3402
3402
  }
3403
3403
 
3404
3404
  // src/mcp/tools/status.ts
3405
+ import { z } from "zod";
3405
3406
  function registerStatusTools(server, callApi) {
3406
3407
  server.registerTool(
3407
3408
  "lexq_whoami",
3408
3409
  {
3409
3410
  title: "Who Am I",
3410
3411
  description: "Show current authentication info (tenant ID, user ID, role).",
3411
- inputSchema: {}
3412
+ inputSchema: z.object({})
3412
3413
  },
3413
3414
  async () => callApi("GET", "whoami")
3414
3415
  );
3415
3416
  }
3416
3417
 
3417
3418
  // src/mcp/tools/groups.ts
3418
- import { z } from "zod";
3419
+ import { z as z2 } from "zod";
3419
3420
  function registerGroupTools(server, callApi) {
3420
3421
  server.registerTool(
3421
3422
  "lexq_groups_list",
3422
3423
  {
3423
3424
  title: "List Policy Groups",
3424
3425
  description: "List all policy groups (tenant-wide, priority ASC).",
3425
- inputSchema: {}
3426
+ inputSchema: z2.object({})
3426
3427
  },
3427
3428
  async () => callApi("GET", "policy-groups")
3428
3429
  );
@@ -3431,9 +3432,9 @@ function registerGroupTools(server, callApi) {
3431
3432
  {
3432
3433
  title: "Get Policy Group",
3433
3434
  description: "Get a single policy group by ID.",
3434
- inputSchema: {
3435
- groupId: z.string().uuid().describe("Policy group ID")
3436
- }
3435
+ inputSchema: z2.object({
3436
+ groupId: z2.string().uuid().describe("Policy group ID")
3437
+ })
3437
3438
  },
3438
3439
  async ({ groupId }) => callApi("GET", `policy-groups/${groupId}`)
3439
3440
  );
@@ -3442,18 +3443,18 @@ function registerGroupTools(server, callApi) {
3442
3443
  {
3443
3444
  title: "Create Policy Group",
3444
3445
  description: "Create a new policy group. Requires name. Priority is auto-assigned (appended last, tenant-wide); use lexq_groups_reorder to change order. Optionally set conflict resolution, activation group, and description. Policy groups that share an activationGroup form a cluster and must share the same activationMode / activationStrategy / executionLimit; executionLimit is how many of those groups run, not how many rules.",
3445
- inputSchema: {
3446
- name: z.string().describe("Group name (unique among non-ARCHIVED)"),
3447
- description: z.string().optional().describe("Group description"),
3448
- activationMode: z.enum(ConflictResolutionMode).optional().describe("Conflict resolution mode"),
3449
- activationStrategy: z.enum(ConflictResolutionStrategy).optional().describe("Ranking used to pick the winning groups when mode is EXCLUSIVE or MAX_N"),
3450
- executionLimit: z.number().int().min(1).optional().describe(
3446
+ inputSchema: z2.object({
3447
+ name: z2.string().describe("Group name (unique among non-ARCHIVED)"),
3448
+ description: z2.string().optional().describe("Group description"),
3449
+ activationMode: z2.enum(ConflictResolutionMode).optional().describe("Conflict resolution mode"),
3450
+ activationStrategy: z2.enum(ConflictResolutionStrategy).optional().describe("Ranking used to pick the winning groups when mode is EXCLUSIVE or MAX_N"),
3451
+ executionLimit: z2.number().int().min(1).optional().describe(
3451
3452
  "How many policy groups sharing this activationGroup may run (required when mode is MAX_N). Counts groups, not rules: every rule of a winning group runs."
3452
3453
  ),
3453
- activationGroup: z.string().optional().describe(
3454
+ activationGroup: z2.string().optional().describe(
3454
3455
  "Activation group (Execution Group) cluster key. Policy groups sharing this key compete, and group priority picks the winners."
3455
3456
  )
3456
- }
3457
+ })
3457
3458
  },
3458
3459
  async (args) => {
3459
3460
  const body = {
@@ -3472,20 +3473,20 @@ function registerGroupTools(server, callApi) {
3472
3473
  {
3473
3474
  title: "Update Policy Group",
3474
3475
  description: "Update a policy group. Only provided fields are updated; omitted fields remain unchanged.",
3475
- inputSchema: {
3476
- groupId: z.string().uuid().describe("Policy group ID"),
3477
- name: z.string().optional().describe("New name"),
3478
- description: z.string().optional().describe("New description"),
3479
- status: z.enum(["ACTIVE", "DISABLED"]).optional().describe("Status (DISABLED = emergency stop)"),
3480
- activationGroup: z.string().optional().describe(
3476
+ inputSchema: z2.object({
3477
+ groupId: z2.string().uuid().describe("Policy group ID"),
3478
+ name: z2.string().optional().describe("New name"),
3479
+ description: z2.string().optional().describe("New description"),
3480
+ status: z2.enum(["ACTIVE", "DISABLED"]).optional().describe("Status (DISABLED = emergency stop)"),
3481
+ activationGroup: z2.string().optional().describe(
3481
3482
  "Activation group (Execution Group) cluster key. Policy groups sharing this key compete, and group priority picks the winners."
3482
3483
  ),
3483
- activationMode: z.enum(ConflictResolutionMode).optional().describe("Conflict resolution mode"),
3484
- activationStrategy: z.enum(ConflictResolutionStrategy).optional().describe("Ranking used to pick the winning groups"),
3485
- executionLimit: z.number().int().min(1).optional().describe(
3484
+ activationMode: z2.enum(ConflictResolutionMode).optional().describe("Conflict resolution mode"),
3485
+ activationStrategy: z2.enum(ConflictResolutionStrategy).optional().describe("Ranking used to pick the winning groups"),
3486
+ executionLimit: z2.number().int().min(1).optional().describe(
3486
3487
  "How many policy groups sharing this activationGroup may run. Counts groups, not rules."
3487
3488
  )
3488
- }
3489
+ })
3489
3490
  },
3490
3491
  async ({ groupId, ...body }) => callApi("PUT", `policy-groups/${groupId}`, { body })
3491
3492
  );
@@ -3494,9 +3495,9 @@ function registerGroupTools(server, callApi) {
3494
3495
  {
3495
3496
  title: "Delete Policy Group",
3496
3497
  description: "Archive a policy group. Only non-live groups can be deleted. This is irreversible.",
3497
- inputSchema: {
3498
- groupId: z.string().uuid().describe("Policy group ID")
3499
- }
3498
+ inputSchema: z2.object({
3499
+ groupId: z2.string().uuid().describe("Policy group ID")
3500
+ })
3500
3501
  },
3501
3502
  async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}`)
3502
3503
  );
@@ -3505,9 +3506,9 @@ function registerGroupTools(server, callApi) {
3505
3506
  {
3506
3507
  title: "Reorder Policy Groups",
3507
3508
  description: "Reorder policy groups by priority. Priority is tenant-wide and flat (1...N continuous); array index 0 = priority 1 (highest precedence). activationGroup is not affected \u2014 this only changes priority.",
3508
- inputSchema: {
3509
- groupIds: z.array(z.string().uuid()).describe("Group IDs in desired priority order (index 0 = priority 1)")
3510
- }
3509
+ inputSchema: z2.object({
3510
+ groupIds: z2.array(z2.string().uuid()).describe("Group IDs in desired priority order (index 0 = priority 1)")
3511
+ })
3511
3512
  },
3512
3513
  async ({ groupIds }) => {
3513
3514
  const groups = groupIds.map((groupId, index) => ({
@@ -3522,11 +3523,11 @@ function registerGroupTools(server, callApi) {
3522
3523
  {
3523
3524
  title: "Start A/B Test",
3524
3525
  description: "Start an A/B test on a policy group. Requires a challenger version ID and traffic rate. The split is computed from context.trafficKey on each execution request; requests that omit it never reach the challenger and the test stays at 0%.",
3525
- inputSchema: {
3526
- groupId: z.string().uuid().describe("Policy group ID"),
3527
- testVersionId: z.string().uuid().describe("Challenger version ID to test"),
3528
- trafficRate: z.number().int().min(1).max(99).describe("Traffic percentage routed to challenger (1-99)")
3529
- }
3526
+ inputSchema: z2.object({
3527
+ groupId: z2.string().uuid().describe("Policy group ID"),
3528
+ testVersionId: z2.string().uuid().describe("Challenger version ID to test"),
3529
+ trafficRate: z2.number().int().min(1).max(99).describe("Traffic percentage routed to challenger (1-99)")
3530
+ })
3530
3531
  },
3531
3532
  async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/ab-test`, { body })
3532
3533
  );
@@ -3535,9 +3536,9 @@ function registerGroupTools(server, callApi) {
3535
3536
  {
3536
3537
  title: "Stop A/B Test",
3537
3538
  description: "Stop a running A/B test. All traffic is restored to the control (current) version.",
3538
- inputSchema: {
3539
- groupId: z.string().uuid().describe("Policy group ID")
3540
- }
3539
+ inputSchema: z2.object({
3540
+ groupId: z2.string().uuid().describe("Policy group ID")
3541
+ })
3541
3542
  },
3542
3543
  async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}/ab-test`)
3543
3544
  );
@@ -3546,28 +3547,28 @@ function registerGroupTools(server, callApi) {
3546
3547
  {
3547
3548
  title: "Adjust A/B Test",
3548
3549
  description: "Adjust traffic rate of a running A/B test.",
3549
- inputSchema: {
3550
- groupId: z.string().uuid().describe("Policy group ID"),
3551
- trafficRate: z.number().int().min(1).max(99).describe("New traffic percentage for challenger (1-99)")
3552
- }
3550
+ inputSchema: z2.object({
3551
+ groupId: z2.string().uuid().describe("Policy group ID"),
3552
+ trafficRate: z2.number().int().min(1).max(99).describe("New traffic percentage for challenger (1-99)")
3553
+ })
3553
3554
  },
3554
3555
  async ({ groupId, ...body }) => callApi("PATCH", `policy-groups/${groupId}/ab-test/traffic-rate`, { body })
3555
3556
  );
3556
3557
  }
3557
3558
 
3558
3559
  // src/mcp/tools/versions.ts
3559
- import { z as z2 } from "zod";
3560
+ import { z as z3 } from "zod";
3560
3561
  function registerVersionTools(server, callApi) {
3561
3562
  server.registerTool(
3562
3563
  "lexq_versions_list",
3563
3564
  {
3564
3565
  title: "List Policy Versions",
3565
3566
  description: "List all versions of a policy group.",
3566
- inputSchema: {
3567
- groupId: z2.string().uuid().describe("Policy group ID"),
3568
- page: z2.number().int().min(0).default(0).describe("Page number"),
3569
- size: z2.number().int().min(1).max(100).default(20).describe("Page size")
3570
- }
3567
+ inputSchema: z3.object({
3568
+ groupId: z3.string().uuid().describe("Policy group ID"),
3569
+ page: z3.number().int().min(0).default(0).describe("Page number"),
3570
+ size: z3.number().int().min(1).max(100).default(20).describe("Page size")
3571
+ })
3571
3572
  },
3572
3573
  async ({ groupId, page, size }) => callApi("GET", `policy-groups/${groupId}/versions`, {
3573
3574
  params: paginationParams(page, size)
@@ -3578,10 +3579,10 @@ function registerVersionTools(server, callApi) {
3578
3579
  {
3579
3580
  title: "Get Policy Version",
3580
3581
  description: "Get a single version by ID, including its rules and fact requirements.",
3581
- inputSchema: {
3582
- groupId: z2.string().uuid().describe("Policy group ID"),
3583
- versionId: z2.string().uuid().describe("Version ID")
3584
- }
3582
+ inputSchema: z3.object({
3583
+ groupId: z3.string().uuid().describe("Policy group ID"),
3584
+ versionId: z3.string().uuid().describe("Version ID")
3585
+ })
3585
3586
  },
3586
3587
  async ({ groupId, versionId }) => callApi("GET", `policy-groups/${groupId}/versions/${versionId}`)
3587
3588
  );
@@ -3590,12 +3591,12 @@ function registerVersionTools(server, callApi) {
3590
3591
  {
3591
3592
  title: "Create Policy Version",
3592
3593
  description: "Create a new DRAFT version in a policy group. Optionally provide a commit message and effective date range.",
3593
- inputSchema: {
3594
- groupId: z2.string().uuid().describe("Policy group ID"),
3595
- commitMessage: z2.string().optional().describe("Commit message describing this version"),
3596
- effectiveFrom: z2.string().optional().describe("Effective start date (ISO 8601)"),
3597
- effectiveTo: z2.string().optional().describe("Effective end date (ISO 8601)")
3598
- }
3594
+ inputSchema: z3.object({
3595
+ groupId: z3.string().uuid().describe("Policy group ID"),
3596
+ commitMessage: z3.string().optional().describe("Commit message describing this version"),
3597
+ effectiveFrom: z3.string().optional().describe("Effective start date (ISO 8601)"),
3598
+ effectiveTo: z3.string().optional().describe("Effective end date (ISO 8601)")
3599
+ })
3599
3600
  },
3600
3601
  async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/versions`, { body })
3601
3602
  );
@@ -3604,13 +3605,13 @@ function registerVersionTools(server, callApi) {
3604
3605
  {
3605
3606
  title: "Update Policy Version",
3606
3607
  description: "Update a DRAFT version. Only DRAFT versions can be modified. Only provided fields are changed.",
3607
- inputSchema: {
3608
- groupId: z2.string().uuid().describe("Policy group ID"),
3609
- versionId: z2.string().uuid().describe("Version ID"),
3610
- commitMessage: z2.string().optional().describe("New commit message"),
3611
- effectiveFrom: z2.string().optional().describe("New effective start date"),
3612
- effectiveTo: z2.string().optional().describe("New effective end date")
3613
- }
3608
+ inputSchema: z3.object({
3609
+ groupId: z3.string().uuid().describe("Policy group ID"),
3610
+ versionId: z3.string().uuid().describe("Version ID"),
3611
+ commitMessage: z3.string().optional().describe("New commit message"),
3612
+ effectiveFrom: z3.string().optional().describe("New effective start date"),
3613
+ effectiveTo: z3.string().optional().describe("New effective end date")
3614
+ })
3614
3615
  },
3615
3616
  async ({ groupId, versionId, ...body }) => callApi("PUT", `policy-groups/${groupId}/versions/${versionId}`, { body })
3616
3617
  );
@@ -3619,10 +3620,10 @@ function registerVersionTools(server, callApi) {
3619
3620
  {
3620
3621
  title: "Delete Policy Version",
3621
3622
  description: "Delete a DRAFT version. Only DRAFT versions can be deleted.",
3622
- inputSchema: {
3623
- groupId: z2.string().uuid().describe("Policy group ID"),
3624
- versionId: z2.string().uuid().describe("Version ID")
3625
- }
3623
+ inputSchema: z3.object({
3624
+ groupId: z3.string().uuid().describe("Policy group ID"),
3625
+ versionId: z3.string().uuid().describe("Version ID")
3626
+ })
3626
3627
  },
3627
3628
  async ({ groupId, versionId }) => callApi("DELETE", `policy-groups/${groupId}/versions/${versionId}`)
3628
3629
  );
@@ -3631,10 +3632,10 @@ function registerVersionTools(server, callApi) {
3631
3632
  {
3632
3633
  title: "Clone Policy Version",
3633
3634
  description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
3634
- inputSchema: {
3635
- groupId: z2.string().uuid().describe("Policy group ID"),
3636
- versionId: z2.string().uuid().describe("Source version ID to clone")
3637
- }
3635
+ inputSchema: z3.object({
3636
+ groupId: z3.string().uuid().describe("Policy group ID"),
3637
+ versionId: z3.string().uuid().describe("Source version ID to clone")
3638
+ })
3638
3639
  },
3639
3640
  async ({ groupId, versionId }) => {
3640
3641
  return callApi("POST", `policy-groups/${groupId}/versions/${versionId}/clone`, {
@@ -3645,7 +3646,7 @@ function registerVersionTools(server, callApi) {
3645
3646
  }
3646
3647
 
3647
3648
  // src/mcp/tools/rules.ts
3648
- import { z as z3 } from "zod";
3649
+ import { z as z4 } from "zod";
3649
3650
  import dedent15 from "dedent";
3650
3651
  function registerRuleTools(server, callApi) {
3651
3652
  server.registerTool(
@@ -3653,10 +3654,10 @@ function registerRuleTools(server, callApi) {
3653
3654
  {
3654
3655
  title: "List Rules",
3655
3656
  description: "List all rules in a version (priority ASC). Returns summary with conditionSummary and actionSummary.",
3656
- inputSchema: {
3657
- groupId: z3.string().uuid().describe("Policy group ID"),
3658
- versionId: z3.string().uuid().describe("Version ID")
3659
- }
3657
+ inputSchema: z4.object({
3658
+ groupId: z4.string().uuid().describe("Policy group ID"),
3659
+ versionId: z4.string().uuid().describe("Version ID")
3660
+ })
3660
3661
  },
3661
3662
  async ({ groupId, versionId }) => callApi("GET", `policy-groups/${groupId}/versions/${versionId}/rules`)
3662
3663
  );
@@ -3665,11 +3666,11 @@ function registerRuleTools(server, callApi) {
3665
3666
  {
3666
3667
  title: "Get Rule Detail",
3667
3668
  description: "Get full rule detail including condition tree and action definitions.",
3668
- inputSchema: {
3669
- groupId: z3.string().uuid().describe("Policy group ID"),
3670
- versionId: z3.string().uuid().describe("Version ID"),
3671
- ruleId: z3.string().uuid().describe("Rule ID")
3672
- }
3669
+ inputSchema: z4.object({
3670
+ groupId: z4.string().uuid().describe("Policy group ID"),
3671
+ versionId: z4.string().uuid().describe("Version ID"),
3672
+ ruleId: z4.string().uuid().describe("Rule ID")
3673
+ })
3673
3674
  },
3674
3675
  async ({ groupId, versionId, ruleId }) => callApi("GET", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}`)
3675
3676
  );
@@ -3738,13 +3739,13 @@ function registerRuleTools(server, callApi) {
3738
3739
 
3739
3740
  RoundingOption (optional, MUTATE_FACT only): { scale: integer (0..${MAX_ROUNDING_SCALE}), mode?: "HALF_UP"|"HALF_DOWN"|"HALF_EVEN"|"FLOOR"|"CEILING"|"DOWN"|"UP" } mode defaults to HALF_UP. When omitted, calculator output is preserved at full precision (lossless).
3740
3741
  `,
3741
- inputSchema: {
3742
- groupId: z3.string().uuid().describe("Policy group ID"),
3743
- versionId: z3.string().uuid().describe("Version ID"),
3744
- rule: z3.string().describe(
3742
+ inputSchema: z4.object({
3743
+ groupId: z4.string().uuid().describe("Policy group ID"),
3744
+ versionId: z4.string().uuid().describe("Version ID"),
3745
+ rule: z4.string().describe(
3745
3746
  "JSON string of CreateRuleRequest: { name, condition, actions, mutexGroup?, mutexMode?, mutexStrategy?, mutexLimit?, isEnabled? }"
3746
3747
  )
3747
- }
3748
+ })
3748
3749
  },
3749
3750
  async ({ groupId, versionId, rule }) => {
3750
3751
  const body = parseJson(rule);
@@ -3756,14 +3757,14 @@ function registerRuleTools(server, callApi) {
3756
3757
  {
3757
3758
  title: "Update Rule",
3758
3759
  description: "Update an existing rule in a DRAFT version. Only provided fields are changed.",
3759
- inputSchema: {
3760
- groupId: z3.string().uuid().describe("Policy group ID"),
3761
- versionId: z3.string().uuid().describe("Version ID"),
3762
- ruleId: z3.string().uuid().describe("Rule ID"),
3763
- rule: z3.string().describe(
3760
+ inputSchema: z4.object({
3761
+ groupId: z4.string().uuid().describe("Policy group ID"),
3762
+ versionId: z4.string().uuid().describe("Version ID"),
3763
+ ruleId: z4.string().uuid().describe("Rule ID"),
3764
+ rule: z4.string().describe(
3764
3765
  "JSON string of UpdateRuleRequest: { name?, condition?, actions?, mutexGroup?, mutexMode?, mutexStrategy?, mutexLimit?, isEnabled? }"
3765
3766
  )
3766
- }
3767
+ })
3767
3768
  },
3768
3769
  async ({ groupId, versionId, ruleId, rule }) => {
3769
3770
  const body = parseJson(rule);
@@ -3777,12 +3778,12 @@ function registerRuleTools(server, callApi) {
3777
3778
  {
3778
3779
  title: "Delete Rule",
3779
3780
  description: "Delete a rule from a DRAFT version.",
3780
- inputSchema: {
3781
- groupId: z3.string().uuid().describe("Policy group ID"),
3782
- versionId: z3.string().uuid().describe("Version ID"),
3783
- ruleId: z3.string().uuid().describe("Rule ID"),
3784
- force: z3.boolean().default(false).describe("Skip confirmation (for the last rule in a version)")
3785
- }
3781
+ inputSchema: z4.object({
3782
+ groupId: z4.string().uuid().describe("Policy group ID"),
3783
+ versionId: z4.string().uuid().describe("Version ID"),
3784
+ ruleId: z4.string().uuid().describe("Rule ID"),
3785
+ force: z4.boolean().default(false).describe("Skip confirmation (for the last rule in a version)")
3786
+ })
3786
3787
  },
3787
3788
  async ({ groupId, versionId, ruleId, force }) => {
3788
3789
  const params = {};
@@ -3797,11 +3798,11 @@ function registerRuleTools(server, callApi) {
3797
3798
  {
3798
3799
  title: "Reorder Rules",
3799
3800
  description: "Reorder rules by specifying rule IDs in desired order. Priorities are assigned 1...N (1-based, continuous); array index 0 = priority 1 (highest precedence).",
3800
- inputSchema: {
3801
- groupId: z3.string().uuid().describe("Policy group ID"),
3802
- versionId: z3.string().uuid().describe("Version ID"),
3803
- ruleIds: z3.array(z3.string().uuid()).describe("Rule IDs in desired priority order")
3804
- }
3801
+ inputSchema: z4.object({
3802
+ groupId: z4.string().uuid().describe("Policy group ID"),
3803
+ versionId: z4.string().uuid().describe("Version ID"),
3804
+ ruleIds: z4.array(z4.string().uuid()).describe("Rule IDs in desired priority order")
3805
+ })
3805
3806
  },
3806
3807
  async ({ groupId, versionId, ruleIds }) => {
3807
3808
  const rules = ruleIds.map((ruleId, index) => ({
@@ -3818,12 +3819,12 @@ function registerRuleTools(server, callApi) {
3818
3819
  {
3819
3820
  title: "Toggle Rule",
3820
3821
  description: "Enable or disable a rule without deleting it.",
3821
- inputSchema: {
3822
- groupId: z3.string().uuid().describe("Policy group ID"),
3823
- versionId: z3.string().uuid().describe("Version ID"),
3824
- ruleId: z3.string().uuid().describe("Rule ID"),
3825
- isEnabled: z3.boolean().describe("true to enable, false to disable")
3826
- }
3822
+ inputSchema: z4.object({
3823
+ groupId: z4.string().uuid().describe("Policy group ID"),
3824
+ versionId: z4.string().uuid().describe("Version ID"),
3825
+ ruleId: z4.string().uuid().describe("Rule ID"),
3826
+ isEnabled: z4.boolean().describe("true to enable, false to disable")
3827
+ })
3827
3828
  },
3828
3829
  async ({ groupId, versionId, ruleId, isEnabled }) => callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}/enabled`, {
3829
3830
  body: { isEnabled }
@@ -3832,7 +3833,7 @@ function registerRuleTools(server, callApi) {
3832
3833
  }
3833
3834
 
3834
3835
  // src/mcp/tools/facts.ts
3835
- import { z as z4 } from "zod";
3836
+ import { z as z5 } from "zod";
3836
3837
 
3837
3838
  // src/types/facts.ts
3838
3839
  var FACT_KEY_PATTERN = /^[a-zA-Z][a-zA-Z0-9_]*$/;
@@ -3845,11 +3846,11 @@ function registerFactTools(server, callApi) {
3845
3846
  {
3846
3847
  title: "List Fact Definitions",
3847
3848
  description: "List all fact definitions (input variable schema). Shows key, type, required, and PII status. Always check this before creating rules.",
3848
- inputSchema: {
3849
- page: z4.number().int().min(0).default(0).describe("Page number"),
3850
- size: z4.number().int().min(1).max(100).default(20).describe("Page size"),
3851
- keyword: z4.string().optional().describe("Search keyword")
3852
- }
3849
+ inputSchema: z5.object({
3850
+ page: z5.number().int().min(0).default(0).describe("Page number"),
3851
+ size: z5.number().int().min(1).max(100).default(20).describe("Page size"),
3852
+ keyword: z5.string().optional().describe("Search keyword")
3853
+ })
3853
3854
  },
3854
3855
  async ({ page, size, keyword }) => {
3855
3856
  const params = paginationParams(page, size);
@@ -3862,16 +3863,16 @@ function registerFactTools(server, callApi) {
3862
3863
  {
3863
3864
  title: "Create Fact Definition",
3864
3865
  description: "Register a new input variable. Key starts with a letter, then letters, numbers, and underscores (e.g. paymentAmount). Casing is not enforced. Types: STRING, NUMBER, BOOLEAN, LIST_STRING, LIST_NUMBER.",
3865
- inputSchema: {
3866
- key: z4.string().regex(FACT_KEY_PATTERN).describe("Variable key. Any casing; must start with a letter."),
3867
- name: z4.string().describe("Display name"),
3868
- type: z4.enum(VALUE_TYPES).describe("Value type"),
3869
- description: z4.string().optional().describe("Description"),
3870
- isRequired: z4.boolean().default(false).describe("Whether this fact is required for rule evaluation"),
3871
- isPii: z4.boolean().default(false).describe(
3866
+ inputSchema: z5.object({
3867
+ key: z5.string().regex(FACT_KEY_PATTERN).describe("Variable key. Any casing; must start with a letter."),
3868
+ name: z5.string().describe("Display name"),
3869
+ type: z5.enum(VALUE_TYPES).describe("Value type"),
3870
+ description: z5.string().optional().describe("Description"),
3871
+ isRequired: z5.boolean().default(false).describe("Whether this fact is required for rule evaluation"),
3872
+ isPii: z5.boolean().default(false).describe(
3872
3873
  "Mark as PII \u2014 masked on every read surface, revealable only in the console (audited)"
3873
3874
  )
3874
- }
3875
+ })
3875
3876
  },
3876
3877
  async (args) => callApi("POST", "schema/facts", { body: args })
3877
3878
  );
@@ -3880,16 +3881,16 @@ function registerFactTools(server, callApi) {
3880
3881
  {
3881
3882
  title: "Update Fact Definition",
3882
3883
  description: "Update a fact definition. The key is immutable. The type can change only while no rule references the fact; if any does, the call fails with FD-007 and reports the count. Only the fields you send are changed. System facts accept name, description, and PII only.",
3883
- inputSchema: {
3884
- factId: z4.string().uuid().describe("Fact definition ID"),
3885
- name: z4.string().optional().describe("Display name"),
3886
- description: z4.string().optional().describe("Description"),
3887
- type: z4.enum(VALUE_TYPES).optional().describe(
3884
+ inputSchema: z5.object({
3885
+ factId: z5.string().uuid().describe("Fact definition ID"),
3886
+ name: z5.string().optional().describe("Display name"),
3887
+ description: z5.string().optional().describe("Description"),
3888
+ type: z5.enum(VALUE_TYPES).optional().describe(
3888
3889
  "Value type. Omit to leave it unchanged. Changing it fails with FD-007 while any rule references the fact."
3889
3890
  ),
3890
- isRequired: z4.boolean().optional().describe("Required flag"),
3891
- isPii: z4.boolean().optional().describe("PII flag \u2014 enables/disables masking (changeable even on system facts)")
3892
- }
3891
+ isRequired: z5.boolean().optional().describe("Required flag"),
3892
+ isPii: z5.boolean().optional().describe("PII flag \u2014 enables/disables masking (changeable even on system facts)")
3893
+ })
3893
3894
  },
3894
3895
  async ({ factId, ...body }) => callApi("PUT", `schema/facts/${factId}`, { body })
3895
3896
  );
@@ -3898,9 +3899,9 @@ function registerFactTools(server, callApi) {
3898
3899
  {
3899
3900
  title: "Delete Fact Definition",
3900
3901
  description: "Delete a fact definition. System facts cannot be deleted. Neither can a fact that any rule references: that call fails with FD-006 and reports the count. Remove the references first.",
3901
- inputSchema: {
3902
- factId: z4.string().uuid().describe("Fact definition ID")
3903
- }
3902
+ inputSchema: z5.object({
3903
+ factId: z5.string().uuid().describe("Fact definition ID")
3904
+ })
3904
3905
  },
3905
3906
  async ({ factId }) => callApi("DELETE", `schema/facts/${factId}`)
3906
3907
  );
@@ -3909,7 +3910,7 @@ function registerFactTools(server, callApi) {
3909
3910
  {
3910
3911
  title: "Get Action Runtime Fact Metadata",
3911
3912
  description: "Retrieve runtime fact requirements per Action type. For each Action, shows which input facts must be present in the execution payload \u2014 e.g. MUTATE_FACT always requires its targetVar fact, plus refVar when one is specified. The factRequired flag describes the FACT, not the parameter: refVar is an optional parameter, but if you specify it the named fact must exist. A required fact absent at runtime throws \u2014 the engine never defaults to 0. Facts are supplied as input or written by a prior action in the same rule; only SET_FACT creates a fact from nothing. Static data, safe to cache in-session.",
3912
- inputSchema: {}
3913
+ inputSchema: z5.object({})
3913
3914
  },
3914
3915
  async () => callApi("GET", "schema/action-metadata")
3915
3916
  );
@@ -3918,10 +3919,10 @@ function registerFactTools(server, callApi) {
3918
3919
  {
3919
3920
  title: "List Unregistered Facts",
3920
3921
  description: "List facts referenced by a version's rules but not yet defined (read-only \u2014 does not block publish/deploy, INV-4). Version-wide: covers every rule in the version. Each entry carries the inferred type, suggested name, and where it is referenced (condition/action). Register them with lexq_facts_create to enable type validation and the dry-run requirements analyzer.",
3921
- inputSchema: {
3922
- groupId: z4.string().uuid().describe("Policy group ID"),
3923
- versionId: z4.string().uuid().describe("Version ID")
3924
- }
3922
+ inputSchema: z5.object({
3923
+ groupId: z5.string().uuid().describe("Policy group ID"),
3924
+ versionId: z5.string().uuid().describe("Version ID")
3925
+ })
3925
3926
  },
3926
3927
  async ({ groupId, versionId }) => callApi("GET", `policy-groups/${groupId}/versions/${versionId}/unregistered-facts`)
3927
3928
  );
@@ -3930,10 +3931,10 @@ function registerFactTools(server, callApi) {
3930
3931
  {
3931
3932
  title: "Export Fact Catalog",
3932
3933
  description: "Export the fact catalog. The two formats carry different things: CSV is the catalog as it stands, system facts included, for reading in a spreadsheet; JSON matches the shape that batch create accepts, so it can be fed straight back in, which is why it leaves out the fields that endpoint does not take. Returns the file contents as text.",
3933
- inputSchema: {
3934
- format: z4.enum(EXPORT_FORMATS).default("csv").describe("Export format"),
3935
- keyword: z4.string().optional().describe("Filter by key or name")
3936
- }
3934
+ inputSchema: z5.object({
3935
+ format: z5.enum(EXPORT_FORMATS).default("csv").describe("Export format"),
3936
+ keyword: z5.string().optional().describe("Filter by key or name")
3937
+ })
3937
3938
  },
3938
3939
  async ({ format, keyword }) => callApi("GET", "schema/facts/export", {
3939
3940
  params: keyword ? { format, keyword } : { format }
@@ -3942,18 +3943,18 @@ function registerFactTools(server, callApi) {
3942
3943
  }
3943
3944
 
3944
3945
  // src/mcp/tools/deploy.ts
3945
- import { z as z5 } from "zod";
3946
+ import { z as z6 } from "zod";
3946
3947
  function registerDeployTools(server, callApi) {
3947
3948
  server.registerTool(
3948
3949
  "lexq_deploy_publish",
3949
3950
  {
3950
3951
  title: "Publish Version",
3951
3952
  description: "Publish a DRAFT version (DRAFT \u2192 ACTIVE). Locks the version from further edits. Must have at least one rule. Undefined facts referenced by rules do not block publishing (INV-4); call lexq_facts_unregistered first to review them.",
3952
- inputSchema: {
3953
- groupId: z5.string().uuid().describe("Policy group ID"),
3954
- versionId: z5.string().uuid().describe("Version ID to publish"),
3955
- memo: z5.string().min(1).describe("Publish memo (required)")
3956
- }
3953
+ inputSchema: z6.object({
3954
+ groupId: z6.string().uuid().describe("Policy group ID"),
3955
+ versionId: z6.string().uuid().describe("Version ID to publish"),
3956
+ memo: z6.string().min(1).describe("Publish memo (required)")
3957
+ })
3957
3958
  },
3958
3959
  async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/versions/${versionId}/publish`, { body: { memo } })
3959
3960
  );
@@ -3962,11 +3963,11 @@ function registerDeployTools(server, callApi) {
3962
3963
  {
3963
3964
  title: "Deploy to Live",
3964
3965
  description: "Deploy an ACTIVE (published) version to live traffic. Takes effect immediately. Versions whose effective start date has not arrived are rejected (P-037) \u2014 use lexq_deploy_schedule for those. Undefined facts do not block deployment (INV-4); use lexq_facts_unregistered to review what the version references but has not defined.",
3965
- inputSchema: {
3966
- groupId: z5.string().uuid().describe("Policy group ID"),
3967
- versionId: z5.string().uuid().describe("Version ID to deploy"),
3968
- memo: z5.string().min(1).describe("Deployment memo (required)")
3969
- }
3966
+ inputSchema: z6.object({
3967
+ groupId: z6.string().uuid().describe("Policy group ID"),
3968
+ versionId: z6.string().uuid().describe("Version ID to deploy"),
3969
+ memo: z6.string().min(1).describe("Deployment memo (required)")
3970
+ })
3970
3971
  },
3971
3972
  async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/deploy`, {
3972
3973
  body: { versionId, memo }
@@ -3977,10 +3978,10 @@ function registerDeployTools(server, callApi) {
3977
3978
  {
3978
3979
  title: "Rollback Deployment",
3979
3980
  description: "Rollback to the previous deployed version. Only available if there is a previous version.",
3980
- inputSchema: {
3981
- groupId: z5.string().uuid().describe("Policy group ID"),
3982
- memo: z5.string().min(1).describe("Rollback reason (required)")
3983
- }
3981
+ inputSchema: z6.object({
3982
+ groupId: z6.string().uuid().describe("Policy group ID"),
3983
+ memo: z6.string().min(1).describe("Rollback reason (required)")
3984
+ })
3984
3985
  },
3985
3986
  async ({ groupId, memo }) => callApi("POST", `policy-groups/${groupId}/rollback`, {
3986
3987
  body: { memo }
@@ -3991,10 +3992,10 @@ function registerDeployTools(server, callApi) {
3991
3992
  {
3992
3993
  title: "Undeploy",
3993
3994
  description: "Remove the live version from traffic. The version stays ACTIVE but no longer serves requests.",
3994
- inputSchema: {
3995
- groupId: z5.string().uuid().describe("Policy group ID"),
3996
- memo: z5.string().min(1).describe("Undeploy reason (required)")
3997
- }
3995
+ inputSchema: z6.object({
3996
+ groupId: z6.string().uuid().describe("Policy group ID"),
3997
+ memo: z6.string().min(1).describe("Undeploy reason (required)")
3998
+ })
3998
3999
  },
3999
4000
  async ({ groupId, memo }) => callApi("POST", `policy-groups/${groupId}/undeploy`, {
4000
4001
  body: { memo }
@@ -4005,11 +4006,11 @@ function registerDeployTools(server, callApi) {
4005
4006
  {
4006
4007
  title: "Schedule Deployment",
4007
4008
  description: "Schedule an ACTIVE version with a future effective start date to auto-deploy at that time (Scheduled Deployment). One pending schedule per group; manual deploy/rollback/undeploy, starting an A/B test, or archiving the group cancels it. The snapshot hash is sealed at scheduling and re-verified at execution (fail-closed).",
4008
- inputSchema: {
4009
- groupId: z5.string().uuid().describe("Policy group ID"),
4010
- versionId: z5.string().uuid().describe("ACTIVE version ID with a future effective start date"),
4011
- memo: z5.string().min(1).describe("Schedule memo (required)")
4012
- }
4009
+ inputSchema: z6.object({
4010
+ groupId: z6.string().uuid().describe("Policy group ID"),
4011
+ versionId: z6.string().uuid().describe("ACTIVE version ID with a future effective start date"),
4012
+ memo: z6.string().min(1).describe("Schedule memo (required)")
4013
+ })
4013
4014
  },
4014
4015
  async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/schedule`, {
4015
4016
  body: { versionId, memo }
@@ -4020,9 +4021,9 @@ function registerDeployTools(server, callApi) {
4020
4021
  {
4021
4022
  title: "Cancel Scheduled Deployment",
4022
4023
  description: "Cancel the pending scheduled deployment for a group. The version itself is not affected. Fails with P-039 if no pending schedule exists.",
4023
- inputSchema: {
4024
- groupId: z5.string().uuid().describe("Policy group ID")
4025
- }
4024
+ inputSchema: z6.object({
4025
+ groupId: z6.string().uuid().describe("Policy group ID")
4026
+ })
4026
4027
  },
4027
4028
  async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}/schedule`)
4028
4029
  );
@@ -4031,10 +4032,10 @@ function registerDeployTools(server, callApi) {
4031
4032
  {
4032
4033
  title: "List Scheduled Deployments",
4033
4034
  description: "List scheduled deployments across all groups (all statuses: PENDING, EXECUTED, CANCELED, FAILED), newest first.",
4034
- inputSchema: {
4035
- page: z5.number().int().min(0).default(0).describe("Page number"),
4036
- size: z5.number().int().min(1).max(100).default(20).describe("Page size")
4037
- }
4035
+ inputSchema: z6.object({
4036
+ page: z6.number().int().min(0).default(0).describe("Page number"),
4037
+ size: z6.number().int().min(1).max(100).default(20).describe("Page size")
4038
+ })
4038
4039
  },
4039
4040
  async ({ page, size }) => callApi("GET", "policy-groups/schedules", { params: paginationParams(page, size) })
4040
4041
  );
@@ -4043,14 +4044,14 @@ function registerDeployTools(server, callApi) {
4043
4044
  {
4044
4045
  title: "Deployment History",
4045
4046
  description: "List deployment history across all groups.",
4046
- inputSchema: {
4047
- page: z5.number().int().min(0).default(0).describe("Page number"),
4048
- size: z5.number().int().min(1).max(100).default(20).describe("Page size"),
4049
- groupId: z5.string().uuid().optional().describe("Filter by group ID"),
4050
- types: z5.string().optional().describe("Filter by deployment types (comma-separated: DEPLOY,ROLLBACK,UNDEPLOY)"),
4051
- startDate: z5.string().optional().describe("Start date (yyyy-MM-dd)"),
4052
- endDate: z5.string().optional().describe("End date (yyyy-MM-dd)")
4053
- }
4047
+ inputSchema: z6.object({
4048
+ page: z6.number().int().min(0).default(0).describe("Page number"),
4049
+ size: z6.number().int().min(1).max(100).default(20).describe("Page size"),
4050
+ groupId: z6.string().uuid().optional().describe("Filter by group ID"),
4051
+ types: z6.string().optional().describe("Filter by deployment types (comma-separated: DEPLOY,ROLLBACK,UNDEPLOY)"),
4052
+ startDate: z6.string().optional().describe("Start date (yyyy-MM-dd)"),
4053
+ endDate: z6.string().optional().describe("End date (yyyy-MM-dd)")
4054
+ })
4054
4055
  },
4055
4056
  async ({ page, size, groupId, types, startDate, endDate }) => {
4056
4057
  const params = paginationParams(page, size);
@@ -4066,9 +4067,9 @@ function registerDeployTools(server, callApi) {
4066
4067
  {
4067
4068
  title: "Deployment Detail",
4068
4069
  description: "Get detailed info about a specific deployment including snapshot hash and integrity check.",
4069
- inputSchema: {
4070
- deploymentId: z5.string().uuid().describe("Deployment ID")
4071
- }
4070
+ inputSchema: z6.object({
4071
+ deploymentId: z6.string().uuid().describe("Deployment ID")
4072
+ })
4072
4073
  },
4073
4074
  async ({ deploymentId }) => callApi("GET", `deployments/${deploymentId}`)
4074
4075
  );
@@ -4077,7 +4078,7 @@ function registerDeployTools(server, callApi) {
4077
4078
  {
4078
4079
  title: "Deployment Overview",
4079
4080
  description: "Show current deployment status of all groups \u2014 which version is live, last deployment type, and deployer.",
4080
- inputSchema: {}
4081
+ inputSchema: z6.object({})
4081
4082
  },
4082
4083
  async () => callApi("GET", "deployments/overview")
4083
4084
  );
@@ -4086,9 +4087,9 @@ function registerDeployTools(server, callApi) {
4086
4087
  {
4087
4088
  title: "List Deployable Versions",
4088
4089
  description: "List ACTIVE (published) versions that can be deployed for a group. Use this to find which versions are available before calling deploy live.",
4089
- inputSchema: {
4090
- groupId: z5.string().uuid().describe("Policy group ID")
4091
- }
4090
+ inputSchema: z6.object({
4091
+ groupId: z6.string().uuid().describe("Policy group ID")
4092
+ })
4092
4093
  },
4093
4094
  async ({ groupId }) => callApi("GET", `deployments/groups/${groupId}/deployable-versions`)
4094
4095
  );
@@ -4097,10 +4098,10 @@ function registerDeployTools(server, callApi) {
4097
4098
  {
4098
4099
  title: "Deployment Diff",
4099
4100
  description: "Compare rule snapshots between two versions. Shows added, removed, and modified rules. Useful for reviewing changes before deploying a new version.",
4100
- inputSchema: {
4101
- baseVersionId: z5.string().uuid().describe("Base version ID (typically the current live)"),
4102
- targetVersionId: z5.string().uuid().describe("Target version ID (the one you want to deploy)")
4103
- }
4101
+ inputSchema: z6.object({
4102
+ baseVersionId: z6.string().uuid().describe("Base version ID (typically the current live)"),
4103
+ targetVersionId: z6.string().uuid().describe("Target version ID (the one you want to deploy)")
4104
+ })
4104
4105
  },
4105
4106
  async ({ baseVersionId, targetVersionId }) => callApi("GET", "deployments/diff", {
4106
4107
  params: { baseVersionId, targetVersionId }
@@ -4109,7 +4110,7 @@ function registerDeployTools(server, callApi) {
4109
4110
  }
4110
4111
 
4111
4112
  // src/mcp/tools/analytics.ts
4112
- import { z as z6 } from "zod";
4113
+ import { z as z7 } from "zod";
4113
4114
  import dedent16 from "dedent";
4114
4115
  function registerAnalyticsTools(server, callApi) {
4115
4116
  server.registerTool(
@@ -4128,11 +4129,11 @@ function registerAnalyticsTools(server, callApi) {
4128
4129
 
4129
4130
  Example input: { "facts": { "paymentAmount": 100000, "customerTier": "VIP" } }
4130
4131
  Always dry-run before publishing to validate rule behavior.`,
4131
- inputSchema: {
4132
- versionId: z6.string().uuid().describe("Policy version ID to test against"),
4133
- facts: z6.string().describe('JSON string of facts object, e.g. {"paymentAmount":100000}'),
4134
- includeDebugInfo: z6.boolean().default(true).describe("Include execution and decision traces")
4135
- }
4132
+ inputSchema: z7.object({
4133
+ versionId: z7.string().uuid().describe("Policy version ID to test against"),
4134
+ facts: z7.string().describe('JSON string of facts object, e.g. {"paymentAmount":100000}'),
4135
+ includeDebugInfo: z7.boolean().default(true).describe("Include execution and decision traces")
4136
+ })
4136
4137
  },
4137
4138
  async ({ versionId, facts, includeDebugInfo }) => {
4138
4139
  const parsedFacts = parseJson(facts);
@@ -4152,11 +4153,11 @@ function registerAnalyticsTools(server, callApi) {
4152
4153
  resultA / resultB — full DryRunResponse for each version
4153
4154
  diff.mutatedDiff — changes in mutatedFacts between A and B (key → {before, after})
4154
4155
  diff.generatedDiff — changes in generatedVariables between A and B`,
4155
- inputSchema: {
4156
- versionIdA: z6.string().uuid().describe("Baseline version ID"),
4157
- versionIdB: z6.string().uuid().describe("Candidate version ID"),
4158
- facts: z6.string().describe("JSON string of facts object")
4159
- }
4156
+ inputSchema: z7.object({
4157
+ versionIdA: z7.string().uuid().describe("Baseline version ID"),
4158
+ versionIdB: z7.string().uuid().describe("Candidate version ID"),
4159
+ facts: z7.string().describe("JSON string of facts object")
4160
+ })
4160
4161
  },
4161
4162
  async ({ versionIdA, versionIdB, facts }) => {
4162
4163
  const parsedFacts = parseJson(facts);
@@ -4170,10 +4171,10 @@ function registerAnalyticsTools(server, callApi) {
4170
4171
  {
4171
4172
  title: "Analyze Requirements",
4172
4173
  description: "Analyze which input facts a version requires. Returns required keys, types, and an example request body.",
4173
- inputSchema: {
4174
- groupId: z6.string().uuid().describe("Policy group ID"),
4175
- versionId: z6.string().uuid().describe("Version ID")
4176
- }
4174
+ inputSchema: z7.object({
4175
+ groupId: z7.string().uuid().describe("Policy group ID"),
4176
+ versionId: z7.string().uuid().describe("Version ID")
4177
+ })
4177
4178
  },
4178
4179
  async ({ groupId, versionId }) => callApi("GET", `analytics/groups/${groupId}/versions/${versionId}/requirements`)
4179
4180
  );
@@ -4209,9 +4210,9 @@ function registerAnalyticsTools(server, callApi) {
4209
4210
  "options": { "baselinePolicyVersionId": "<uuid>", "includeRuleStats": true }
4210
4211
  }
4211
4212
  `,
4212
- inputSchema: {
4213
- body: z6.string().describe("JSON string of SimulationRequest")
4214
- }
4213
+ inputSchema: z7.object({
4214
+ body: z7.string().describe("JSON string of SimulationRequest")
4215
+ })
4215
4216
  },
4216
4217
  async ({ body }) => {
4217
4218
  const parsed = parseJson(body);
@@ -4223,9 +4224,9 @@ function registerAnalyticsTools(server, callApi) {
4223
4224
  {
4224
4225
  title: "Simulation Status",
4225
4226
  description: "Get simulation status and results. Poll until status is COMPLETED or FAILED.",
4226
- inputSchema: {
4227
- simulationId: z6.string().uuid().describe("Simulation ID")
4228
- }
4227
+ inputSchema: z7.object({
4228
+ simulationId: z7.string().uuid().describe("Simulation ID")
4229
+ })
4229
4230
  },
4230
4231
  async ({ simulationId }) => callApi("GET", `analytics/simulations/${simulationId}`)
4231
4232
  );
@@ -4234,13 +4235,13 @@ function registerAnalyticsTools(server, callApi) {
4234
4235
  {
4235
4236
  title: "List Simulations",
4236
4237
  description: "List simulation history with optional filters.",
4237
- inputSchema: {
4238
- page: z6.number().int().min(0).default(0).describe("Page number"),
4239
- size: z6.number().int().min(1).max(100).default(20).describe("Page size"),
4240
- status: z6.enum(["PENDING", "RUNNING", "COMPLETED", "FAILED", "CANCELED"]).optional().describe("Filter by status"),
4241
- from: z6.string().optional().describe("Start date (yyyy-MM-dd)"),
4242
- to: z6.string().optional().describe("End date (yyyy-MM-dd)")
4243
- }
4238
+ inputSchema: z7.object({
4239
+ page: z7.number().int().min(0).default(0).describe("Page number"),
4240
+ size: z7.number().int().min(1).max(100).default(20).describe("Page size"),
4241
+ status: z7.enum(["PENDING", "RUNNING", "COMPLETED", "FAILED", "CANCELED"]).optional().describe("Filter by status"),
4242
+ from: z7.string().optional().describe("Start date (yyyy-MM-dd)"),
4243
+ to: z7.string().optional().describe("End date (yyyy-MM-dd)")
4244
+ })
4244
4245
  },
4245
4246
  async ({ page, size, status, from, to }) => {
4246
4247
  const params = paginationParams(page, size);
@@ -4255,9 +4256,9 @@ function registerAnalyticsTools(server, callApi) {
4255
4256
  {
4256
4257
  title: "Cancel Simulation",
4257
4258
  description: "Cancel a running or pending simulation.",
4258
- inputSchema: {
4259
- simulationId: z6.string().uuid().describe("Simulation ID")
4260
- }
4259
+ inputSchema: z7.object({
4260
+ simulationId: z7.string().uuid().describe("Simulation ID")
4261
+ })
4261
4262
  },
4262
4263
  async ({ simulationId }) => callApi("DELETE", `analytics/simulations/${simulationId}`)
4263
4264
  );
@@ -4266,10 +4267,10 @@ function registerAnalyticsTools(server, callApi) {
4266
4267
  {
4267
4268
  title: "Export Simulation",
4268
4269
  description: "Export simulation results as JSON or CSV. Returns the raw data.",
4269
- inputSchema: {
4270
- simulationId: z6.string().uuid().describe("Simulation ID"),
4271
- format: z6.enum(EXPORT_FORMATS).default("json").describe("Export format")
4272
- }
4270
+ inputSchema: z7.object({
4271
+ simulationId: z7.string().uuid().describe("Simulation ID"),
4272
+ format: z7.enum(EXPORT_FORMATS).default("json").describe("Export format")
4273
+ })
4273
4274
  },
4274
4275
  async ({ simulationId, format }) => callApi("GET", `analytics/simulations/${simulationId}/export`, {
4275
4276
  params: { format }
@@ -4293,10 +4294,10 @@ function registerAnalyticsTools(server, callApi) {
4293
4294
 
4294
4295
  JSON example: [{"userId":"user_001","paymentAmount":150000}, {"userId":"user_002","paymentAmount":50000}]
4295
4296
  `,
4296
- inputSchema: {
4297
- content: z6.string().describe("CSV or JSON content as string"),
4298
- filename: z6.string().default("dataset.csv").describe("Filename with extension (.csv or .json)")
4299
- }
4297
+ inputSchema: z7.object({
4298
+ content: z7.string().describe("CSV or JSON content as string"),
4299
+ filename: z7.string().default("dataset.csv").describe("Filename with extension (.csv or .json)")
4300
+ })
4300
4301
  },
4301
4302
  async ({ content, filename }) => {
4302
4303
  const result = await callApi("POST", "analytics/datasets/upload", {
@@ -4323,11 +4324,11 @@ function registerAnalyticsTools(server, callApi) {
4323
4324
  {
4324
4325
  title: "Download Dataset Template",
4325
4326
  description: "Generate a sample CSV or JSON template based on the required facts of a version. Use this to understand the expected data format before uploading a dataset.",
4326
- inputSchema: {
4327
- groupId: z6.string().uuid().describe("Policy group ID"),
4328
- versionId: z6.string().uuid().describe("Version ID"),
4329
- format: z6.enum(EXPORT_FORMATS).default("csv").describe("Template format")
4330
- }
4327
+ inputSchema: z7.object({
4328
+ groupId: z7.string().uuid().describe("Policy group ID"),
4329
+ versionId: z7.string().uuid().describe("Version ID"),
4330
+ format: z7.enum(EXPORT_FORMATS).default("csv").describe("Template format")
4331
+ })
4331
4332
  },
4332
4333
  async ({ groupId, versionId, format }) => callApi("GET", `analytics/groups/${groupId}/versions/${versionId}/dataset-template`, {
4333
4334
  params: { format }
@@ -4336,7 +4337,7 @@ function registerAnalyticsTools(server, callApi) {
4336
4337
  }
4337
4338
 
4338
4339
  // src/mcp/tools/profile.ts
4339
- import { z as z7 } from "zod";
4340
+ import { z as z8 } from "zod";
4340
4341
  var RELATIVE_THRESHOLD = `flagged = p50 \u2265 ${SLOW_MULTIPLIER}\xD7 median of per-rule p50s within the group; absolute thresholds are intentionally not supported.`;
4341
4342
  function profileParams(opts) {
4342
4343
  const params = {};
@@ -4352,15 +4353,15 @@ function registerProfileTools(server, callApi) {
4352
4353
  {
4353
4354
  title: "Group Latency Profile",
4354
4355
  description: "Per-rule latency profile of a policy group over a time window: group TOTAL distribution split by cache state (HIT = compiled ruleset cache hit, MISS = deep-load + compile), a per-rule CONDITION/ACTION percentile table, and slow-rule flags. " + RELATIVE_THRESHOLD + ` Every percentile is accompanied by its sample count n; a percentile is withheld (null) unless n\xD7(1\u2212q) \u2265 ${TAIL_MIN_OBS} (p50 needs n \u2265 6, p95 n \u2265 60, p99 n \u2265 300 \u2014 display gate, separate from the n \u2265 ${MIN_SAMPLES} judgment gate). Baselines report INSUFFICIENT_COHORT when fewer than ${MIN_COHORT_SIZE} rules qualify. Rule detail comes from a deterministic ${PROFILE_SAMPLE_PERMILLE / 10}% sample of calls; TOTAL is recorded for every call. Defaults: last ${PROFILE_DEFAULT_WINDOW_HOURS}h, live version, cacheState HIT.`,
4355
- inputSchema: {
4356
- groupId: z7.string().uuid().describe("Policy group ID"),
4357
- versionId: z7.string().uuid().optional().describe("Version to inspect (default: live version)"),
4358
- from: z7.string().optional().describe(
4356
+ inputSchema: z8.object({
4357
+ groupId: z8.string().uuid().describe("Policy group ID"),
4358
+ versionId: z8.string().uuid().optional().describe("Version to inspect (default: live version)"),
4359
+ from: z8.string().optional().describe(
4359
4360
  `Window start, ISO-8601 instant (e.g. 2026-07-01T00:00:00Z). Default: ${PROFILE_DEFAULT_WINDOW_HOURS}h ago`
4360
4361
  ),
4361
- to: z7.string().optional().describe("Window end, ISO-8601 instant. Default: now"),
4362
- cacheState: z7.enum(["HIT", "MISS"]).optional().describe("Cache dimension for the rule table and judgment (default: HIT)")
4363
- }
4362
+ to: z8.string().optional().describe("Window end, ISO-8601 instant. Default: now"),
4363
+ cacheState: z8.enum(["HIT", "MISS"]).optional().describe("Cache dimension for the rule table and judgment (default: HIT)")
4364
+ })
4364
4365
  },
4365
4366
  async ({ groupId, versionId, from, to, cacheState }) => callApi("GET", `policy-groups/${groupId}/profile`, {
4366
4367
  params: profileParams({ versionId, from, to, cacheState })
@@ -4371,15 +4372,15 @@ function registerProfileTools(server, callApi) {
4371
4372
  {
4372
4373
  title: "Rule Latency Detail",
4373
4374
  description: `Single-rule latency detail: merged phase \xD7 cacheState distributions plus a per-window time series (${LATENCY_WINDOW_MILLIS / 1e3}s windows). Missing windows are genuine gaps \u2014 never interpolated. Series points carry each window's own values; percentiles in merged distributions are withheld (null) unless n\xD7(1\u2212q) \u2265 ${TAIL_MIN_OBS} (p50 n \u2265 6, p95 n \u2265 60, p99 n \u2265 300). ` + RELATIVE_THRESHOLD,
4374
- inputSchema: {
4375
- groupId: z7.string().uuid().describe("Policy group ID"),
4376
- ruleId: z7.string().uuid().describe("Rule ID (from lexq_profile_overview)"),
4377
- versionId: z7.string().uuid().optional().describe("Version to inspect (default: live version)"),
4378
- from: z7.string().optional().describe(
4375
+ inputSchema: z8.object({
4376
+ groupId: z8.string().uuid().describe("Policy group ID"),
4377
+ ruleId: z8.string().uuid().describe("Rule ID (from lexq_profile_overview)"),
4378
+ versionId: z8.string().uuid().optional().describe("Version to inspect (default: live version)"),
4379
+ from: z8.string().optional().describe(
4379
4380
  `Window start, ISO-8601 instant. Default: ${PROFILE_DEFAULT_WINDOW_HOURS}h ago`
4380
4381
  ),
4381
- to: z7.string().optional().describe("Window end, ISO-8601 instant. Default: now")
4382
- }
4382
+ to: z8.string().optional().describe("Window end, ISO-8601 instant. Default: now")
4383
+ })
4383
4384
  },
4384
4385
  async ({ groupId, ruleId, versionId, from, to }) => callApi("GET", `policy-groups/${groupId}/profile/rules/${ruleId}`, {
4385
4386
  params: profileParams({ versionId, from, to })
@@ -4388,17 +4389,17 @@ function registerProfileTools(server, callApi) {
4388
4389
  }
4389
4390
 
4390
4391
  // src/mcp/tools/replay.ts
4391
- import { z as z8 } from "zod";
4392
+ import { z as z9 } from "zod";
4392
4393
  function registerReplayTools(server, callApi) {
4393
4394
  server.registerTool(
4394
4395
  "lexq_replay_decision",
4395
4396
  {
4396
4397
  title: "Replay a Decision",
4397
4398
  description: "Re-evaluate a past execution (traceId) against a candidate version and return the decision diff (decisionChanged, effect changes, fired rules) plus a determinism verdict. Synchronous and free of charge (TPS throttle only). A replay sends no webhook, notification, or event: rule actions produce no outward effects.",
4398
- inputSchema: {
4399
- traceId: z8.string().describe("Trace ID of the past execution to replay"),
4400
- candidateVersionId: z8.string().uuid().describe("Version to re-evaluate against")
4401
- }
4399
+ inputSchema: z9.object({
4400
+ traceId: z9.string().describe("Trace ID of the past execution to replay"),
4401
+ candidateVersionId: z9.string().uuid().describe("Version to re-evaluate against")
4402
+ })
4402
4403
  },
4403
4404
  async ({ traceId, candidateVersionId }) => callApi("POST", "replay/decisions", { body: { traceId, candidateVersionId } })
4404
4405
  );
@@ -4407,14 +4408,14 @@ function registerReplayTools(server, callApi) {
4407
4408
  {
4408
4409
  title: "Start Window Replay (Blast Radius)",
4409
4410
  description: "Submit an async job that replays a date window of past executions against a candidate version and measures the blast radius (how many decisions change). Billed per replayed record (REPLAY metric); VIEWER role cannot submit. Poll with lexq_replay_status.",
4410
- inputSchema: {
4411
- candidateVersionId: z8.string().uuid().describe("Version to re-evaluate against"),
4412
- from: z8.string().describe("Window start date (yyyy-MM-dd)"),
4413
- to: z8.string().describe("Window end date (yyyy-MM-dd)"),
4414
- maxRecords: z8.number().int().min(1).optional().describe(
4411
+ inputSchema: z9.object({
4412
+ candidateVersionId: z9.string().uuid().describe("Version to re-evaluate against"),
4413
+ from: z9.string().describe("Window start date (yyyy-MM-dd)"),
4414
+ to: z9.string().describe("Window end date (yyyy-MM-dd)"),
4415
+ maxRecords: z9.number().int().min(1).optional().describe(
4415
4416
  `Sample cap (server default applies; hard cap ${REPLAY_WINDOW_MAX_RECORDS / 1e3}k)`
4416
4417
  )
4417
- }
4418
+ })
4418
4419
  },
4419
4420
  async ({ candidateVersionId, from, to, maxRecords }) => callApi("POST", "replay/jobs", { body: { candidateVersionId, from, to, maxRecords } })
4420
4421
  );
@@ -4423,9 +4424,9 @@ function registerReplayTools(server, callApi) {
4423
4424
  {
4424
4425
  title: "Get Replay Job Status",
4425
4426
  description: "Poll a window replay job. RUNNING shows progress 0\u2013100; COMPLETED fills summary and changedSamples; FAILED carries errorMessage. capped=true means the window exceeded the sample cap and only part was replayed.",
4426
- inputSchema: {
4427
- jobId: z8.string().describe("Replay job ID from lexq_replay_start")
4428
- }
4427
+ inputSchema: z9.object({
4428
+ jobId: z9.string().describe("Replay job ID from lexq_replay_start")
4429
+ })
4429
4430
  },
4430
4431
  async ({ jobId }) => callApi("GET", `replay/jobs/${jobId}`)
4431
4432
  );
@@ -4434,10 +4435,10 @@ function registerReplayTools(server, callApi) {
4434
4435
  {
4435
4436
  title: "List Replay Jobs",
4436
4437
  description: "List window replay job history (reverse-chronological). Lightweight items \u2014 use lexq_replay_status for summary and changed samples.",
4437
- inputSchema: {
4438
- page: z8.number().int().min(0).default(0).describe("Page number"),
4439
- size: z8.number().int().min(1).max(100).default(20).describe("Page size")
4440
- }
4438
+ inputSchema: z9.object({
4439
+ page: z9.number().int().min(0).default(0).describe("Page number"),
4440
+ size: z9.number().int().min(1).max(100).default(20).describe("Page size")
4441
+ })
4441
4442
  },
4442
4443
  async ({ page, size }) => callApi("GET", "replay/jobs", { params: paginationParams(page, size) })
4443
4444
  );
@@ -4446,9 +4447,9 @@ function registerReplayTools(server, callApi) {
4446
4447
  {
4447
4448
  title: "Cancel Replay Job",
4448
4449
  description: "Cooperatively cancel a PENDING or RUNNING window replay job. Other states are rejected. VIEWER role cannot cancel.",
4449
- inputSchema: {
4450
- jobId: z8.string().describe("Replay job ID")
4451
- }
4450
+ inputSchema: z9.object({
4451
+ jobId: z9.string().describe("Replay job ID")
4452
+ })
4452
4453
  },
4453
4454
  async ({ jobId }) => callApi("POST", `replay/jobs/${jobId}/cancel`)
4454
4455
  );
@@ -4457,33 +4458,33 @@ function registerReplayTools(server, callApi) {
4457
4458
  {
4458
4459
  title: "Export Replay Result",
4459
4460
  description: "Export a COMPLETED window replay job. A running job is rejected \u2014 a partial result reads as the whole thing on the receiving end. The two formats carry different things: CSV holds the effect blast radius, whose columns are fixed; JSON holds the changed samples and action parameters, which nest and whose keys differ per tenant. JSON is not a superset of CSV. Returns the file contents as text.",
4460
- inputSchema: {
4461
- jobId: z8.string().describe("Replay job ID"),
4462
- format: z8.enum(EXPORT_FORMATS).default("json").describe("Export format")
4463
- }
4461
+ inputSchema: z9.object({
4462
+ jobId: z9.string().describe("Replay job ID"),
4463
+ format: z9.enum(EXPORT_FORMATS).default("json").describe("Export format")
4464
+ })
4464
4465
  },
4465
4466
  async ({ jobId, format }) => callApi("GET", `replay/jobs/${jobId}/export`, { params: { format } })
4466
4467
  );
4467
4468
  }
4468
4469
 
4469
4470
  // src/mcp/tools/history.ts
4470
- import { z as z9 } from "zod";
4471
+ import { z as z10 } from "zod";
4471
4472
  function registerHistoryTools(server, callApi) {
4472
4473
  server.registerTool(
4473
4474
  "lexq_history_list",
4474
4475
  {
4475
4476
  title: "List Execution History",
4476
4477
  description: "List policy execution history. Shows trace ID, group, version, status, match result, and latency.",
4477
- inputSchema: {
4478
- page: z9.number().int().min(0).default(0).describe("Page number"),
4479
- size: z9.number().int().min(1).max(100).default(20).describe("Page size"),
4480
- traceId: z9.string().optional().describe("Filter by trace ID"),
4481
- groupId: z9.string().uuid().optional().describe("Filter by policy group"),
4482
- versionId: z9.string().uuid().optional().describe("Filter by version"),
4483
- status: z9.enum(["SUCCESS", "NO_MATCH", "ERROR", "TIMEOUT"]).optional().describe("Filter by execution status"),
4484
- startDate: z9.string().optional().describe("Start date (yyyy-MM-dd)"),
4485
- endDate: z9.string().optional().describe("End date (yyyy-MM-dd)")
4486
- }
4478
+ inputSchema: z10.object({
4479
+ page: z10.number().int().min(0).default(0).describe("Page number"),
4480
+ size: z10.number().int().min(1).max(100).default(20).describe("Page size"),
4481
+ traceId: z10.string().optional().describe("Filter by trace ID"),
4482
+ groupId: z10.string().uuid().optional().describe("Filter by policy group"),
4483
+ versionId: z10.string().uuid().optional().describe("Filter by version"),
4484
+ status: z10.enum(["SUCCESS", "NO_MATCH", "ERROR", "TIMEOUT"]).optional().describe("Filter by execution status"),
4485
+ startDate: z10.string().optional().describe("Start date (yyyy-MM-dd)"),
4486
+ endDate: z10.string().optional().describe("End date (yyyy-MM-dd)")
4487
+ })
4487
4488
  },
4488
4489
  async ({ page, size, traceId, groupId, versionId, status, startDate, endDate }) => {
4489
4490
  const params = paginationParams(page, size);
@@ -4501,9 +4502,9 @@ function registerHistoryTools(server, callApi) {
4501
4502
  {
4502
4503
  title: "Get Execution Detail",
4503
4504
  description: "Get full execution detail including inputFacts, mutatedFacts, generatedVariables, executionTraces, and decisionTraces.",
4504
- inputSchema: {
4505
- traceId: z9.string().describe("Trace ID from execution history")
4506
- }
4505
+ inputSchema: z10.object({
4506
+ traceId: z10.string().describe("Trace ID from execution history")
4507
+ })
4507
4508
  },
4508
4509
  async ({ traceId }) => callApi("GET", `execution/history/${traceId}`)
4509
4510
  );
@@ -4512,11 +4513,11 @@ function registerHistoryTools(server, callApi) {
4512
4513
  {
4513
4514
  title: "Execution Statistics",
4514
4515
  description: "Get execution KPIs: total executions, success/failure counts, success rate, and average latency.",
4515
- inputSchema: {
4516
- groupId: z9.string().uuid().optional().describe("Filter by policy group"),
4517
- startDate: z9.string().optional().describe("Start date (yyyy-MM-dd)"),
4518
- endDate: z9.string().optional().describe("End date (yyyy-MM-dd)")
4519
- }
4516
+ inputSchema: z10.object({
4517
+ groupId: z10.string().uuid().optional().describe("Filter by policy group"),
4518
+ startDate: z10.string().optional().describe("Start date (yyyy-MM-dd)"),
4519
+ endDate: z10.string().optional().describe("End date (yyyy-MM-dd)")
4520
+ })
4520
4521
  },
4521
4522
  async ({ groupId, startDate, endDate }) => {
4522
4523
  const params = {};
@@ -4529,16 +4530,16 @@ function registerHistoryTools(server, callApi) {
4529
4530
  }
4530
4531
 
4531
4532
  // src/mcp/tools/provenance.ts
4532
- import { z as z10 } from "zod";
4533
+ import { z as z11 } from "zod";
4533
4534
  function registerProvenanceTools(server, callApi) {
4534
4535
  server.registerTool(
4535
4536
  "lexq_provenance_get",
4536
4537
  {
4537
4538
  title: "Get Decision Provenance",
4538
4539
  description: "Get the lineage of a single decision: what was decided, deterministic why per rule, input facts (PII facts are masked as \u2022\u2022\u2022\u2022\u2022\u2022 with maskedKeys listing them \u2014 values are revealable only in the console, audited), the authored/published/deployed responsibility chain, and the rule snapshot fingerprint.",
4539
- inputSchema: {
4540
- traceId: z10.string().describe("Trace ID of the execution")
4541
- }
4540
+ inputSchema: z11.object({
4541
+ traceId: z11.string().describe("Trace ID of the execution")
4542
+ })
4542
4543
  },
4543
4544
  async ({ traceId }) => callApi("GET", `provenance/${traceId}`)
4544
4545
  );
@@ -4547,15 +4548,15 @@ function registerProvenanceTools(server, callApi) {
4547
4548
  {
4548
4549
  title: "List PII Reveal Audits",
4549
4550
  description: "List the PII reveal audit ledger \u2014 who revealed which fact of which trace, and when. Metadata only; revealed values are never stored or returned. Use for monthly access-log inspection and SIEM collection.",
4550
- inputSchema: {
4551
- page: z10.number().int().min(0).default(0).describe("Page number"),
4552
- size: z10.number().int().min(1).max(100).default(20).describe("Page size"),
4553
- traceId: z10.string().optional().describe("Filter by trace ID (exact match)"),
4554
- revealedBy: z10.string().optional().describe("Filter by operator ID (exact match)"),
4555
- factKey: z10.string().optional().describe("Filter by fact key (partial match, case-insensitive)"),
4556
- startDate: z10.string().optional().describe("Start date (yyyy-MM-dd)"),
4557
- endDate: z10.string().optional().describe("End date (yyyy-MM-dd)")
4558
- }
4551
+ inputSchema: z11.object({
4552
+ page: z11.number().int().min(0).default(0).describe("Page number"),
4553
+ size: z11.number().int().min(1).max(100).default(20).describe("Page size"),
4554
+ traceId: z11.string().optional().describe("Filter by trace ID (exact match)"),
4555
+ revealedBy: z11.string().optional().describe("Filter by operator ID (exact match)"),
4556
+ factKey: z11.string().optional().describe("Filter by fact key (partial match, case-insensitive)"),
4557
+ startDate: z11.string().optional().describe("Start date (yyyy-MM-dd)"),
4558
+ endDate: z11.string().optional().describe("End date (yyyy-MM-dd)")
4559
+ })
4559
4560
  },
4560
4561
  async ({ page, size, traceId, revealedBy, factKey, startDate, endDate }) => {
4561
4562
  const params = paginationParams(page, size);
@@ -4570,22 +4571,22 @@ function registerProvenanceTools(server, callApi) {
4570
4571
  }
4571
4572
 
4572
4573
  // src/mcp/tools/logs.ts
4573
- import { z as z11 } from "zod";
4574
+ import { z as z12 } from "zod";
4574
4575
  function registerLogTools(server, callApi) {
4575
4576
  server.registerTool(
4576
4577
  "lexq_logs_list",
4577
4578
  {
4578
4579
  title: "List Failure Logs",
4579
4580
  description: "List system failure logs from background tasks (platform event webhooks, scheduled deployments).",
4580
- inputSchema: {
4581
- page: z11.number().int().min(0).default(0).describe("Page number"),
4582
- size: z11.number().int().min(1).max(100).default(20).describe("Page size"),
4583
- taskType: z11.enum(TaskType).optional().describe("Task type"),
4584
- status: z11.enum(FailureStatus).optional().describe("Log status"),
4585
- keyword: z11.string().optional().describe("Search in refId, refSubId, errorMessage"),
4586
- startDate: z11.string().optional().describe("Start date (yyyy-MM-dd)"),
4587
- endDate: z11.string().optional().describe("End date (yyyy-MM-dd)")
4588
- }
4581
+ inputSchema: z12.object({
4582
+ page: z12.number().int().min(0).default(0).describe("Page number"),
4583
+ size: z12.number().int().min(1).max(100).default(20).describe("Page size"),
4584
+ taskType: z12.enum(TaskType).optional().describe("Task type"),
4585
+ status: z12.enum(FailureStatus).optional().describe("Log status"),
4586
+ keyword: z12.string().optional().describe("Search in refId, refSubId, errorMessage"),
4587
+ startDate: z12.string().optional().describe("Start date (yyyy-MM-dd)"),
4588
+ endDate: z12.string().optional().describe("End date (yyyy-MM-dd)")
4589
+ })
4589
4590
  },
4590
4591
  async ({ page, size, taskType, status, keyword, startDate, endDate }) => {
4591
4592
  const params = paginationParams(page, size);
@@ -4602,9 +4603,9 @@ function registerLogTools(server, callApi) {
4602
4603
  {
4603
4604
  title: "Get Failure Log",
4604
4605
  description: "Get failure log detail by ID.",
4605
- inputSchema: {
4606
- logId: z11.string().uuid().describe("Failure log ID")
4607
- }
4606
+ inputSchema: z12.object({
4607
+ logId: z12.string().uuid().describe("Failure log ID")
4608
+ })
4608
4609
  },
4609
4610
  async ({ logId }) => callApi("GET", `failure-logs/${logId}`)
4610
4611
  );
@@ -4613,10 +4614,10 @@ function registerLogTools(server, callApi) {
4613
4614
  {
4614
4615
  title: "Process Failure Log",
4615
4616
  description: "Process a single failure log: RESOLVE (mark as manually fixed) or IGNORE (skip intentionally).",
4616
- inputSchema: {
4617
- logId: z11.string().uuid().describe("Failure log ID"),
4618
- action: z11.enum(FailureAction).describe("Action to take")
4619
- }
4617
+ inputSchema: z12.object({
4618
+ logId: z12.string().uuid().describe("Failure log ID"),
4619
+ action: z12.enum(FailureAction).describe("Action to take")
4620
+ })
4620
4621
  },
4621
4622
  async ({ logId, action }) => callApi("POST", `failure-logs/${logId}/actions`, {
4622
4623
  params: { action }
@@ -4627,10 +4628,10 @@ function registerLogTools(server, callApi) {
4627
4628
  {
4628
4629
  title: "Bulk Process Failure Logs",
4629
4630
  description: "Process multiple failure logs at once. Provide an array of log IDs and the action.",
4630
- inputSchema: {
4631
- logIds: z11.array(z11.string().uuid()).describe("Array of failure log IDs"),
4632
- action: z11.enum(FailureAction).describe("Action to apply to all logs")
4633
- }
4631
+ inputSchema: z12.object({
4632
+ logIds: z12.array(z12.string().uuid()).describe("Array of failure log IDs"),
4633
+ action: z12.enum(FailureAction).describe("Action to apply to all logs")
4634
+ })
4634
4635
  },
4635
4636
  async ({ logIds, action }) => callApi("POST", "failure-logs/bulk-actions", {
4636
4637
  body: { logIds, action }
@@ -4639,17 +4640,17 @@ function registerLogTools(server, callApi) {
4639
4640
  }
4640
4641
 
4641
4642
  // src/mcp/tools/webhook-subscriptions.ts
4642
- import { z as z12 } from "zod";
4643
+ import { z as z13 } from "zod";
4643
4644
  function registerWebhookSubscriptionTools(server, callApi) {
4644
4645
  server.registerTool(
4645
4646
  "lexq_webhook_subscriptions_list",
4646
4647
  {
4647
4648
  title: "List Webhook Subscriptions",
4648
4649
  description: "List platform event webhook subscriptions. These receive deployment lifecycle notifications (publish, deploy, rollback, undeploy).",
4649
- inputSchema: {
4650
- page: z12.number().int().min(0).default(0).describe("Page number"),
4651
- size: z12.number().int().min(1).max(100).default(20).describe("Page size")
4652
- }
4650
+ inputSchema: z13.object({
4651
+ page: z13.number().int().min(0).default(0).describe("Page number"),
4652
+ size: z13.number().int().min(1).max(100).default(20).describe("Page size")
4653
+ })
4653
4654
  },
4654
4655
  async ({ page, size }) => {
4655
4656
  const params = paginationParams(page, size);
@@ -4661,9 +4662,9 @@ function registerWebhookSubscriptionTools(server, callApi) {
4661
4662
  {
4662
4663
  title: "Get Webhook Subscription",
4663
4664
  description: "Get webhook subscription detail by ID.",
4664
- inputSchema: {
4665
- id: z12.string().uuid().describe("Webhook subscription ID")
4666
- }
4665
+ inputSchema: z13.object({
4666
+ id: z13.string().uuid().describe("Webhook subscription ID")
4667
+ })
4667
4668
  },
4668
4669
  async ({ id }) => callApi("GET", `webhook-subscriptions/${id}`)
4669
4670
  );
@@ -4672,15 +4673,15 @@ function registerWebhookSubscriptionTools(server, callApi) {
4672
4673
  {
4673
4674
  title: "Save Webhook Subscription",
4674
4675
  description: 'Create or update a webhook subscription. Omit id to create, provide id to update. Events: VERSION_PUBLISHED, DEPLOYED, ROLLED_BACK, UNDEPLOYED. Formats: GENERIC (full JSON), SLACK ({"text": "..."}).',
4675
- inputSchema: {
4676
- id: z12.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
4677
- name: z12.string().min(1).describe("Subscription name (unique per tenant)"),
4678
- webhookUrl: z12.string().url().describe("Webhook endpoint URL"),
4679
- subscribedEvents: z12.array(z12.enum(PlatformEventType)).min(1).describe("Events to subscribe to"),
4680
- payloadFormat: z12.enum(WebhookPayloadFormat).optional().default("GENERIC").describe("Payload format"),
4681
- secret: z12.string().optional().describe("HMAC-SHA256 signing secret"),
4682
- isActive: z12.boolean().optional().default(true).describe("Whether the subscription is active")
4683
- }
4676
+ inputSchema: z13.object({
4677
+ id: z13.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
4678
+ name: z13.string().min(1).describe("Subscription name (unique per tenant)"),
4679
+ webhookUrl: z13.string().url().describe("Webhook endpoint URL"),
4680
+ subscribedEvents: z13.array(z13.enum(PlatformEventType)).min(1).describe("Events to subscribe to"),
4681
+ payloadFormat: z13.enum(WebhookPayloadFormat).optional().default("GENERIC").describe("Payload format"),
4682
+ secret: z13.string().optional().describe("HMAC-SHA256 signing secret"),
4683
+ isActive: z13.boolean().optional().default(true).describe("Whether the subscription is active")
4684
+ })
4684
4685
  },
4685
4686
  async ({ ...body }) => callApi("POST", "webhook-subscriptions", { body })
4686
4687
  );
@@ -4689,9 +4690,9 @@ function registerWebhookSubscriptionTools(server, callApi) {
4689
4690
  {
4690
4691
  title: "Delete Webhook Subscription",
4691
4692
  description: "Delete a webhook subscription by ID.",
4692
- inputSchema: {
4693
- id: z12.string().uuid().describe("Webhook subscription ID")
4694
- }
4693
+ inputSchema: z13.object({
4694
+ id: z13.string().uuid().describe("Webhook subscription ID")
4695
+ })
4695
4696
  },
4696
4697
  async ({ id }) => callApi("DELETE", `webhook-subscriptions/${id}`)
4697
4698
  );
@@ -4700,23 +4701,23 @@ function registerWebhookSubscriptionTools(server, callApi) {
4700
4701
  {
4701
4702
  title: "Test Webhook Subscription",
4702
4703
  description: "Send a test event to verify webhook connectivity. Returns the HTTP status code and success/failure message.",
4703
- inputSchema: {
4704
- id: z12.string().uuid().describe("Webhook subscription ID")
4705
- }
4704
+ inputSchema: z13.object({
4705
+ id: z13.string().uuid().describe("Webhook subscription ID")
4706
+ })
4706
4707
  },
4707
4708
  async ({ id }) => callApi("POST", `webhook-subscriptions/${id}/test`)
4708
4709
  );
4709
4710
  }
4710
4711
 
4711
4712
  // src/mcp/tools/domain-templates.ts
4712
- import { z as z13 } from "zod";
4713
+ import { z as z14 } from "zod";
4713
4714
  function registerDomainTemplateTools(server, callApi) {
4714
4715
  server.registerTool(
4715
4716
  "lexq_domain_templates_list",
4716
4717
  {
4717
4718
  title: "List Domain Templates",
4718
4719
  description: "List all domain templates. A domain template is a curated, industry-specific starter pack of fact definitions and sample rules (e.g. ECOMMERCE). Each entry reports its key, status (ACTIVE or COMING_SOON), and a summary of what it provisions. Call this before preview or apply to discover which templates can currently be applied.",
4719
- inputSchema: {}
4720
+ inputSchema: z14.object({})
4720
4721
  },
4721
4722
  async () => callApi("GET", "domain-templates")
4722
4723
  );
@@ -4725,11 +4726,11 @@ function registerDomainTemplateTools(server, callApi) {
4725
4726
  {
4726
4727
  title: "Preview Domain Template",
4727
4728
  description: "Preview exactly what a domain template will provision before applying it: the fact definitions it registers, the sample rules it creates, and an apply plan. This is a read-only dry run \u2014 nothing is created. Only ACTIVE templates can be previewed.",
4728
- inputSchema: {
4729
- template: z13.string().describe(
4729
+ inputSchema: z14.object({
4730
+ template: z14.string().describe(
4730
4731
  "Domain template key (e.g. ECOMMERCE). Use lexq_domain_templates_list to see available keys \u2014 currently only ECOMMERCE is ACTIVE."
4731
4732
  )
4732
- }
4733
+ })
4733
4734
  },
4734
4735
  async ({ template }) => callApi("GET", `domain-templates/${template}/preview`)
4735
4736
  );
@@ -4738,12 +4739,12 @@ function registerDomainTemplateTools(server, callApi) {
4738
4739
  {
4739
4740
  title: "Apply Domain Template",
4740
4741
  description: "Apply a domain template to the current tenant. Creates the template's fact definitions and a new policy group pre-populated with its sample rules as a DRAFT version. Existing facts are skipped \u2014 apply is additive and never overwrites existing schema. Run lexq_domain_templates_preview first to review what will be created. Only ACTIVE templates can be applied.",
4741
- inputSchema: {
4742
- template: z13.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
4743
- customName: z13.string().optional().describe(
4742
+ inputSchema: z14.object({
4743
+ template: z14.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
4744
+ customName: z14.string().optional().describe(
4744
4745
  "Optional custom name for the policy group that gets created. If omitted, the template's default name is used."
4745
4746
  )
4746
- }
4747
+ })
4747
4748
  },
4748
4749
  async ({ template, customName }) => {
4749
4750
  const body = {};