@lexq/cli 0.1.58 → 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
  );
@@ -3441,15 +3442,19 @@ function registerGroupTools(server, callApi) {
3441
3442
  "lexq_groups_create",
3442
3443
  {
3443
3444
  title: "Create Policy Group",
3444
- 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. Groups sharing an activationGroup must share the same activationMode / activationStrategy / executionLimit.",
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("Strategy when mode is EXCLUSIVE or MAX_N"),
3450
- executionLimit: z.number().int().min(1).optional().describe("Max rule executions (required when mode is MAX_N)"),
3451
- activationGroup: z.string().optional().describe("Activation group name")
3452
- }
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.",
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(
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."
3453
+ ),
3454
+ activationGroup: z2.string().optional().describe(
3455
+ "Activation group (Execution Group) cluster key. Policy groups sharing this key compete, and group priority picks the winners."
3456
+ )
3457
+ })
3453
3458
  },
3454
3459
  async (args) => {
3455
3460
  const body = {
@@ -3468,16 +3473,20 @@ function registerGroupTools(server, callApi) {
3468
3473
  {
3469
3474
  title: "Update Policy Group",
3470
3475
  description: "Update a policy group. Only provided fields are updated; omitted fields remain unchanged.",
3471
- inputSchema: {
3472
- groupId: z.string().uuid().describe("Policy group ID"),
3473
- name: z.string().optional().describe("New name"),
3474
- description: z.string().optional().describe("New description"),
3475
- status: z.enum(["ACTIVE", "DISABLED"]).optional().describe("Status (DISABLED = emergency stop)"),
3476
- activationGroup: z.string().optional().describe("Activation group (Execution Group) cluster key"),
3477
- activationMode: z.enum(ConflictResolutionMode).optional().describe("Conflict resolution mode"),
3478
- activationStrategy: z.enum(ConflictResolutionStrategy).optional().describe("Strategy"),
3479
- executionLimit: z.number().int().min(1).optional().describe("Max rule executions")
3480
- }
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(
3482
+ "Activation group (Execution Group) cluster key. Policy groups sharing this key compete, and group priority picks the winners."
3483
+ ),
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(
3487
+ "How many policy groups sharing this activationGroup may run. Counts groups, not rules."
3488
+ )
3489
+ })
3481
3490
  },
3482
3491
  async ({ groupId, ...body }) => callApi("PUT", `policy-groups/${groupId}`, { body })
3483
3492
  );
@@ -3486,9 +3495,9 @@ function registerGroupTools(server, callApi) {
3486
3495
  {
3487
3496
  title: "Delete Policy Group",
3488
3497
  description: "Archive a policy group. Only non-live groups can be deleted. This is irreversible.",
3489
- inputSchema: {
3490
- groupId: z.string().uuid().describe("Policy group ID")
3491
- }
3498
+ inputSchema: z2.object({
3499
+ groupId: z2.string().uuid().describe("Policy group ID")
3500
+ })
3492
3501
  },
3493
3502
  async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}`)
3494
3503
  );
@@ -3497,9 +3506,9 @@ function registerGroupTools(server, callApi) {
3497
3506
  {
3498
3507
  title: "Reorder Policy Groups",
3499
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.",
3500
- inputSchema: {
3501
- groupIds: z.array(z.string().uuid()).describe("Group IDs in desired priority order (index 0 = priority 1)")
3502
- }
3509
+ inputSchema: z2.object({
3510
+ groupIds: z2.array(z2.string().uuid()).describe("Group IDs in desired priority order (index 0 = priority 1)")
3511
+ })
3503
3512
  },
3504
3513
  async ({ groupIds }) => {
3505
3514
  const groups = groupIds.map((groupId, index) => ({
@@ -3514,11 +3523,11 @@ function registerGroupTools(server, callApi) {
3514
3523
  {
3515
3524
  title: "Start A/B Test",
3516
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%.",
3517
- inputSchema: {
3518
- groupId: z.string().uuid().describe("Policy group ID"),
3519
- testVersionId: z.string().uuid().describe("Challenger version ID to test"),
3520
- trafficRate: z.number().int().min(1).max(99).describe("Traffic percentage routed to challenger (1-99)")
3521
- }
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
+ })
3522
3531
  },
3523
3532
  async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/ab-test`, { body })
3524
3533
  );
@@ -3527,9 +3536,9 @@ function registerGroupTools(server, callApi) {
3527
3536
  {
3528
3537
  title: "Stop A/B Test",
3529
3538
  description: "Stop a running A/B test. All traffic is restored to the control (current) version.",
3530
- inputSchema: {
3531
- groupId: z.string().uuid().describe("Policy group ID")
3532
- }
3539
+ inputSchema: z2.object({
3540
+ groupId: z2.string().uuid().describe("Policy group ID")
3541
+ })
3533
3542
  },
3534
3543
  async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}/ab-test`)
3535
3544
  );
@@ -3538,28 +3547,28 @@ function registerGroupTools(server, callApi) {
3538
3547
  {
3539
3548
  title: "Adjust A/B Test",
3540
3549
  description: "Adjust traffic rate of a running A/B test.",
3541
- inputSchema: {
3542
- groupId: z.string().uuid().describe("Policy group ID"),
3543
- trafficRate: z.number().int().min(1).max(99).describe("New traffic percentage for challenger (1-99)")
3544
- }
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
+ })
3545
3554
  },
3546
3555
  async ({ groupId, ...body }) => callApi("PATCH", `policy-groups/${groupId}/ab-test/traffic-rate`, { body })
3547
3556
  );
3548
3557
  }
3549
3558
 
3550
3559
  // src/mcp/tools/versions.ts
3551
- import { z as z2 } from "zod";
3560
+ import { z as z3 } from "zod";
3552
3561
  function registerVersionTools(server, callApi) {
3553
3562
  server.registerTool(
3554
3563
  "lexq_versions_list",
3555
3564
  {
3556
3565
  title: "List Policy Versions",
3557
3566
  description: "List all versions of a policy group.",
3558
- inputSchema: {
3559
- groupId: z2.string().uuid().describe("Policy group ID"),
3560
- page: z2.number().int().min(0).default(0).describe("Page number"),
3561
- size: z2.number().int().min(1).max(100).default(20).describe("Page size")
3562
- }
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
+ })
3563
3572
  },
3564
3573
  async ({ groupId, page, size }) => callApi("GET", `policy-groups/${groupId}/versions`, {
3565
3574
  params: paginationParams(page, size)
@@ -3570,10 +3579,10 @@ function registerVersionTools(server, callApi) {
3570
3579
  {
3571
3580
  title: "Get Policy Version",
3572
3581
  description: "Get a single version by ID, including its rules and fact requirements.",
3573
- inputSchema: {
3574
- groupId: z2.string().uuid().describe("Policy group ID"),
3575
- versionId: z2.string().uuid().describe("Version ID")
3576
- }
3582
+ inputSchema: z3.object({
3583
+ groupId: z3.string().uuid().describe("Policy group ID"),
3584
+ versionId: z3.string().uuid().describe("Version ID")
3585
+ })
3577
3586
  },
3578
3587
  async ({ groupId, versionId }) => callApi("GET", `policy-groups/${groupId}/versions/${versionId}`)
3579
3588
  );
@@ -3582,12 +3591,12 @@ function registerVersionTools(server, callApi) {
3582
3591
  {
3583
3592
  title: "Create Policy Version",
3584
3593
  description: "Create a new DRAFT version in a policy group. Optionally provide a commit message and effective date range.",
3585
- inputSchema: {
3586
- groupId: z2.string().uuid().describe("Policy group ID"),
3587
- commitMessage: z2.string().optional().describe("Commit message describing this version"),
3588
- effectiveFrom: z2.string().optional().describe("Effective start date (ISO 8601)"),
3589
- effectiveTo: z2.string().optional().describe("Effective end date (ISO 8601)")
3590
- }
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
+ })
3591
3600
  },
3592
3601
  async ({ groupId, ...body }) => callApi("POST", `policy-groups/${groupId}/versions`, { body })
3593
3602
  );
@@ -3596,13 +3605,13 @@ function registerVersionTools(server, callApi) {
3596
3605
  {
3597
3606
  title: "Update Policy Version",
3598
3607
  description: "Update a DRAFT version. Only DRAFT versions can be modified. Only provided fields are changed.",
3599
- inputSchema: {
3600
- groupId: z2.string().uuid().describe("Policy group ID"),
3601
- versionId: z2.string().uuid().describe("Version ID"),
3602
- commitMessage: z2.string().optional().describe("New commit message"),
3603
- effectiveFrom: z2.string().optional().describe("New effective start date"),
3604
- effectiveTo: z2.string().optional().describe("New effective end date")
3605
- }
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
+ })
3606
3615
  },
3607
3616
  async ({ groupId, versionId, ...body }) => callApi("PUT", `policy-groups/${groupId}/versions/${versionId}`, { body })
3608
3617
  );
@@ -3611,10 +3620,10 @@ function registerVersionTools(server, callApi) {
3611
3620
  {
3612
3621
  title: "Delete Policy Version",
3613
3622
  description: "Delete a DRAFT version. Only DRAFT versions can be deleted.",
3614
- inputSchema: {
3615
- groupId: z2.string().uuid().describe("Policy group ID"),
3616
- versionId: z2.string().uuid().describe("Version ID")
3617
- }
3623
+ inputSchema: z3.object({
3624
+ groupId: z3.string().uuid().describe("Policy group ID"),
3625
+ versionId: z3.string().uuid().describe("Version ID")
3626
+ })
3618
3627
  },
3619
3628
  async ({ groupId, versionId }) => callApi("DELETE", `policy-groups/${groupId}/versions/${versionId}`)
3620
3629
  );
@@ -3623,10 +3632,10 @@ function registerVersionTools(server, callApi) {
3623
3632
  {
3624
3633
  title: "Clone Policy Version",
3625
3634
  description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
3626
- inputSchema: {
3627
- groupId: z2.string().uuid().describe("Policy group ID"),
3628
- versionId: z2.string().uuid().describe("Source version ID to clone")
3629
- }
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
+ })
3630
3639
  },
3631
3640
  async ({ groupId, versionId }) => {
3632
3641
  return callApi("POST", `policy-groups/${groupId}/versions/${versionId}/clone`, {
@@ -3637,7 +3646,7 @@ function registerVersionTools(server, callApi) {
3637
3646
  }
3638
3647
 
3639
3648
  // src/mcp/tools/rules.ts
3640
- import { z as z3 } from "zod";
3649
+ import { z as z4 } from "zod";
3641
3650
  import dedent15 from "dedent";
3642
3651
  function registerRuleTools(server, callApi) {
3643
3652
  server.registerTool(
@@ -3645,10 +3654,10 @@ function registerRuleTools(server, callApi) {
3645
3654
  {
3646
3655
  title: "List Rules",
3647
3656
  description: "List all rules in a version (priority ASC). Returns summary with conditionSummary and actionSummary.",
3648
- inputSchema: {
3649
- groupId: z3.string().uuid().describe("Policy group ID"),
3650
- versionId: z3.string().uuid().describe("Version ID")
3651
- }
3657
+ inputSchema: z4.object({
3658
+ groupId: z4.string().uuid().describe("Policy group ID"),
3659
+ versionId: z4.string().uuid().describe("Version ID")
3660
+ })
3652
3661
  },
3653
3662
  async ({ groupId, versionId }) => callApi("GET", `policy-groups/${groupId}/versions/${versionId}/rules`)
3654
3663
  );
@@ -3657,11 +3666,11 @@ function registerRuleTools(server, callApi) {
3657
3666
  {
3658
3667
  title: "Get Rule Detail",
3659
3668
  description: "Get full rule detail including condition tree and action definitions.",
3660
- inputSchema: {
3661
- groupId: z3.string().uuid().describe("Policy group ID"),
3662
- versionId: z3.string().uuid().describe("Version ID"),
3663
- ruleId: z3.string().uuid().describe("Rule ID")
3664
- }
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
+ })
3665
3674
  },
3666
3675
  async ({ groupId, versionId, ruleId }) => callApi("GET", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}`)
3667
3676
  );
@@ -3730,13 +3739,13 @@ function registerRuleTools(server, callApi) {
3730
3739
 
3731
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).
3732
3741
  `,
3733
- inputSchema: {
3734
- groupId: z3.string().uuid().describe("Policy group ID"),
3735
- versionId: z3.string().uuid().describe("Version ID"),
3736
- 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(
3737
3746
  "JSON string of CreateRuleRequest: { name, condition, actions, mutexGroup?, mutexMode?, mutexStrategy?, mutexLimit?, isEnabled? }"
3738
3747
  )
3739
- }
3748
+ })
3740
3749
  },
3741
3750
  async ({ groupId, versionId, rule }) => {
3742
3751
  const body = parseJson(rule);
@@ -3748,14 +3757,14 @@ function registerRuleTools(server, callApi) {
3748
3757
  {
3749
3758
  title: "Update Rule",
3750
3759
  description: "Update an existing rule in a DRAFT version. Only provided fields are changed.",
3751
- inputSchema: {
3752
- groupId: z3.string().uuid().describe("Policy group ID"),
3753
- versionId: z3.string().uuid().describe("Version ID"),
3754
- ruleId: z3.string().uuid().describe("Rule ID"),
3755
- 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(
3756
3765
  "JSON string of UpdateRuleRequest: { name?, condition?, actions?, mutexGroup?, mutexMode?, mutexStrategy?, mutexLimit?, isEnabled? }"
3757
3766
  )
3758
- }
3767
+ })
3759
3768
  },
3760
3769
  async ({ groupId, versionId, ruleId, rule }) => {
3761
3770
  const body = parseJson(rule);
@@ -3769,12 +3778,12 @@ function registerRuleTools(server, callApi) {
3769
3778
  {
3770
3779
  title: "Delete Rule",
3771
3780
  description: "Delete a rule from a DRAFT version.",
3772
- inputSchema: {
3773
- groupId: z3.string().uuid().describe("Policy group ID"),
3774
- versionId: z3.string().uuid().describe("Version ID"),
3775
- ruleId: z3.string().uuid().describe("Rule ID"),
3776
- force: z3.boolean().default(false).describe("Skip confirmation (for the last rule in a version)")
3777
- }
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
+ })
3778
3787
  },
3779
3788
  async ({ groupId, versionId, ruleId, force }) => {
3780
3789
  const params = {};
@@ -3789,11 +3798,11 @@ function registerRuleTools(server, callApi) {
3789
3798
  {
3790
3799
  title: "Reorder Rules",
3791
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).",
3792
- inputSchema: {
3793
- groupId: z3.string().uuid().describe("Policy group ID"),
3794
- versionId: z3.string().uuid().describe("Version ID"),
3795
- ruleIds: z3.array(z3.string().uuid()).describe("Rule IDs in desired priority order")
3796
- }
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
+ })
3797
3806
  },
3798
3807
  async ({ groupId, versionId, ruleIds }) => {
3799
3808
  const rules = ruleIds.map((ruleId, index) => ({
@@ -3810,12 +3819,12 @@ function registerRuleTools(server, callApi) {
3810
3819
  {
3811
3820
  title: "Toggle Rule",
3812
3821
  description: "Enable or disable a rule without deleting it.",
3813
- inputSchema: {
3814
- groupId: z3.string().uuid().describe("Policy group ID"),
3815
- versionId: z3.string().uuid().describe("Version ID"),
3816
- ruleId: z3.string().uuid().describe("Rule ID"),
3817
- isEnabled: z3.boolean().describe("true to enable, false to disable")
3818
- }
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
+ })
3819
3828
  },
3820
3829
  async ({ groupId, versionId, ruleId, isEnabled }) => callApi("PATCH", `policy-groups/${groupId}/versions/${versionId}/rules/${ruleId}/enabled`, {
3821
3830
  body: { isEnabled }
@@ -3824,7 +3833,7 @@ function registerRuleTools(server, callApi) {
3824
3833
  }
3825
3834
 
3826
3835
  // src/mcp/tools/facts.ts
3827
- import { z as z4 } from "zod";
3836
+ import { z as z5 } from "zod";
3828
3837
 
3829
3838
  // src/types/facts.ts
3830
3839
  var FACT_KEY_PATTERN = /^[a-zA-Z][a-zA-Z0-9_]*$/;
@@ -3837,11 +3846,11 @@ function registerFactTools(server, callApi) {
3837
3846
  {
3838
3847
  title: "List Fact Definitions",
3839
3848
  description: "List all fact definitions (input variable schema). Shows key, type, required, and PII status. Always check this before creating rules.",
3840
- inputSchema: {
3841
- page: z4.number().int().min(0).default(0).describe("Page number"),
3842
- size: z4.number().int().min(1).max(100).default(20).describe("Page size"),
3843
- keyword: z4.string().optional().describe("Search keyword")
3844
- }
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
+ })
3845
3854
  },
3846
3855
  async ({ page, size, keyword }) => {
3847
3856
  const params = paginationParams(page, size);
@@ -3854,16 +3863,16 @@ function registerFactTools(server, callApi) {
3854
3863
  {
3855
3864
  title: "Create Fact Definition",
3856
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.",
3857
- inputSchema: {
3858
- key: z4.string().regex(FACT_KEY_PATTERN).describe("Variable key. Any casing; must start with a letter."),
3859
- name: z4.string().describe("Display name"),
3860
- type: z4.enum(VALUE_TYPES).describe("Value type"),
3861
- description: z4.string().optional().describe("Description"),
3862
- isRequired: z4.boolean().default(false).describe("Whether this fact is required for rule evaluation"),
3863
- 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(
3864
3873
  "Mark as PII \u2014 masked on every read surface, revealable only in the console (audited)"
3865
3874
  )
3866
- }
3875
+ })
3867
3876
  },
3868
3877
  async (args) => callApi("POST", "schema/facts", { body: args })
3869
3878
  );
@@ -3872,16 +3881,16 @@ function registerFactTools(server, callApi) {
3872
3881
  {
3873
3882
  title: "Update Fact Definition",
3874
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.",
3875
- inputSchema: {
3876
- factId: z4.string().uuid().describe("Fact definition ID"),
3877
- name: z4.string().optional().describe("Display name"),
3878
- description: z4.string().optional().describe("Description"),
3879
- 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(
3880
3889
  "Value type. Omit to leave it unchanged. Changing it fails with FD-007 while any rule references the fact."
3881
3890
  ),
3882
- isRequired: z4.boolean().optional().describe("Required flag"),
3883
- isPii: z4.boolean().optional().describe("PII flag \u2014 enables/disables masking (changeable even on system facts)")
3884
- }
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
+ })
3885
3894
  },
3886
3895
  async ({ factId, ...body }) => callApi("PUT", `schema/facts/${factId}`, { body })
3887
3896
  );
@@ -3890,9 +3899,9 @@ function registerFactTools(server, callApi) {
3890
3899
  {
3891
3900
  title: "Delete Fact Definition",
3892
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.",
3893
- inputSchema: {
3894
- factId: z4.string().uuid().describe("Fact definition ID")
3895
- }
3902
+ inputSchema: z5.object({
3903
+ factId: z5.string().uuid().describe("Fact definition ID")
3904
+ })
3896
3905
  },
3897
3906
  async ({ factId }) => callApi("DELETE", `schema/facts/${factId}`)
3898
3907
  );
@@ -3901,7 +3910,7 @@ function registerFactTools(server, callApi) {
3901
3910
  {
3902
3911
  title: "Get Action Runtime Fact Metadata",
3903
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.",
3904
- inputSchema: {}
3913
+ inputSchema: z5.object({})
3905
3914
  },
3906
3915
  async () => callApi("GET", "schema/action-metadata")
3907
3916
  );
@@ -3910,10 +3919,10 @@ function registerFactTools(server, callApi) {
3910
3919
  {
3911
3920
  title: "List Unregistered Facts",
3912
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.",
3913
- inputSchema: {
3914
- groupId: z4.string().uuid().describe("Policy group ID"),
3915
- versionId: z4.string().uuid().describe("Version ID")
3916
- }
3922
+ inputSchema: z5.object({
3923
+ groupId: z5.string().uuid().describe("Policy group ID"),
3924
+ versionId: z5.string().uuid().describe("Version ID")
3925
+ })
3917
3926
  },
3918
3927
  async ({ groupId, versionId }) => callApi("GET", `policy-groups/${groupId}/versions/${versionId}/unregistered-facts`)
3919
3928
  );
@@ -3922,10 +3931,10 @@ function registerFactTools(server, callApi) {
3922
3931
  {
3923
3932
  title: "Export Fact Catalog",
3924
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.",
3925
- inputSchema: {
3926
- format: z4.enum(EXPORT_FORMATS).default("csv").describe("Export format"),
3927
- keyword: z4.string().optional().describe("Filter by key or name")
3928
- }
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
+ })
3929
3938
  },
3930
3939
  async ({ format, keyword }) => callApi("GET", "schema/facts/export", {
3931
3940
  params: keyword ? { format, keyword } : { format }
@@ -3934,18 +3943,18 @@ function registerFactTools(server, callApi) {
3934
3943
  }
3935
3944
 
3936
3945
  // src/mcp/tools/deploy.ts
3937
- import { z as z5 } from "zod";
3946
+ import { z as z6 } from "zod";
3938
3947
  function registerDeployTools(server, callApi) {
3939
3948
  server.registerTool(
3940
3949
  "lexq_deploy_publish",
3941
3950
  {
3942
3951
  title: "Publish Version",
3943
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.",
3944
- inputSchema: {
3945
- groupId: z5.string().uuid().describe("Policy group ID"),
3946
- versionId: z5.string().uuid().describe("Version ID to publish"),
3947
- memo: z5.string().min(1).describe("Publish memo (required)")
3948
- }
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
+ })
3949
3958
  },
3950
3959
  async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/versions/${versionId}/publish`, { body: { memo } })
3951
3960
  );
@@ -3954,11 +3963,11 @@ function registerDeployTools(server, callApi) {
3954
3963
  {
3955
3964
  title: "Deploy to Live",
3956
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.",
3957
- inputSchema: {
3958
- groupId: z5.string().uuid().describe("Policy group ID"),
3959
- versionId: z5.string().uuid().describe("Version ID to deploy"),
3960
- memo: z5.string().min(1).describe("Deployment memo (required)")
3961
- }
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
+ })
3962
3971
  },
3963
3972
  async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/deploy`, {
3964
3973
  body: { versionId, memo }
@@ -3969,10 +3978,10 @@ function registerDeployTools(server, callApi) {
3969
3978
  {
3970
3979
  title: "Rollback Deployment",
3971
3980
  description: "Rollback to the previous deployed version. Only available if there is a previous version.",
3972
- inputSchema: {
3973
- groupId: z5.string().uuid().describe("Policy group ID"),
3974
- memo: z5.string().min(1).describe("Rollback reason (required)")
3975
- }
3981
+ inputSchema: z6.object({
3982
+ groupId: z6.string().uuid().describe("Policy group ID"),
3983
+ memo: z6.string().min(1).describe("Rollback reason (required)")
3984
+ })
3976
3985
  },
3977
3986
  async ({ groupId, memo }) => callApi("POST", `policy-groups/${groupId}/rollback`, {
3978
3987
  body: { memo }
@@ -3983,10 +3992,10 @@ function registerDeployTools(server, callApi) {
3983
3992
  {
3984
3993
  title: "Undeploy",
3985
3994
  description: "Remove the live version from traffic. The version stays ACTIVE but no longer serves requests.",
3986
- inputSchema: {
3987
- groupId: z5.string().uuid().describe("Policy group ID"),
3988
- memo: z5.string().min(1).describe("Undeploy reason (required)")
3989
- }
3995
+ inputSchema: z6.object({
3996
+ groupId: z6.string().uuid().describe("Policy group ID"),
3997
+ memo: z6.string().min(1).describe("Undeploy reason (required)")
3998
+ })
3990
3999
  },
3991
4000
  async ({ groupId, memo }) => callApi("POST", `policy-groups/${groupId}/undeploy`, {
3992
4001
  body: { memo }
@@ -3997,11 +4006,11 @@ function registerDeployTools(server, callApi) {
3997
4006
  {
3998
4007
  title: "Schedule Deployment",
3999
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).",
4000
- inputSchema: {
4001
- groupId: z5.string().uuid().describe("Policy group ID"),
4002
- versionId: z5.string().uuid().describe("ACTIVE version ID with a future effective start date"),
4003
- memo: z5.string().min(1).describe("Schedule memo (required)")
4004
- }
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
+ })
4005
4014
  },
4006
4015
  async ({ groupId, versionId, memo }) => callApi("POST", `policy-groups/${groupId}/schedule`, {
4007
4016
  body: { versionId, memo }
@@ -4012,9 +4021,9 @@ function registerDeployTools(server, callApi) {
4012
4021
  {
4013
4022
  title: "Cancel Scheduled Deployment",
4014
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.",
4015
- inputSchema: {
4016
- groupId: z5.string().uuid().describe("Policy group ID")
4017
- }
4024
+ inputSchema: z6.object({
4025
+ groupId: z6.string().uuid().describe("Policy group ID")
4026
+ })
4018
4027
  },
4019
4028
  async ({ groupId }) => callApi("DELETE", `policy-groups/${groupId}/schedule`)
4020
4029
  );
@@ -4023,10 +4032,10 @@ function registerDeployTools(server, callApi) {
4023
4032
  {
4024
4033
  title: "List Scheduled Deployments",
4025
4034
  description: "List scheduled deployments across all groups (all statuses: PENDING, EXECUTED, CANCELED, FAILED), newest first.",
4026
- inputSchema: {
4027
- page: z5.number().int().min(0).default(0).describe("Page number"),
4028
- size: z5.number().int().min(1).max(100).default(20).describe("Page size")
4029
- }
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
+ })
4030
4039
  },
4031
4040
  async ({ page, size }) => callApi("GET", "policy-groups/schedules", { params: paginationParams(page, size) })
4032
4041
  );
@@ -4035,14 +4044,14 @@ function registerDeployTools(server, callApi) {
4035
4044
  {
4036
4045
  title: "Deployment History",
4037
4046
  description: "List deployment history across all groups.",
4038
- inputSchema: {
4039
- page: z5.number().int().min(0).default(0).describe("Page number"),
4040
- size: z5.number().int().min(1).max(100).default(20).describe("Page size"),
4041
- groupId: z5.string().uuid().optional().describe("Filter by group ID"),
4042
- types: z5.string().optional().describe("Filter by deployment types (comma-separated: DEPLOY,ROLLBACK,UNDEPLOY)"),
4043
- startDate: z5.string().optional().describe("Start date (yyyy-MM-dd)"),
4044
- endDate: z5.string().optional().describe("End date (yyyy-MM-dd)")
4045
- }
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
+ })
4046
4055
  },
4047
4056
  async ({ page, size, groupId, types, startDate, endDate }) => {
4048
4057
  const params = paginationParams(page, size);
@@ -4058,9 +4067,9 @@ function registerDeployTools(server, callApi) {
4058
4067
  {
4059
4068
  title: "Deployment Detail",
4060
4069
  description: "Get detailed info about a specific deployment including snapshot hash and integrity check.",
4061
- inputSchema: {
4062
- deploymentId: z5.string().uuid().describe("Deployment ID")
4063
- }
4070
+ inputSchema: z6.object({
4071
+ deploymentId: z6.string().uuid().describe("Deployment ID")
4072
+ })
4064
4073
  },
4065
4074
  async ({ deploymentId }) => callApi("GET", `deployments/${deploymentId}`)
4066
4075
  );
@@ -4069,7 +4078,7 @@ function registerDeployTools(server, callApi) {
4069
4078
  {
4070
4079
  title: "Deployment Overview",
4071
4080
  description: "Show current deployment status of all groups \u2014 which version is live, last deployment type, and deployer.",
4072
- inputSchema: {}
4081
+ inputSchema: z6.object({})
4073
4082
  },
4074
4083
  async () => callApi("GET", "deployments/overview")
4075
4084
  );
@@ -4078,9 +4087,9 @@ function registerDeployTools(server, callApi) {
4078
4087
  {
4079
4088
  title: "List Deployable Versions",
4080
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.",
4081
- inputSchema: {
4082
- groupId: z5.string().uuid().describe("Policy group ID")
4083
- }
4090
+ inputSchema: z6.object({
4091
+ groupId: z6.string().uuid().describe("Policy group ID")
4092
+ })
4084
4093
  },
4085
4094
  async ({ groupId }) => callApi("GET", `deployments/groups/${groupId}/deployable-versions`)
4086
4095
  );
@@ -4089,10 +4098,10 @@ function registerDeployTools(server, callApi) {
4089
4098
  {
4090
4099
  title: "Deployment Diff",
4091
4100
  description: "Compare rule snapshots between two versions. Shows added, removed, and modified rules. Useful for reviewing changes before deploying a new version.",
4092
- inputSchema: {
4093
- baseVersionId: z5.string().uuid().describe("Base version ID (typically the current live)"),
4094
- targetVersionId: z5.string().uuid().describe("Target version ID (the one you want to deploy)")
4095
- }
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
+ })
4096
4105
  },
4097
4106
  async ({ baseVersionId, targetVersionId }) => callApi("GET", "deployments/diff", {
4098
4107
  params: { baseVersionId, targetVersionId }
@@ -4101,7 +4110,7 @@ function registerDeployTools(server, callApi) {
4101
4110
  }
4102
4111
 
4103
4112
  // src/mcp/tools/analytics.ts
4104
- import { z as z6 } from "zod";
4113
+ import { z as z7 } from "zod";
4105
4114
  import dedent16 from "dedent";
4106
4115
  function registerAnalyticsTools(server, callApi) {
4107
4116
  server.registerTool(
@@ -4120,11 +4129,11 @@ function registerAnalyticsTools(server, callApi) {
4120
4129
 
4121
4130
  Example input: { "facts": { "paymentAmount": 100000, "customerTier": "VIP" } }
4122
4131
  Always dry-run before publishing to validate rule behavior.`,
4123
- inputSchema: {
4124
- versionId: z6.string().uuid().describe("Policy version ID to test against"),
4125
- facts: z6.string().describe('JSON string of facts object, e.g. {"paymentAmount":100000}'),
4126
- includeDebugInfo: z6.boolean().default(true).describe("Include execution and decision traces")
4127
- }
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
+ })
4128
4137
  },
4129
4138
  async ({ versionId, facts, includeDebugInfo }) => {
4130
4139
  const parsedFacts = parseJson(facts);
@@ -4144,11 +4153,11 @@ function registerAnalyticsTools(server, callApi) {
4144
4153
  resultA / resultB — full DryRunResponse for each version
4145
4154
  diff.mutatedDiff — changes in mutatedFacts between A and B (key → {before, after})
4146
4155
  diff.generatedDiff — changes in generatedVariables between A and B`,
4147
- inputSchema: {
4148
- versionIdA: z6.string().uuid().describe("Baseline version ID"),
4149
- versionIdB: z6.string().uuid().describe("Candidate version ID"),
4150
- facts: z6.string().describe("JSON string of facts object")
4151
- }
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
+ })
4152
4161
  },
4153
4162
  async ({ versionIdA, versionIdB, facts }) => {
4154
4163
  const parsedFacts = parseJson(facts);
@@ -4162,10 +4171,10 @@ function registerAnalyticsTools(server, callApi) {
4162
4171
  {
4163
4172
  title: "Analyze Requirements",
4164
4173
  description: "Analyze which input facts a version requires. Returns required keys, types, and an example request body.",
4165
- inputSchema: {
4166
- groupId: z6.string().uuid().describe("Policy group ID"),
4167
- versionId: z6.string().uuid().describe("Version ID")
4168
- }
4174
+ inputSchema: z7.object({
4175
+ groupId: z7.string().uuid().describe("Policy group ID"),
4176
+ versionId: z7.string().uuid().describe("Version ID")
4177
+ })
4169
4178
  },
4170
4179
  async ({ groupId, versionId }) => callApi("GET", `analytics/groups/${groupId}/versions/${versionId}/requirements`)
4171
4180
  );
@@ -4201,9 +4210,9 @@ function registerAnalyticsTools(server, callApi) {
4201
4210
  "options": { "baselinePolicyVersionId": "<uuid>", "includeRuleStats": true }
4202
4211
  }
4203
4212
  `,
4204
- inputSchema: {
4205
- body: z6.string().describe("JSON string of SimulationRequest")
4206
- }
4213
+ inputSchema: z7.object({
4214
+ body: z7.string().describe("JSON string of SimulationRequest")
4215
+ })
4207
4216
  },
4208
4217
  async ({ body }) => {
4209
4218
  const parsed = parseJson(body);
@@ -4215,9 +4224,9 @@ function registerAnalyticsTools(server, callApi) {
4215
4224
  {
4216
4225
  title: "Simulation Status",
4217
4226
  description: "Get simulation status and results. Poll until status is COMPLETED or FAILED.",
4218
- inputSchema: {
4219
- simulationId: z6.string().uuid().describe("Simulation ID")
4220
- }
4227
+ inputSchema: z7.object({
4228
+ simulationId: z7.string().uuid().describe("Simulation ID")
4229
+ })
4221
4230
  },
4222
4231
  async ({ simulationId }) => callApi("GET", `analytics/simulations/${simulationId}`)
4223
4232
  );
@@ -4226,13 +4235,13 @@ function registerAnalyticsTools(server, callApi) {
4226
4235
  {
4227
4236
  title: "List Simulations",
4228
4237
  description: "List simulation history with optional filters.",
4229
- inputSchema: {
4230
- page: z6.number().int().min(0).default(0).describe("Page number"),
4231
- size: z6.number().int().min(1).max(100).default(20).describe("Page size"),
4232
- status: z6.enum(["PENDING", "RUNNING", "COMPLETED", "FAILED", "CANCELED"]).optional().describe("Filter by status"),
4233
- from: z6.string().optional().describe("Start date (yyyy-MM-dd)"),
4234
- to: z6.string().optional().describe("End date (yyyy-MM-dd)")
4235
- }
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
+ })
4236
4245
  },
4237
4246
  async ({ page, size, status, from, to }) => {
4238
4247
  const params = paginationParams(page, size);
@@ -4247,9 +4256,9 @@ function registerAnalyticsTools(server, callApi) {
4247
4256
  {
4248
4257
  title: "Cancel Simulation",
4249
4258
  description: "Cancel a running or pending simulation.",
4250
- inputSchema: {
4251
- simulationId: z6.string().uuid().describe("Simulation ID")
4252
- }
4259
+ inputSchema: z7.object({
4260
+ simulationId: z7.string().uuid().describe("Simulation ID")
4261
+ })
4253
4262
  },
4254
4263
  async ({ simulationId }) => callApi("DELETE", `analytics/simulations/${simulationId}`)
4255
4264
  );
@@ -4258,10 +4267,10 @@ function registerAnalyticsTools(server, callApi) {
4258
4267
  {
4259
4268
  title: "Export Simulation",
4260
4269
  description: "Export simulation results as JSON or CSV. Returns the raw data.",
4261
- inputSchema: {
4262
- simulationId: z6.string().uuid().describe("Simulation ID"),
4263
- format: z6.enum(EXPORT_FORMATS).default("json").describe("Export format")
4264
- }
4270
+ inputSchema: z7.object({
4271
+ simulationId: z7.string().uuid().describe("Simulation ID"),
4272
+ format: z7.enum(EXPORT_FORMATS).default("json").describe("Export format")
4273
+ })
4265
4274
  },
4266
4275
  async ({ simulationId, format }) => callApi("GET", `analytics/simulations/${simulationId}/export`, {
4267
4276
  params: { format }
@@ -4285,10 +4294,10 @@ function registerAnalyticsTools(server, callApi) {
4285
4294
 
4286
4295
  JSON example: [{"userId":"user_001","paymentAmount":150000}, {"userId":"user_002","paymentAmount":50000}]
4287
4296
  `,
4288
- inputSchema: {
4289
- content: z6.string().describe("CSV or JSON content as string"),
4290
- filename: z6.string().default("dataset.csv").describe("Filename with extension (.csv or .json)")
4291
- }
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
+ })
4292
4301
  },
4293
4302
  async ({ content, filename }) => {
4294
4303
  const result = await callApi("POST", "analytics/datasets/upload", {
@@ -4315,11 +4324,11 @@ function registerAnalyticsTools(server, callApi) {
4315
4324
  {
4316
4325
  title: "Download Dataset Template",
4317
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.",
4318
- inputSchema: {
4319
- groupId: z6.string().uuid().describe("Policy group ID"),
4320
- versionId: z6.string().uuid().describe("Version ID"),
4321
- format: z6.enum(EXPORT_FORMATS).default("csv").describe("Template format")
4322
- }
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
+ })
4323
4332
  },
4324
4333
  async ({ groupId, versionId, format }) => callApi("GET", `analytics/groups/${groupId}/versions/${versionId}/dataset-template`, {
4325
4334
  params: { format }
@@ -4328,7 +4337,7 @@ function registerAnalyticsTools(server, callApi) {
4328
4337
  }
4329
4338
 
4330
4339
  // src/mcp/tools/profile.ts
4331
- import { z as z7 } from "zod";
4340
+ import { z as z8 } from "zod";
4332
4341
  var RELATIVE_THRESHOLD = `flagged = p50 \u2265 ${SLOW_MULTIPLIER}\xD7 median of per-rule p50s within the group; absolute thresholds are intentionally not supported.`;
4333
4342
  function profileParams(opts) {
4334
4343
  const params = {};
@@ -4344,15 +4353,15 @@ function registerProfileTools(server, callApi) {
4344
4353
  {
4345
4354
  title: "Group Latency Profile",
4346
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.`,
4347
- inputSchema: {
4348
- groupId: z7.string().uuid().describe("Policy group ID"),
4349
- versionId: z7.string().uuid().optional().describe("Version to inspect (default: live version)"),
4350
- 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(
4351
4360
  `Window start, ISO-8601 instant (e.g. 2026-07-01T00:00:00Z). Default: ${PROFILE_DEFAULT_WINDOW_HOURS}h ago`
4352
4361
  ),
4353
- to: z7.string().optional().describe("Window end, ISO-8601 instant. Default: now"),
4354
- cacheState: z7.enum(["HIT", "MISS"]).optional().describe("Cache dimension for the rule table and judgment (default: HIT)")
4355
- }
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
+ })
4356
4365
  },
4357
4366
  async ({ groupId, versionId, from, to, cacheState }) => callApi("GET", `policy-groups/${groupId}/profile`, {
4358
4367
  params: profileParams({ versionId, from, to, cacheState })
@@ -4363,15 +4372,15 @@ function registerProfileTools(server, callApi) {
4363
4372
  {
4364
4373
  title: "Rule Latency Detail",
4365
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,
4366
- inputSchema: {
4367
- groupId: z7.string().uuid().describe("Policy group ID"),
4368
- ruleId: z7.string().uuid().describe("Rule ID (from lexq_profile_overview)"),
4369
- versionId: z7.string().uuid().optional().describe("Version to inspect (default: live version)"),
4370
- 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(
4371
4380
  `Window start, ISO-8601 instant. Default: ${PROFILE_DEFAULT_WINDOW_HOURS}h ago`
4372
4381
  ),
4373
- to: z7.string().optional().describe("Window end, ISO-8601 instant. Default: now")
4374
- }
4382
+ to: z8.string().optional().describe("Window end, ISO-8601 instant. Default: now")
4383
+ })
4375
4384
  },
4376
4385
  async ({ groupId, ruleId, versionId, from, to }) => callApi("GET", `policy-groups/${groupId}/profile/rules/${ruleId}`, {
4377
4386
  params: profileParams({ versionId, from, to })
@@ -4380,17 +4389,17 @@ function registerProfileTools(server, callApi) {
4380
4389
  }
4381
4390
 
4382
4391
  // src/mcp/tools/replay.ts
4383
- import { z as z8 } from "zod";
4392
+ import { z as z9 } from "zod";
4384
4393
  function registerReplayTools(server, callApi) {
4385
4394
  server.registerTool(
4386
4395
  "lexq_replay_decision",
4387
4396
  {
4388
4397
  title: "Replay a Decision",
4389
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.",
4390
- inputSchema: {
4391
- traceId: z8.string().describe("Trace ID of the past execution to replay"),
4392
- candidateVersionId: z8.string().uuid().describe("Version to re-evaluate against")
4393
- }
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
+ })
4394
4403
  },
4395
4404
  async ({ traceId, candidateVersionId }) => callApi("POST", "replay/decisions", { body: { traceId, candidateVersionId } })
4396
4405
  );
@@ -4399,14 +4408,14 @@ function registerReplayTools(server, callApi) {
4399
4408
  {
4400
4409
  title: "Start Window Replay (Blast Radius)",
4401
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.",
4402
- inputSchema: {
4403
- candidateVersionId: z8.string().uuid().describe("Version to re-evaluate against"),
4404
- from: z8.string().describe("Window start date (yyyy-MM-dd)"),
4405
- to: z8.string().describe("Window end date (yyyy-MM-dd)"),
4406
- 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(
4407
4416
  `Sample cap (server default applies; hard cap ${REPLAY_WINDOW_MAX_RECORDS / 1e3}k)`
4408
4417
  )
4409
- }
4418
+ })
4410
4419
  },
4411
4420
  async ({ candidateVersionId, from, to, maxRecords }) => callApi("POST", "replay/jobs", { body: { candidateVersionId, from, to, maxRecords } })
4412
4421
  );
@@ -4415,9 +4424,9 @@ function registerReplayTools(server, callApi) {
4415
4424
  {
4416
4425
  title: "Get Replay Job Status",
4417
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.",
4418
- inputSchema: {
4419
- jobId: z8.string().describe("Replay job ID from lexq_replay_start")
4420
- }
4427
+ inputSchema: z9.object({
4428
+ jobId: z9.string().describe("Replay job ID from lexq_replay_start")
4429
+ })
4421
4430
  },
4422
4431
  async ({ jobId }) => callApi("GET", `replay/jobs/${jobId}`)
4423
4432
  );
@@ -4426,10 +4435,10 @@ function registerReplayTools(server, callApi) {
4426
4435
  {
4427
4436
  title: "List Replay Jobs",
4428
4437
  description: "List window replay job history (reverse-chronological). Lightweight items \u2014 use lexq_replay_status for summary and changed samples.",
4429
- inputSchema: {
4430
- page: z8.number().int().min(0).default(0).describe("Page number"),
4431
- size: z8.number().int().min(1).max(100).default(20).describe("Page size")
4432
- }
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
+ })
4433
4442
  },
4434
4443
  async ({ page, size }) => callApi("GET", "replay/jobs", { params: paginationParams(page, size) })
4435
4444
  );
@@ -4438,9 +4447,9 @@ function registerReplayTools(server, callApi) {
4438
4447
  {
4439
4448
  title: "Cancel Replay Job",
4440
4449
  description: "Cooperatively cancel a PENDING or RUNNING window replay job. Other states are rejected. VIEWER role cannot cancel.",
4441
- inputSchema: {
4442
- jobId: z8.string().describe("Replay job ID")
4443
- }
4450
+ inputSchema: z9.object({
4451
+ jobId: z9.string().describe("Replay job ID")
4452
+ })
4444
4453
  },
4445
4454
  async ({ jobId }) => callApi("POST", `replay/jobs/${jobId}/cancel`)
4446
4455
  );
@@ -4449,33 +4458,33 @@ function registerReplayTools(server, callApi) {
4449
4458
  {
4450
4459
  title: "Export Replay Result",
4451
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.",
4452
- inputSchema: {
4453
- jobId: z8.string().describe("Replay job ID"),
4454
- format: z8.enum(EXPORT_FORMATS).default("json").describe("Export format")
4455
- }
4461
+ inputSchema: z9.object({
4462
+ jobId: z9.string().describe("Replay job ID"),
4463
+ format: z9.enum(EXPORT_FORMATS).default("json").describe("Export format")
4464
+ })
4456
4465
  },
4457
4466
  async ({ jobId, format }) => callApi("GET", `replay/jobs/${jobId}/export`, { params: { format } })
4458
4467
  );
4459
4468
  }
4460
4469
 
4461
4470
  // src/mcp/tools/history.ts
4462
- import { z as z9 } from "zod";
4471
+ import { z as z10 } from "zod";
4463
4472
  function registerHistoryTools(server, callApi) {
4464
4473
  server.registerTool(
4465
4474
  "lexq_history_list",
4466
4475
  {
4467
4476
  title: "List Execution History",
4468
4477
  description: "List policy execution history. Shows trace ID, group, version, status, match result, and latency.",
4469
- inputSchema: {
4470
- page: z9.number().int().min(0).default(0).describe("Page number"),
4471
- size: z9.number().int().min(1).max(100).default(20).describe("Page size"),
4472
- traceId: z9.string().optional().describe("Filter by trace ID"),
4473
- groupId: z9.string().uuid().optional().describe("Filter by policy group"),
4474
- versionId: z9.string().uuid().optional().describe("Filter by version"),
4475
- status: z9.enum(["SUCCESS", "NO_MATCH", "ERROR", "TIMEOUT"]).optional().describe("Filter by execution status"),
4476
- startDate: z9.string().optional().describe("Start date (yyyy-MM-dd)"),
4477
- endDate: z9.string().optional().describe("End date (yyyy-MM-dd)")
4478
- }
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
+ })
4479
4488
  },
4480
4489
  async ({ page, size, traceId, groupId, versionId, status, startDate, endDate }) => {
4481
4490
  const params = paginationParams(page, size);
@@ -4493,9 +4502,9 @@ function registerHistoryTools(server, callApi) {
4493
4502
  {
4494
4503
  title: "Get Execution Detail",
4495
4504
  description: "Get full execution detail including inputFacts, mutatedFacts, generatedVariables, executionTraces, and decisionTraces.",
4496
- inputSchema: {
4497
- traceId: z9.string().describe("Trace ID from execution history")
4498
- }
4505
+ inputSchema: z10.object({
4506
+ traceId: z10.string().describe("Trace ID from execution history")
4507
+ })
4499
4508
  },
4500
4509
  async ({ traceId }) => callApi("GET", `execution/history/${traceId}`)
4501
4510
  );
@@ -4504,11 +4513,11 @@ function registerHistoryTools(server, callApi) {
4504
4513
  {
4505
4514
  title: "Execution Statistics",
4506
4515
  description: "Get execution KPIs: total executions, success/failure counts, success rate, and average latency.",
4507
- inputSchema: {
4508
- groupId: z9.string().uuid().optional().describe("Filter by policy group"),
4509
- startDate: z9.string().optional().describe("Start date (yyyy-MM-dd)"),
4510
- endDate: z9.string().optional().describe("End date (yyyy-MM-dd)")
4511
- }
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
+ })
4512
4521
  },
4513
4522
  async ({ groupId, startDate, endDate }) => {
4514
4523
  const params = {};
@@ -4521,16 +4530,16 @@ function registerHistoryTools(server, callApi) {
4521
4530
  }
4522
4531
 
4523
4532
  // src/mcp/tools/provenance.ts
4524
- import { z as z10 } from "zod";
4533
+ import { z as z11 } from "zod";
4525
4534
  function registerProvenanceTools(server, callApi) {
4526
4535
  server.registerTool(
4527
4536
  "lexq_provenance_get",
4528
4537
  {
4529
4538
  title: "Get Decision Provenance",
4530
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.",
4531
- inputSchema: {
4532
- traceId: z10.string().describe("Trace ID of the execution")
4533
- }
4540
+ inputSchema: z11.object({
4541
+ traceId: z11.string().describe("Trace ID of the execution")
4542
+ })
4534
4543
  },
4535
4544
  async ({ traceId }) => callApi("GET", `provenance/${traceId}`)
4536
4545
  );
@@ -4539,15 +4548,15 @@ function registerProvenanceTools(server, callApi) {
4539
4548
  {
4540
4549
  title: "List PII Reveal Audits",
4541
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.",
4542
- inputSchema: {
4543
- page: z10.number().int().min(0).default(0).describe("Page number"),
4544
- size: z10.number().int().min(1).max(100).default(20).describe("Page size"),
4545
- traceId: z10.string().optional().describe("Filter by trace ID (exact match)"),
4546
- revealedBy: z10.string().optional().describe("Filter by operator ID (exact match)"),
4547
- factKey: z10.string().optional().describe("Filter by fact key (partial match, case-insensitive)"),
4548
- startDate: z10.string().optional().describe("Start date (yyyy-MM-dd)"),
4549
- endDate: z10.string().optional().describe("End date (yyyy-MM-dd)")
4550
- }
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
+ })
4551
4560
  },
4552
4561
  async ({ page, size, traceId, revealedBy, factKey, startDate, endDate }) => {
4553
4562
  const params = paginationParams(page, size);
@@ -4562,22 +4571,22 @@ function registerProvenanceTools(server, callApi) {
4562
4571
  }
4563
4572
 
4564
4573
  // src/mcp/tools/logs.ts
4565
- import { z as z11 } from "zod";
4574
+ import { z as z12 } from "zod";
4566
4575
  function registerLogTools(server, callApi) {
4567
4576
  server.registerTool(
4568
4577
  "lexq_logs_list",
4569
4578
  {
4570
4579
  title: "List Failure Logs",
4571
4580
  description: "List system failure logs from background tasks (platform event webhooks, scheduled deployments).",
4572
- inputSchema: {
4573
- page: z11.number().int().min(0).default(0).describe("Page number"),
4574
- size: z11.number().int().min(1).max(100).default(20).describe("Page size"),
4575
- taskType: z11.enum(TaskType).optional().describe("Task type"),
4576
- status: z11.enum(FailureStatus).optional().describe("Log status"),
4577
- keyword: z11.string().optional().describe("Search in refId, refSubId, errorMessage"),
4578
- startDate: z11.string().optional().describe("Start date (yyyy-MM-dd)"),
4579
- endDate: z11.string().optional().describe("End date (yyyy-MM-dd)")
4580
- }
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
+ })
4581
4590
  },
4582
4591
  async ({ page, size, taskType, status, keyword, startDate, endDate }) => {
4583
4592
  const params = paginationParams(page, size);
@@ -4594,9 +4603,9 @@ function registerLogTools(server, callApi) {
4594
4603
  {
4595
4604
  title: "Get Failure Log",
4596
4605
  description: "Get failure log detail by ID.",
4597
- inputSchema: {
4598
- logId: z11.string().uuid().describe("Failure log ID")
4599
- }
4606
+ inputSchema: z12.object({
4607
+ logId: z12.string().uuid().describe("Failure log ID")
4608
+ })
4600
4609
  },
4601
4610
  async ({ logId }) => callApi("GET", `failure-logs/${logId}`)
4602
4611
  );
@@ -4605,10 +4614,10 @@ function registerLogTools(server, callApi) {
4605
4614
  {
4606
4615
  title: "Process Failure Log",
4607
4616
  description: "Process a single failure log: RESOLVE (mark as manually fixed) or IGNORE (skip intentionally).",
4608
- inputSchema: {
4609
- logId: z11.string().uuid().describe("Failure log ID"),
4610
- action: z11.enum(FailureAction).describe("Action to take")
4611
- }
4617
+ inputSchema: z12.object({
4618
+ logId: z12.string().uuid().describe("Failure log ID"),
4619
+ action: z12.enum(FailureAction).describe("Action to take")
4620
+ })
4612
4621
  },
4613
4622
  async ({ logId, action }) => callApi("POST", `failure-logs/${logId}/actions`, {
4614
4623
  params: { action }
@@ -4619,10 +4628,10 @@ function registerLogTools(server, callApi) {
4619
4628
  {
4620
4629
  title: "Bulk Process Failure Logs",
4621
4630
  description: "Process multiple failure logs at once. Provide an array of log IDs and the action.",
4622
- inputSchema: {
4623
- logIds: z11.array(z11.string().uuid()).describe("Array of failure log IDs"),
4624
- action: z11.enum(FailureAction).describe("Action to apply to all logs")
4625
- }
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
+ })
4626
4635
  },
4627
4636
  async ({ logIds, action }) => callApi("POST", "failure-logs/bulk-actions", {
4628
4637
  body: { logIds, action }
@@ -4631,17 +4640,17 @@ function registerLogTools(server, callApi) {
4631
4640
  }
4632
4641
 
4633
4642
  // src/mcp/tools/webhook-subscriptions.ts
4634
- import { z as z12 } from "zod";
4643
+ import { z as z13 } from "zod";
4635
4644
  function registerWebhookSubscriptionTools(server, callApi) {
4636
4645
  server.registerTool(
4637
4646
  "lexq_webhook_subscriptions_list",
4638
4647
  {
4639
4648
  title: "List Webhook Subscriptions",
4640
4649
  description: "List platform event webhook subscriptions. These receive deployment lifecycle notifications (publish, deploy, rollback, undeploy).",
4641
- inputSchema: {
4642
- page: z12.number().int().min(0).default(0).describe("Page number"),
4643
- size: z12.number().int().min(1).max(100).default(20).describe("Page size")
4644
- }
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
+ })
4645
4654
  },
4646
4655
  async ({ page, size }) => {
4647
4656
  const params = paginationParams(page, size);
@@ -4653,9 +4662,9 @@ function registerWebhookSubscriptionTools(server, callApi) {
4653
4662
  {
4654
4663
  title: "Get Webhook Subscription",
4655
4664
  description: "Get webhook subscription detail by ID.",
4656
- inputSchema: {
4657
- id: z12.string().uuid().describe("Webhook subscription ID")
4658
- }
4665
+ inputSchema: z13.object({
4666
+ id: z13.string().uuid().describe("Webhook subscription ID")
4667
+ })
4659
4668
  },
4660
4669
  async ({ id }) => callApi("GET", `webhook-subscriptions/${id}`)
4661
4670
  );
@@ -4664,15 +4673,15 @@ function registerWebhookSubscriptionTools(server, callApi) {
4664
4673
  {
4665
4674
  title: "Save Webhook Subscription",
4666
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": "..."}).',
4667
- inputSchema: {
4668
- id: z12.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
4669
- name: z12.string().min(1).describe("Subscription name (unique per tenant)"),
4670
- webhookUrl: z12.string().url().describe("Webhook endpoint URL"),
4671
- subscribedEvents: z12.array(z12.enum(PlatformEventType)).min(1).describe("Events to subscribe to"),
4672
- payloadFormat: z12.enum(WebhookPayloadFormat).optional().default("GENERIC").describe("Payload format"),
4673
- secret: z12.string().optional().describe("HMAC-SHA256 signing secret"),
4674
- isActive: z12.boolean().optional().default(true).describe("Whether the subscription is active")
4675
- }
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
+ })
4676
4685
  },
4677
4686
  async ({ ...body }) => callApi("POST", "webhook-subscriptions", { body })
4678
4687
  );
@@ -4681,9 +4690,9 @@ function registerWebhookSubscriptionTools(server, callApi) {
4681
4690
  {
4682
4691
  title: "Delete Webhook Subscription",
4683
4692
  description: "Delete a webhook subscription by ID.",
4684
- inputSchema: {
4685
- id: z12.string().uuid().describe("Webhook subscription ID")
4686
- }
4693
+ inputSchema: z13.object({
4694
+ id: z13.string().uuid().describe("Webhook subscription ID")
4695
+ })
4687
4696
  },
4688
4697
  async ({ id }) => callApi("DELETE", `webhook-subscriptions/${id}`)
4689
4698
  );
@@ -4692,23 +4701,23 @@ function registerWebhookSubscriptionTools(server, callApi) {
4692
4701
  {
4693
4702
  title: "Test Webhook Subscription",
4694
4703
  description: "Send a test event to verify webhook connectivity. Returns the HTTP status code and success/failure message.",
4695
- inputSchema: {
4696
- id: z12.string().uuid().describe("Webhook subscription ID")
4697
- }
4704
+ inputSchema: z13.object({
4705
+ id: z13.string().uuid().describe("Webhook subscription ID")
4706
+ })
4698
4707
  },
4699
4708
  async ({ id }) => callApi("POST", `webhook-subscriptions/${id}/test`)
4700
4709
  );
4701
4710
  }
4702
4711
 
4703
4712
  // src/mcp/tools/domain-templates.ts
4704
- import { z as z13 } from "zod";
4713
+ import { z as z14 } from "zod";
4705
4714
  function registerDomainTemplateTools(server, callApi) {
4706
4715
  server.registerTool(
4707
4716
  "lexq_domain_templates_list",
4708
4717
  {
4709
4718
  title: "List Domain Templates",
4710
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.",
4711
- inputSchema: {}
4720
+ inputSchema: z14.object({})
4712
4721
  },
4713
4722
  async () => callApi("GET", "domain-templates")
4714
4723
  );
@@ -4717,11 +4726,11 @@ function registerDomainTemplateTools(server, callApi) {
4717
4726
  {
4718
4727
  title: "Preview Domain Template",
4719
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.",
4720
- inputSchema: {
4721
- template: z13.string().describe(
4729
+ inputSchema: z14.object({
4730
+ template: z14.string().describe(
4722
4731
  "Domain template key (e.g. ECOMMERCE). Use lexq_domain_templates_list to see available keys \u2014 currently only ECOMMERCE is ACTIVE."
4723
4732
  )
4724
- }
4733
+ })
4725
4734
  },
4726
4735
  async ({ template }) => callApi("GET", `domain-templates/${template}/preview`)
4727
4736
  );
@@ -4730,12 +4739,12 @@ function registerDomainTemplateTools(server, callApi) {
4730
4739
  {
4731
4740
  title: "Apply Domain Template",
4732
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.",
4733
- inputSchema: {
4734
- template: z13.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
4735
- 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(
4736
4745
  "Optional custom name for the policy group that gets created. If omitted, the template's default name is used."
4737
4746
  )
4738
- }
4747
+ })
4739
4748
  },
4740
4749
  async ({ template, customName }) => {
4741
4750
  const body = {};