@prysmid/mcp 0.4.0 → 0.6.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
@@ -277,8 +277,8 @@ function clearToken(env = process.env) {
277
277
  function defineTool(t) {
278
278
  return t;
279
279
  }
280
- function registerAll(server, ctx, tools9) {
281
- for (const tool of tools9) {
280
+ function registerAll(server, ctx, tools15) {
281
+ for (const tool of tools15) {
282
282
  server.registerTool(
283
283
  tool.name,
284
284
  {
@@ -429,13 +429,38 @@ var tools = [
429
429
  regenerateAppSecret
430
430
  ];
431
431
 
432
- // src/tools/billing.ts
432
+ // src/tools/audit.ts
433
433
  import { z as z2 } from "zod";
434
+ var exportAuditLog = defineTool({
435
+ name: "export_audit_log",
436
+ description: "Export a workspace's audit trail as NDJSON (default) or CSV. Filter by `org_id` (a specific business org, matches meta.org_id), `action` (exact, e.g. `idp.create`), and a created_at window (`start`/`end`, ISO-8601). `limit` caps rows (default 10000, max 50000). Returns the raw export text \u2014 narrow the window to page through large trails.",
437
+ inputShape: {
438
+ workspace: z2.string().min(1),
439
+ format: z2.enum(["ndjson", "csv"]).default("ndjson").describe(
440
+ "ndjson (default) = one JSON object per line, best for SIEM. csv = flat columns with meta JSON-encoded in one cell."
441
+ ),
442
+ org_id: z2.string().min(1).optional().describe(
443
+ "Scope to one business org (matches meta.org_id). Omit for the whole workspace."
444
+ ),
445
+ action: z2.string().min(1).optional().describe("Exact audit action to filter, e.g. `idp.create`."),
446
+ start: z2.string().optional().describe("ISO-8601 timestamp; only rows created at/after this."),
447
+ end: z2.string().optional().describe("ISO-8601 timestamp; only rows created before this."),
448
+ limit: z2.number().int().min(1).max(5e4).optional()
449
+ },
450
+ handler: async ({ workspace, ...query }, { client }) => client.request(
451
+ `/v1/workspaces/${encodeURIComponent(workspace)}/audit-log/export`,
452
+ { query }
453
+ )
454
+ });
455
+ var tools2 = [exportAuditLog];
456
+
457
+ // src/tools/billing.ts
458
+ import { z as z3 } from "zod";
434
459
  var getBilling = defineTool({
435
460
  name: "get_billing",
436
461
  description: "Get current billing state: plan, subscription status, current period, spending_cap_cents, signups_blocked.",
437
462
  inputShape: {
438
- workspace: z2.string().min(1)
463
+ workspace: z3.string().min(1)
439
464
  },
440
465
  handler: async ({ workspace }, { client }) => client.request(
441
466
  `/v1/workspaces/${encodeURIComponent(workspace)}/billing`
@@ -445,8 +470,8 @@ var setSpendingCap = defineTool({
445
470
  name: "set_spending_cap",
446
471
  description: "Cap monthly Pro overage spend (cents). Pass null to remove cap (unlimited). When projected overage exceeds cap, signups_blocked flips on.",
447
472
  inputShape: {
448
- workspace: z2.string().min(1),
449
- spending_cap_cents: z2.number().int().min(0).max(1e7).nullable().describe("Max overage cents per period; null = unlimited")
473
+ workspace: z3.string().min(1),
474
+ spending_cap_cents: z3.number().int().min(0).max(1e7).nullable().describe("Max overage cents per period; null = unlimited")
450
475
  },
451
476
  handler: async ({ workspace, spending_cap_cents }, { client }) => client.request(
452
477
  `/v1/workspaces/${encodeURIComponent(workspace)}/billing/spending-cap`,
@@ -457,8 +482,8 @@ var startCheckout = defineTool({
457
482
  name: "start_billing_checkout",
458
483
  description: "Create a Stripe Checkout session for upgrading. Returns the URL the user must visit. Plan must be `pro` (Free has no checkout; Enterprise is sales-only).",
459
484
  inputShape: {
460
- workspace: z2.string().min(1),
461
- plan: z2.enum(["pro"])
485
+ workspace: z3.string().min(1),
486
+ plan: z3.enum(["pro"])
462
487
  },
463
488
  handler: async ({ workspace, plan }, { client }) => client.request(
464
489
  `/v1/workspaces/${encodeURIComponent(workspace)}/billing/checkout`,
@@ -469,14 +494,14 @@ var startBillingPortal = defineTool({
469
494
  name: "start_billing_portal",
470
495
  description: "Create a Stripe customer-portal session URL where the user manages payment methods, downloads invoices, cancels subscription.",
471
496
  inputShape: {
472
- workspace: z2.string().min(1)
497
+ workspace: z3.string().min(1)
473
498
  },
474
499
  handler: async ({ workspace }, { client }) => client.request(
475
500
  `/v1/workspaces/${encodeURIComponent(workspace)}/billing/portal`,
476
501
  { method: "POST" }
477
502
  )
478
503
  });
479
- var tools2 = [
504
+ var tools3 = [
480
505
  getBilling,
481
506
  setSpendingCap,
482
507
  startCheckout,
@@ -484,12 +509,12 @@ var tools2 = [
484
509
  ];
485
510
 
486
511
  // src/tools/branding.ts
487
- import { z as z3 } from "zod";
512
+ import { z as z4 } from "zod";
488
513
  var getBranding = defineTool({
489
514
  name: "get_branding",
490
515
  description: "Return the workspace's active branding policy (colors, fonts, hide-prysmid-watermark flag, logo URLs).",
491
516
  inputShape: {
492
- workspace: z3.string().min(1)
517
+ workspace: z4.string().min(1)
493
518
  },
494
519
  handler: async ({ workspace }, { client }) => client.request(
495
520
  `/v1/workspaces/${encodeURIComponent(workspace)}/branding`
@@ -499,12 +524,12 @@ var updateBranding = defineTool({
499
524
  name: "update_branding",
500
525
  description: "Update branding colors and watermark. Hex colors as `#RRGGBB`. Activates the policy after update \u2014 change shows on next login screen render.",
501
526
  inputShape: {
502
- workspace: z3.string().min(1),
503
- primary_color: z3.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
504
- background_color: z3.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
505
- warn_color: z3.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
506
- font_color: z3.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
507
- disable_watermark: z3.boolean().optional().describe(
527
+ workspace: z4.string().min(1),
528
+ primary_color: z4.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
529
+ background_color: z4.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
530
+ warn_color: z4.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
531
+ font_color: z4.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
532
+ disable_watermark: z4.boolean().optional().describe(
508
533
  "Hide 'Powered by Prysmid' on the login screen (Pro+ only \u2014 Free silently ignored)."
509
534
  )
510
535
  },
@@ -513,23 +538,23 @@ var updateBranding = defineTool({
513
538
  { method: "PATCH", body }
514
539
  )
515
540
  });
516
- var tools3 = [getBranding, updateBranding];
541
+ var tools4 = [getBranding, updateBranding];
517
542
 
518
543
  // src/tools/curated.ts
519
- import { z as z4 } from "zod";
520
- var SetupWorkspaceOutput = z4.object({
521
- workspace_id: z4.string(),
522
- slug: z4.string(),
523
- auth_domain: z4.string(),
524
- state: z4.string()
544
+ import { z as z5 } from "zod";
545
+ var SetupWorkspaceOutput = z5.object({
546
+ workspace_id: z5.string(),
547
+ slug: z5.string(),
548
+ auth_domain: z5.string(),
549
+ state: z5.string()
525
550
  });
526
551
  var setupPrysmidWorkspace = defineTool({
527
552
  name: "setup_prysmid_workspace",
528
553
  description: "Create a new workspace and wait until it's fully provisioned (Zitadel instance, SMTP, DNS). Returns the live auth_domain ready to integrate.",
529
554
  inputShape: {
530
- slug: z4.string().min(2).max(63).regex(/^[a-z0-9-]+$/),
531
- display_name: z4.string().min(1),
532
- timeout_seconds: z4.number().int().min(10).max(300).default(120).describe("Max time to wait for provisioning before returning.")
555
+ slug: z5.string().min(2).max(63).regex(/^[a-z0-9-]+$/),
556
+ display_name: z5.string().min(1),
557
+ timeout_seconds: z5.number().int().min(10).max(300).default(120).describe("Max time to wait for provisioning before returning.")
533
558
  },
534
559
  handler: async ({ slug, display_name, timeout_seconds }, { client, log }) => {
535
560
  const created = await client.request("/v1/workspaces", {
@@ -569,10 +594,10 @@ var enableGoogleLogin = defineTool({
569
594
  name: "enable_google_login",
570
595
  description: "Add Google as an identity provider on a workspace and enable external IdPs in the login policy. Hands you a checklist if external IdPs were already disabled \u2014 agent should confirm before flipping that flag.",
571
596
  inputShape: {
572
- workspace: z4.string().min(1),
573
- google_client_id: z4.string().min(1),
574
- google_client_secret: z4.string().min(1),
575
- name: z4.string().default("Google")
597
+ workspace: z5.string().min(1),
598
+ google_client_id: z5.string().min(1),
599
+ google_client_secret: z5.string().min(1),
600
+ name: z5.string().default("Google")
576
601
  },
577
602
  handler: async ({ workspace, google_client_id, google_client_secret, name }, { client }) => {
578
603
  const idp = await client.request(
@@ -600,13 +625,21 @@ function countItems(resp) {
600
625
  if (Array.isArray(resp.items)) return resp.items.length;
601
626
  return 0;
602
627
  }
628
+ function listOf(resp) {
629
+ if (Array.isArray(resp)) return resp;
630
+ if (Array.isArray(resp.items)) return resp.items;
631
+ return [];
632
+ }
603
633
  var prysmidSetupCheck = defineTool({
604
634
  name: "prysmid_setup_check",
605
- description: "Run a readiness checklist on a workspace: state=active, \u22651 OIDC app, \u22651 IdP OR password+register enabled, branding has a primary_color set, login_policy reasonable. Returns pass/fail per item plus a summary verdict.",
635
+ description: "Run a readiness checklist on a workspace: state=active, \u22651 OIDC app, \u22651 IdP OR password+register enabled, branding has a primary_color set, login_policy reasonable, AND (by default) every external IdP probes successfully against its upstream provider. Returns pass/fail per item plus a summary verdict. Set `probe_idps=false` to skip the live probe (faster, but won't catch redirect_uri_mismatch or invalid client_secret until a real end-user hits the broken IdP).",
606
636
  inputShape: {
607
- workspace: z4.string().min(1)
637
+ workspace: z5.string().min(1),
638
+ probe_idps: z5.boolean().optional().describe(
639
+ "Run a live probe against each external IdP's upstream authorize endpoint. Default true. Set false to skip if the latency matters more than the safety (will not catch redirect_uri_mismatch or invalid_client until a real end-user signs in)."
640
+ )
608
641
  },
609
- handler: async ({ workspace }, { client }) => {
642
+ handler: async ({ workspace, probe_idps = true }, { client }) => {
610
643
  const ws = await client.request(
611
644
  `/v1/workspaces/${encodeURIComponent(workspace)}`
612
645
  );
@@ -624,6 +657,7 @@ var prysmidSetupCheck = defineTool({
624
657
  );
625
658
  const appsCount = countItems(appsResp);
626
659
  const idpsCount = countItems(idpsResp);
660
+ const idpItems = listOf(idpsResp);
627
661
  const passwordsOpen = policy.allow_username_password === true && policy.allow_register === true;
628
662
  const checks = [
629
663
  {
@@ -651,134 +685,600 @@ var prysmidSetupCheck = defineTool({
651
685
  details: policy.force_mfa ? "force_mfa=true" : idpsCount > 0 ? `${idpsCount} external IdP(s) \u2014 strength delegated upstream` : "MFA off and no external IdPs \u2014 passwords-only is weak"
652
686
  }
653
687
  ];
688
+ if (probe_idps && idpItems.length > 0) {
689
+ const probeResults = [];
690
+ for (const idp of idpItems) {
691
+ try {
692
+ const probe = await client.request(
693
+ `/v1/workspaces/${encodeURIComponent(workspace)}/idps/${encodeURIComponent(idp.id)}/probe`,
694
+ { method: "POST" }
695
+ );
696
+ probeResults.push({ id: idp.id, result: probe });
697
+ } catch (err) {
698
+ probeResults.push({
699
+ id: idp.id,
700
+ result: { ok: false, provider_reachable: false },
701
+ error: err instanceof Error ? err.message : String(err)
702
+ });
703
+ }
704
+ }
705
+ const allOk = probeResults.every((r) => r.result.ok);
706
+ const summary = probeResults.map((r) => {
707
+ const code = r.result.error_code ? ` (${r.result.error_code})` : "";
708
+ return `${r.id}=${r.result.ok ? "ok" : "fail"}${code}`;
709
+ }).join(", ");
710
+ const firstFailure = probeResults.find((r) => !r.result.ok);
711
+ const details = firstFailure ? `${summary}. First failure: ${firstFailure.result.error_detail ?? firstFailure.error ?? "no detail"}` : summary;
712
+ checks.push({
713
+ ok: allOk,
714
+ name: "idps_functional",
715
+ details
716
+ });
717
+ } else if (idpItems.length > 0) {
718
+ checks.push({
719
+ ok: true,
720
+ name: "idps_functional",
721
+ details: "skipped (probe_idps=false); won't catch redirect_uri_mismatch or invalid_client until a real end-user signs in."
722
+ });
723
+ }
654
724
  const verdict = checks.every((c) => c.ok) ? "ready" : "incomplete";
655
725
  return { verdict, checks };
656
726
  }
657
727
  });
658
- var tools4 = [
728
+ var tools5 = [
659
729
  setupPrysmidWorkspace,
660
730
  enableGoogleLogin,
661
731
  prysmidSetupCheck
662
732
  ];
663
733
 
734
+ // src/tools/grants.ts
735
+ import { z as z6 } from "zod";
736
+ var grantUserToOrganization = defineTool({
737
+ name: "grant_user_to_organization",
738
+ description: "Grant a user access to an organization's project with a set of role keys. The user does NOT need to be a member of the org \u2014 that's the point. Idempotent at the (user, org, project) tuple: duplicates return 502 from Zitadel.",
739
+ inputShape: {
740
+ workspace: z6.string().min(1),
741
+ org_id: z6.string().min(1).describe("Zitadel org id of the org GRANTING access."),
742
+ user_id: z6.string().min(1).describe(
743
+ "Zitadel user id. The user's home org is irrelevant \u2014 grants are cross-org."
744
+ ),
745
+ project_id: z6.string().min(1).describe(
746
+ "Zitadel project id this grant is for. Look it up via list_apps \u2014 every OIDC app belongs to a project."
747
+ ),
748
+ role_keys: z6.array(z6.string()).default([]).describe(
749
+ "Role keys defined on the target project. Empty list = bare membership (still gates access)."
750
+ )
751
+ },
752
+ handler: async ({ workspace, org_id, ...body }, { client }) => client.request(
753
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/grants`,
754
+ { method: "POST", body }
755
+ )
756
+ });
757
+ var listGrantsInOrganization = defineTool({
758
+ name: "list_grants_in_organization",
759
+ description: "List all grants owned by an organization. Returns each grant with the granted user_id, project_id, role_keys, and the org's tenant_id (the value users will see as `tenant_id` claim when this grant is active).",
760
+ inputShape: {
761
+ workspace: z6.string().min(1),
762
+ org_id: z6.string().min(1)
763
+ },
764
+ handler: async ({ workspace, org_id }, { client }) => client.request(
765
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/grants`
766
+ )
767
+ });
768
+ var listGrantsForUser = defineTool({
769
+ name: "list_grants_for_user",
770
+ description: "List all grants held by a user across orgs in this workspace. Useful for 'what does this user have access to?' and offboarding/audit reviews.",
771
+ inputShape: {
772
+ workspace: z6.string().min(1),
773
+ user_id: z6.string().min(1)
774
+ },
775
+ handler: async ({ workspace, user_id }, { client }) => client.request(
776
+ `/v1/workspaces/${encodeURIComponent(workspace)}/users/${encodeURIComponent(user_id)}/grants`
777
+ )
778
+ });
779
+ var updateGrantRoles = defineTool({
780
+ name: "update_grant_roles",
781
+ description: "Replace the role_keys on an existing grant. The set is replaced wholesale \u2014 pass the full desired list, not a delta.",
782
+ inputShape: {
783
+ workspace: z6.string().min(1),
784
+ org_id: z6.string().min(1),
785
+ grant_id: z6.string().min(1),
786
+ role_keys: z6.array(z6.string())
787
+ },
788
+ handler: async ({ workspace, org_id, grant_id, role_keys }, { client }) => client.request(
789
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/grants/${encodeURIComponent(grant_id)}`,
790
+ { method: "PATCH", body: { role_keys } }
791
+ )
792
+ });
793
+ var deactivateGrant = defineTool({
794
+ name: "deactivate_grant",
795
+ description: "Temporarily suspend a grant without revoking it. Idempotent. Re-enable later with reactivate_grant.",
796
+ inputShape: {
797
+ workspace: z6.string().min(1),
798
+ org_id: z6.string().min(1),
799
+ grant_id: z6.string().min(1)
800
+ },
801
+ handler: async ({ workspace, org_id, grant_id }, { client }) => client.request(
802
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/grants/${encodeURIComponent(grant_id)}/_deactivate`,
803
+ { method: "POST" }
804
+ )
805
+ });
806
+ var reactivateGrant = defineTool({
807
+ name: "reactivate_grant",
808
+ description: "Re-enable a previously deactivated grant. Idempotent.",
809
+ inputShape: {
810
+ workspace: z6.string().min(1),
811
+ org_id: z6.string().min(1),
812
+ grant_id: z6.string().min(1)
813
+ },
814
+ handler: async ({ workspace, org_id, grant_id }, { client }) => client.request(
815
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/grants/${encodeURIComponent(grant_id)}/_reactivate`,
816
+ { method: "POST" }
817
+ )
818
+ });
819
+ var revokeGrant = defineTool({
820
+ name: "revoke_grant",
821
+ description: "Permanently revoke a grant. Idempotent \u2014 204 even if the Zitadel-side grant is already gone. Emits a `grant.revoked` audit event (will fire a webhook in slice X5).",
822
+ inputShape: {
823
+ workspace: z6.string().min(1),
824
+ org_id: z6.string().min(1),
825
+ grant_id: z6.string().min(1)
826
+ },
827
+ handler: async ({ workspace, org_id, grant_id }, { client }) => client.request(
828
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/grants/${encodeURIComponent(grant_id)}`,
829
+ { method: "DELETE" }
830
+ )
831
+ });
832
+ var tools6 = [
833
+ grantUserToOrganization,
834
+ listGrantsInOrganization,
835
+ listGrantsForUser,
836
+ updateGrantRoles,
837
+ deactivateGrant,
838
+ reactivateGrant,
839
+ revokeGrant
840
+ ];
841
+
664
842
  // src/tools/idps.ts
665
- import { z as z5 } from "zod";
843
+ import { z as z7 } from "zod";
844
+ var orgIdArg = z7.string().min(1).optional().describe(
845
+ "Optional Zitadel org id to scope this operation to a specific business org inside the workspace. Omit for the workspace's home org (backwards-compat)."
846
+ );
847
+ var providerOptionsSchema = z7.object({
848
+ is_creation_allowed: z7.boolean().optional(),
849
+ is_auto_creation: z7.boolean().optional().describe(
850
+ "JIT provisioning: True auto-creates a Prysm:ID user on first external login. The most common X6 flag \u2014 set False for tightly-controlled enterprise tenants where seats are granted manually."
851
+ ),
852
+ is_auto_update: z7.boolean().optional(),
853
+ is_linking_allowed: z7.boolean().optional(),
854
+ auto_linking: z7.enum(["unspecified", "username", "email"]).optional().describe(
855
+ "How to merge an external first-login into an existing Prysm:ID user. `username` matches user_name, `email` matches verified email, `unspecified` disables auto-linking."
856
+ )
857
+ }).optional().describe(
858
+ "X6: JIT + linking behaviour. Omitted fields fall back to defaults on create (auto-create + auto-update + link-by-username) or preserve current state on patch."
859
+ );
666
860
  var listIdps = defineTool({
667
861
  name: "list_idps",
668
- description: "List identity providers (Google/GitHub/Microsoft/OIDC) configured on a workspace.",
862
+ description: "List identity providers (Google/GitHub/Microsoft/OIDC) configured on a workspace. Pass `org_id` to list IdPs of a specific business org.",
669
863
  inputShape: {
670
- workspace: z5.string().min(1)
864
+ workspace: z7.string().min(1),
865
+ org_id: orgIdArg
671
866
  },
672
- handler: async ({ workspace }, { client }) => client.request(`/v1/workspaces/${encodeURIComponent(workspace)}/idps`)
867
+ handler: async ({ workspace, org_id }, { client }) => client.request(`/v1/workspaces/${encodeURIComponent(workspace)}/idps`, {
868
+ query: { org_id }
869
+ })
673
870
  });
674
871
  var addIdp = defineTool({
675
872
  name: "add_idp",
676
- description: "Add an identity provider to the workspace and attach it to the login policy in one atomic call.",
873
+ description: "Add an identity provider to the workspace and attach it to the login policy in one atomic call. Pass `org_id` to attach the IdP to a specific business org (multi-tenant setup) instead of the workspace's home org. Pass `provider_options` to control JIT provisioning + account-linking behaviour (X6).",
677
874
  inputShape: {
678
- workspace: z5.string().min(1),
679
- type: z5.enum(["google", "github", "microsoft", "oidc"]).describe("Identity provider kind. `microsoft` covers Azure AD / Entra."),
680
- name: z5.string().min(1).describe("Display name shown on login screen"),
681
- client_id: z5.string().min(1),
682
- client_secret: z5.string().min(1),
683
- scopes: z5.array(z5.string()).optional(),
684
- issuer: z5.string().url().optional().describe("Required for `oidc`; ignored otherwise"),
685
- tenant_id: z5.string().optional().describe(
875
+ workspace: z7.string().min(1),
876
+ org_id: orgIdArg,
877
+ type: z7.enum(["google", "github", "microsoft", "oidc"]).describe("Identity provider kind. `microsoft` covers Azure AD / Entra."),
878
+ name: z7.string().min(1).describe("Display name shown on login screen"),
879
+ client_id: z7.string().min(1),
880
+ client_secret: z7.string().min(1),
881
+ scopes: z7.array(z7.string()).optional(),
882
+ issuer: z7.string().url().optional().describe("Required for `oidc`; ignored otherwise"),
883
+ tenant_id: z7.string().optional().describe(
686
884
  "Optional for `microsoft` \u2014 lock to a specific Entra tenant GUID. Default accepts any account."
687
- )
885
+ ),
886
+ provider_options: providerOptionsSchema
688
887
  },
689
- handler: async ({ workspace, ...body }, { client }) => client.request(
690
- `/v1/workspaces/${encodeURIComponent(workspace)}/idps`,
691
- { method: "POST", body }
692
- )
888
+ handler: async ({ workspace, org_id, ...body }, { client }) => client.request(`/v1/workspaces/${encodeURIComponent(workspace)}/idps`, {
889
+ method: "POST",
890
+ body,
891
+ query: { org_id }
892
+ })
693
893
  });
694
894
  var deleteIdp = defineTool({
695
895
  name: "delete_idp",
696
- description: "Remove an identity provider. Strips it from the login policy then deletes the config. Idempotent.",
896
+ description: "Remove an identity provider. Strips it from the login policy then deletes the config. Idempotent. Pass `org_id` to target a specific business org's IdP.",
697
897
  inputShape: {
698
- workspace: z5.string().min(1),
699
- idp_id: z5.string().min(1)
898
+ workspace: z7.string().min(1),
899
+ org_id: orgIdArg,
900
+ idp_id: z7.string().min(1)
700
901
  },
701
- handler: async ({ workspace, idp_id }, { client }) => client.request(
902
+ handler: async ({ workspace, org_id, idp_id }, { client }) => client.request(
702
903
  `/v1/workspaces/${encodeURIComponent(workspace)}/idps/${encodeURIComponent(idp_id)}`,
703
- { method: "DELETE" }
904
+ { method: "DELETE", query: { org_id } }
704
905
  )
705
906
  });
706
907
  var getIdp = defineTool({
707
908
  name: "get_idp",
708
- description: "Fetch full detail for one identity provider: type, state, client_id, issuer/tenant (when applicable), scopes, secret_updated_at, created_at. Never returns the client_secret.",
909
+ description: "Fetch full detail for one identity provider: type, state, client_id, issuer/tenant (when applicable), scopes, secret_updated_at, created_at. Never returns the client_secret. Pass `org_id` to scope to a business org.",
709
910
  inputShape: {
710
- workspace: z5.string().min(1),
711
- idp_id: z5.string().min(1)
911
+ workspace: z7.string().min(1),
912
+ org_id: orgIdArg,
913
+ idp_id: z7.string().min(1)
712
914
  },
713
- handler: async ({ workspace, idp_id }, { client }) => client.request(
714
- `/v1/workspaces/${encodeURIComponent(workspace)}/idps/${encodeURIComponent(idp_id)}`
915
+ handler: async ({ workspace, org_id, idp_id }, { client }) => client.request(
916
+ `/v1/workspaces/${encodeURIComponent(workspace)}/idps/${encodeURIComponent(idp_id)}`,
917
+ { query: { org_id } }
715
918
  )
716
919
  });
717
920
  var updateIdp = defineTool({
718
921
  name: "update_idp",
719
- description: "Patch mutable fields on an identity provider. All fields optional. Passing client_secret rotates the upstream-issued value (Google/GitHub/Microsoft/OIDC client secret stored in Prysmid). Passing client_id retargets to a different upstream client. issuer/tenant_id apply only when relevant to the IdP type.",
922
+ description: "Patch mutable fields on an identity provider. All fields optional. Passing client_secret rotates the upstream-issued value (Google/GitHub/Microsoft/OIDC client secret stored in Prysmid). Passing client_id retargets to a different upstream client. issuer/tenant_id apply only when relevant to the IdP type. Pass `org_id` to scope to a business org. Pass `provider_options` to flip JIT or linking flags \u2014 only the keys you set change, others are preserved (X6).",
720
923
  inputShape: {
721
- workspace: z5.string().min(1),
722
- idp_id: z5.string().min(1),
723
- name: z5.string().min(1).optional(),
724
- client_id: z5.string().min(1).optional(),
725
- client_secret: z5.string().min(1).optional().describe(
924
+ workspace: z7.string().min(1),
925
+ org_id: orgIdArg,
926
+ idp_id: z7.string().min(1),
927
+ name: z7.string().min(1).optional(),
928
+ client_id: z7.string().min(1).optional(),
929
+ client_secret: z7.string().min(1).optional().describe(
726
930
  "Rotate the upstream-issued client secret. Not the Prysmid app secret \u2014 that one is rotated via regenerate_app_secret."
727
931
  ),
728
- scopes: z5.array(z5.string()).optional(),
729
- issuer: z5.string().url().optional().describe("Only meaningful for type=oidc."),
730
- tenant_id: z5.string().optional().describe("Only meaningful for type=microsoft (Entra tenant GUID).")
932
+ scopes: z7.array(z7.string()).optional(),
933
+ issuer: z7.string().url().optional().describe("Only meaningful for type=oidc."),
934
+ tenant_id: z7.string().optional().describe("Only meaningful for type=microsoft (Entra tenant GUID)."),
935
+ provider_options: providerOptionsSchema
731
936
  },
732
- handler: async ({ workspace, idp_id, ...patch }, { client }) => client.request(
937
+ handler: async ({ workspace, org_id, idp_id, ...patch }, { client }) => client.request(
733
938
  `/v1/workspaces/${encodeURIComponent(workspace)}/idps/${encodeURIComponent(idp_id)}`,
734
- { method: "PATCH", body: patch }
939
+ { method: "PATCH", body: patch, query: { org_id } }
940
+ )
941
+ });
942
+ var probeIdp = defineTool({
943
+ name: "probe_idp",
944
+ description: "Probe an external identity provider end-to-end against its upstream authorize endpoint. Catches redirect_uri_mismatch (URI not registered at Google Cloud / GitHub / etc.), invalid_client (client_id rotated or deleted upstream), and provider_unreachable failures BEFORE a real end-user hits them. Use after enable_google_login / add_idp, and any time you suspect the IdP is misconfigured. Today: Google + GitHub get full classification; Microsoft + OIDC generic return `skipped` for the deterministic dimensions (only reachability is verified). Pass `org_id` to scope to a business org.",
945
+ inputShape: {
946
+ workspace: z7.string().min(1),
947
+ org_id: orgIdArg,
948
+ idp_id: z7.string().min(1)
949
+ },
950
+ handler: async ({ workspace, org_id, idp_id }, { client }) => client.request(
951
+ `/v1/workspaces/${encodeURIComponent(workspace)}/idps/${encodeURIComponent(idp_id)}/probe`,
952
+ { method: "POST", query: { org_id } }
735
953
  )
736
954
  });
737
- var tools5 = [listIdps, addIdp, deleteIdp, getIdp, updateIdp];
955
+ var tools7 = [listIdps, addIdp, deleteIdp, getIdp, updateIdp, probeIdp];
738
956
 
739
957
  // src/tools/login_policy.ts
740
- import { z as z6 } from "zod";
958
+ import { z as z8 } from "zod";
959
+ var orgIdArg2 = z8.string().min(1).optional().describe(
960
+ "Optional Zitadel org id to scope this operation to a specific business org. Omit for the workspace's home org (backwards-compat)."
961
+ );
962
+ var SECOND_FACTORS = ["otp", "u2f", "otp_email", "otp_sms"];
963
+ var MULTI_FACTORS = ["u2f_verified"];
741
964
  var getLoginPolicy = defineTool({
742
965
  name: "get_login_policy",
743
- description: "Return the workspace's current login policy (password rules, MFA, IdPs allowed, lockout, etc.).",
966
+ description: "Return the workspace's current login policy (auth methods, MFA factors, passwordless, domain discovery, hide-password-reset, etc.). Pass `org_id` to read a specific business org's policy.",
744
967
  inputShape: {
745
- workspace: z6.string().min(1)
968
+ workspace: z8.string().min(1),
969
+ org_id: orgIdArg2
746
970
  },
747
- handler: async ({ workspace }, { client }) => client.request(
748
- `/v1/workspaces/${encodeURIComponent(workspace)}/login-policy`
971
+ handler: async ({ workspace, org_id }, { client }) => client.request(
972
+ `/v1/workspaces/${encodeURIComponent(workspace)}/login-policy`,
973
+ { query: { org_id } }
749
974
  )
750
975
  });
751
976
  var updateLoginPolicy = defineTool({
752
977
  name: "update_login_policy",
753
- description: "Update the login policy. PATCH semantics \u2014 only fields you pass are changed; other policy fields stay as they were.",
978
+ description: "Update the login policy. PATCH semantics \u2014 only fields you pass are changed; other policy fields stay as they were. Pass `org_id` to scope to a specific business org (P3a-3). Set `allow_domain_discovery=true` together with a verified org domain (see `verify_organization_domain`) to route email-based logins to that org automatically.",
754
979
  inputShape: {
755
- workspace: z6.string().min(1),
756
- allow_username_password: z6.boolean().optional(),
757
- allow_register: z6.boolean().optional(),
758
- allow_external_idp: z6.boolean().optional(),
759
- force_mfa: z6.boolean().optional().describe("Require any second factor at login"),
760
- passwordless_type: z6.enum([
761
- "PASSWORDLESS_TYPE_NOT_ALLOWED",
762
- "PASSWORDLESS_TYPE_ALLOWED"
763
- ]).optional().describe("Enables passkey-first when set to ALLOWED"),
764
- max_password_attempts: z6.number().int().min(0).max(20).optional(),
765
- lockout_password_attempts: z6.number().int().min(0).max(20).optional()
980
+ workspace: z8.string().min(1),
981
+ org_id: orgIdArg2,
982
+ allow_username_password: z8.boolean().optional(),
983
+ allow_register: z8.boolean().optional(),
984
+ allow_external_idp: z8.boolean().optional(),
985
+ force_mfa: z8.boolean().optional().describe("Require any second factor at login."),
986
+ force_mfa_local_only: z8.boolean().optional().describe(
987
+ "X2: require MFA only for username/password logins, exempting external-IdP logins (which may already enforce MFA upstream). Only meaningful when force_mfa is also true."
988
+ ),
989
+ passwordless_allowed: z8.boolean().optional().describe("Allow passkey-first sign-in flows."),
990
+ second_factors: z8.array(z8.enum(SECOND_FACTORS)).optional().describe(
991
+ "Replaces the full list of allowed second-factor methods. Pass `[]` to disable all 2FA."
992
+ ),
993
+ multi_factors: z8.array(z8.enum(MULTI_FACTORS)).optional().describe(
994
+ "Replaces the full list of allowed multi-factor (passwordless+verification) methods."
995
+ ),
996
+ hide_password_reset: z8.boolean().optional(),
997
+ ignore_unknown_usernames: z8.boolean().optional(),
998
+ allow_domain_discovery: z8.boolean().optional().describe(
999
+ "P3a-3: route logins to the org that owns the typed email's verified domain, skipping the IdP picker. Requires at least one verified domain on the org (see verify_organization_domain)."
1000
+ )
766
1001
  },
767
- handler: async ({ workspace, ...body }, { client }) => client.request(
1002
+ handler: async ({ workspace, org_id, ...body }, { client }) => client.request(
768
1003
  `/v1/workspaces/${encodeURIComponent(workspace)}/login-policy`,
1004
+ { method: "PATCH", body, query: { org_id } }
1005
+ )
1006
+ });
1007
+ var tools8 = [getLoginPolicy, updateLoginPolicy];
1008
+
1009
+ // src/tools/org_domains.ts
1010
+ import { z as z9 } from "zod";
1011
+ var workspaceArg = z9.string().min(1);
1012
+ var orgIdArg3 = z9.string().min(1).describe(
1013
+ "Zitadel org id (the `id` returned by create/list_organizations). Per-org scoping."
1014
+ );
1015
+ var domainArg = z9.string().min(3).max(253).regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/).describe(
1016
+ "Fully-qualified domain to manage. Lower-case only \u2014 `Acme.com` and `acme.com` are different to Zitadel."
1017
+ );
1018
+ var listOrganizationDomains = defineTool({
1019
+ name: "list_organization_domains",
1020
+ description: "List every domain attached to an organization with its verification state. Use after add/verify to confirm the domain shows `is_verified=true`.",
1021
+ inputShape: {
1022
+ workspace: workspaceArg,
1023
+ org_id: orgIdArg3
1024
+ },
1025
+ handler: async ({ workspace, org_id }, { client }) => client.request(
1026
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/domains`
1027
+ )
1028
+ });
1029
+ var addOrganizationDomain = defineTool({
1030
+ name: "add_organization_domain",
1031
+ description: "Attach a domain to an organization. State starts UNVERIFIED \u2014 chain `generate_organization_domain_verification` and `verify_organization_domain` to complete setup. 409 if already attached.",
1032
+ inputShape: {
1033
+ workspace: workspaceArg,
1034
+ org_id: orgIdArg3,
1035
+ domain: domainArg
1036
+ },
1037
+ handler: async ({ workspace, org_id, domain }, { client }) => client.request(
1038
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/domains`,
1039
+ { method: "POST", body: { domain } }
1040
+ )
1041
+ });
1042
+ var generateOrganizationDomainVerification = defineTool({
1043
+ name: "generate_organization_domain_verification",
1044
+ description: "Generate (or rotate) the verification token + record location for an attached domain. Returns `{token, url, method}`. The operator must publish the token at `url` (DNS TXT for method=dns; HTTP file for method=http) before calling `verify_organization_domain`. DNS is the default \u2014 works on apex domains, does not require HTTP control.",
1045
+ inputShape: {
1046
+ workspace: workspaceArg,
1047
+ org_id: orgIdArg3,
1048
+ domain: domainArg,
1049
+ method: z9.enum(["dns", "http"]).default("dns").describe(
1050
+ "Verification method. `dns` (default) \u2192 publish a TXT record. `http` \u2192 serve a file at `.well-known/zitadel-challenge/<token>` on the domain."
1051
+ )
1052
+ },
1053
+ handler: async ({ workspace, org_id, domain, method }, { client }) => client.request(
1054
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/domains/${encodeURIComponent(domain)}/_generate_verification`,
1055
+ { method: "POST", body: { method } }
1056
+ )
1057
+ });
1058
+ var verifyOrganizationDomain = defineTool({
1059
+ name: "verify_organization_domain",
1060
+ description: "Trigger Zitadel to look up the published verification token and mark the domain verified. Returns the updated domain projection with `is_verified=true` on success. 400 if the token is not found (DNS not propagated yet, wrong record, etc.) \u2014 retry after publishing.",
1061
+ inputShape: {
1062
+ workspace: workspaceArg,
1063
+ org_id: orgIdArg3,
1064
+ domain: domainArg
1065
+ },
1066
+ handler: async ({ workspace, org_id, domain }, { client }) => client.request(
1067
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/domains/${encodeURIComponent(domain)}/_verify`,
1068
+ { method: "POST" }
1069
+ )
1070
+ });
1071
+ var deleteOrganizationDomain = defineTool({
1072
+ name: "delete_organization_domain",
1073
+ description: "Detach a domain from an organization. Idempotent (204 even if already gone). Verified domains can be removed too \u2014 domain discovery will no longer route logins of that email domain to this org.",
1074
+ inputShape: {
1075
+ workspace: workspaceArg,
1076
+ org_id: orgIdArg3,
1077
+ domain: domainArg
1078
+ },
1079
+ handler: async ({ workspace, org_id, domain }, { client }) => client.request(
1080
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/domains/${encodeURIComponent(domain)}`,
1081
+ { method: "DELETE" }
1082
+ )
1083
+ });
1084
+ var tools9 = [
1085
+ listOrganizationDomains,
1086
+ addOrganizationDomain,
1087
+ generateOrganizationDomainVerification,
1088
+ verifyOrganizationDomain,
1089
+ deleteOrganizationDomain
1090
+ ];
1091
+
1092
+ // src/tools/organizations.ts
1093
+ import { z as z10 } from "zod";
1094
+ var createOrganization = defineTool({
1095
+ name: "create_organization",
1096
+ description: "Create a new organization inside a workspace. Returns the org with a stable `tenant_id` UUID \u2014 that's the value users will see as the `tenant_id` claim on their JWT when an active grant resolves to this org. Idempotent on slug: re-creating a duplicate slug returns 409.",
1097
+ inputShape: {
1098
+ workspace: z10.string().min(1),
1099
+ name: z10.string().min(1).max(255).describe("Display name (mutable)."),
1100
+ slug: z10.string().min(3).max(63).regex(/^[a-z][a-z0-9-]*[a-z0-9]$/).describe(
1101
+ "URL-safe slug, unique per workspace. Immutable. Cannot be `__consumer__` (reserved)."
1102
+ ),
1103
+ allow_register: z10.boolean().default(false).describe(
1104
+ "Whether self-registration is allowed for this org. Default false (invite-only)."
1105
+ )
1106
+ },
1107
+ handler: async ({ workspace, ...body }, { client }) => client.request(
1108
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations`,
1109
+ { method: "POST", body }
1110
+ )
1111
+ });
1112
+ var listOrganizations = defineTool({
1113
+ name: "list_organizations",
1114
+ description: "List all organizations in a workspace, oldest first. Each item includes the stable `tenant_id` UUID and the consumer flag.",
1115
+ inputShape: {
1116
+ workspace: z10.string().min(1)
1117
+ },
1118
+ handler: async ({ workspace }, { client }) => client.request(
1119
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations`
1120
+ )
1121
+ });
1122
+ var getOrganization = defineTool({
1123
+ name: "get_organization",
1124
+ description: "Read one organization by its Zitadel org id (the `id` returned by create/list, not the internal Prysm:ID UUID).",
1125
+ inputShape: {
1126
+ workspace: z10.string().min(1),
1127
+ org_id: z10.string().min(1)
1128
+ },
1129
+ handler: async ({ workspace, org_id }, { client }) => client.request(
1130
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}`
1131
+ )
1132
+ });
1133
+ var updateOrganization = defineTool({
1134
+ name: "update_organization",
1135
+ description: "Rename an organization and/or toggle `allow_register` / `domain_auto_claim`. Sparse \u2014 omit fields to leave them untouched. Rename propagates to Zitadel synchronously.",
1136
+ inputShape: {
1137
+ workspace: z10.string().min(1),
1138
+ org_id: z10.string().min(1),
1139
+ name: z10.string().min(1).max(255).optional(),
1140
+ allow_register: z10.boolean().optional(),
1141
+ domain_auto_claim: z10.boolean().optional().describe(
1142
+ "P2e opt-in: when True, verifying a domain on this org (or calling reconcile_organization_domain_claims) auto-grants the org access over consumer-org users with a matching verified email domain. Public domains are always excluded; the user's home org is never moved (the claim is an additional, revocable grant)."
1143
+ )
1144
+ },
1145
+ handler: async ({ workspace, org_id, ...body }, { client }) => client.request(
1146
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}`,
769
1147
  { method: "PATCH", body }
770
1148
  )
771
1149
  });
772
- var tools6 = [getLoginPolicy, updateLoginPolicy];
1150
+ var reconcileOrganizationDomainClaims = defineTool({
1151
+ name: "reconcile_organization_domain_claims",
1152
+ description: "P2e: grant this org access over consumer-org users whose verified email domain matches one of the org's verified domains. Idempotent and re-runnable \u2014 catches users who self-registered after a domain was verified. Requires domain_auto_claim=true on the org (returns skipped with a reason otherwise). Public email domains are always excluded; the user's home org is never moved. Returns counts: granted / already_present / candidates + the domains matched.",
1153
+ inputShape: {
1154
+ workspace: z10.string().min(1),
1155
+ org_id: z10.string().min(1)
1156
+ },
1157
+ handler: async ({ workspace, org_id }, { client }) => client.request(
1158
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/_reconcile-domain-claims`,
1159
+ { method: "POST" }
1160
+ )
1161
+ });
1162
+ var deactivateOrganization = defineTool({
1163
+ name: "deactivate_organization",
1164
+ description: "Block all logins to an organization. Idempotent. Consumer org cannot be deactivated \u2014 toggle `allow_consumer_org=false` on the workspace instead.",
1165
+ inputShape: {
1166
+ workspace: z10.string().min(1),
1167
+ org_id: z10.string().min(1)
1168
+ },
1169
+ handler: async ({ workspace, org_id }, { client }) => client.request(
1170
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/_deactivate`,
1171
+ { method: "POST" }
1172
+ )
1173
+ });
1174
+ var reactivateOrganization = defineTool({
1175
+ name: "reactivate_organization",
1176
+ description: "Re-enable logins for a previously deactivated organization. Idempotent.",
1177
+ inputShape: {
1178
+ workspace: z10.string().min(1),
1179
+ org_id: z10.string().min(1)
1180
+ },
1181
+ handler: async ({ workspace, org_id }, { client }) => client.request(
1182
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}/_reactivate`,
1183
+ { method: "POST" }
1184
+ )
1185
+ });
1186
+ var deleteOrganization = defineTool({
1187
+ name: "delete_organization",
1188
+ description: "Hard-delete an organization. Cascades users/projects/grants on the Zitadel side. Idempotent against out-of-band Zitadel removal. Consumer org is protected \u2014 toggle `allow_consumer_org=false` on the workspace to remove it.",
1189
+ inputShape: {
1190
+ workspace: z10.string().min(1),
1191
+ org_id: z10.string().min(1)
1192
+ },
1193
+ handler: async ({ workspace, org_id }, { client }) => client.request(
1194
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/${encodeURIComponent(org_id)}`,
1195
+ { method: "DELETE" }
1196
+ )
1197
+ });
1198
+ var ensureConsumerOrganization = defineTool({
1199
+ name: "ensure_consumer_organization",
1200
+ description: "Idempotently provision the workspace's consumer organization for self-registered users. Requires `workspace.allow_consumer_org=true` (toggle it via update_workspace first). Returns the org row whether newly created or already present. Slug `__consumer__`, `allow_register=true`, `is_consumer=true`.",
1201
+ inputShape: {
1202
+ workspace: z10.string().min(1)
1203
+ },
1204
+ handler: async ({ workspace }, { client }) => client.request(
1205
+ `/v1/workspaces/${encodeURIComponent(workspace)}/organizations/_ensure-consumer`,
1206
+ { method: "POST" }
1207
+ )
1208
+ });
1209
+ var tools10 = [
1210
+ createOrganization,
1211
+ listOrganizations,
1212
+ getOrganization,
1213
+ updateOrganization,
1214
+ reconcileOrganizationDomainClaims,
1215
+ deactivateOrganization,
1216
+ reactivateOrganization,
1217
+ deleteOrganization,
1218
+ ensureConsumerOrganization
1219
+ ];
1220
+
1221
+ // src/tools/service_accounts.ts
1222
+ import { z as z11 } from "zod";
1223
+ var orgIdArg4 = z11.string().min(1).optional().describe(
1224
+ "Optional Zitadel org id to scope the service account to a specific business org. Omit for the workspace's home org (backwards-compat)."
1225
+ );
1226
+ var listServiceAccounts = defineTool({
1227
+ name: "list_service_accounts",
1228
+ description: "List the workspace's service accounts (machine users). The platform-internal provisioner SA is filtered out. Pass `org_id` to list a specific business org's machine users.",
1229
+ inputShape: {
1230
+ workspace: z11.string().min(1),
1231
+ org_id: orgIdArg4
1232
+ },
1233
+ handler: async ({ workspace, org_id }, { client }) => client.request(
1234
+ `/v1/workspaces/${encodeURIComponent(workspace)}/service-accounts`,
1235
+ { query: { org_id } }
1236
+ )
1237
+ });
1238
+ var createServiceAccount = defineTool({
1239
+ name: "create_service_account",
1240
+ description: "Create a service account (machine user) and mint its JSON key. The `key` is returned ONCE in the response and never stored by Prysmid \u2014 surface it to the operator and instruct them to save it in a secret manager. Pass `org_id` to create the SA inside a specific business org.",
1241
+ inputShape: {
1242
+ workspace: z11.string().min(1),
1243
+ org_id: orgIdArg4,
1244
+ user_name: z11.string().regex(/^[a-zA-Z][a-zA-Z0-9._-]{1,49}$/).describe(
1245
+ "Machine username (Zitadel handle). Cannot be the reserved `prysmid-provisioner`."
1246
+ ),
1247
+ name: z11.string().min(1).max(200).describe("Human-readable display name."),
1248
+ description: z11.string().max(500).optional()
1249
+ },
1250
+ handler: async ({ workspace, org_id, ...body }, { client }) => client.request(
1251
+ `/v1/workspaces/${encodeURIComponent(workspace)}/service-accounts`,
1252
+ { method: "POST", body, query: { org_id } }
1253
+ )
1254
+ });
1255
+ var deleteServiceAccount = defineTool({
1256
+ name: "delete_service_account",
1257
+ description: "Revoke a service account. Idempotent (204 even if already gone). Refuses to delete the platform provisioner SA. Pass `org_id` to target a specific business org's machine user.",
1258
+ inputShape: {
1259
+ workspace: z11.string().min(1),
1260
+ org_id: orgIdArg4,
1261
+ service_account_id: z11.string().min(1)
1262
+ },
1263
+ handler: async ({ workspace, org_id, service_account_id }, { client }) => client.request(
1264
+ `/v1/workspaces/${encodeURIComponent(workspace)}/service-accounts/${encodeURIComponent(service_account_id)}`,
1265
+ { method: "DELETE", query: { org_id } }
1266
+ )
1267
+ });
1268
+ var tools11 = [
1269
+ listServiceAccounts,
1270
+ createServiceAccount,
1271
+ deleteServiceAccount
1272
+ ];
773
1273
 
774
1274
  // src/tools/users.ts
775
- import { z as z7 } from "zod";
1275
+ import { z as z12 } from "zod";
776
1276
  var listUsers = defineTool({
777
1277
  name: "list_users",
778
1278
  description: "List human users in a workspace.",
779
1279
  inputShape: {
780
- workspace: z7.string().min(1),
781
- limit: z7.number().int().min(1).max(500).default(100)
1280
+ workspace: z12.string().min(1),
1281
+ limit: z12.number().int().min(1).max(500).default(100)
782
1282
  },
783
1283
  handler: async ({ workspace, limit }, { client }) => client.request(
784
1284
  `/v1/workspaces/${encodeURIComponent(workspace)}/users`,
@@ -789,11 +1289,11 @@ var inviteUser = defineTool({
789
1289
  name: "invite_user",
790
1290
  description: "Invite a user by email. Idempotent by email \u2014 re-inviting an existing user is a no-op. Triggers a Zitadel init email with a 'set your password' link.",
791
1291
  inputShape: {
792
- workspace: z7.string().min(1),
793
- email: z7.string().regex(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, "must be a valid email"),
794
- first_name: z7.string().min(1),
795
- last_name: z7.string().min(1),
796
- preferred_language: z7.string().length(2).default("en").describe("ISO 639-1, e.g. en/es/pt")
1292
+ workspace: z12.string().min(1),
1293
+ email: z12.string().regex(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, "must be a valid email"),
1294
+ first_name: z12.string().min(1),
1295
+ last_name: z12.string().min(1),
1296
+ preferred_language: z12.string().length(2).default("en").describe("ISO 639-1, e.g. en/es/pt")
797
1297
  },
798
1298
  handler: async ({ workspace, ...body }, { client }) => client.request(
799
1299
  `/v1/workspaces/${encodeURIComponent(workspace)}/users/invite`,
@@ -804,18 +1304,115 @@ var deleteUser = defineTool({
804
1304
  name: "delete_user",
805
1305
  description: "Delete a user by id. Idempotent.",
806
1306
  inputShape: {
807
- workspace: z7.string().min(1),
808
- user_id: z7.string().min(1)
1307
+ workspace: z12.string().min(1),
1308
+ user_id: z12.string().min(1)
809
1309
  },
810
1310
  handler: async ({ workspace, user_id }, { client }) => client.request(
811
1311
  `/v1/workspaces/${encodeURIComponent(workspace)}/users/${encodeURIComponent(user_id)}`,
812
1312
  { method: "DELETE" }
813
1313
  )
814
1314
  });
815
- var tools7 = [listUsers, inviteUser, deleteUser];
1315
+ var tools12 = [listUsers, inviteUser, deleteUser];
1316
+
1317
+ // src/tools/webhooks.ts
1318
+ import { z as z13 } from "zod";
1319
+ var KNOWN_EVENTS = [
1320
+ "user.created",
1321
+ "user.deleted",
1322
+ "user.deactivated",
1323
+ "user.reactivated",
1324
+ "session.created",
1325
+ "org.created",
1326
+ "org.updated",
1327
+ "org.deactivated",
1328
+ "org.reactivated",
1329
+ "org.deleted",
1330
+ "grant.granted",
1331
+ "grant.updated",
1332
+ "grant.deactivated",
1333
+ "grant.reactivated",
1334
+ "grant.revoked"
1335
+ ];
1336
+ var eventName = z13.enum(KNOWN_EVENTS);
1337
+ var createWebhookEndpoint = defineTool({
1338
+ name: "create_webhook_endpoint",
1339
+ description: "Register a new outbound webhook endpoint for a workspace. Returns the freshly-generated `signing_secret` EXACTLY ONCE \u2014 store it immediately to verify deliveries; it is NOT retrievable later. HTTPS required in prod. Empty `enabled_events` = catch-all (subscribe to everything).",
1340
+ inputShape: {
1341
+ workspace: z13.string().min(1),
1342
+ url: z13.string().url().describe(
1343
+ "Destination URL. Must be https:// in production; http:// is permitted only on dev/staging environments."
1344
+ ),
1345
+ description: z13.string().max(255).optional().describe("Human label so you can tell endpoints apart in the dashboard."),
1346
+ enabled_events: z13.array(eventName).default([]).describe(
1347
+ "Event types this endpoint subscribes to. Empty = catch-all. Unknown event types return 422."
1348
+ )
1349
+ },
1350
+ handler: async ({ workspace, ...body }, { client }) => client.request(
1351
+ `/v1/workspaces/${encodeURIComponent(workspace)}/webhook-endpoints`,
1352
+ { method: "POST", body }
1353
+ )
1354
+ });
1355
+ var listWebhookEndpoints = defineTool({
1356
+ name: "list_webhook_endpoints",
1357
+ description: "List all outbound webhook endpoints registered for a workspace. Does NOT return signing secrets \u2014 that's only on create.",
1358
+ inputShape: {
1359
+ workspace: z13.string().min(1)
1360
+ },
1361
+ handler: async ({ workspace }, { client }) => client.request(
1362
+ `/v1/workspaces/${encodeURIComponent(workspace)}/webhook-endpoints`
1363
+ )
1364
+ });
1365
+ var getWebhookEndpoint = defineTool({
1366
+ name: "get_webhook_endpoint",
1367
+ description: "Read one webhook endpoint by id. Omits the signing secret \u2014 recreate the endpoint if it was lost.",
1368
+ inputShape: {
1369
+ workspace: z13.string().min(1),
1370
+ endpoint_id: z13.string().min(1)
1371
+ },
1372
+ handler: async ({ workspace, endpoint_id }, { client }) => client.request(
1373
+ `/v1/workspaces/${encodeURIComponent(workspace)}/webhook-endpoints/${encodeURIComponent(endpoint_id)}`
1374
+ )
1375
+ });
1376
+ var updateWebhookEndpoint = defineTool({
1377
+ name: "update_webhook_endpoint",
1378
+ description: "Sparse update of an endpoint's url / description / enabled_events / enabled flag. Omit fields to leave them untouched. signing_secret is NOT mutable \u2014 to rotate, delete and recreate.",
1379
+ inputShape: {
1380
+ workspace: z13.string().min(1),
1381
+ endpoint_id: z13.string().min(1),
1382
+ url: z13.string().url().optional(),
1383
+ description: z13.string().max(255).optional(),
1384
+ enabled_events: z13.array(eventName).optional(),
1385
+ enabled: z13.boolean().optional().describe(
1386
+ "Toggle deliveries without losing config. Useful when the destination is temporarily down."
1387
+ )
1388
+ },
1389
+ handler: async ({ workspace, endpoint_id, ...body }, { client }) => client.request(
1390
+ `/v1/workspaces/${encodeURIComponent(workspace)}/webhook-endpoints/${encodeURIComponent(endpoint_id)}`,
1391
+ { method: "PATCH", body }
1392
+ )
1393
+ });
1394
+ var deleteWebhookEndpoint = defineTool({
1395
+ name: "delete_webhook_endpoint",
1396
+ description: "Permanently remove a webhook endpoint. Pending deliveries to it are NOT removed (operator can inspect them) but no new deliveries will be queued.",
1397
+ inputShape: {
1398
+ workspace: z13.string().min(1),
1399
+ endpoint_id: z13.string().min(1)
1400
+ },
1401
+ handler: async ({ workspace, endpoint_id }, { client }) => client.request(
1402
+ `/v1/workspaces/${encodeURIComponent(workspace)}/webhook-endpoints/${encodeURIComponent(endpoint_id)}`,
1403
+ { method: "DELETE" }
1404
+ )
1405
+ });
1406
+ var tools13 = [
1407
+ createWebhookEndpoint,
1408
+ listWebhookEndpoints,
1409
+ getWebhookEndpoint,
1410
+ updateWebhookEndpoint,
1411
+ deleteWebhookEndpoint
1412
+ ];
816
1413
 
817
1414
  // src/tools/workspaces.ts
818
- import { z as z8 } from "zod";
1415
+ import { z as z14 } from "zod";
819
1416
  var listWorkspaces = defineTool({
820
1417
  name: "list_workspaces",
821
1418
  description: "List Prysmid workspaces accessible to the current API token. Returns an array of {id, slug, display_name, plan, state}.",
@@ -826,7 +1423,7 @@ var getWorkspace = defineTool({
826
1423
  name: "get_workspace",
827
1424
  description: "Get a single workspace by slug or id.",
828
1425
  inputShape: {
829
- workspace: z8.string().min(1).describe("Workspace slug or UUID")
1426
+ workspace: z14.string().min(1).describe("Workspace slug or UUID")
830
1427
  },
831
1428
  handler: async ({ workspace }, { client }) => client.request(`/v1/workspaces/${encodeURIComponent(workspace)}`)
832
1429
  });
@@ -834,25 +1431,25 @@ var createWorkspace = defineTool({
834
1431
  name: "create_workspace",
835
1432
  description: "Create a new Prysmid workspace. Provisioning runs in the background; the response returns immediately with state=provisioning. Poll `get_workspace` until state=active (~30s).",
836
1433
  inputShape: {
837
- slug: z8.string().min(2).max(63).regex(/^[a-z0-9-]+$/, "lowercase alphanumeric and hyphens only").describe("Subdomain-safe slug \u2014 becomes auth.<slug>.prysmid.com"),
838
- display_name: z8.string().min(1).max(255)
1434
+ slug: z14.string().min(2).max(63).regex(/^[a-z0-9-]+$/, "lowercase alphanumeric and hyphens only").describe("Subdomain-safe slug \u2014 becomes auth.<slug>.prysmid.com"),
1435
+ display_name: z14.string().min(1).max(255)
839
1436
  },
840
1437
  handler: async (input, { client }) => client.request("/v1/workspaces", { method: "POST", body: input })
841
1438
  });
842
- var tools8 = [listWorkspaces, getWorkspace, createWorkspace];
1439
+ var tools14 = [listWorkspaces, getWorkspace, createWorkspace];
843
1440
 
844
1441
  // src/tools/generated/apps.ts
845
- import { z as z9 } from "zod";
1442
+ import { z as z15 } from "zod";
846
1443
  var createApp = defineTool({
847
1444
  name: "create_app",
848
1445
  description: "Create App",
849
1446
  inputShape: {
850
- workspace_id: z9.string().uuid(),
851
- name: z9.string().min(1).max(200),
852
- redirect_uris: z9.array(z9.string().url().min(1).max(2083)).describe("Where the IdP sends the user back after auth. At least one required."),
853
- post_logout_redirect_uris: z9.array(z9.string().url().min(1).max(2083)).describe("Where the IdP sends the user after logout.").optional(),
854
- app_type: z9.enum(["web", "spa", "native"]).describe("App kind, drives OIDC grant + auth_method defaults.\n\n- `web`: server-rendered confidential client. Gets a `client_secret`.\n- `spa`: single-page app (user-agent). Public, PKCE required, no secret.\n- `native`: desktop/mobile. Public, PKCE required, no secret.").optional(),
855
- dev_mode: z9.boolean().describe("Relax HTTPS requirement on redirect_uris (allows http://localhost). Use only for local development; never in production.").default(false)
1447
+ workspace_id: z15.string().uuid(),
1448
+ name: z15.string().min(1).max(200),
1449
+ redirect_uris: z15.array(z15.string().url().min(1).max(2083)).describe("Where the IdP sends the user back after auth. At least one required."),
1450
+ post_logout_redirect_uris: z15.array(z15.string().url().min(1).max(2083)).describe("Where the IdP sends the user after logout.").optional(),
1451
+ app_type: z15.enum(["web", "spa", "native"]).describe("App kind, drives OIDC grant + auth_method defaults.\n\n- `web`: server-rendered confidential client. Gets a `client_secret`.\n- `spa`: single-page app (user-agent). Public, PKCE required, no secret.\n- `native`: desktop/mobile. Public, PKCE required, no secret.").optional(),
1452
+ dev_mode: z15.boolean().describe("Relax HTTPS requirement on redirect_uris (allows http://localhost). Use only for local development; never in production.").default(false)
856
1453
  },
857
1454
  handler: async (input, { client }) => {
858
1455
  const { workspace_id, ...__body } = input;
@@ -863,8 +1460,8 @@ var deleteApp = defineTool({
863
1460
  name: "delete_app",
864
1461
  description: "Delete App",
865
1462
  inputShape: {
866
- workspace_id: z9.string().uuid(),
867
- app_id: z9.string()
1463
+ workspace_id: z15.string().uuid(),
1464
+ app_id: z15.string()
868
1465
  },
869
1466
  handler: async (input, { client }) => {
870
1467
  const { workspace_id, app_id } = input;
@@ -875,7 +1472,7 @@ var listApps2 = defineTool({
875
1472
  name: "list_apps",
876
1473
  description: "List Apps",
877
1474
  inputShape: {
878
- workspace_id: z9.string().uuid()
1475
+ workspace_id: z15.string().uuid()
879
1476
  },
880
1477
  handler: async (input, { client }) => {
881
1478
  const { workspace_id } = input;
@@ -889,13 +1486,13 @@ var generatedAppsTools = [
889
1486
  ];
890
1487
 
891
1488
  // src/tools/generated/billing.ts
892
- import { z as z10 } from "zod";
1489
+ import { z as z16 } from "zod";
893
1490
  var billingCheckout = defineTool({
894
1491
  name: "billing_checkout",
895
1492
  description: "Checkout",
896
1493
  inputShape: {
897
- workspace_id: z10.string().uuid(),
898
- plan: z10.enum(["free", "pro", "enterprise"])
1494
+ workspace_id: z16.string().uuid(),
1495
+ plan: z16.enum(["free", "pro", "enterprise"])
899
1496
  },
900
1497
  handler: async (input, { client }) => {
901
1498
  const { workspace_id, ...__body } = input;
@@ -906,7 +1503,7 @@ var billingGetState = defineTool({
906
1503
  name: "billing_get_state",
907
1504
  description: "Get State",
908
1505
  inputShape: {
909
- workspace_id: z10.string().uuid()
1506
+ workspace_id: z16.string().uuid()
910
1507
  },
911
1508
  handler: async (input, { client }) => {
912
1509
  const { workspace_id } = input;
@@ -917,7 +1514,7 @@ var billingPortal = defineTool({
917
1514
  name: "billing_portal",
918
1515
  description: "Portal",
919
1516
  inputShape: {
920
- workspace_id: z10.string().uuid()
1517
+ workspace_id: z16.string().uuid()
921
1518
  },
922
1519
  handler: async (input, { client }) => {
923
1520
  const { workspace_id } = input;
@@ -928,8 +1525,8 @@ var updateSpendingCap = defineTool({
928
1525
  name: "update_spending_cap",
929
1526
  description: "Update Spending Cap",
930
1527
  inputShape: {
931
- workspace_id: z10.string().uuid(),
932
- cents: z10.number().int().min(0).nullable().optional()
1528
+ workspace_id: z16.string().uuid(),
1529
+ cents: z16.number().int().min(0).nullable().optional()
933
1530
  },
934
1531
  handler: async (input, { client }) => {
935
1532
  const { workspace_id, ...__body } = input;
@@ -944,12 +1541,12 @@ var generatedBillingTools = [
944
1541
  ];
945
1542
 
946
1543
  // src/tools/generated/branding.ts
947
- import { z as z11 } from "zod";
1544
+ import { z as z17 } from "zod";
948
1545
  var deleteLogo = defineTool({
949
1546
  name: "delete_logo",
950
1547
  description: "Delete Logo",
951
1548
  inputShape: {
952
- workspace_id: z11.string().uuid()
1549
+ workspace_id: z17.string().uuid()
953
1550
  },
954
1551
  handler: async (input, { client }) => {
955
1552
  const { workspace_id } = input;
@@ -960,7 +1557,7 @@ var getBranding2 = defineTool({
960
1557
  name: "get_branding",
961
1558
  description: "Get Branding",
962
1559
  inputShape: {
963
- workspace_id: z11.string().uuid()
1560
+ workspace_id: z17.string().uuid()
964
1561
  },
965
1562
  handler: async (input, { client }) => {
966
1563
  const { workspace_id } = input;
@@ -971,17 +1568,17 @@ var updateBranding2 = defineTool({
971
1568
  name: "update_branding",
972
1569
  description: "Update Branding",
973
1570
  inputShape: {
974
- workspace_id: z11.string().uuid(),
975
- primary_color: z11.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
976
- background_color: z11.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
977
- warn_color: z11.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
978
- font_color: z11.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
979
- primary_color_dark: z11.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
980
- background_color_dark: z11.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
981
- warn_color_dark: z11.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
982
- font_color_dark: z11.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
983
- hide_login_name_suffix: z11.boolean().nullable().optional(),
984
- disable_watermark: z11.boolean().nullable().optional()
1571
+ workspace_id: z17.string().uuid(),
1572
+ primary_color: z17.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
1573
+ background_color: z17.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
1574
+ warn_color: z17.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
1575
+ font_color: z17.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
1576
+ primary_color_dark: z17.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
1577
+ background_color_dark: z17.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
1578
+ warn_color_dark: z17.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
1579
+ font_color_dark: z17.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/).nullable().optional(),
1580
+ hide_login_name_suffix: z17.boolean().nullable().optional(),
1581
+ disable_watermark: z17.boolean().nullable().optional()
985
1582
  },
986
1583
  handler: async (input, { client }) => {
987
1584
  const { workspace_id, ...__body } = input;
@@ -995,19 +1592,19 @@ var generatedBrandingTools = [
995
1592
  ];
996
1593
 
997
1594
  // src/tools/generated/idps.ts
998
- import { z as z12 } from "zod";
1595
+ import { z as z18 } from "zod";
999
1596
  var createIdp = defineTool({
1000
1597
  name: "create_idp",
1001
1598
  description: "Create Idp",
1002
1599
  inputShape: {
1003
- workspace_id: z12.string().uuid(),
1004
- type: z12.enum(["google", "github", "microsoft", "oidc"]),
1005
- name: z12.string().min(1).max(200),
1006
- client_id: z12.string().min(1),
1007
- client_secret: z12.string().min(1),
1008
- issuer: z12.string().url().min(1).max(2083).nullable().optional(),
1009
- tenant_id: z12.string().nullable().optional(),
1010
- scopes: z12.array(z12.string()).nullable().optional()
1600
+ workspace_id: z18.string().uuid(),
1601
+ type: z18.enum(["google", "github", "microsoft", "oidc"]),
1602
+ name: z18.string().min(1).max(200),
1603
+ client_id: z18.string().min(1),
1604
+ client_secret: z18.string().min(1),
1605
+ issuer: z18.string().url().min(1).max(2083).nullable().optional(),
1606
+ tenant_id: z18.string().nullable().optional(),
1607
+ scopes: z18.array(z18.string()).nullable().optional()
1011
1608
  },
1012
1609
  handler: async (input, { client }) => {
1013
1610
  const { workspace_id, ...__body } = input;
@@ -1018,8 +1615,8 @@ var deleteIdp2 = defineTool({
1018
1615
  name: "delete_idp",
1019
1616
  description: "Delete Idp",
1020
1617
  inputShape: {
1021
- workspace_id: z12.string().uuid(),
1022
- idp_id: z12.string()
1618
+ workspace_id: z18.string().uuid(),
1619
+ idp_id: z18.string()
1023
1620
  },
1024
1621
  handler: async (input, { client }) => {
1025
1622
  const { workspace_id, idp_id } = input;
@@ -1030,7 +1627,7 @@ var listIdps2 = defineTool({
1030
1627
  name: "list_idps",
1031
1628
  description: "List Idps",
1032
1629
  inputShape: {
1033
- workspace_id: z12.string().uuid()
1630
+ workspace_id: z18.string().uuid()
1034
1631
  },
1035
1632
  handler: async (input, { client }) => {
1036
1633
  const { workspace_id } = input;
@@ -1044,12 +1641,12 @@ var generatedIdpsTools = [
1044
1641
  ];
1045
1642
 
1046
1643
  // src/tools/generated/login-policy.ts
1047
- import { z as z13 } from "zod";
1644
+ import { z as z19 } from "zod";
1048
1645
  var getLoginPolicy2 = defineTool({
1049
1646
  name: "get_login_policy",
1050
1647
  description: "Get Login Policy",
1051
1648
  inputShape: {
1052
- workspace_id: z13.string().uuid()
1649
+ workspace_id: z19.string().uuid()
1053
1650
  },
1054
1651
  handler: async (input, { client }) => {
1055
1652
  const { workspace_id } = input;
@@ -1060,16 +1657,16 @@ var updateLoginPolicy2 = defineTool({
1060
1657
  name: "update_login_policy",
1061
1658
  description: "Update Login Policy",
1062
1659
  inputShape: {
1063
- workspace_id: z13.string().uuid(),
1064
- allow_username_password: z13.boolean().nullable().optional(),
1065
- allow_register: z13.boolean().nullable().optional(),
1066
- allow_external_idp: z13.boolean().nullable().optional(),
1067
- force_mfa: z13.boolean().nullable().optional(),
1068
- passwordless_allowed: z13.boolean().nullable().optional(),
1069
- second_factors: z13.array(z13.enum(["otp", "u2f", "otp_email", "otp_sms"])).nullable().optional(),
1070
- multi_factors: z13.array(z13.enum(["u2f_verified"])).nullable().optional(),
1071
- hide_password_reset: z13.boolean().nullable().optional(),
1072
- ignore_unknown_usernames: z13.boolean().nullable().optional()
1660
+ workspace_id: z19.string().uuid(),
1661
+ allow_username_password: z19.boolean().nullable().optional(),
1662
+ allow_register: z19.boolean().nullable().optional(),
1663
+ allow_external_idp: z19.boolean().nullable().optional(),
1664
+ force_mfa: z19.boolean().nullable().optional(),
1665
+ passwordless_allowed: z19.boolean().nullable().optional(),
1666
+ second_factors: z19.array(z19.enum(["otp", "u2f", "otp_email", "otp_sms"])).nullable().optional(),
1667
+ multi_factors: z19.array(z19.enum(["u2f_verified"])).nullable().optional(),
1668
+ hide_password_reset: z19.boolean().nullable().optional(),
1669
+ ignore_unknown_usernames: z19.boolean().nullable().optional()
1073
1670
  },
1074
1671
  handler: async (input, { client }) => {
1075
1672
  const { workspace_id, ...__body } = input;
@@ -1082,12 +1679,12 @@ var generatedLoginPolicyTools = [
1082
1679
  ];
1083
1680
 
1084
1681
  // src/tools/generated/smtp.ts
1085
- import { z as z14 } from "zod";
1682
+ import { z as z20 } from "zod";
1086
1683
  var getSmtp = defineTool({
1087
1684
  name: "get_smtp",
1088
1685
  description: "Get Smtp",
1089
1686
  inputShape: {
1090
- workspace_id: z14.string().uuid()
1687
+ workspace_id: z20.string().uuid()
1091
1688
  },
1092
1689
  handler: async (input, { client }) => {
1093
1690
  const { workspace_id } = input;
@@ -1098,7 +1695,7 @@ var revertToPlatformDefault = defineTool({
1098
1695
  name: "revert_to_platform_default",
1099
1696
  description: "Revert To Platform Default",
1100
1697
  inputShape: {
1101
- workspace_id: z14.string().uuid()
1698
+ workspace_id: z20.string().uuid()
1102
1699
  },
1103
1700
  handler: async (input, { client }) => {
1104
1701
  const { workspace_id } = input;
@@ -1109,15 +1706,15 @@ var setCustomSmtp = defineTool({
1109
1706
  name: "set_custom_smtp",
1110
1707
  description: "Set Custom Smtp",
1111
1708
  inputShape: {
1112
- workspace_id: z14.string().uuid(),
1113
- host: z14.string().min(1),
1114
- port: z14.number().int().min(1).max(65535),
1115
- tls: z14.boolean().default(true),
1116
- sender_address: z14.string().min(3).describe("Address that appears in the From header."),
1117
- sender_name: z14.string().min(1).max(200),
1118
- user: z14.string().min(1).describe("SMTP auth username."),
1119
- password: z14.string().min(1).describe("SMTP auth password / API key."),
1120
- reply_to_address: z14.string().describe("Optional Reply-To header.").default("")
1709
+ workspace_id: z20.string().uuid(),
1710
+ host: z20.string().min(1),
1711
+ port: z20.number().int().min(1).max(65535),
1712
+ tls: z20.boolean().default(true),
1713
+ sender_address: z20.string().min(3).describe("Address that appears in the From header."),
1714
+ sender_name: z20.string().min(1).max(200),
1715
+ user: z20.string().min(1).describe("SMTP auth username."),
1716
+ password: z20.string().min(1).describe("SMTP auth password / API key."),
1717
+ reply_to_address: z20.string().describe("Optional Reply-To header.").default("")
1121
1718
  },
1122
1719
  handler: async (input, { client }) => {
1123
1720
  const { workspace_id, ...__body } = input;
@@ -1131,13 +1728,13 @@ var generatedSmtpTools = [
1131
1728
  ];
1132
1729
 
1133
1730
  // src/tools/generated/users.ts
1134
- import { z as z15 } from "zod";
1731
+ import { z as z21 } from "zod";
1135
1732
  var deleteUser2 = defineTool({
1136
1733
  name: "delete_user",
1137
1734
  description: "Delete User",
1138
1735
  inputShape: {
1139
- workspace_id: z15.string().uuid(),
1140
- user_id: z15.string()
1736
+ workspace_id: z21.string().uuid(),
1737
+ user_id: z21.string()
1141
1738
  },
1142
1739
  handler: async (input, { client }) => {
1143
1740
  const { workspace_id, user_id } = input;
@@ -1148,11 +1745,11 @@ var inviteUser2 = defineTool({
1148
1745
  name: "invite_user",
1149
1746
  description: "Invite User",
1150
1747
  inputShape: {
1151
- workspace_id: z15.string().uuid(),
1152
- email: z15.string().max(320).regex(/^[^\s@]+@[^\s@]+\.[^\s@]+$/),
1153
- first_name: z15.string().min(1).max(100),
1154
- last_name: z15.string().min(1).max(100),
1155
- user_name: z15.string().nullable().optional()
1748
+ workspace_id: z21.string().uuid(),
1749
+ email: z21.string().max(320).regex(/^[^\s@]+@[^\s@]+\.[^\s@]+$/),
1750
+ first_name: z21.string().min(1).max(100),
1751
+ last_name: z21.string().min(1).max(100),
1752
+ user_name: z21.string().nullable().optional()
1156
1753
  },
1157
1754
  handler: async (input, { client }) => {
1158
1755
  const { workspace_id, ...__body } = input;
@@ -1163,7 +1760,7 @@ var listUsers2 = defineTool({
1163
1760
  name: "list_users",
1164
1761
  description: "List Users",
1165
1762
  inputShape: {
1166
- workspace_id: z15.string().uuid()
1763
+ workspace_id: z21.string().uuid()
1167
1764
  },
1168
1765
  handler: async (input, { client }) => {
1169
1766
  const { workspace_id } = input;
@@ -1177,14 +1774,14 @@ var generatedUsersTools = [
1177
1774
  ];
1178
1775
 
1179
1776
  // src/tools/generated/workspaces.ts
1180
- import { z as z16 } from "zod";
1777
+ import { z as z22 } from "zod";
1181
1778
  var createWorkspace2 = defineTool({
1182
1779
  name: "create_workspace",
1183
1780
  description: "Create Workspace",
1184
1781
  inputShape: {
1185
- slug: z16.string().min(3).max(63).regex(/^[a-z][a-z0-9-]*[a-z0-9]$/).describe("URL-safe lowercase slug. Becomes part of auth.<slug>.prysmid.com."),
1186
- display_name: z16.string().min(1).max(255),
1187
- plan: z16.enum(["free", "pro", "enterprise"]).optional()
1782
+ slug: z22.string().min(3).max(63).regex(/^[a-z][a-z0-9-]*[a-z0-9]$/).describe("URL-safe lowercase slug. Becomes part of auth.<slug>.prysmid.com."),
1783
+ display_name: z22.string().min(1).max(255),
1784
+ plan: z22.enum(["free", "pro", "enterprise"]).optional()
1188
1785
  },
1189
1786
  handler: async (input, { client }) => {
1190
1787
  return client.request(`/v1/workspaces`, { method: "POST", body: input });
@@ -1194,7 +1791,7 @@ var deleteWorkspace = defineTool({
1194
1791
  name: "delete_workspace",
1195
1792
  description: "Delete Workspace",
1196
1793
  inputShape: {
1197
- workspace_id: z16.string().uuid()
1794
+ workspace_id: z22.string().uuid()
1198
1795
  },
1199
1796
  handler: async (input, { client }) => {
1200
1797
  const { workspace_id } = input;
@@ -1205,7 +1802,7 @@ var getWorkspace2 = defineTool({
1205
1802
  name: "get_workspace",
1206
1803
  description: "Get Workspace",
1207
1804
  inputShape: {
1208
- workspace_id: z16.string().uuid()
1805
+ workspace_id: z22.string().uuid()
1209
1806
  },
1210
1807
  handler: async (input, { client }) => {
1211
1808
  const { workspace_id } = input;
@@ -1224,7 +1821,7 @@ var retryProvisioning = defineTool({
1224
1821
  name: "retry_provisioning",
1225
1822
  description: "Retry Provisioning",
1226
1823
  inputShape: {
1227
- workspace_id: z16.string().uuid()
1824
+ workspace_id: z22.string().uuid()
1228
1825
  },
1229
1826
  handler: async (input, { client }) => {
1230
1827
  const { workspace_id } = input;
@@ -1235,8 +1832,8 @@ var updateWorkspace = defineTool({
1235
1832
  name: "update_workspace",
1236
1833
  description: "Update Workspace",
1237
1834
  inputShape: {
1238
- workspace_id: z16.string().uuid(),
1239
- display_name: z16.string().min(1).max(255).nullable().optional()
1835
+ workspace_id: z22.string().uuid(),
1836
+ display_name: z22.string().min(1).max(255).nullable().optional()
1240
1837
  },
1241
1838
  handler: async (input, { client }) => {
1242
1839
  const { workspace_id, ...__body } = input;
@@ -1292,14 +1889,20 @@ var GENERATED_ALIASES = {
1292
1889
  };
1293
1890
  function composeToolset() {
1294
1891
  const handwrittenAndCurated = [
1295
- ...tools8,
1296
- ...tools,
1297
- ...tools5,
1892
+ ...tools14,
1893
+ ...tools10,
1894
+ ...tools9,
1298
1895
  ...tools6,
1896
+ ...tools,
1299
1897
  ...tools7,
1300
- ...tools3,
1898
+ ...tools8,
1899
+ ...tools11,
1301
1900
  ...tools2,
1302
- ...tools4
1901
+ ...tools12,
1902
+ ...tools4,
1903
+ ...tools3,
1904
+ ...tools13,
1905
+ ...tools5
1303
1906
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1304
1907
  ];
1305
1908
  const handwrittenNames = new Set(handwrittenAndCurated.map((t) => t.name));