@lexq/cli 0.3.0 → 0.4.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/README.md +58 -2
- package/dist/index.js +77 -0
- package/dist/mcp/register.js +77 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
> your deploy pipeline, prove every change with Impact Simulation, and ship without
|
|
6
6
|
> a git push.
|
|
7
7
|
|
|
8
|
-
**[Website](https://lexq.io)** · **[Docs](https://docs.lexq.io)** · **[Console](https://console.lexq.io)**
|
|
8
|
+
**[Website](https://lexq.io)** · **[Docs](https://docs.lexq.io)** · **[Console](https://console.lexq.io)** · **[MCP Registry](https://registry.modelcontextprotocol.io)**
|
|
9
9
|
|
|
10
10
|
[](https://www.npmjs.com/package/@lexq/cli)
|
|
11
11
|
[](LICENSE)
|
|
@@ -146,7 +146,27 @@ Add to `claude_desktop_config.json`:
|
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
> **Prerequisite:** `lexq auth login` must have been run once to store an
|
|
149
|
-
> API key in `~/.lexq/config.json
|
|
149
|
+
> API key in `~/.lexq/config.json`, or `LEXQ_API_KEY` must be set in the client's
|
|
150
|
+
> environment block.
|
|
151
|
+
|
|
152
|
+
### Registry
|
|
153
|
+
|
|
154
|
+
The server is listed on the official MCP Registry as **`io.lexq/lexq`**. Clients that
|
|
155
|
+
browse the registry find both the npm package and the hosted endpoint in that one entry.
|
|
156
|
+
|
|
157
|
+
## Protocol Support
|
|
158
|
+
|
|
159
|
+
The local stdio server and the hosted Streamable HTTP endpoint both serve two MCP
|
|
160
|
+
revisions from one set of tool definitions, so a client sees the same tools either way.
|
|
161
|
+
|
|
162
|
+
| Revision | How a client reaches it |
|
|
163
|
+
|----------|-------------------------|
|
|
164
|
+
| `2026-07-28` | A per-request `_meta` envelope. No handshake. |
|
|
165
|
+
| `2025-11-25` | The `initialize` handshake. |
|
|
166
|
+
|
|
167
|
+
There is nothing to configure. The server answers in whichever revision the opening message
|
|
168
|
+
used, so a client can move to 2026-07-28 on its own schedule and one that has not moved
|
|
169
|
+
keeps working.
|
|
150
170
|
|
|
151
171
|
## AI Agent Skills
|
|
152
172
|
|
|
@@ -222,6 +242,21 @@ Config is stored at `~/.lexq/config.json`:
|
|
|
222
242
|
}
|
|
223
243
|
```
|
|
224
244
|
|
|
245
|
+
The file holds an API key in plain text, so it is written `0600` inside a `0700` directory —
|
|
246
|
+
readable by its owner and nobody else on the machine. An install created by an older version
|
|
247
|
+
is repaired on the next save.
|
|
248
|
+
|
|
249
|
+
### Environment variables
|
|
250
|
+
|
|
251
|
+
These are read by the MCP server (`lexq serve --mcp`) and take precedence over the stored
|
|
252
|
+
config. They let an editor or CI target an environment through the client's own config block,
|
|
253
|
+
without writing to `~/.lexq/config.json`. CLI commands use `--api-key` and `--base-url` instead.
|
|
254
|
+
|
|
255
|
+
| Variable | Overrides |
|
|
256
|
+
|----------|-----------|
|
|
257
|
+
| `LEXQ_API_KEY` | `apiKey` |
|
|
258
|
+
| `PARTNER_BASE_URL` | `baseUrl` |
|
|
259
|
+
|
|
225
260
|
## Development
|
|
226
261
|
|
|
227
262
|
```bash
|
|
@@ -235,10 +270,31 @@ pnpm start -- groups list
|
|
|
235
270
|
```bash
|
|
236
271
|
pnpm typecheck # Type check
|
|
237
272
|
pnpm lint # ESLint
|
|
273
|
+
pnpm build # Bundle to dist/
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Checks that guard a stated fact against the thing that owns it. All of them run in CI.
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
pnpm enums:check # Generated enums match the engine contract
|
|
280
|
+
pnpm constants:check # Numbers written in prose match the contract
|
|
281
|
+
pnpm ab-key:check # Tool descriptions still name the A/B traffic key
|
|
282
|
+
pnpm surface:check # Nothing internal reached a public file
|
|
283
|
+
pnpm registry:check # server.json agrees with package.json
|
|
284
|
+
pnpm schemas:check # tools/list matches the recorded snapshot (needs a build)
|
|
238
285
|
pnpm test:fact-key # Fact key grammar
|
|
239
286
|
pnpm test:decimals # Metric precision display
|
|
287
|
+
pnpm test:export-format # Export byte fidelity
|
|
288
|
+
pnpm protocol:check # README matches the revisions the server serves
|
|
240
289
|
```
|
|
241
290
|
|
|
291
|
+
## Security
|
|
292
|
+
|
|
293
|
+
Report a vulnerability through
|
|
294
|
+
[GitHub's private reporting form](https://github.com/lexq-io/lexq-cli/security/advisories/new).
|
|
295
|
+
The policy, including what is in scope, is in
|
|
296
|
+
[SECURITY.md](https://github.com/lexq-io/lexq-cli/blob/main/SECURITY.md).
|
|
297
|
+
|
|
242
298
|
## License
|
|
243
299
|
|
|
244
300
|
[Apache-2.0](LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -3421,6 +3421,7 @@ function registerStatusTools(server, callApi) {
|
|
|
3421
3421
|
"lexq_whoami",
|
|
3422
3422
|
{
|
|
3423
3423
|
title: "Who Am I",
|
|
3424
|
+
annotations: { readOnlyHint: true },
|
|
3424
3425
|
description: "Show current authentication info (tenant ID, user ID, role).",
|
|
3425
3426
|
inputSchema: z.object({})
|
|
3426
3427
|
},
|
|
@@ -3435,6 +3436,7 @@ function registerGroupTools(server, callApi) {
|
|
|
3435
3436
|
"lexq_groups_list",
|
|
3436
3437
|
{
|
|
3437
3438
|
title: "List Policy Groups",
|
|
3439
|
+
annotations: { readOnlyHint: true },
|
|
3438
3440
|
description: "List all policy groups (tenant-wide, priority ASC).",
|
|
3439
3441
|
inputSchema: z2.object({})
|
|
3440
3442
|
},
|
|
@@ -3444,6 +3446,7 @@ function registerGroupTools(server, callApi) {
|
|
|
3444
3446
|
"lexq_groups_get",
|
|
3445
3447
|
{
|
|
3446
3448
|
title: "Get Policy Group",
|
|
3449
|
+
annotations: { readOnlyHint: true },
|
|
3447
3450
|
description: "Get a single policy group by ID.",
|
|
3448
3451
|
inputSchema: z2.object({
|
|
3449
3452
|
groupId: z2.string().uuid().describe("Policy group ID")
|
|
@@ -3455,6 +3458,7 @@ function registerGroupTools(server, callApi) {
|
|
|
3455
3458
|
"lexq_groups_create",
|
|
3456
3459
|
{
|
|
3457
3460
|
title: "Create Policy Group",
|
|
3461
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
3458
3462
|
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.",
|
|
3459
3463
|
inputSchema: z2.object({
|
|
3460
3464
|
name: z2.string().describe("Group name (unique among non-ARCHIVED)"),
|
|
@@ -3485,6 +3489,7 @@ function registerGroupTools(server, callApi) {
|
|
|
3485
3489
|
"lexq_groups_update",
|
|
3486
3490
|
{
|
|
3487
3491
|
title: "Update Policy Group",
|
|
3492
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3488
3493
|
description: "Update a policy group. Only provided fields are updated; omitted fields remain unchanged.",
|
|
3489
3494
|
inputSchema: z2.object({
|
|
3490
3495
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
@@ -3507,6 +3512,7 @@ function registerGroupTools(server, callApi) {
|
|
|
3507
3512
|
"lexq_groups_delete",
|
|
3508
3513
|
{
|
|
3509
3514
|
title: "Delete Policy Group",
|
|
3515
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3510
3516
|
description: "Archive a policy group. Only non-live groups can be deleted. This is irreversible.",
|
|
3511
3517
|
inputSchema: z2.object({
|
|
3512
3518
|
groupId: z2.string().uuid().describe("Policy group ID")
|
|
@@ -3518,6 +3524,7 @@ function registerGroupTools(server, callApi) {
|
|
|
3518
3524
|
"lexq_groups_reorder",
|
|
3519
3525
|
{
|
|
3520
3526
|
title: "Reorder Policy Groups",
|
|
3527
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3521
3528
|
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.",
|
|
3522
3529
|
inputSchema: z2.object({
|
|
3523
3530
|
groupIds: z2.array(z2.string().uuid()).describe("Group IDs in desired priority order (index 0 = priority 1)")
|
|
@@ -3535,6 +3542,7 @@ function registerGroupTools(server, callApi) {
|
|
|
3535
3542
|
"lexq_ab_test_start",
|
|
3536
3543
|
{
|
|
3537
3544
|
title: "Start A/B Test",
|
|
3545
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
3538
3546
|
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%.",
|
|
3539
3547
|
inputSchema: z2.object({
|
|
3540
3548
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
@@ -3548,6 +3556,7 @@ function registerGroupTools(server, callApi) {
|
|
|
3548
3556
|
"lexq_ab_test_stop",
|
|
3549
3557
|
{
|
|
3550
3558
|
title: "Stop A/B Test",
|
|
3559
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3551
3560
|
description: "Stop a running A/B test. All traffic is restored to the control (current) version.",
|
|
3552
3561
|
inputSchema: z2.object({
|
|
3553
3562
|
groupId: z2.string().uuid().describe("Policy group ID")
|
|
@@ -3559,6 +3568,7 @@ function registerGroupTools(server, callApi) {
|
|
|
3559
3568
|
"lexq_ab_test_adjust",
|
|
3560
3569
|
{
|
|
3561
3570
|
title: "Adjust A/B Test",
|
|
3571
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3562
3572
|
description: "Adjust traffic rate of a running A/B test.",
|
|
3563
3573
|
inputSchema: z2.object({
|
|
3564
3574
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
@@ -3576,6 +3586,7 @@ function registerVersionTools(server, callApi) {
|
|
|
3576
3586
|
"lexq_versions_list",
|
|
3577
3587
|
{
|
|
3578
3588
|
title: "List Policy Versions",
|
|
3589
|
+
annotations: { readOnlyHint: true },
|
|
3579
3590
|
description: "List all versions of a policy group.",
|
|
3580
3591
|
inputSchema: z3.object({
|
|
3581
3592
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -3591,6 +3602,7 @@ function registerVersionTools(server, callApi) {
|
|
|
3591
3602
|
"lexq_versions_get",
|
|
3592
3603
|
{
|
|
3593
3604
|
title: "Get Policy Version",
|
|
3605
|
+
annotations: { readOnlyHint: true },
|
|
3594
3606
|
description: "Get a single version by ID, including its rules and fact requirements.",
|
|
3595
3607
|
inputSchema: z3.object({
|
|
3596
3608
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -3603,6 +3615,7 @@ function registerVersionTools(server, callApi) {
|
|
|
3603
3615
|
"lexq_versions_create",
|
|
3604
3616
|
{
|
|
3605
3617
|
title: "Create Policy Version",
|
|
3618
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
3606
3619
|
description: "Create a new DRAFT version in a policy group. Optionally provide a commit message and effective date range.",
|
|
3607
3620
|
inputSchema: z3.object({
|
|
3608
3621
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -3617,6 +3630,7 @@ function registerVersionTools(server, callApi) {
|
|
|
3617
3630
|
"lexq_versions_update",
|
|
3618
3631
|
{
|
|
3619
3632
|
title: "Update Policy Version",
|
|
3633
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3620
3634
|
description: "Update a DRAFT version. Only DRAFT versions can be modified. Only provided fields are changed.",
|
|
3621
3635
|
inputSchema: z3.object({
|
|
3622
3636
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -3632,6 +3646,7 @@ function registerVersionTools(server, callApi) {
|
|
|
3632
3646
|
"lexq_versions_delete",
|
|
3633
3647
|
{
|
|
3634
3648
|
title: "Delete Policy Version",
|
|
3649
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3635
3650
|
description: "Delete a DRAFT version. Only DRAFT versions can be deleted.",
|
|
3636
3651
|
inputSchema: z3.object({
|
|
3637
3652
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -3644,6 +3659,7 @@ function registerVersionTools(server, callApi) {
|
|
|
3644
3659
|
"lexq_versions_clone",
|
|
3645
3660
|
{
|
|
3646
3661
|
title: "Clone Policy Version",
|
|
3662
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
3647
3663
|
description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
|
|
3648
3664
|
inputSchema: z3.object({
|
|
3649
3665
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -3666,6 +3682,7 @@ function registerRuleTools(server, callApi) {
|
|
|
3666
3682
|
"lexq_rules_list",
|
|
3667
3683
|
{
|
|
3668
3684
|
title: "List Rules",
|
|
3685
|
+
annotations: { readOnlyHint: true },
|
|
3669
3686
|
description: "List all rules in a version (priority ASC). Returns summary with conditionSummary and actionSummary.",
|
|
3670
3687
|
inputSchema: z4.object({
|
|
3671
3688
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -3678,6 +3695,7 @@ function registerRuleTools(server, callApi) {
|
|
|
3678
3695
|
"lexq_rules_get",
|
|
3679
3696
|
{
|
|
3680
3697
|
title: "Get Rule Detail",
|
|
3698
|
+
annotations: { readOnlyHint: true },
|
|
3681
3699
|
description: "Get full rule detail including condition tree and action definitions.",
|
|
3682
3700
|
inputSchema: z4.object({
|
|
3683
3701
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -3691,6 +3709,7 @@ function registerRuleTools(server, callApi) {
|
|
|
3691
3709
|
"lexq_rules_create",
|
|
3692
3710
|
{
|
|
3693
3711
|
title: "Create Rule",
|
|
3712
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
3694
3713
|
description: dedent15`
|
|
3695
3714
|
Create a rule in a DRAFT version. Requires name, condition tree, and actions array. priority is auto-assigned (appended last); use lexq_rules_reorder to change order.
|
|
3696
3715
|
|
|
@@ -3769,6 +3788,7 @@ function registerRuleTools(server, callApi) {
|
|
|
3769
3788
|
"lexq_rules_update",
|
|
3770
3789
|
{
|
|
3771
3790
|
title: "Update Rule",
|
|
3791
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3772
3792
|
description: "Update an existing rule in a DRAFT version. Only provided fields are changed.",
|
|
3773
3793
|
inputSchema: z4.object({
|
|
3774
3794
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -3790,6 +3810,7 @@ function registerRuleTools(server, callApi) {
|
|
|
3790
3810
|
"lexq_rules_delete",
|
|
3791
3811
|
{
|
|
3792
3812
|
title: "Delete Rule",
|
|
3813
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3793
3814
|
description: "Delete a rule from a DRAFT version.",
|
|
3794
3815
|
inputSchema: z4.object({
|
|
3795
3816
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -3810,6 +3831,7 @@ function registerRuleTools(server, callApi) {
|
|
|
3810
3831
|
"lexq_rules_reorder",
|
|
3811
3832
|
{
|
|
3812
3833
|
title: "Reorder Rules",
|
|
3834
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3813
3835
|
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).",
|
|
3814
3836
|
inputSchema: z4.object({
|
|
3815
3837
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -3831,6 +3853,7 @@ function registerRuleTools(server, callApi) {
|
|
|
3831
3853
|
"lexq_rules_toggle",
|
|
3832
3854
|
{
|
|
3833
3855
|
title: "Toggle Rule",
|
|
3856
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3834
3857
|
description: "Enable or disable a rule without deleting it.",
|
|
3835
3858
|
inputSchema: z4.object({
|
|
3836
3859
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -3858,6 +3881,7 @@ function registerFactTools(server, callApi) {
|
|
|
3858
3881
|
"lexq_facts_list",
|
|
3859
3882
|
{
|
|
3860
3883
|
title: "List Fact Definitions",
|
|
3884
|
+
annotations: { readOnlyHint: true },
|
|
3861
3885
|
description: "List all fact definitions (input variable schema). Shows key, type, required, and PII status. Always check this before creating rules.",
|
|
3862
3886
|
inputSchema: z5.object({
|
|
3863
3887
|
page: z5.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -3875,6 +3899,7 @@ function registerFactTools(server, callApi) {
|
|
|
3875
3899
|
"lexq_facts_create",
|
|
3876
3900
|
{
|
|
3877
3901
|
title: "Create Fact Definition",
|
|
3902
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
3878
3903
|
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.",
|
|
3879
3904
|
inputSchema: z5.object({
|
|
3880
3905
|
key: z5.string().regex(FACT_KEY_PATTERN).describe("Variable key. Any casing; must start with a letter."),
|
|
@@ -3893,6 +3918,7 @@ function registerFactTools(server, callApi) {
|
|
|
3893
3918
|
"lexq_facts_update",
|
|
3894
3919
|
{
|
|
3895
3920
|
title: "Update Fact Definition",
|
|
3921
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3896
3922
|
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.",
|
|
3897
3923
|
inputSchema: z5.object({
|
|
3898
3924
|
factId: z5.string().uuid().describe("Fact definition ID"),
|
|
@@ -3911,6 +3937,7 @@ function registerFactTools(server, callApi) {
|
|
|
3911
3937
|
"lexq_facts_delete",
|
|
3912
3938
|
{
|
|
3913
3939
|
title: "Delete Fact Definition",
|
|
3940
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3914
3941
|
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.",
|
|
3915
3942
|
inputSchema: z5.object({
|
|
3916
3943
|
factId: z5.string().uuid().describe("Fact definition ID")
|
|
@@ -3922,6 +3949,7 @@ function registerFactTools(server, callApi) {
|
|
|
3922
3949
|
"lexq_facts_action_metadata",
|
|
3923
3950
|
{
|
|
3924
3951
|
title: "Get Action Runtime Fact Metadata",
|
|
3952
|
+
annotations: { readOnlyHint: true },
|
|
3925
3953
|
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.",
|
|
3926
3954
|
inputSchema: z5.object({})
|
|
3927
3955
|
},
|
|
@@ -3931,6 +3959,7 @@ function registerFactTools(server, callApi) {
|
|
|
3931
3959
|
"lexq_facts_unregistered",
|
|
3932
3960
|
{
|
|
3933
3961
|
title: "List Unregistered Facts",
|
|
3962
|
+
annotations: { readOnlyHint: true },
|
|
3934
3963
|
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.",
|
|
3935
3964
|
inputSchema: z5.object({
|
|
3936
3965
|
groupId: z5.string().uuid().describe("Policy group ID"),
|
|
@@ -3943,6 +3972,7 @@ function registerFactTools(server, callApi) {
|
|
|
3943
3972
|
"lexq_facts_export",
|
|
3944
3973
|
{
|
|
3945
3974
|
title: "Export Fact Catalog",
|
|
3975
|
+
annotations: { readOnlyHint: true },
|
|
3946
3976
|
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.",
|
|
3947
3977
|
inputSchema: z5.object({
|
|
3948
3978
|
format: z5.enum(EXPORT_FORMATS).default("csv").describe("Export format"),
|
|
@@ -3962,6 +3992,7 @@ function registerDeployTools(server, callApi) {
|
|
|
3962
3992
|
"lexq_deploy_publish",
|
|
3963
3993
|
{
|
|
3964
3994
|
title: "Publish Version",
|
|
3995
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
3965
3996
|
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.",
|
|
3966
3997
|
inputSchema: z6.object({
|
|
3967
3998
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -3975,6 +4006,7 @@ function registerDeployTools(server, callApi) {
|
|
|
3975
4006
|
"lexq_deploy_live",
|
|
3976
4007
|
{
|
|
3977
4008
|
title: "Deploy to Live",
|
|
4009
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3978
4010
|
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.",
|
|
3979
4011
|
inputSchema: z6.object({
|
|
3980
4012
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -3990,6 +4022,7 @@ function registerDeployTools(server, callApi) {
|
|
|
3990
4022
|
"lexq_deploy_rollback",
|
|
3991
4023
|
{
|
|
3992
4024
|
title: "Rollback Deployment",
|
|
4025
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3993
4026
|
description: "Rollback to the previous deployed version. Only available if there is a previous version.",
|
|
3994
4027
|
inputSchema: z6.object({
|
|
3995
4028
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -4004,6 +4037,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4004
4037
|
"lexq_deploy_undeploy",
|
|
4005
4038
|
{
|
|
4006
4039
|
title: "Undeploy",
|
|
4040
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
4007
4041
|
description: "Remove the live version from traffic. The version stays ACTIVE but no longer serves requests.",
|
|
4008
4042
|
inputSchema: z6.object({
|
|
4009
4043
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -4018,6 +4052,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4018
4052
|
"lexq_deploy_schedule",
|
|
4019
4053
|
{
|
|
4020
4054
|
title: "Schedule Deployment",
|
|
4055
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4021
4056
|
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).",
|
|
4022
4057
|
inputSchema: z6.object({
|
|
4023
4058
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -4033,6 +4068,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4033
4068
|
"lexq_deploy_unschedule",
|
|
4034
4069
|
{
|
|
4035
4070
|
title: "Cancel Scheduled Deployment",
|
|
4071
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
4036
4072
|
description: "Cancel the pending scheduled deployment for a group. The version itself is not affected. Fails with P-039 if no pending schedule exists.",
|
|
4037
4073
|
inputSchema: z6.object({
|
|
4038
4074
|
groupId: z6.string().uuid().describe("Policy group ID")
|
|
@@ -4044,6 +4080,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4044
4080
|
"lexq_deploy_schedules",
|
|
4045
4081
|
{
|
|
4046
4082
|
title: "List Scheduled Deployments",
|
|
4083
|
+
annotations: { readOnlyHint: true },
|
|
4047
4084
|
description: "List scheduled deployments across all groups (all statuses: PENDING, EXECUTED, CANCELED, FAILED), newest first.",
|
|
4048
4085
|
inputSchema: z6.object({
|
|
4049
4086
|
page: z6.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -4056,6 +4093,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4056
4093
|
"lexq_deploy_history",
|
|
4057
4094
|
{
|
|
4058
4095
|
title: "Deployment History",
|
|
4096
|
+
annotations: { readOnlyHint: true },
|
|
4059
4097
|
description: "List deployment history across all groups.",
|
|
4060
4098
|
inputSchema: z6.object({
|
|
4061
4099
|
page: z6.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -4079,6 +4117,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4079
4117
|
"lexq_deploy_detail",
|
|
4080
4118
|
{
|
|
4081
4119
|
title: "Deployment Detail",
|
|
4120
|
+
annotations: { readOnlyHint: true },
|
|
4082
4121
|
description: "Get detailed info about a specific deployment including snapshot hash and integrity check.",
|
|
4083
4122
|
inputSchema: z6.object({
|
|
4084
4123
|
deploymentId: z6.string().uuid().describe("Deployment ID")
|
|
@@ -4090,6 +4129,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4090
4129
|
"lexq_deploy_overview",
|
|
4091
4130
|
{
|
|
4092
4131
|
title: "Deployment Overview",
|
|
4132
|
+
annotations: { readOnlyHint: true },
|
|
4093
4133
|
description: "Show current deployment status of all groups \u2014 which version is live, last deployment type, and deployer.",
|
|
4094
4134
|
inputSchema: z6.object({})
|
|
4095
4135
|
},
|
|
@@ -4099,6 +4139,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4099
4139
|
"lexq_deploy_deployable",
|
|
4100
4140
|
{
|
|
4101
4141
|
title: "List Deployable Versions",
|
|
4142
|
+
annotations: { readOnlyHint: true },
|
|
4102
4143
|
description: "List ACTIVE (published) versions that can be deployed for a group. Use this to find which versions are available before calling deploy live.",
|
|
4103
4144
|
inputSchema: z6.object({
|
|
4104
4145
|
groupId: z6.string().uuid().describe("Policy group ID")
|
|
@@ -4110,6 +4151,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4110
4151
|
"lexq_deploy_diff",
|
|
4111
4152
|
{
|
|
4112
4153
|
title: "Deployment Diff",
|
|
4154
|
+
annotations: { readOnlyHint: true },
|
|
4113
4155
|
description: "Compare rule snapshots between two versions. Shows added, removed, and modified rules. Useful for reviewing changes before deploying a new version.",
|
|
4114
4156
|
inputSchema: z6.object({
|
|
4115
4157
|
baseVersionId: z6.string().uuid().describe("Base version ID (typically the current live)"),
|
|
@@ -4130,6 +4172,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4130
4172
|
"lexq_dry_run",
|
|
4131
4173
|
{
|
|
4132
4174
|
title: "Dry Run",
|
|
4175
|
+
annotations: { readOnlyHint: true },
|
|
4133
4176
|
description: dedent16`
|
|
4134
4177
|
Execute a single dry run against a version. Tests how rules evaluate given input facts without side effects.
|
|
4135
4178
|
|
|
@@ -4159,6 +4202,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4159
4202
|
"lexq_dry_run_compare",
|
|
4160
4203
|
{
|
|
4161
4204
|
title: "Dry Run Compare",
|
|
4205
|
+
annotations: { readOnlyHint: true },
|
|
4162
4206
|
description: dedent16`
|
|
4163
4207
|
Compare dry run results between two versions using the same input facts. Useful for validating changes.
|
|
4164
4208
|
|
|
@@ -4183,6 +4227,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4183
4227
|
"lexq_requirements",
|
|
4184
4228
|
{
|
|
4185
4229
|
title: "Analyze Requirements",
|
|
4230
|
+
annotations: { readOnlyHint: true },
|
|
4186
4231
|
description: "Analyze which input facts a version requires. Returns required keys, types, and an example request body.",
|
|
4187
4232
|
inputSchema: z7.object({
|
|
4188
4233
|
groupId: z7.string().uuid().describe("Policy group ID"),
|
|
@@ -4195,6 +4240,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4195
4240
|
"lexq_simulation_start",
|
|
4196
4241
|
{
|
|
4197
4242
|
title: "Start Simulation",
|
|
4243
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4198
4244
|
description: dedent16`
|
|
4199
4245
|
Start an Impact Simulation against historical, uploaded, or inline data.
|
|
4200
4246
|
|
|
@@ -4236,6 +4282,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4236
4282
|
"lexq_simulation_status",
|
|
4237
4283
|
{
|
|
4238
4284
|
title: "Simulation Status",
|
|
4285
|
+
annotations: { readOnlyHint: true },
|
|
4239
4286
|
description: "Get simulation status and results. Poll until status is COMPLETED or FAILED.",
|
|
4240
4287
|
inputSchema: z7.object({
|
|
4241
4288
|
simulationId: z7.string().uuid().describe("Simulation ID")
|
|
@@ -4247,6 +4294,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4247
4294
|
"lexq_simulation_list",
|
|
4248
4295
|
{
|
|
4249
4296
|
title: "List Simulations",
|
|
4297
|
+
annotations: { readOnlyHint: true },
|
|
4250
4298
|
description: "List simulation history with optional filters.",
|
|
4251
4299
|
inputSchema: z7.object({
|
|
4252
4300
|
page: z7.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -4268,6 +4316,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4268
4316
|
"lexq_simulation_cancel",
|
|
4269
4317
|
{
|
|
4270
4318
|
title: "Cancel Simulation",
|
|
4319
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
4271
4320
|
description: "Cancel a running or pending simulation.",
|
|
4272
4321
|
inputSchema: z7.object({
|
|
4273
4322
|
simulationId: z7.string().uuid().describe("Simulation ID")
|
|
@@ -4279,6 +4328,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4279
4328
|
"lexq_simulation_export",
|
|
4280
4329
|
{
|
|
4281
4330
|
title: "Export Simulation",
|
|
4331
|
+
annotations: { readOnlyHint: true },
|
|
4282
4332
|
description: "Export simulation results as JSON or CSV. Returns the raw data.",
|
|
4283
4333
|
inputSchema: z7.object({
|
|
4284
4334
|
simulationId: z7.string().uuid().describe("Simulation ID"),
|
|
@@ -4293,6 +4343,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4293
4343
|
"lexq_dataset_upload",
|
|
4294
4344
|
{
|
|
4295
4345
|
title: "Upload Dataset",
|
|
4346
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4296
4347
|
description: dedent16`
|
|
4297
4348
|
Upload inline CSV or JSON content as a simulation dataset.
|
|
4298
4349
|
The content is uploaded to S3 and a path is returned in the "path" field.
|
|
@@ -4336,6 +4387,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
4336
4387
|
"lexq_dataset_template",
|
|
4337
4388
|
{
|
|
4338
4389
|
title: "Download Dataset Template",
|
|
4390
|
+
annotations: { readOnlyHint: true },
|
|
4339
4391
|
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.",
|
|
4340
4392
|
inputSchema: z7.object({
|
|
4341
4393
|
groupId: z7.string().uuid().describe("Policy group ID"),
|
|
@@ -4365,6 +4417,7 @@ function registerProfileTools(server, callApi) {
|
|
|
4365
4417
|
"lexq_profile_overview",
|
|
4366
4418
|
{
|
|
4367
4419
|
title: "Group Latency Profile",
|
|
4420
|
+
annotations: { readOnlyHint: true },
|
|
4368
4421
|
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.`,
|
|
4369
4422
|
inputSchema: z8.object({
|
|
4370
4423
|
groupId: z8.string().uuid().describe("Policy group ID"),
|
|
@@ -4384,6 +4437,7 @@ function registerProfileTools(server, callApi) {
|
|
|
4384
4437
|
"lexq_profile_rule",
|
|
4385
4438
|
{
|
|
4386
4439
|
title: "Rule Latency Detail",
|
|
4440
|
+
annotations: { readOnlyHint: true },
|
|
4387
4441
|
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,
|
|
4388
4442
|
inputSchema: z8.object({
|
|
4389
4443
|
groupId: z8.string().uuid().describe("Policy group ID"),
|
|
@@ -4408,6 +4462,7 @@ function registerReplayTools(server, callApi) {
|
|
|
4408
4462
|
"lexq_replay_decision",
|
|
4409
4463
|
{
|
|
4410
4464
|
title: "Replay a Decision",
|
|
4465
|
+
annotations: { readOnlyHint: true },
|
|
4411
4466
|
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.",
|
|
4412
4467
|
inputSchema: z9.object({
|
|
4413
4468
|
traceId: z9.string().describe("Trace ID of the past execution to replay"),
|
|
@@ -4420,6 +4475,7 @@ function registerReplayTools(server, callApi) {
|
|
|
4420
4475
|
"lexq_replay_start",
|
|
4421
4476
|
{
|
|
4422
4477
|
title: "Start Window Replay (Blast Radius)",
|
|
4478
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4423
4479
|
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.",
|
|
4424
4480
|
inputSchema: z9.object({
|
|
4425
4481
|
candidateVersionId: z9.string().uuid().describe("Version to re-evaluate against"),
|
|
@@ -4436,6 +4492,7 @@ function registerReplayTools(server, callApi) {
|
|
|
4436
4492
|
"lexq_replay_status",
|
|
4437
4493
|
{
|
|
4438
4494
|
title: "Get Replay Job Status",
|
|
4495
|
+
annotations: { readOnlyHint: true },
|
|
4439
4496
|
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.",
|
|
4440
4497
|
inputSchema: z9.object({
|
|
4441
4498
|
jobId: z9.string().describe("Replay job ID from lexq_replay_start")
|
|
@@ -4447,6 +4504,7 @@ function registerReplayTools(server, callApi) {
|
|
|
4447
4504
|
"lexq_replay_list",
|
|
4448
4505
|
{
|
|
4449
4506
|
title: "List Replay Jobs",
|
|
4507
|
+
annotations: { readOnlyHint: true },
|
|
4450
4508
|
description: "List window replay job history (reverse-chronological). Lightweight items \u2014 use lexq_replay_status for summary and changed samples.",
|
|
4451
4509
|
inputSchema: z9.object({
|
|
4452
4510
|
page: z9.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -4459,6 +4517,7 @@ function registerReplayTools(server, callApi) {
|
|
|
4459
4517
|
"lexq_replay_cancel",
|
|
4460
4518
|
{
|
|
4461
4519
|
title: "Cancel Replay Job",
|
|
4520
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
4462
4521
|
description: "Cooperatively cancel a PENDING or RUNNING window replay job. Other states are rejected. VIEWER role cannot cancel.",
|
|
4463
4522
|
inputSchema: z9.object({
|
|
4464
4523
|
jobId: z9.string().describe("Replay job ID")
|
|
@@ -4470,6 +4529,7 @@ function registerReplayTools(server, callApi) {
|
|
|
4470
4529
|
"lexq_replay_export",
|
|
4471
4530
|
{
|
|
4472
4531
|
title: "Export Replay Result",
|
|
4532
|
+
annotations: { readOnlyHint: true },
|
|
4473
4533
|
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.",
|
|
4474
4534
|
inputSchema: z9.object({
|
|
4475
4535
|
jobId: z9.string().describe("Replay job ID"),
|
|
@@ -4487,6 +4547,7 @@ function registerHistoryTools(server, callApi) {
|
|
|
4487
4547
|
"lexq_history_list",
|
|
4488
4548
|
{
|
|
4489
4549
|
title: "List Execution History",
|
|
4550
|
+
annotations: { readOnlyHint: true },
|
|
4490
4551
|
description: "List policy execution history. Shows trace ID, group, version, status, match result, and latency.",
|
|
4491
4552
|
inputSchema: z10.object({
|
|
4492
4553
|
page: z10.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -4514,6 +4575,7 @@ function registerHistoryTools(server, callApi) {
|
|
|
4514
4575
|
"lexq_history_get",
|
|
4515
4576
|
{
|
|
4516
4577
|
title: "Get Execution Detail",
|
|
4578
|
+
annotations: { readOnlyHint: true },
|
|
4517
4579
|
description: "Get full execution detail including inputFacts, mutatedFacts, generatedVariables, executionTraces, and decisionTraces.",
|
|
4518
4580
|
inputSchema: z10.object({
|
|
4519
4581
|
traceId: z10.string().describe("Trace ID from execution history")
|
|
@@ -4525,6 +4587,7 @@ function registerHistoryTools(server, callApi) {
|
|
|
4525
4587
|
"lexq_history_stats",
|
|
4526
4588
|
{
|
|
4527
4589
|
title: "Execution Statistics",
|
|
4590
|
+
annotations: { readOnlyHint: true },
|
|
4528
4591
|
description: "Get execution KPIs: total executions, success/failure counts, success rate, and average latency.",
|
|
4529
4592
|
inputSchema: z10.object({
|
|
4530
4593
|
groupId: z10.string().uuid().optional().describe("Filter by policy group"),
|
|
@@ -4549,6 +4612,7 @@ function registerProvenanceTools(server, callApi) {
|
|
|
4549
4612
|
"lexq_provenance_get",
|
|
4550
4613
|
{
|
|
4551
4614
|
title: "Get Decision Provenance",
|
|
4615
|
+
annotations: { readOnlyHint: true },
|
|
4552
4616
|
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.",
|
|
4553
4617
|
inputSchema: z11.object({
|
|
4554
4618
|
traceId: z11.string().describe("Trace ID of the execution")
|
|
@@ -4560,6 +4624,7 @@ function registerProvenanceTools(server, callApi) {
|
|
|
4560
4624
|
"lexq_pii_reveals_list",
|
|
4561
4625
|
{
|
|
4562
4626
|
title: "List PII Reveal Audits",
|
|
4627
|
+
annotations: { readOnlyHint: true },
|
|
4563
4628
|
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.",
|
|
4564
4629
|
inputSchema: z11.object({
|
|
4565
4630
|
page: z11.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -4590,6 +4655,7 @@ function registerLogTools(server, callApi) {
|
|
|
4590
4655
|
"lexq_logs_list",
|
|
4591
4656
|
{
|
|
4592
4657
|
title: "List Failure Logs",
|
|
4658
|
+
annotations: { readOnlyHint: true },
|
|
4593
4659
|
description: "List system failure logs from background tasks (platform event webhooks, scheduled deployments).",
|
|
4594
4660
|
inputSchema: z12.object({
|
|
4595
4661
|
page: z12.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -4615,6 +4681,7 @@ function registerLogTools(server, callApi) {
|
|
|
4615
4681
|
"lexq_logs_get",
|
|
4616
4682
|
{
|
|
4617
4683
|
title: "Get Failure Log",
|
|
4684
|
+
annotations: { readOnlyHint: true },
|
|
4618
4685
|
description: "Get failure log detail by ID.",
|
|
4619
4686
|
inputSchema: z12.object({
|
|
4620
4687
|
logId: z12.string().uuid().describe("Failure log ID")
|
|
@@ -4626,6 +4693,7 @@ function registerLogTools(server, callApi) {
|
|
|
4626
4693
|
"lexq_logs_action",
|
|
4627
4694
|
{
|
|
4628
4695
|
title: "Process Failure Log",
|
|
4696
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4629
4697
|
description: "Process a single failure log: RESOLVE (mark as manually fixed) or IGNORE (skip intentionally).",
|
|
4630
4698
|
inputSchema: z12.object({
|
|
4631
4699
|
logId: z12.string().uuid().describe("Failure log ID"),
|
|
@@ -4640,6 +4708,7 @@ function registerLogTools(server, callApi) {
|
|
|
4640
4708
|
"lexq_logs_bulk_action",
|
|
4641
4709
|
{
|
|
4642
4710
|
title: "Bulk Process Failure Logs",
|
|
4711
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4643
4712
|
description: "Process multiple failure logs at once. Provide an array of log IDs and the action.",
|
|
4644
4713
|
inputSchema: z12.object({
|
|
4645
4714
|
logIds: z12.array(z12.string().uuid()).describe("Array of failure log IDs"),
|
|
@@ -4659,6 +4728,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
4659
4728
|
"lexq_webhook_subscriptions_list",
|
|
4660
4729
|
{
|
|
4661
4730
|
title: "List Webhook Subscriptions",
|
|
4731
|
+
annotations: { readOnlyHint: true },
|
|
4662
4732
|
description: "List platform event webhook subscriptions. These receive deployment lifecycle notifications (publish, deploy, rollback, undeploy).",
|
|
4663
4733
|
inputSchema: z13.object({
|
|
4664
4734
|
page: z13.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -4674,6 +4744,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
4674
4744
|
"lexq_webhook_subscriptions_get",
|
|
4675
4745
|
{
|
|
4676
4746
|
title: "Get Webhook Subscription",
|
|
4747
|
+
annotations: { readOnlyHint: true },
|
|
4677
4748
|
description: "Get webhook subscription detail by ID.",
|
|
4678
4749
|
inputSchema: z13.object({
|
|
4679
4750
|
id: z13.string().uuid().describe("Webhook subscription ID")
|
|
@@ -4685,6 +4756,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
4685
4756
|
"lexq_webhook_subscriptions_save",
|
|
4686
4757
|
{
|
|
4687
4758
|
title: "Save Webhook Subscription",
|
|
4759
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
4688
4760
|
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": "..."}).',
|
|
4689
4761
|
inputSchema: z13.object({
|
|
4690
4762
|
id: z13.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
|
|
@@ -4702,6 +4774,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
4702
4774
|
"lexq_webhook_subscriptions_delete",
|
|
4703
4775
|
{
|
|
4704
4776
|
title: "Delete Webhook Subscription",
|
|
4777
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
4705
4778
|
description: "Delete a webhook subscription by ID.",
|
|
4706
4779
|
inputSchema: z13.object({
|
|
4707
4780
|
id: z13.string().uuid().describe("Webhook subscription ID")
|
|
@@ -4713,6 +4786,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
4713
4786
|
"lexq_webhook_subscriptions_test",
|
|
4714
4787
|
{
|
|
4715
4788
|
title: "Test Webhook Subscription",
|
|
4789
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4716
4790
|
description: "Send a test event to verify webhook connectivity. Returns the HTTP status code and success/failure message.",
|
|
4717
4791
|
inputSchema: z13.object({
|
|
4718
4792
|
id: z13.string().uuid().describe("Webhook subscription ID")
|
|
@@ -4729,6 +4803,7 @@ function registerDomainTemplateTools(server, callApi) {
|
|
|
4729
4803
|
"lexq_domain_templates_list",
|
|
4730
4804
|
{
|
|
4731
4805
|
title: "List Domain Templates",
|
|
4806
|
+
annotations: { readOnlyHint: true },
|
|
4732
4807
|
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.",
|
|
4733
4808
|
inputSchema: z14.object({})
|
|
4734
4809
|
},
|
|
@@ -4738,6 +4813,7 @@ function registerDomainTemplateTools(server, callApi) {
|
|
|
4738
4813
|
"lexq_domain_templates_preview",
|
|
4739
4814
|
{
|
|
4740
4815
|
title: "Preview Domain Template",
|
|
4816
|
+
annotations: { readOnlyHint: true },
|
|
4741
4817
|
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.",
|
|
4742
4818
|
inputSchema: z14.object({
|
|
4743
4819
|
template: z14.string().describe(
|
|
@@ -4751,6 +4827,7 @@ function registerDomainTemplateTools(server, callApi) {
|
|
|
4751
4827
|
"lexq_domain_templates_apply",
|
|
4752
4828
|
{
|
|
4753
4829
|
title: "Apply Domain Template",
|
|
4830
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4754
4831
|
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.",
|
|
4755
4832
|
inputSchema: z14.object({
|
|
4756
4833
|
template: z14.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
|
package/dist/mcp/register.js
CHANGED
|
@@ -5,6 +5,7 @@ function registerStatusTools(server, callApi) {
|
|
|
5
5
|
"lexq_whoami",
|
|
6
6
|
{
|
|
7
7
|
title: "Who Am I",
|
|
8
|
+
annotations: { readOnlyHint: true },
|
|
8
9
|
description: "Show current authentication info (tenant ID, user ID, role).",
|
|
9
10
|
inputSchema: z.object({})
|
|
10
11
|
},
|
|
@@ -39,6 +40,7 @@ function registerGroupTools(server, callApi) {
|
|
|
39
40
|
"lexq_groups_list",
|
|
40
41
|
{
|
|
41
42
|
title: "List Policy Groups",
|
|
43
|
+
annotations: { readOnlyHint: true },
|
|
42
44
|
description: "List all policy groups (tenant-wide, priority ASC).",
|
|
43
45
|
inputSchema: z2.object({})
|
|
44
46
|
},
|
|
@@ -48,6 +50,7 @@ function registerGroupTools(server, callApi) {
|
|
|
48
50
|
"lexq_groups_get",
|
|
49
51
|
{
|
|
50
52
|
title: "Get Policy Group",
|
|
53
|
+
annotations: { readOnlyHint: true },
|
|
51
54
|
description: "Get a single policy group by ID.",
|
|
52
55
|
inputSchema: z2.object({
|
|
53
56
|
groupId: z2.string().uuid().describe("Policy group ID")
|
|
@@ -59,6 +62,7 @@ function registerGroupTools(server, callApi) {
|
|
|
59
62
|
"lexq_groups_create",
|
|
60
63
|
{
|
|
61
64
|
title: "Create Policy Group",
|
|
65
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
62
66
|
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.",
|
|
63
67
|
inputSchema: z2.object({
|
|
64
68
|
name: z2.string().describe("Group name (unique among non-ARCHIVED)"),
|
|
@@ -89,6 +93,7 @@ function registerGroupTools(server, callApi) {
|
|
|
89
93
|
"lexq_groups_update",
|
|
90
94
|
{
|
|
91
95
|
title: "Update Policy Group",
|
|
96
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
92
97
|
description: "Update a policy group. Only provided fields are updated; omitted fields remain unchanged.",
|
|
93
98
|
inputSchema: z2.object({
|
|
94
99
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
@@ -111,6 +116,7 @@ function registerGroupTools(server, callApi) {
|
|
|
111
116
|
"lexq_groups_delete",
|
|
112
117
|
{
|
|
113
118
|
title: "Delete Policy Group",
|
|
119
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
114
120
|
description: "Archive a policy group. Only non-live groups can be deleted. This is irreversible.",
|
|
115
121
|
inputSchema: z2.object({
|
|
116
122
|
groupId: z2.string().uuid().describe("Policy group ID")
|
|
@@ -122,6 +128,7 @@ function registerGroupTools(server, callApi) {
|
|
|
122
128
|
"lexq_groups_reorder",
|
|
123
129
|
{
|
|
124
130
|
title: "Reorder Policy Groups",
|
|
131
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
125
132
|
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.",
|
|
126
133
|
inputSchema: z2.object({
|
|
127
134
|
groupIds: z2.array(z2.string().uuid()).describe("Group IDs in desired priority order (index 0 = priority 1)")
|
|
@@ -139,6 +146,7 @@ function registerGroupTools(server, callApi) {
|
|
|
139
146
|
"lexq_ab_test_start",
|
|
140
147
|
{
|
|
141
148
|
title: "Start A/B Test",
|
|
149
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
142
150
|
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%.",
|
|
143
151
|
inputSchema: z2.object({
|
|
144
152
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
@@ -152,6 +160,7 @@ function registerGroupTools(server, callApi) {
|
|
|
152
160
|
"lexq_ab_test_stop",
|
|
153
161
|
{
|
|
154
162
|
title: "Stop A/B Test",
|
|
163
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
155
164
|
description: "Stop a running A/B test. All traffic is restored to the control (current) version.",
|
|
156
165
|
inputSchema: z2.object({
|
|
157
166
|
groupId: z2.string().uuid().describe("Policy group ID")
|
|
@@ -163,6 +172,7 @@ function registerGroupTools(server, callApi) {
|
|
|
163
172
|
"lexq_ab_test_adjust",
|
|
164
173
|
{
|
|
165
174
|
title: "Adjust A/B Test",
|
|
175
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
166
176
|
description: "Adjust traffic rate of a running A/B test.",
|
|
167
177
|
inputSchema: z2.object({
|
|
168
178
|
groupId: z2.string().uuid().describe("Policy group ID"),
|
|
@@ -238,6 +248,7 @@ function registerVersionTools(server, callApi) {
|
|
|
238
248
|
"lexq_versions_list",
|
|
239
249
|
{
|
|
240
250
|
title: "List Policy Versions",
|
|
251
|
+
annotations: { readOnlyHint: true },
|
|
241
252
|
description: "List all versions of a policy group.",
|
|
242
253
|
inputSchema: z3.object({
|
|
243
254
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -253,6 +264,7 @@ function registerVersionTools(server, callApi) {
|
|
|
253
264
|
"lexq_versions_get",
|
|
254
265
|
{
|
|
255
266
|
title: "Get Policy Version",
|
|
267
|
+
annotations: { readOnlyHint: true },
|
|
256
268
|
description: "Get a single version by ID, including its rules and fact requirements.",
|
|
257
269
|
inputSchema: z3.object({
|
|
258
270
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -265,6 +277,7 @@ function registerVersionTools(server, callApi) {
|
|
|
265
277
|
"lexq_versions_create",
|
|
266
278
|
{
|
|
267
279
|
title: "Create Policy Version",
|
|
280
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
268
281
|
description: "Create a new DRAFT version in a policy group. Optionally provide a commit message and effective date range.",
|
|
269
282
|
inputSchema: z3.object({
|
|
270
283
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -279,6 +292,7 @@ function registerVersionTools(server, callApi) {
|
|
|
279
292
|
"lexq_versions_update",
|
|
280
293
|
{
|
|
281
294
|
title: "Update Policy Version",
|
|
295
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
282
296
|
description: "Update a DRAFT version. Only DRAFT versions can be modified. Only provided fields are changed.",
|
|
283
297
|
inputSchema: z3.object({
|
|
284
298
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -294,6 +308,7 @@ function registerVersionTools(server, callApi) {
|
|
|
294
308
|
"lexq_versions_delete",
|
|
295
309
|
{
|
|
296
310
|
title: "Delete Policy Version",
|
|
311
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
297
312
|
description: "Delete a DRAFT version. Only DRAFT versions can be deleted.",
|
|
298
313
|
inputSchema: z3.object({
|
|
299
314
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -306,6 +321,7 @@ function registerVersionTools(server, callApi) {
|
|
|
306
321
|
"lexq_versions_clone",
|
|
307
322
|
{
|
|
308
323
|
title: "Clone Policy Version",
|
|
324
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
309
325
|
description: "Clone an existing version to create a new DRAFT. Useful when the source version is already published.",
|
|
310
326
|
inputSchema: z3.object({
|
|
311
327
|
groupId: z3.string().uuid().describe("Policy group ID"),
|
|
@@ -339,6 +355,7 @@ function registerRuleTools(server, callApi) {
|
|
|
339
355
|
"lexq_rules_list",
|
|
340
356
|
{
|
|
341
357
|
title: "List Rules",
|
|
358
|
+
annotations: { readOnlyHint: true },
|
|
342
359
|
description: "List all rules in a version (priority ASC). Returns summary with conditionSummary and actionSummary.",
|
|
343
360
|
inputSchema: z4.object({
|
|
344
361
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -351,6 +368,7 @@ function registerRuleTools(server, callApi) {
|
|
|
351
368
|
"lexq_rules_get",
|
|
352
369
|
{
|
|
353
370
|
title: "Get Rule Detail",
|
|
371
|
+
annotations: { readOnlyHint: true },
|
|
354
372
|
description: "Get full rule detail including condition tree and action definitions.",
|
|
355
373
|
inputSchema: z4.object({
|
|
356
374
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -364,6 +382,7 @@ function registerRuleTools(server, callApi) {
|
|
|
364
382
|
"lexq_rules_create",
|
|
365
383
|
{
|
|
366
384
|
title: "Create Rule",
|
|
385
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
367
386
|
description: dedent`
|
|
368
387
|
Create a rule in a DRAFT version. Requires name, condition tree, and actions array. priority is auto-assigned (appended last); use lexq_rules_reorder to change order.
|
|
369
388
|
|
|
@@ -442,6 +461,7 @@ function registerRuleTools(server, callApi) {
|
|
|
442
461
|
"lexq_rules_update",
|
|
443
462
|
{
|
|
444
463
|
title: "Update Rule",
|
|
464
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
445
465
|
description: "Update an existing rule in a DRAFT version. Only provided fields are changed.",
|
|
446
466
|
inputSchema: z4.object({
|
|
447
467
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -463,6 +483,7 @@ function registerRuleTools(server, callApi) {
|
|
|
463
483
|
"lexq_rules_delete",
|
|
464
484
|
{
|
|
465
485
|
title: "Delete Rule",
|
|
486
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
466
487
|
description: "Delete a rule from a DRAFT version.",
|
|
467
488
|
inputSchema: z4.object({
|
|
468
489
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -483,6 +504,7 @@ function registerRuleTools(server, callApi) {
|
|
|
483
504
|
"lexq_rules_reorder",
|
|
484
505
|
{
|
|
485
506
|
title: "Reorder Rules",
|
|
507
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
486
508
|
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).",
|
|
487
509
|
inputSchema: z4.object({
|
|
488
510
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -504,6 +526,7 @@ function registerRuleTools(server, callApi) {
|
|
|
504
526
|
"lexq_rules_toggle",
|
|
505
527
|
{
|
|
506
528
|
title: "Toggle Rule",
|
|
529
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
507
530
|
description: "Enable or disable a rule without deleting it.",
|
|
508
531
|
inputSchema: z4.object({
|
|
509
532
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
@@ -535,6 +558,7 @@ function registerFactTools(server, callApi) {
|
|
|
535
558
|
"lexq_facts_list",
|
|
536
559
|
{
|
|
537
560
|
title: "List Fact Definitions",
|
|
561
|
+
annotations: { readOnlyHint: true },
|
|
538
562
|
description: "List all fact definitions (input variable schema). Shows key, type, required, and PII status. Always check this before creating rules.",
|
|
539
563
|
inputSchema: z5.object({
|
|
540
564
|
page: z5.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -552,6 +576,7 @@ function registerFactTools(server, callApi) {
|
|
|
552
576
|
"lexq_facts_create",
|
|
553
577
|
{
|
|
554
578
|
title: "Create Fact Definition",
|
|
579
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
555
580
|
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.",
|
|
556
581
|
inputSchema: z5.object({
|
|
557
582
|
key: z5.string().regex(FACT_KEY_PATTERN).describe("Variable key. Any casing; must start with a letter."),
|
|
@@ -570,6 +595,7 @@ function registerFactTools(server, callApi) {
|
|
|
570
595
|
"lexq_facts_update",
|
|
571
596
|
{
|
|
572
597
|
title: "Update Fact Definition",
|
|
598
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
573
599
|
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.",
|
|
574
600
|
inputSchema: z5.object({
|
|
575
601
|
factId: z5.string().uuid().describe("Fact definition ID"),
|
|
@@ -588,6 +614,7 @@ function registerFactTools(server, callApi) {
|
|
|
588
614
|
"lexq_facts_delete",
|
|
589
615
|
{
|
|
590
616
|
title: "Delete Fact Definition",
|
|
617
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
591
618
|
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.",
|
|
592
619
|
inputSchema: z5.object({
|
|
593
620
|
factId: z5.string().uuid().describe("Fact definition ID")
|
|
@@ -599,6 +626,7 @@ function registerFactTools(server, callApi) {
|
|
|
599
626
|
"lexq_facts_action_metadata",
|
|
600
627
|
{
|
|
601
628
|
title: "Get Action Runtime Fact Metadata",
|
|
629
|
+
annotations: { readOnlyHint: true },
|
|
602
630
|
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.",
|
|
603
631
|
inputSchema: z5.object({})
|
|
604
632
|
},
|
|
@@ -608,6 +636,7 @@ function registerFactTools(server, callApi) {
|
|
|
608
636
|
"lexq_facts_unregistered",
|
|
609
637
|
{
|
|
610
638
|
title: "List Unregistered Facts",
|
|
639
|
+
annotations: { readOnlyHint: true },
|
|
611
640
|
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.",
|
|
612
641
|
inputSchema: z5.object({
|
|
613
642
|
groupId: z5.string().uuid().describe("Policy group ID"),
|
|
@@ -620,6 +649,7 @@ function registerFactTools(server, callApi) {
|
|
|
620
649
|
"lexq_facts_export",
|
|
621
650
|
{
|
|
622
651
|
title: "Export Fact Catalog",
|
|
652
|
+
annotations: { readOnlyHint: true },
|
|
623
653
|
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.",
|
|
624
654
|
inputSchema: z5.object({
|
|
625
655
|
format: z5.enum(EXPORT_FORMATS).default("csv").describe("Export format"),
|
|
@@ -639,6 +669,7 @@ function registerDeployTools(server, callApi) {
|
|
|
639
669
|
"lexq_deploy_publish",
|
|
640
670
|
{
|
|
641
671
|
title: "Publish Version",
|
|
672
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
642
673
|
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.",
|
|
643
674
|
inputSchema: z6.object({
|
|
644
675
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -652,6 +683,7 @@ function registerDeployTools(server, callApi) {
|
|
|
652
683
|
"lexq_deploy_live",
|
|
653
684
|
{
|
|
654
685
|
title: "Deploy to Live",
|
|
686
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
655
687
|
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.",
|
|
656
688
|
inputSchema: z6.object({
|
|
657
689
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -667,6 +699,7 @@ function registerDeployTools(server, callApi) {
|
|
|
667
699
|
"lexq_deploy_rollback",
|
|
668
700
|
{
|
|
669
701
|
title: "Rollback Deployment",
|
|
702
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
670
703
|
description: "Rollback to the previous deployed version. Only available if there is a previous version.",
|
|
671
704
|
inputSchema: z6.object({
|
|
672
705
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -681,6 +714,7 @@ function registerDeployTools(server, callApi) {
|
|
|
681
714
|
"lexq_deploy_undeploy",
|
|
682
715
|
{
|
|
683
716
|
title: "Undeploy",
|
|
717
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
684
718
|
description: "Remove the live version from traffic. The version stays ACTIVE but no longer serves requests.",
|
|
685
719
|
inputSchema: z6.object({
|
|
686
720
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -695,6 +729,7 @@ function registerDeployTools(server, callApi) {
|
|
|
695
729
|
"lexq_deploy_schedule",
|
|
696
730
|
{
|
|
697
731
|
title: "Schedule Deployment",
|
|
732
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
698
733
|
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).",
|
|
699
734
|
inputSchema: z6.object({
|
|
700
735
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
@@ -710,6 +745,7 @@ function registerDeployTools(server, callApi) {
|
|
|
710
745
|
"lexq_deploy_unschedule",
|
|
711
746
|
{
|
|
712
747
|
title: "Cancel Scheduled Deployment",
|
|
748
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
713
749
|
description: "Cancel the pending scheduled deployment for a group. The version itself is not affected. Fails with P-039 if no pending schedule exists.",
|
|
714
750
|
inputSchema: z6.object({
|
|
715
751
|
groupId: z6.string().uuid().describe("Policy group ID")
|
|
@@ -721,6 +757,7 @@ function registerDeployTools(server, callApi) {
|
|
|
721
757
|
"lexq_deploy_schedules",
|
|
722
758
|
{
|
|
723
759
|
title: "List Scheduled Deployments",
|
|
760
|
+
annotations: { readOnlyHint: true },
|
|
724
761
|
description: "List scheduled deployments across all groups (all statuses: PENDING, EXECUTED, CANCELED, FAILED), newest first.",
|
|
725
762
|
inputSchema: z6.object({
|
|
726
763
|
page: z6.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -733,6 +770,7 @@ function registerDeployTools(server, callApi) {
|
|
|
733
770
|
"lexq_deploy_history",
|
|
734
771
|
{
|
|
735
772
|
title: "Deployment History",
|
|
773
|
+
annotations: { readOnlyHint: true },
|
|
736
774
|
description: "List deployment history across all groups.",
|
|
737
775
|
inputSchema: z6.object({
|
|
738
776
|
page: z6.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -756,6 +794,7 @@ function registerDeployTools(server, callApi) {
|
|
|
756
794
|
"lexq_deploy_detail",
|
|
757
795
|
{
|
|
758
796
|
title: "Deployment Detail",
|
|
797
|
+
annotations: { readOnlyHint: true },
|
|
759
798
|
description: "Get detailed info about a specific deployment including snapshot hash and integrity check.",
|
|
760
799
|
inputSchema: z6.object({
|
|
761
800
|
deploymentId: z6.string().uuid().describe("Deployment ID")
|
|
@@ -767,6 +806,7 @@ function registerDeployTools(server, callApi) {
|
|
|
767
806
|
"lexq_deploy_overview",
|
|
768
807
|
{
|
|
769
808
|
title: "Deployment Overview",
|
|
809
|
+
annotations: { readOnlyHint: true },
|
|
770
810
|
description: "Show current deployment status of all groups \u2014 which version is live, last deployment type, and deployer.",
|
|
771
811
|
inputSchema: z6.object({})
|
|
772
812
|
},
|
|
@@ -776,6 +816,7 @@ function registerDeployTools(server, callApi) {
|
|
|
776
816
|
"lexq_deploy_deployable",
|
|
777
817
|
{
|
|
778
818
|
title: "List Deployable Versions",
|
|
819
|
+
annotations: { readOnlyHint: true },
|
|
779
820
|
description: "List ACTIVE (published) versions that can be deployed for a group. Use this to find which versions are available before calling deploy live.",
|
|
780
821
|
inputSchema: z6.object({
|
|
781
822
|
groupId: z6.string().uuid().describe("Policy group ID")
|
|
@@ -787,6 +828,7 @@ function registerDeployTools(server, callApi) {
|
|
|
787
828
|
"lexq_deploy_diff",
|
|
788
829
|
{
|
|
789
830
|
title: "Deployment Diff",
|
|
831
|
+
annotations: { readOnlyHint: true },
|
|
790
832
|
description: "Compare rule snapshots between two versions. Shows added, removed, and modified rules. Useful for reviewing changes before deploying a new version.",
|
|
791
833
|
inputSchema: z6.object({
|
|
792
834
|
baseVersionId: z6.string().uuid().describe("Base version ID (typically the current live)"),
|
|
@@ -807,6 +849,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
807
849
|
"lexq_dry_run",
|
|
808
850
|
{
|
|
809
851
|
title: "Dry Run",
|
|
852
|
+
annotations: { readOnlyHint: true },
|
|
810
853
|
description: dedent2`
|
|
811
854
|
Execute a single dry run against a version. Tests how rules evaluate given input facts without side effects.
|
|
812
855
|
|
|
@@ -836,6 +879,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
836
879
|
"lexq_dry_run_compare",
|
|
837
880
|
{
|
|
838
881
|
title: "Dry Run Compare",
|
|
882
|
+
annotations: { readOnlyHint: true },
|
|
839
883
|
description: dedent2`
|
|
840
884
|
Compare dry run results between two versions using the same input facts. Useful for validating changes.
|
|
841
885
|
|
|
@@ -860,6 +904,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
860
904
|
"lexq_requirements",
|
|
861
905
|
{
|
|
862
906
|
title: "Analyze Requirements",
|
|
907
|
+
annotations: { readOnlyHint: true },
|
|
863
908
|
description: "Analyze which input facts a version requires. Returns required keys, types, and an example request body.",
|
|
864
909
|
inputSchema: z7.object({
|
|
865
910
|
groupId: z7.string().uuid().describe("Policy group ID"),
|
|
@@ -872,6 +917,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
872
917
|
"lexq_simulation_start",
|
|
873
918
|
{
|
|
874
919
|
title: "Start Simulation",
|
|
920
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
875
921
|
description: dedent2`
|
|
876
922
|
Start an Impact Simulation against historical, uploaded, or inline data.
|
|
877
923
|
|
|
@@ -913,6 +959,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
913
959
|
"lexq_simulation_status",
|
|
914
960
|
{
|
|
915
961
|
title: "Simulation Status",
|
|
962
|
+
annotations: { readOnlyHint: true },
|
|
916
963
|
description: "Get simulation status and results. Poll until status is COMPLETED or FAILED.",
|
|
917
964
|
inputSchema: z7.object({
|
|
918
965
|
simulationId: z7.string().uuid().describe("Simulation ID")
|
|
@@ -924,6 +971,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
924
971
|
"lexq_simulation_list",
|
|
925
972
|
{
|
|
926
973
|
title: "List Simulations",
|
|
974
|
+
annotations: { readOnlyHint: true },
|
|
927
975
|
description: "List simulation history with optional filters.",
|
|
928
976
|
inputSchema: z7.object({
|
|
929
977
|
page: z7.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -945,6 +993,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
945
993
|
"lexq_simulation_cancel",
|
|
946
994
|
{
|
|
947
995
|
title: "Cancel Simulation",
|
|
996
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
948
997
|
description: "Cancel a running or pending simulation.",
|
|
949
998
|
inputSchema: z7.object({
|
|
950
999
|
simulationId: z7.string().uuid().describe("Simulation ID")
|
|
@@ -956,6 +1005,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
956
1005
|
"lexq_simulation_export",
|
|
957
1006
|
{
|
|
958
1007
|
title: "Export Simulation",
|
|
1008
|
+
annotations: { readOnlyHint: true },
|
|
959
1009
|
description: "Export simulation results as JSON or CSV. Returns the raw data.",
|
|
960
1010
|
inputSchema: z7.object({
|
|
961
1011
|
simulationId: z7.string().uuid().describe("Simulation ID"),
|
|
@@ -970,6 +1020,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
970
1020
|
"lexq_dataset_upload",
|
|
971
1021
|
{
|
|
972
1022
|
title: "Upload Dataset",
|
|
1023
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
973
1024
|
description: dedent2`
|
|
974
1025
|
Upload inline CSV or JSON content as a simulation dataset.
|
|
975
1026
|
The content is uploaded to S3 and a path is returned in the "path" field.
|
|
@@ -1013,6 +1064,7 @@ function registerAnalyticsTools(server, callApi) {
|
|
|
1013
1064
|
"lexq_dataset_template",
|
|
1014
1065
|
{
|
|
1015
1066
|
title: "Download Dataset Template",
|
|
1067
|
+
annotations: { readOnlyHint: true },
|
|
1016
1068
|
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.",
|
|
1017
1069
|
inputSchema: z7.object({
|
|
1018
1070
|
groupId: z7.string().uuid().describe("Policy group ID"),
|
|
@@ -1042,6 +1094,7 @@ function registerProfileTools(server, callApi) {
|
|
|
1042
1094
|
"lexq_profile_overview",
|
|
1043
1095
|
{
|
|
1044
1096
|
title: "Group Latency Profile",
|
|
1097
|
+
annotations: { readOnlyHint: true },
|
|
1045
1098
|
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.`,
|
|
1046
1099
|
inputSchema: z8.object({
|
|
1047
1100
|
groupId: z8.string().uuid().describe("Policy group ID"),
|
|
@@ -1061,6 +1114,7 @@ function registerProfileTools(server, callApi) {
|
|
|
1061
1114
|
"lexq_profile_rule",
|
|
1062
1115
|
{
|
|
1063
1116
|
title: "Rule Latency Detail",
|
|
1117
|
+
annotations: { readOnlyHint: true },
|
|
1064
1118
|
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,
|
|
1065
1119
|
inputSchema: z8.object({
|
|
1066
1120
|
groupId: z8.string().uuid().describe("Policy group ID"),
|
|
@@ -1085,6 +1139,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1085
1139
|
"lexq_replay_decision",
|
|
1086
1140
|
{
|
|
1087
1141
|
title: "Replay a Decision",
|
|
1142
|
+
annotations: { readOnlyHint: true },
|
|
1088
1143
|
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.",
|
|
1089
1144
|
inputSchema: z9.object({
|
|
1090
1145
|
traceId: z9.string().describe("Trace ID of the past execution to replay"),
|
|
@@ -1097,6 +1152,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1097
1152
|
"lexq_replay_start",
|
|
1098
1153
|
{
|
|
1099
1154
|
title: "Start Window Replay (Blast Radius)",
|
|
1155
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1100
1156
|
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.",
|
|
1101
1157
|
inputSchema: z9.object({
|
|
1102
1158
|
candidateVersionId: z9.string().uuid().describe("Version to re-evaluate against"),
|
|
@@ -1113,6 +1169,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1113
1169
|
"lexq_replay_status",
|
|
1114
1170
|
{
|
|
1115
1171
|
title: "Get Replay Job Status",
|
|
1172
|
+
annotations: { readOnlyHint: true },
|
|
1116
1173
|
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.",
|
|
1117
1174
|
inputSchema: z9.object({
|
|
1118
1175
|
jobId: z9.string().describe("Replay job ID from lexq_replay_start")
|
|
@@ -1124,6 +1181,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1124
1181
|
"lexq_replay_list",
|
|
1125
1182
|
{
|
|
1126
1183
|
title: "List Replay Jobs",
|
|
1184
|
+
annotations: { readOnlyHint: true },
|
|
1127
1185
|
description: "List window replay job history (reverse-chronological). Lightweight items \u2014 use lexq_replay_status for summary and changed samples.",
|
|
1128
1186
|
inputSchema: z9.object({
|
|
1129
1187
|
page: z9.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1136,6 +1194,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1136
1194
|
"lexq_replay_cancel",
|
|
1137
1195
|
{
|
|
1138
1196
|
title: "Cancel Replay Job",
|
|
1197
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
1139
1198
|
description: "Cooperatively cancel a PENDING or RUNNING window replay job. Other states are rejected. VIEWER role cannot cancel.",
|
|
1140
1199
|
inputSchema: z9.object({
|
|
1141
1200
|
jobId: z9.string().describe("Replay job ID")
|
|
@@ -1147,6 +1206,7 @@ function registerReplayTools(server, callApi) {
|
|
|
1147
1206
|
"lexq_replay_export",
|
|
1148
1207
|
{
|
|
1149
1208
|
title: "Export Replay Result",
|
|
1209
|
+
annotations: { readOnlyHint: true },
|
|
1150
1210
|
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.",
|
|
1151
1211
|
inputSchema: z9.object({
|
|
1152
1212
|
jobId: z9.string().describe("Replay job ID"),
|
|
@@ -1164,6 +1224,7 @@ function registerHistoryTools(server, callApi) {
|
|
|
1164
1224
|
"lexq_history_list",
|
|
1165
1225
|
{
|
|
1166
1226
|
title: "List Execution History",
|
|
1227
|
+
annotations: { readOnlyHint: true },
|
|
1167
1228
|
description: "List policy execution history. Shows trace ID, group, version, status, match result, and latency.",
|
|
1168
1229
|
inputSchema: z10.object({
|
|
1169
1230
|
page: z10.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1191,6 +1252,7 @@ function registerHistoryTools(server, callApi) {
|
|
|
1191
1252
|
"lexq_history_get",
|
|
1192
1253
|
{
|
|
1193
1254
|
title: "Get Execution Detail",
|
|
1255
|
+
annotations: { readOnlyHint: true },
|
|
1194
1256
|
description: "Get full execution detail including inputFacts, mutatedFacts, generatedVariables, executionTraces, and decisionTraces.",
|
|
1195
1257
|
inputSchema: z10.object({
|
|
1196
1258
|
traceId: z10.string().describe("Trace ID from execution history")
|
|
@@ -1202,6 +1264,7 @@ function registerHistoryTools(server, callApi) {
|
|
|
1202
1264
|
"lexq_history_stats",
|
|
1203
1265
|
{
|
|
1204
1266
|
title: "Execution Statistics",
|
|
1267
|
+
annotations: { readOnlyHint: true },
|
|
1205
1268
|
description: "Get execution KPIs: total executions, success/failure counts, success rate, and average latency.",
|
|
1206
1269
|
inputSchema: z10.object({
|
|
1207
1270
|
groupId: z10.string().uuid().optional().describe("Filter by policy group"),
|
|
@@ -1226,6 +1289,7 @@ function registerProvenanceTools(server, callApi) {
|
|
|
1226
1289
|
"lexq_provenance_get",
|
|
1227
1290
|
{
|
|
1228
1291
|
title: "Get Decision Provenance",
|
|
1292
|
+
annotations: { readOnlyHint: true },
|
|
1229
1293
|
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.",
|
|
1230
1294
|
inputSchema: z11.object({
|
|
1231
1295
|
traceId: z11.string().describe("Trace ID of the execution")
|
|
@@ -1237,6 +1301,7 @@ function registerProvenanceTools(server, callApi) {
|
|
|
1237
1301
|
"lexq_pii_reveals_list",
|
|
1238
1302
|
{
|
|
1239
1303
|
title: "List PII Reveal Audits",
|
|
1304
|
+
annotations: { readOnlyHint: true },
|
|
1240
1305
|
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.",
|
|
1241
1306
|
inputSchema: z11.object({
|
|
1242
1307
|
page: z11.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1267,6 +1332,7 @@ function registerLogTools(server, callApi) {
|
|
|
1267
1332
|
"lexq_logs_list",
|
|
1268
1333
|
{
|
|
1269
1334
|
title: "List Failure Logs",
|
|
1335
|
+
annotations: { readOnlyHint: true },
|
|
1270
1336
|
description: "List system failure logs from background tasks (platform event webhooks, scheduled deployments).",
|
|
1271
1337
|
inputSchema: z12.object({
|
|
1272
1338
|
page: z12.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1292,6 +1358,7 @@ function registerLogTools(server, callApi) {
|
|
|
1292
1358
|
"lexq_logs_get",
|
|
1293
1359
|
{
|
|
1294
1360
|
title: "Get Failure Log",
|
|
1361
|
+
annotations: { readOnlyHint: true },
|
|
1295
1362
|
description: "Get failure log detail by ID.",
|
|
1296
1363
|
inputSchema: z12.object({
|
|
1297
1364
|
logId: z12.string().uuid().describe("Failure log ID")
|
|
@@ -1303,6 +1370,7 @@ function registerLogTools(server, callApi) {
|
|
|
1303
1370
|
"lexq_logs_action",
|
|
1304
1371
|
{
|
|
1305
1372
|
title: "Process Failure Log",
|
|
1373
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1306
1374
|
description: "Process a single failure log: RESOLVE (mark as manually fixed) or IGNORE (skip intentionally).",
|
|
1307
1375
|
inputSchema: z12.object({
|
|
1308
1376
|
logId: z12.string().uuid().describe("Failure log ID"),
|
|
@@ -1317,6 +1385,7 @@ function registerLogTools(server, callApi) {
|
|
|
1317
1385
|
"lexq_logs_bulk_action",
|
|
1318
1386
|
{
|
|
1319
1387
|
title: "Bulk Process Failure Logs",
|
|
1388
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1320
1389
|
description: "Process multiple failure logs at once. Provide an array of log IDs and the action.",
|
|
1321
1390
|
inputSchema: z12.object({
|
|
1322
1391
|
logIds: z12.array(z12.string().uuid()).describe("Array of failure log IDs"),
|
|
@@ -1336,6 +1405,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1336
1405
|
"lexq_webhook_subscriptions_list",
|
|
1337
1406
|
{
|
|
1338
1407
|
title: "List Webhook Subscriptions",
|
|
1408
|
+
annotations: { readOnlyHint: true },
|
|
1339
1409
|
description: "List platform event webhook subscriptions. These receive deployment lifecycle notifications (publish, deploy, rollback, undeploy).",
|
|
1340
1410
|
inputSchema: z13.object({
|
|
1341
1411
|
page: z13.number().int().min(0).default(0).describe("Page number"),
|
|
@@ -1351,6 +1421,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1351
1421
|
"lexq_webhook_subscriptions_get",
|
|
1352
1422
|
{
|
|
1353
1423
|
title: "Get Webhook Subscription",
|
|
1424
|
+
annotations: { readOnlyHint: true },
|
|
1354
1425
|
description: "Get webhook subscription detail by ID.",
|
|
1355
1426
|
inputSchema: z13.object({
|
|
1356
1427
|
id: z13.string().uuid().describe("Webhook subscription ID")
|
|
@@ -1362,6 +1433,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1362
1433
|
"lexq_webhook_subscriptions_save",
|
|
1363
1434
|
{
|
|
1364
1435
|
title: "Save Webhook Subscription",
|
|
1436
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
1365
1437
|
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": "..."}).',
|
|
1366
1438
|
inputSchema: z13.object({
|
|
1367
1439
|
id: z13.string().uuid().optional().describe("Subscription ID (omit to create, provide to update)"),
|
|
@@ -1379,6 +1451,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1379
1451
|
"lexq_webhook_subscriptions_delete",
|
|
1380
1452
|
{
|
|
1381
1453
|
title: "Delete Webhook Subscription",
|
|
1454
|
+
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
1382
1455
|
description: "Delete a webhook subscription by ID.",
|
|
1383
1456
|
inputSchema: z13.object({
|
|
1384
1457
|
id: z13.string().uuid().describe("Webhook subscription ID")
|
|
@@ -1390,6 +1463,7 @@ function registerWebhookSubscriptionTools(server, callApi) {
|
|
|
1390
1463
|
"lexq_webhook_subscriptions_test",
|
|
1391
1464
|
{
|
|
1392
1465
|
title: "Test Webhook Subscription",
|
|
1466
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1393
1467
|
description: "Send a test event to verify webhook connectivity. Returns the HTTP status code and success/failure message.",
|
|
1394
1468
|
inputSchema: z13.object({
|
|
1395
1469
|
id: z13.string().uuid().describe("Webhook subscription ID")
|
|
@@ -1406,6 +1480,7 @@ function registerDomainTemplateTools(server, callApi) {
|
|
|
1406
1480
|
"lexq_domain_templates_list",
|
|
1407
1481
|
{
|
|
1408
1482
|
title: "List Domain Templates",
|
|
1483
|
+
annotations: { readOnlyHint: true },
|
|
1409
1484
|
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.",
|
|
1410
1485
|
inputSchema: z14.object({})
|
|
1411
1486
|
},
|
|
@@ -1415,6 +1490,7 @@ function registerDomainTemplateTools(server, callApi) {
|
|
|
1415
1490
|
"lexq_domain_templates_preview",
|
|
1416
1491
|
{
|
|
1417
1492
|
title: "Preview Domain Template",
|
|
1493
|
+
annotations: { readOnlyHint: true },
|
|
1418
1494
|
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.",
|
|
1419
1495
|
inputSchema: z14.object({
|
|
1420
1496
|
template: z14.string().describe(
|
|
@@ -1428,6 +1504,7 @@ function registerDomainTemplateTools(server, callApi) {
|
|
|
1428
1504
|
"lexq_domain_templates_apply",
|
|
1429
1505
|
{
|
|
1430
1506
|
title: "Apply Domain Template",
|
|
1507
|
+
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
1431
1508
|
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.",
|
|
1432
1509
|
inputSchema: z14.object({
|
|
1433
1510
|
template: z14.string().describe("Domain template key to apply (e.g. ECOMMERCE)."),
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lexq/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"mcpName": "io.lexq/lexq",
|
|
4
5
|
"description": "LexQ CLI — manage policies, simulate rules, and deploy from the terminal. Built for humans and AI agents.",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"bin": {
|
|
@@ -32,6 +33,8 @@
|
|
|
32
33
|
"constants:check": "node scripts/check-constants.mjs",
|
|
33
34
|
"surface:check": "node scripts/check-public-surface.mjs",
|
|
34
35
|
"ab-key:check": "node scripts/check-ab-key.mjs",
|
|
36
|
+
"registry:check": "node scripts/check-registry-manifest.mjs",
|
|
37
|
+
"protocol:check": "node scripts/check-protocol-revisions.mjs",
|
|
35
38
|
"schemas:check": "node scripts/check-tool-schemas.mjs",
|
|
36
39
|
"schemas:update": "node scripts/check-tool-schemas.mjs --update",
|
|
37
40
|
"start": "node dist/index.js",
|