@smartbear/mcp 0.17.0 → 0.18.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.
@@ -1,6 +1,7 @@
1
1
  import zod__default from "zod";
2
2
  import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
3
3
  import { isSamplingPolyfillResult } from "../common/pollyfills.js";
4
+ import { getRequestHeader } from "../common/request-context.js";
4
5
  import { ToolError } from "../common/tools.js";
5
6
  import { getOADMatcherRecommendations, getUserMatcherSelection } from "./client/prompt-utils.js";
6
7
  import { PROMPTS } from "./client/prompts.js";
@@ -18,38 +19,42 @@ class PactflowClient {
18
19
  toolPrefix = "contract-testing";
19
20
  configPrefix = "Pact-Broker";
20
21
  config = ConfigurationSchema;
21
- headers;
22
+ token;
23
+ username;
24
+ password;
22
25
  aiBaseUrl;
23
26
  baseUrl;
24
27
  _clientType;
25
28
  _server;
29
+ /** Returns the configured MCP server instance. @throws Error if not yet configured. */
26
30
  get server() {
27
31
  if (!this._server) throw new Error("Server not configured");
28
32
  return this._server;
29
33
  }
34
+ /**
35
+ * Initialises the client with auth credentials and the MCP server reference.
36
+ * Accepts either a Bearer token (PactFlow) or username/password (Pact Broker).
37
+ * Does nothing if neither is supplied.
38
+ *
39
+ * @param server - The MCP server instance to bind to.
40
+ * @param config - Connection config (base_url + token OR username/password).
41
+ */
30
42
  async configure(server, config) {
43
+ this.token = config.token;
44
+ this.username = config.username;
45
+ this.password = config.password;
31
46
  if (typeof config.token === "string") {
32
- this.headers = {
33
- Authorization: `Bearer ${config.token}`,
34
- "Content-Type": "application/json",
35
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
36
- };
37
47
  this._clientType = "pactflow";
38
48
  } else if (typeof config.username === "string" && typeof config.password === "string") {
39
- const authString = `${config.username}:${config.password}`;
40
- this.headers = {
41
- Authorization: `Basic ${Buffer.from(authString).toString("base64")}`,
42
- "Content-Type": "application/json",
43
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
44
- };
45
49
  this._clientType = "pact_broker";
46
50
  } else {
47
- return;
51
+ this._clientType = "pactflow";
48
52
  }
49
53
  this.baseUrl = config.base_url;
50
54
  this.aiBaseUrl = `${this.baseUrl}/api/ai`;
51
55
  this._server = server;
52
56
  }
57
+ /** Returns true if the client has been configured with a base URL and credentials. */
53
58
  isConfigured() {
54
59
  return this.baseUrl !== void 0;
55
60
  }
@@ -136,29 +141,84 @@ class PactflowClient {
136
141
  errorContext: "PactFlow AI Entitlements Request"
137
142
  });
138
143
  }
144
+ /**
145
+ * Polls the given status URL with a HEAD request to check operation progress.
146
+ *
147
+ * @param statusUrl - The URL returned by the async AI operation.
148
+ * @returns HTTP status code and whether the operation has completed (status 200).
149
+ */
139
150
  async getStatus(statusUrl) {
140
151
  const response = await fetch(statusUrl, {
141
152
  method: "HEAD",
142
- headers: this.headers
153
+ headers: this.requestHeaders
143
154
  });
144
155
  return {
145
156
  status: response.status,
146
157
  isComplete: response.status === 200
147
158
  };
148
159
  }
160
+ /** Returns the current auth/content-type headers used for all requests. */
149
161
  get requestHeaders() {
150
- return this.headers;
162
+ let contextToken = getRequestHeader("Pact-Token") || getRequestHeader("Authorization");
163
+ if (Array.isArray(contextToken)) {
164
+ contextToken = contextToken[0];
165
+ }
166
+ if (contextToken) {
167
+ let authHeader = contextToken;
168
+ if (!contextToken.startsWith("Basic ") && !contextToken.startsWith("Bearer ")) {
169
+ authHeader = `Bearer ${contextToken}`;
170
+ }
171
+ return {
172
+ Authorization: authHeader,
173
+ "Content-Type": "application/json",
174
+ "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
175
+ };
176
+ }
177
+ if (this.token) {
178
+ let authHeader = this.token;
179
+ if (!authHeader.startsWith("Basic ") && !authHeader.startsWith("Bearer ")) {
180
+ authHeader = `Bearer ${authHeader}`;
181
+ }
182
+ return {
183
+ Authorization: authHeader,
184
+ "Content-Type": "application/json",
185
+ "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
186
+ };
187
+ } else if (this.username && this.password) {
188
+ const authString = `${this.username}:${this.password}`;
189
+ return {
190
+ Authorization: `Basic ${Buffer.from(authString).toString("base64")}`,
191
+ "Content-Type": "application/json",
192
+ "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
193
+ };
194
+ }
195
+ return void 0;
151
196
  }
197
+ /**
198
+ * Fetches the final result of a completed async operation.
199
+ *
200
+ * @param resultUrl - The result URL returned by the async AI operation.
201
+ * @returns The parsed JSON result of type T.
202
+ * @throws ToolError if the response is not OK.
203
+ */
152
204
  async getResult(resultUrl) {
153
205
  const response = await fetch(resultUrl, {
154
206
  method: "GET",
155
- headers: this.headers
207
+ headers: this.requestHeaders
156
208
  });
157
209
  if (!response.ok) {
158
210
  throw new ToolError(`HTTP error! status: ${response.status}`);
159
211
  }
160
212
  return response.json();
161
213
  }
214
+ /**
215
+ * Polls status_url every second until the operation completes or times out (120s).
216
+ *
217
+ * @param status_response - URLs returned by the initial async submission.
218
+ * @param operationName - Human-readable name used in error messages.
219
+ * @returns The parsed result of type T on success.
220
+ * @throws ToolError on non-202 status or timeout.
221
+ */
162
222
  async pollForCompletion(status_response, operationName) {
163
223
  const startTime = Date.now();
164
224
  const timeout = 12e4;
@@ -192,7 +252,7 @@ class PactflowClient {
192
252
  try {
193
253
  const response = await fetch(url, {
194
254
  method,
195
- headers: this.headers,
255
+ headers: this.requestHeaders,
196
256
  ...body && { body: JSON.stringify(body) }
197
257
  });
198
258
  if (!response.ok) {
@@ -203,6 +263,9 @@ class PactflowClient {
203
263
  /* @__PURE__ */ new Map([["responseStatus", response.status]])
204
264
  );
205
265
  }
266
+ if (response.status === 204) {
267
+ return void 0;
268
+ }
206
269
  return await response.json();
207
270
  } catch (error) {
208
271
  if (error instanceof ToolError) {
@@ -236,6 +299,13 @@ class PactflowClient {
236
299
  );
237
300
  }
238
301
  // PactFlow / Pact_Broker client methods
302
+ /**
303
+ * Retrieves all provider states declared by a provider's pact tests.
304
+ *
305
+ * @param params - `provider`: The name of the provider.
306
+ * @returns List of provider state strings the provider supports.
307
+ * @throws ToolError if the request fails.
308
+ */
239
309
  async getProviderStates({
240
310
  provider
241
311
  }) {
@@ -332,7 +402,7 @@ class PactflowClient {
332
402
  try {
333
403
  const response = await fetch(url, {
334
404
  method: "GET",
335
- headers: this.headers
405
+ headers: this.requestHeaders
336
406
  });
337
407
  if (!response.ok) {
338
408
  const errorText = await response.text().catch(() => "");
@@ -357,7 +427,7 @@ class PactflowClient {
357
427
  try {
358
428
  const response = await fetch(url, {
359
429
  method: "GET",
360
- headers: this.headers
430
+ headers: this.requestHeaders
361
431
  });
362
432
  if (!response.ok) {
363
433
  const errorText = await response.text().catch(() => "");
@@ -371,6 +441,1615 @@ class PactflowClient {
371
441
  throw error;
372
442
  }
373
443
  }
444
+ /**
445
+ * Retrieves all pacticipants (applications/services) registered in the workspace,
446
+ * with optional pagination.
447
+ *
448
+ * @param params - Optional pagination parameters (`pageNumber`, `pageSize`).
449
+ * @returns List of pacticipants with their metadata.
450
+ * @throws ToolError if the request fails.
451
+ */
452
+ async listPacticipants(params) {
453
+ const queryParams = new URLSearchParams();
454
+ if (params?.pageNumber) queryParams.set("page", String(params.pageNumber));
455
+ if (params?.pageSize) queryParams.set("size", String(params.pageSize));
456
+ const qs = queryParams.toString();
457
+ return await this.fetchJson(
458
+ `${this.baseUrl}/pacticipants${qs ? `?${qs}` : ""}`,
459
+ { method: "GET", errorContext: "List Pacticipants" }
460
+ );
461
+ }
462
+ /**
463
+ * Retrieves metadata for a specific pacticipant by name.
464
+ *
465
+ * @param params - `pacticipantName`: The name of the pacticipant to fetch.
466
+ * @returns Pacticipant metadata including display name, main branch, and repository URL.
467
+ * @throws ToolError if the pacticipant is not found or the request fails.
468
+ */
469
+ async getPacticipant({ pacticipantName }) {
470
+ return await this.fetchJson(
471
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}`,
472
+ { method: "GET", errorContext: "Get Pacticipant" }
473
+ );
474
+ }
475
+ /**
476
+ * Retrieves all branches for a given pacticipant, with optional name filtering
477
+ * and pagination.
478
+ *
479
+ * @param params - `pacticipantName`, optional `q` (name filter), `pageNumber`, `pageSize`.
480
+ * @returns List of branches for the pacticipant.
481
+ * @throws ToolError if the request fails.
482
+ */
483
+ async listBranches({
484
+ pacticipantName,
485
+ q,
486
+ pageNumber,
487
+ pageSize
488
+ }) {
489
+ const queryParams = new URLSearchParams();
490
+ if (q) queryParams.set("q", q);
491
+ if (pageNumber) queryParams.set("pageNumber", String(pageNumber));
492
+ if (pageSize) queryParams.set("pageSize", String(pageSize));
493
+ const qs = queryParams.toString();
494
+ return await this.fetchJson(
495
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/branches${qs ? `?${qs}` : ""}`,
496
+ { method: "GET", errorContext: "List Branches" }
497
+ );
498
+ }
499
+ /**
500
+ * Retrieves all published versions for a given pacticipant, with optional pagination.
501
+ *
502
+ * @param params - `pacticipantName`, optional `pageNumber` and `pageSize`.
503
+ * @returns List of versions with their branch and tag associations.
504
+ * @throws ToolError if the request fails.
505
+ */
506
+ async listVersions({
507
+ pacticipantName,
508
+ pageNumber,
509
+ pageSize
510
+ }) {
511
+ const queryParams = new URLSearchParams();
512
+ if (pageNumber) queryParams.set("page", String(pageNumber));
513
+ if (pageSize) queryParams.set("size", String(pageSize));
514
+ const qs = queryParams.toString();
515
+ return await this.fetchJson(
516
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/versions${qs ? `?${qs}` : ""}`,
517
+ { method: "GET", errorContext: "List Versions" }
518
+ );
519
+ }
520
+ /**
521
+ * Retrieves metadata for a specific version of a pacticipant.
522
+ *
523
+ * @param params - `pacticipantName` and `versionNumber` to retrieve.
524
+ * @returns Version metadata including branches, tags, and build URL.
525
+ * @throws ToolError if the version is not found or the request fails.
526
+ */
527
+ async getVersion({
528
+ pacticipantName,
529
+ versionNumber
530
+ }) {
531
+ return await this.fetchJson(
532
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/versions/${encodeURIComponent(versionNumber)}`,
533
+ { method: "GET", errorContext: "Get Version" }
534
+ );
535
+ }
536
+ /**
537
+ * Retrieves the latest version of a pacticipant, optionally filtered by tag.
538
+ *
539
+ * @param params - `pacticipantName` and optional `tag` to filter by.
540
+ * @returns The latest matching version.
541
+ * @throws ToolError if the request fails.
542
+ */
543
+ async getLatestVersion({
544
+ pacticipantName,
545
+ tag
546
+ }) {
547
+ const path = tag ? `/pacticipants/${encodeURIComponent(pacticipantName)}/latest-version/${encodeURIComponent(tag)}` : `/pacticipants/${encodeURIComponent(pacticipantName)}/latest-version`;
548
+ return await this.fetchJson(`${this.baseUrl}${path}`, {
549
+ method: "GET",
550
+ errorContext: "Get Latest Version"
551
+ });
552
+ }
553
+ /**
554
+ * Retrieves all environments configured in the workspace.
555
+ *
556
+ * @returns List of environments with their UUIDs, names, and production flags.
557
+ * @throws ToolError if the request fails.
558
+ */
559
+ async listEnvironments() {
560
+ return await this.fetchJson(`${this.baseUrl}/environments`, {
561
+ method: "GET",
562
+ errorContext: "List Environments"
563
+ });
564
+ }
565
+ /**
566
+ * Retrieves metadata for a specific environment by UUID.
567
+ *
568
+ * @param params - `environmentId`: The UUID of the environment.
569
+ * @returns Environment metadata including name, display name, and production flag.
570
+ * @throws ToolError if the environment is not found or the request fails.
571
+ */
572
+ async getEnvironment({ environmentId }) {
573
+ return await this.fetchJson(
574
+ `${this.baseUrl}/environments/${encodeURIComponent(environmentId)}`,
575
+ { method: "GET", errorContext: "Get Environment" }
576
+ );
577
+ }
578
+ /**
579
+ * Records that a specific version of a pacticipant has been deployed to an environment.
580
+ *
581
+ * @param params - `pacticipantName`, `versionNumber`, `environmentId`, and optional
582
+ * `applicationInstance` (for blue/green or multi-instance deployments).
583
+ * @returns The created deployment record.
584
+ * @throws ToolError if the request fails.
585
+ */
586
+ async recordDeployment({
587
+ pacticipantName,
588
+ versionNumber,
589
+ environmentId,
590
+ applicationInstance
591
+ }) {
592
+ return await this.fetchJson(
593
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/versions/${encodeURIComponent(versionNumber)}/deployed-versions/environment/${encodeURIComponent(environmentId)}`,
594
+ {
595
+ method: "POST",
596
+ body: applicationInstance ? { applicationInstance } : {},
597
+ errorContext: "Record Deployment"
598
+ }
599
+ );
600
+ }
601
+ /**
602
+ * Retrieves all versions currently deployed to a given environment.
603
+ *
604
+ * @param params - `environmentId`: The UUID of the environment to query.
605
+ * @returns List of currently deployed versions across all pacticipants.
606
+ * @throws ToolError if the request fails.
607
+ */
608
+ async getCurrentlyDeployed({
609
+ environmentId
610
+ }) {
611
+ return await this.fetchJson(
612
+ `${this.baseUrl}/environments/${encodeURIComponent(environmentId)}/deployed-versions/currently-deployed`,
613
+ { method: "GET", errorContext: "Get Currently Deployed" }
614
+ );
615
+ }
616
+ /**
617
+ * Records that a version of a pacticipant has been released to an environment.
618
+ * Used for mobile/library workflows where multiple versions coexist simultaneously.
619
+ *
620
+ * @param params - `pacticipantName`, `versionNumber`, and `environmentId`.
621
+ * @returns The created release record.
622
+ * @throws ToolError if the request fails.
623
+ */
624
+ async recordRelease({
625
+ pacticipantName,
626
+ versionNumber,
627
+ environmentId
628
+ }) {
629
+ return await this.fetchJson(
630
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/versions/${encodeURIComponent(versionNumber)}/released-versions/environment/${encodeURIComponent(environmentId)}`,
631
+ { method: "POST", body: {}, errorContext: "Record Release" }
632
+ );
633
+ }
634
+ /**
635
+ * Retrieves all versions currently released and supported in a given environment.
636
+ *
637
+ * @param params - `environmentId`: The UUID of the environment to query.
638
+ * @returns List of currently supported released versions.
639
+ * @throws ToolError if the request fails.
640
+ */
641
+ async getCurrentlySupported({
642
+ environmentId
643
+ }) {
644
+ return await this.fetchJson(
645
+ `${this.baseUrl}/environments/${encodeURIComponent(environmentId)}/released-versions/currently-supported`,
646
+ { method: "GET", errorContext: "Get Currently Supported" }
647
+ );
648
+ }
649
+ /**
650
+ * Publishes one or more consumer Pact contracts to the Pact Broker or PactFlow.
651
+ *
652
+ * @param body - Consumer name, version number, contract files (base64-encoded),
653
+ * and optional branch/tag metadata.
654
+ * @returns Publication result including the pacticipant version number.
655
+ * @throws ToolError if the request fails.
656
+ */
657
+ async publishContracts(body) {
658
+ return await this.fetchJson(`${this.baseUrl}/contracts/publish`, {
659
+ method: "POST",
660
+ body,
661
+ errorContext: "Publish Consumer Contracts"
662
+ });
663
+ }
664
+ /**
665
+ * Publishes a provider OpenAPI contract and its self-verification results to PactFlow
666
+ * for use in Bi-Directional Contract Testing.
667
+ *
668
+ * @param params - `providerName`, version number, base64-encoded OpenAPI spec,
669
+ * content type, and self-verification results.
670
+ * @returns Publication result.
671
+ * @throws ToolError if the request fails.
672
+ */
673
+ async publishProviderContract({
674
+ providerName,
675
+ ...body
676
+ }) {
677
+ return await this.fetchJson(
678
+ `${this.baseUrl}/provider-contracts/provider/${encodeURIComponent(providerName)}/publish`,
679
+ { method: "POST", body, errorContext: "Publish Provider Contract" }
680
+ );
681
+ }
682
+ /**
683
+ * Retrieves the set of consumer pacts a provider should verify in its current CI run,
684
+ * based on consumer version selectors and WIP/pending pact configuration.
685
+ *
686
+ * @param params - `providerName`, consumer version selectors, pending/WIP flags,
687
+ * and optional provider branch/tag context.
688
+ * @returns List of pact URLs and metadata the provider must verify.
689
+ * @throws ToolError if the request fails.
690
+ */
691
+ async getPactsForVerification({
692
+ providerName,
693
+ ...body
694
+ }) {
695
+ return await this.fetchJson(
696
+ `${this.baseUrl}/pacts/provider/${encodeURIComponent(providerName)}/for-verification`,
697
+ { method: "POST", body, errorContext: "Get Pacts for Verification" }
698
+ );
699
+ }
700
+ /**
701
+ * Fetches the provider OpenAPI contract for a given provider version in BDCT.
702
+ *
703
+ * @param params - `providerName` and `providerVersionNumber`.
704
+ * @returns The published OpenAPI spec and its verification status.
705
+ * @throws ToolError if the request fails.
706
+ */
707
+ async getBiDirectionalProviderContract({
708
+ providerName,
709
+ providerVersionNumber
710
+ }) {
711
+ return await this.fetchJson(
712
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/provider-contract`,
713
+ { method: "GET", errorContext: "Get BDCT Provider Contract" }
714
+ );
715
+ }
716
+ /**
717
+ * Fetches the self-verification results for a provider contract version in BDCT.
718
+ *
719
+ * @param params - `providerName` and `providerVersionNumber`.
720
+ * @returns The results of the tool (e.g. Dredd, Schemathesis) that verified the provider.
721
+ * @throws ToolError if the request fails.
722
+ */
723
+ async getBiDirectionalProviderContractVerificationResults({
724
+ providerName,
725
+ providerVersionNumber
726
+ }) {
727
+ return await this.fetchJson(
728
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/provider-contract-verification-results`,
729
+ {
730
+ method: "GET",
731
+ errorContext: "Get BDCT Provider Contract Verification Results"
732
+ }
733
+ );
734
+ }
735
+ /**
736
+ * Fetches all consumer Pact contracts relevant to a given provider version in BDCT.
737
+ *
738
+ * @param params - `providerName` and `providerVersionNumber`.
739
+ * @returns Consumer contracts compared against the provider's OpenAPI spec.
740
+ * @throws ToolError if the request fails.
741
+ */
742
+ async getBiDirectionalConsumerContract({
743
+ providerName,
744
+ providerVersionNumber
745
+ }) {
746
+ return await this.fetchJson(
747
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/consumer-contract`,
748
+ { method: "GET", errorContext: "Get BDCT Consumer Contract" }
749
+ );
750
+ }
751
+ /**
752
+ * Fetches the consumer contract verification results for a given provider version in BDCT.
753
+ *
754
+ * @param params - `providerName` and `providerVersionNumber`.
755
+ * @returns Results of comparing all consumer pacts against the provider's OpenAPI spec.
756
+ * @throws ToolError if the request fails.
757
+ */
758
+ async getBiDirectionalConsumerContractVerificationResults({
759
+ providerName,
760
+ providerVersionNumber
761
+ }) {
762
+ return await this.fetchJson(
763
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/consumer-contract-verification-results`,
764
+ {
765
+ method: "GET",
766
+ errorContext: "Get BDCT Consumer Contract Verification Results"
767
+ }
768
+ );
769
+ }
770
+ /**
771
+ * Fetches the cross-contract verification results for a given provider version in BDCT.
772
+ *
773
+ * @param params - `providerName` and `providerVersionNumber`.
774
+ * @returns Combined outcome of PactFlow's automated comparison of the provider spec
775
+ * against all relevant consumer pacts.
776
+ * @throws ToolError if the request fails.
777
+ */
778
+ async getBiDirectionalCrossContractVerificationResults({
779
+ providerName,
780
+ providerVersionNumber
781
+ }) {
782
+ return await this.fetchJson(
783
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/cross-contract-verification-results`,
784
+ {
785
+ method: "GET",
786
+ errorContext: "Get BDCT Cross-Contract Verification Results"
787
+ }
788
+ );
789
+ }
790
+ /**
791
+ * Fetches the consumer Pact contract for a specific consumer-provider version pair in BDCT.
792
+ *
793
+ * @param params - `providerName`, `providerVersionNumber`, `consumerName`,
794
+ * and `consumerVersionNumber`.
795
+ * @returns The Pact contract published by the specified consumer version.
796
+ * @throws ToolError if the request fails.
797
+ */
798
+ async getBiDirectionalConsumerContractByConsumer({
799
+ providerName,
800
+ providerVersionNumber,
801
+ consumerName,
802
+ consumerVersionNumber
803
+ }) {
804
+ return await this.fetchJson(
805
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/consumer/${encodeURIComponent(consumerName)}/version/${encodeURIComponent(consumerVersionNumber)}/consumer-contract`,
806
+ {
807
+ method: "GET",
808
+ errorContext: "Get BDCT Consumer Contract (by consumer version)"
809
+ }
810
+ );
811
+ }
812
+ /**
813
+ * Fetches the provider OpenAPI contract for a specific consumer-provider version pair in BDCT.
814
+ *
815
+ * @param params - `providerName`, `providerVersionNumber`, `consumerName`,
816
+ * and `consumerVersionNumber`.
817
+ * @returns The provider's OpenAPI spec in the context of the given consumer version.
818
+ * @throws ToolError if the request fails.
819
+ */
820
+ async getBiDirectionalProviderContractByConsumer({
821
+ providerName,
822
+ providerVersionNumber,
823
+ consumerName,
824
+ consumerVersionNumber
825
+ }) {
826
+ return await this.fetchJson(
827
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/consumer/${encodeURIComponent(consumerName)}/version/${encodeURIComponent(consumerVersionNumber)}/provider-contract`,
828
+ {
829
+ method: "GET",
830
+ errorContext: "Get BDCT Provider Contract (by consumer version)"
831
+ }
832
+ );
833
+ }
834
+ /**
835
+ * Fetches the provider contract self-verification results for a specific
836
+ * consumer-provider version pair in BDCT.
837
+ *
838
+ * @param params - `providerName`, `providerVersionNumber`, `consumerName`,
839
+ * and `consumerVersionNumber`.
840
+ * @returns Provider self-verification results scoped to the given consumer version.
841
+ * @throws ToolError if the request fails.
842
+ */
843
+ async getBiDirectionalProviderContractVerificationResultsByConsumer({
844
+ providerName,
845
+ providerVersionNumber,
846
+ consumerName,
847
+ consumerVersionNumber
848
+ }) {
849
+ return await this.fetchJson(
850
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/consumer/${encodeURIComponent(consumerName)}/version/${encodeURIComponent(consumerVersionNumber)}/provider-contract-verification-results`,
851
+ {
852
+ method: "GET",
853
+ errorContext: "Get BDCT Provider Contract Verification Results (by consumer version)"
854
+ }
855
+ );
856
+ }
857
+ /**
858
+ * Fetches the consumer contract verification results for a specific
859
+ * consumer-provider version pair in BDCT.
860
+ *
861
+ * @param params - `providerName`, `providerVersionNumber`, `consumerName`,
862
+ * and `consumerVersionNumber`.
863
+ * @returns Results of comparing the specific consumer pact against the provider's OpenAPI spec.
864
+ * @throws ToolError if the request fails.
865
+ */
866
+ async getBiDirectionalConsumerContractVerificationResultsByConsumer({
867
+ providerName,
868
+ providerVersionNumber,
869
+ consumerName,
870
+ consumerVersionNumber
871
+ }) {
872
+ return await this.fetchJson(
873
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/consumer/${encodeURIComponent(consumerName)}/version/${encodeURIComponent(consumerVersionNumber)}/consumer-contract-verification-results`,
874
+ {
875
+ method: "GET",
876
+ errorContext: "Get BDCT Consumer Contract Verification Results (by consumer version)"
877
+ }
878
+ );
879
+ }
880
+ /**
881
+ * Fetches the cross-contract verification results for a specific
882
+ * consumer-provider version pair in BDCT.
883
+ *
884
+ * @param params - `providerName`, `providerVersionNumber`, `consumerName`,
885
+ * and `consumerVersionNumber`.
886
+ * @returns The precise cross-contract comparison outcome for the given pairing.
887
+ * @throws ToolError if the request fails.
888
+ */
889
+ async getBiDirectionalCrossContractVerificationResultsByConsumer({
890
+ providerName,
891
+ providerVersionNumber,
892
+ consumerName,
893
+ consumerVersionNumber
894
+ }) {
895
+ return await this.fetchJson(
896
+ `${this.baseUrl}/contracts/bi-directional/provider/${encodeURIComponent(providerName)}/version/${encodeURIComponent(providerVersionNumber)}/consumer/${encodeURIComponent(consumerName)}/version/${encodeURIComponent(consumerVersionNumber)}/cross-contract-verification-results`,
897
+ {
898
+ method: "GET",
899
+ errorContext: "Get BDCT Cross-Contract Verification Results (by consumer version)"
900
+ }
901
+ );
902
+ }
903
+ /**
904
+ * Retrieves all consumer-provider integrations registered in the workspace.
905
+ *
906
+ * @returns List of all consumer-provider pairings that have pacts published.
907
+ * @throws ToolError if the request fails.
908
+ */
909
+ async listIntegrations() {
910
+ return await this.fetchJson(`${this.baseUrl}/integrations`, {
911
+ method: "GET",
912
+ errorContext: "List Integrations"
913
+ });
914
+ }
915
+ /**
916
+ * Retrieves the integration network graph for a specific pacticipant,
917
+ * showing all services it consumes and all consumers that depend on it.
918
+ *
919
+ * @param params - `pacticipantName`: The name of the pacticipant.
920
+ * @returns Network graph of consumer-provider relationships for the pacticipant.
921
+ * @throws ToolError if the request fails.
922
+ */
923
+ async getPacticipantNetwork({
924
+ pacticipantName
925
+ }) {
926
+ return await this.fetchJson(
927
+ `${this.baseUrl}/pacticipant/${encodeURIComponent(pacticipantName)}/network`,
928
+ { method: "GET", errorContext: "Get Pacticipant Network" }
929
+ );
930
+ }
931
+ /**
932
+ * Retrieves all labels used across the workspace, with optional pagination.
933
+ *
934
+ * @param params - Optional `pageNumber` and `pageSize`.
935
+ * @returns List of every label applied to any pacticipant.
936
+ * @throws ToolError if the request fails.
937
+ */
938
+ async listLabels(params) {
939
+ const queryParams = new URLSearchParams();
940
+ if (params?.pageNumber) queryParams.set("page", String(params.pageNumber));
941
+ if (params?.pageSize) queryParams.set("size", String(params.pageSize));
942
+ const qs = queryParams.toString();
943
+ return await this.fetchJson(
944
+ `${this.baseUrl}/labels${qs ? `?${qs}` : ""}`,
945
+ { method: "GET", errorContext: "List Labels" }
946
+ );
947
+ }
948
+ /**
949
+ * Checks whether a specific label is applied to a pacticipant.
950
+ *
951
+ * @param params - `pacticipantName` and `labelName`.
952
+ * @returns The label resource if it exists (404 if not applied).
953
+ * @throws ToolError if the request fails.
954
+ */
955
+ async getPacticipantLabel({
956
+ pacticipantName,
957
+ labelName
958
+ }) {
959
+ return await this.fetchJson(
960
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/labels/${encodeURIComponent(labelName)}`,
961
+ { method: "GET", errorContext: "Get Pacticipant Label" }
962
+ );
963
+ }
964
+ /**
965
+ * Retrieves all pacticipants that have a specific label applied.
966
+ *
967
+ * @param params - `labelName`: The label to filter by.
968
+ * @returns List of pacticipants with the given label.
969
+ * @throws ToolError if the request fails.
970
+ */
971
+ async listPacticipantsByLabel({ labelName }) {
972
+ return await this.fetchJson(
973
+ `${this.baseUrl}/pacticipants/label/${encodeURIComponent(labelName)}`,
974
+ { method: "GET", errorContext: "List Pacticipants by Label" }
975
+ );
976
+ }
977
+ /**
978
+ * Fully replaces a pacticipant's metadata. All fields not provided are cleared.
979
+ *
980
+ * @param params - `pacticipantName` plus optional metadata fields
981
+ * (displayName, mainBranch, repositoryUrl, etc.).
982
+ * @returns The updated pacticipant resource.
983
+ * @throws ToolError if the request fails.
984
+ */
985
+ async updatePacticipant({
986
+ pacticipantName,
987
+ ...body
988
+ }) {
989
+ return await this.fetchJson(
990
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}`,
991
+ { method: "PUT", body, errorContext: "Update Pacticipant" }
992
+ );
993
+ }
994
+ /**
995
+ * Partially updates a pacticipant's metadata — only the fields provided are changed.
996
+ *
997
+ * @param params - `pacticipantName` plus the specific fields to update.
998
+ * @returns The updated pacticipant resource.
999
+ * @throws ToolError if the request fails.
1000
+ */
1001
+ async patchPacticipant({
1002
+ pacticipantName,
1003
+ ...body
1004
+ }) {
1005
+ return await this.fetchJson(
1006
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}`,
1007
+ { method: "PATCH", body, errorContext: "Patch Pacticipant" }
1008
+ );
1009
+ }
1010
+ /**
1011
+ * Updates metadata for a specific pacticipant version (e.g. sets the build URL).
1012
+ *
1013
+ * @param params - `pacticipantName`, `versionNumber`, and optional `buildUrl`.
1014
+ * @returns The updated version resource.
1015
+ * @throws ToolError if the request fails.
1016
+ */
1017
+ async updateVersion({
1018
+ pacticipantName,
1019
+ versionNumber,
1020
+ ...body
1021
+ }) {
1022
+ return await this.fetchJson(
1023
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/versions/${encodeURIComponent(versionNumber)}`,
1024
+ { method: "PUT", body, errorContext: "Update Version" }
1025
+ );
1026
+ }
1027
+ /**
1028
+ * Retrieves all versions published from a specific branch of a pacticipant.
1029
+ *
1030
+ * @param params - `pacticipantName`, `branchName`, optional `pageNumber` and `pageSize`.
1031
+ * @returns List of versions created on the given branch.
1032
+ * @throws ToolError if the request fails.
1033
+ */
1034
+ async getBranchVersions({
1035
+ pacticipantName,
1036
+ branchName,
1037
+ pageNumber,
1038
+ pageSize
1039
+ }) {
1040
+ const queryParams = new URLSearchParams();
1041
+ if (pageNumber) queryParams.set("page", String(pageNumber));
1042
+ if (pageSize) queryParams.set("size", String(pageSize));
1043
+ const qs = queryParams.toString();
1044
+ return await this.fetchJson(
1045
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/branches/${encodeURIComponent(branchName)}/versions${qs ? `?${qs}` : ""}`,
1046
+ { method: "GET", errorContext: "Get Branch Versions" }
1047
+ );
1048
+ }
1049
+ /**
1050
+ * Retrieves deployment records for a specific pacticipant version in a given environment.
1051
+ *
1052
+ * @param params - `pacticipantName`, `versionNumber`, and `environmentId`.
1053
+ * @returns All deployment records for the version, including whether each is currently active.
1054
+ * @throws ToolError if the request fails.
1055
+ */
1056
+ async getDeployedVersions({
1057
+ pacticipantName,
1058
+ versionNumber,
1059
+ environmentId
1060
+ }) {
1061
+ return await this.fetchJson(
1062
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/versions/${encodeURIComponent(versionNumber)}/deployed-versions/environment/${encodeURIComponent(environmentId)}`,
1063
+ { method: "GET", errorContext: "Get Deployed Versions" }
1064
+ );
1065
+ }
1066
+ /**
1067
+ * Retrieves release records for a specific pacticipant version in a given environment.
1068
+ *
1069
+ * @param params - `pacticipantName`, `versionNumber`, and `environmentId`.
1070
+ * @returns All release records for the version in the environment.
1071
+ * @throws ToolError if the request fails.
1072
+ */
1073
+ async getReleasedVersions({
1074
+ pacticipantName,
1075
+ versionNumber,
1076
+ environmentId
1077
+ }) {
1078
+ return await this.fetchJson(
1079
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/versions/${encodeURIComponent(versionNumber)}/released-versions/environment/${encodeURIComponent(environmentId)}`,
1080
+ { method: "GET", errorContext: "Get Released Versions" }
1081
+ );
1082
+ }
1083
+ /**
1084
+ * Creates a new deployment environment in the workspace.
1085
+ *
1086
+ * @param body - Environment name, display name, and whether it is a production environment.
1087
+ * @returns The created environment resource.
1088
+ * @throws ToolError if the request fails.
1089
+ */
1090
+ async createEnvironment({
1091
+ ...body
1092
+ }) {
1093
+ return await this.fetchJson(`${this.baseUrl}/environments`, {
1094
+ method: "POST",
1095
+ body,
1096
+ errorContext: "Create Environment"
1097
+ });
1098
+ }
1099
+ /**
1100
+ * Fully replaces an environment's configuration.
1101
+ *
1102
+ * @param params - `environmentId` (UUID) plus updated name, display name, and production flag.
1103
+ * @returns The updated environment resource.
1104
+ * @throws ToolError if the environment is not found or the request fails.
1105
+ */
1106
+ async updateEnvironment({
1107
+ environmentId,
1108
+ ...body
1109
+ }) {
1110
+ return await this.fetchJson(
1111
+ `${this.baseUrl}/environments/${encodeURIComponent(environmentId)}`,
1112
+ {
1113
+ method: "PUT",
1114
+ body,
1115
+ errorContext: "Update Environment"
1116
+ }
1117
+ );
1118
+ }
1119
+ /**
1120
+ * Deletes a deployment environment from the workspace.
1121
+ *
1122
+ * @param params - `environmentId`: UUID of the environment to delete.
1123
+ * @throws ToolError if the environment is not found or the request fails.
1124
+ */
1125
+ async deleteEnvironment({
1126
+ environmentId
1127
+ }) {
1128
+ return await this.fetchJson(
1129
+ `${this.baseUrl}/environments/${encodeURIComponent(environmentId)}`,
1130
+ {
1131
+ method: "DELETE",
1132
+ errorContext: "Delete Environment"
1133
+ }
1134
+ );
1135
+ }
1136
+ /**
1137
+ * Registers a new pacticipant (application/service) in the workspace.
1138
+ *
1139
+ * @param body - Name, optional display name, main branch, and repository URL.
1140
+ * @returns The created pacticipant resource.
1141
+ * @throws ToolError if the request fails.
1142
+ */
1143
+ async createPacticipant({
1144
+ ...body
1145
+ }) {
1146
+ return await this.fetchJson(`${this.baseUrl}/pacticipants`, {
1147
+ method: "POST",
1148
+ body,
1149
+ errorContext: "Create Pacticipant"
1150
+ });
1151
+ }
1152
+ /**
1153
+ * Permanently removes a pacticipant and all its associated data from the workspace.
1154
+ *
1155
+ * @param params - `pacticipantName`: The name of the pacticipant to delete.
1156
+ * @throws ToolError if the request fails.
1157
+ */
1158
+ async deletePacticipant({
1159
+ pacticipantName
1160
+ }) {
1161
+ return await this.fetchJson(
1162
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}`,
1163
+ {
1164
+ method: "DELETE",
1165
+ errorContext: "Delete Pacticipant"
1166
+ }
1167
+ );
1168
+ }
1169
+ /**
1170
+ * Retrieves metadata for a specific branch of a pacticipant.
1171
+ *
1172
+ * @param params - `pacticipantName` and `branchName`.
1173
+ * @returns Branch metadata including its versions.
1174
+ * @throws ToolError if the branch is not found or the request fails.
1175
+ */
1176
+ async getBranch({
1177
+ pacticipantName,
1178
+ branchName
1179
+ }) {
1180
+ return await this.fetchJson(
1181
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/branches/${encodeURIComponent(branchName)}`,
1182
+ { method: "GET", errorContext: "Get Branch" }
1183
+ );
1184
+ }
1185
+ /**
1186
+ * Deletes a branch and its version associations from a pacticipant.
1187
+ *
1188
+ * @param params - `pacticipantName` and `branchName`.
1189
+ * @throws ToolError if the branch is not found or the request fails.
1190
+ */
1191
+ async deleteBranch({
1192
+ pacticipantName,
1193
+ branchName
1194
+ }) {
1195
+ return await this.fetchJson(
1196
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/branches/${encodeURIComponent(branchName)}`,
1197
+ { method: "DELETE", errorContext: "Delete Branch" }
1198
+ );
1199
+ }
1200
+ /**
1201
+ * Applies a label to a pacticipant.
1202
+ *
1203
+ * @param params - `pacticipantName` and `labelName` to apply.
1204
+ * @returns The created label resource.
1205
+ * @throws ToolError if the request fails.
1206
+ */
1207
+ async addLabel({
1208
+ pacticipantName,
1209
+ labelName
1210
+ }) {
1211
+ return await this.fetchJson(
1212
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/labels/${encodeURIComponent(labelName)}`,
1213
+ { method: "PUT", body: {}, errorContext: "Add Label" }
1214
+ );
1215
+ }
1216
+ /**
1217
+ * Removes a label from a pacticipant.
1218
+ *
1219
+ * @param params - `pacticipantName` and `labelName` to remove.
1220
+ * @throws ToolError if the label or pacticipant is not found, or the request fails.
1221
+ */
1222
+ async removeLabel({
1223
+ pacticipantName,
1224
+ labelName
1225
+ }) {
1226
+ return await this.fetchJson(
1227
+ `${this.baseUrl}/pacticipants/${encodeURIComponent(pacticipantName)}/labels/${encodeURIComponent(labelName)}`,
1228
+ { method: "DELETE", errorContext: "Remove Label" }
1229
+ );
1230
+ }
1231
+ /**
1232
+ * Retrieves all consumer-provider integrations assigned to a specific team.
1233
+ *
1234
+ * @param params - `teamId`: UUID of the team.
1235
+ * @returns List of integrations associated with the team.
1236
+ * @throws ToolError if the request fails.
1237
+ */
1238
+ async getIntegrationsByTeam({
1239
+ teamId
1240
+ }) {
1241
+ return await this.fetchJson(
1242
+ `${this.baseUrl}/integrations/team/${encodeURIComponent(teamId)}`,
1243
+ {
1244
+ method: "GET",
1245
+ errorContext: "Get Integrations by Team"
1246
+ }
1247
+ );
1248
+ }
1249
+ /**
1250
+ * Deletes the integration (pact relationship) between a specific consumer and provider.
1251
+ *
1252
+ * @param params - `providerName` and `consumerName`.
1253
+ * @throws ToolError if the integration is not found or the request fails.
1254
+ */
1255
+ async deleteIntegration({
1256
+ providerName,
1257
+ consumerName
1258
+ }) {
1259
+ return await this.fetchJson(
1260
+ `${this.baseUrl}/integrations/provider/${encodeURIComponent(providerName)}/consumer/${encodeURIComponent(consumerName)}`,
1261
+ { method: "DELETE", errorContext: "Delete Integration" }
1262
+ );
1263
+ }
1264
+ /**
1265
+ * Deletes all consumer-provider integrations in the workspace. Use with caution.
1266
+ *
1267
+ * @throws ToolError if the request fails.
1268
+ */
1269
+ async deleteAllIntegrations() {
1270
+ return await this.fetchJson(`${this.baseUrl}/integrations`, {
1271
+ method: "DELETE",
1272
+ errorContext: "Delete All Integrations"
1273
+ });
1274
+ }
1275
+ /**
1276
+ * Retrieves all webhooks configured in the workspace.
1277
+ *
1278
+ * @returns List of webhook definitions and their trigger configurations.
1279
+ * @throws ToolError if the request fails.
1280
+ */
1281
+ async listWebhooks() {
1282
+ return await this.fetchJson(`${this.baseUrl}/webhooks`, {
1283
+ method: "GET",
1284
+ errorContext: "List Webhooks"
1285
+ });
1286
+ }
1287
+ /**
1288
+ * Retrieves the configuration for a specific webhook by UUID.
1289
+ *
1290
+ * @param params - `webhookId`: UUID of the webhook.
1291
+ * @returns Webhook definition including its URL, events, and consumer/provider filters.
1292
+ * @throws ToolError if the webhook is not found or the request fails.
1293
+ */
1294
+ async getWebhook({
1295
+ webhookId
1296
+ }) {
1297
+ return await this.fetchJson(
1298
+ `${this.baseUrl}/webhooks/${encodeURIComponent(webhookId)}`,
1299
+ {
1300
+ method: "GET",
1301
+ errorContext: "Get Webhook"
1302
+ }
1303
+ );
1304
+ }
1305
+ /**
1306
+ * Creates a new webhook triggered by pact publication or verification events.
1307
+ *
1308
+ * @param body - Webhook URL, HTTP method, headers, body, events, and optional
1309
+ * consumer/provider filters.
1310
+ * @returns The created webhook resource.
1311
+ * @throws ToolError if the request fails.
1312
+ */
1313
+ async createWebhook({
1314
+ ...body
1315
+ }) {
1316
+ return await this.fetchJson(`${this.baseUrl}/webhooks`, {
1317
+ method: "POST",
1318
+ body,
1319
+ errorContext: "Create Webhook"
1320
+ });
1321
+ }
1322
+ /**
1323
+ * Replaces the configuration of an existing webhook.
1324
+ *
1325
+ * @param params - `webhookId` (UUID) plus the full updated webhook definition.
1326
+ * @returns The updated webhook resource.
1327
+ * @throws ToolError if the webhook is not found or the request fails.
1328
+ */
1329
+ async updateWebhook({
1330
+ webhookId,
1331
+ ...body
1332
+ }) {
1333
+ return await this.fetchJson(
1334
+ `${this.baseUrl}/webhooks/${encodeURIComponent(webhookId)}`,
1335
+ {
1336
+ method: "PUT",
1337
+ body,
1338
+ errorContext: "Update Webhook"
1339
+ }
1340
+ );
1341
+ }
1342
+ /**
1343
+ * Deletes a webhook by UUID.
1344
+ *
1345
+ * @param params - `webhookId`: UUID of the webhook to delete.
1346
+ * @throws ToolError if the webhook is not found or the request fails.
1347
+ */
1348
+ async deleteWebhook({
1349
+ webhookId
1350
+ }) {
1351
+ return await this.fetchJson(
1352
+ `${this.baseUrl}/webhooks/${encodeURIComponent(webhookId)}`,
1353
+ {
1354
+ method: "DELETE",
1355
+ errorContext: "Delete Webhook"
1356
+ }
1357
+ );
1358
+ }
1359
+ /**
1360
+ * Fires all webhooks in the workspace as a test, regardless of their trigger conditions.
1361
+ *
1362
+ * @throws ToolError if the request fails.
1363
+ */
1364
+ async executeWebhooks() {
1365
+ return await this.fetchJson(`${this.baseUrl}/webhooks/execute`, {
1366
+ method: "POST",
1367
+ body: {},
1368
+ errorContext: "Execute Webhooks"
1369
+ });
1370
+ }
1371
+ /**
1372
+ * Fires a specific webhook as a test, regardless of its trigger conditions.
1373
+ *
1374
+ * @param params - `webhookId`: UUID of the webhook to execute.
1375
+ * @throws ToolError if the webhook is not found or the request fails.
1376
+ */
1377
+ async executeWebhook({
1378
+ webhookId
1379
+ }) {
1380
+ return await this.fetchJson(
1381
+ `${this.baseUrl}/webhooks/${encodeURIComponent(webhookId)}/execute`,
1382
+ {
1383
+ method: "POST",
1384
+ body: {},
1385
+ errorContext: "Execute Webhook"
1386
+ }
1387
+ );
1388
+ }
1389
+ /**
1390
+ * Retrieves all secrets stored in the workspace (names only, not values).
1391
+ *
1392
+ * @returns List of secret metadata.
1393
+ * @throws ToolError if the request fails.
1394
+ */
1395
+ async listSecrets() {
1396
+ return await this.fetchJson(`${this.baseUrl}/secrets`, {
1397
+ method: "GET",
1398
+ errorContext: "List Secrets"
1399
+ });
1400
+ }
1401
+ /**
1402
+ * Retrieves metadata for a specific secret by UUID (value is not returned).
1403
+ *
1404
+ * @param params - `secretId`: UUID of the secret.
1405
+ * @throws ToolError if the secret is not found or the request fails.
1406
+ */
1407
+ async getSecret({
1408
+ secretId
1409
+ }) {
1410
+ return await this.fetchJson(
1411
+ `${this.baseUrl}/secrets/${encodeURIComponent(secretId)}`,
1412
+ {
1413
+ method: "GET",
1414
+ errorContext: "Get Secret"
1415
+ }
1416
+ );
1417
+ }
1418
+ /**
1419
+ * Creates a new secret for use in webhook configurations.
1420
+ *
1421
+ * @param body - Secret name, description, and value.
1422
+ * @returns The created secret resource (value is not echoed back).
1423
+ * @throws ToolError if the request fails.
1424
+ */
1425
+ async createSecret({
1426
+ ...body
1427
+ }) {
1428
+ return await this.fetchJson(`${this.baseUrl}/secrets`, {
1429
+ method: "POST",
1430
+ body,
1431
+ errorContext: "Create Secret"
1432
+ });
1433
+ }
1434
+ /**
1435
+ * Replaces the value and/or description of an existing secret.
1436
+ *
1437
+ * @param params - `secretId` (UUID) plus updated name, description, and/or value.
1438
+ * @throws ToolError if the secret is not found or the request fails.
1439
+ */
1440
+ async updateSecret({
1441
+ secretId,
1442
+ ...body
1443
+ }) {
1444
+ return await this.fetchJson(
1445
+ `${this.baseUrl}/secrets/${encodeURIComponent(secretId)}`,
1446
+ {
1447
+ method: "PUT",
1448
+ body,
1449
+ errorContext: "Update Secret"
1450
+ }
1451
+ );
1452
+ }
1453
+ /**
1454
+ * Permanently deletes a secret from the workspace.
1455
+ *
1456
+ * @param params - `secretId`: UUID of the secret to delete.
1457
+ * @throws ToolError if the secret is not found or the request fails.
1458
+ */
1459
+ async deleteSecret({
1460
+ secretId
1461
+ }) {
1462
+ return await this.fetchJson(
1463
+ `${this.baseUrl}/secrets/${encodeURIComponent(secretId)}`,
1464
+ {
1465
+ method: "DELETE",
1466
+ errorContext: "Delete Secret"
1467
+ }
1468
+ );
1469
+ }
1470
+ /**
1471
+ * Retrieves the profile of the currently authenticated user.
1472
+ *
1473
+ * @returns Current user's name, email, roles, and active status.
1474
+ * @throws ToolError if the request fails.
1475
+ */
1476
+ async getCurrentUser() {
1477
+ return await this.fetchJson(`${this.baseUrl}/user`, {
1478
+ method: "GET",
1479
+ errorContext: "Get Current User"
1480
+ });
1481
+ }
1482
+ /**
1483
+ * Lists all API tokens associated with the current user's account.
1484
+ *
1485
+ * @returns Token metadata (IDs, descriptions) — values are not returned.
1486
+ * @throws ToolError if the request fails.
1487
+ */
1488
+ async listTokens() {
1489
+ return await this.fetchJson(`${this.baseUrl}/settings/tokens`, {
1490
+ method: "GET",
1491
+ errorContext: "List Tokens"
1492
+ });
1493
+ }
1494
+ /**
1495
+ * Regenerates (rotates) an API token, invalidating the previous value.
1496
+ *
1497
+ * @param params - `tokenId`: The identifier of the token to regenerate.
1498
+ * @returns The new token value.
1499
+ * @throws ToolError if the token is not found or the request fails.
1500
+ */
1501
+ async regenerateToken({
1502
+ tokenId
1503
+ }) {
1504
+ return await this.fetchJson(
1505
+ `${this.baseUrl}/settings/tokens/${encodeURIComponent(tokenId)}/regenerate`,
1506
+ {
1507
+ method: "POST",
1508
+ body: {},
1509
+ errorContext: "Regenerate Token"
1510
+ }
1511
+ );
1512
+ }
1513
+ /**
1514
+ * Retrieves UI and notification preferences for the currently authenticated user.
1515
+ *
1516
+ * @returns User preference settings.
1517
+ * @throws ToolError if the request fails.
1518
+ */
1519
+ async getUserPreferences() {
1520
+ return await this.fetchJson(
1521
+ `${this.baseUrl}/preferences/current-user`,
1522
+ {
1523
+ method: "GET",
1524
+ errorContext: "Get User Preferences"
1525
+ }
1526
+ );
1527
+ }
1528
+ /**
1529
+ * Retrieves workspace-level system preferences and configuration.
1530
+ *
1531
+ * @returns System preference settings.
1532
+ * @throws ToolError if the request fails.
1533
+ */
1534
+ async getSystemPreferences() {
1535
+ return await this.fetchJson(`${this.baseUrl}/preferences/system`, {
1536
+ method: "GET",
1537
+ errorContext: "Get System Preferences"
1538
+ });
1539
+ }
1540
+ /**
1541
+ * Retrieves the workspace audit log with optional filtering and pagination.
1542
+ *
1543
+ * @param params - Optional filters: `since` (ISO date), `userUuid`, `type`,
1544
+ * `sort`, `from` cursor, `pageNumber`, and `pageSize`.
1545
+ * @returns Paginated list of audit events.
1546
+ * @throws ToolError if the request fails.
1547
+ */
1548
+ async getAuditLog(params) {
1549
+ const queryParams = new URLSearchParams();
1550
+ if (params.since) queryParams.set("since", params.since);
1551
+ if (params.userUuid) queryParams.set("userUuid", params.userUuid);
1552
+ if (params.type) queryParams.set("type", params.type);
1553
+ if (params.sort) queryParams.set("sort", params.sort);
1554
+ if (params.from) queryParams.set("from", params.from);
1555
+ if (params.pageNumber)
1556
+ queryParams.set("pageNumber", String(params.pageNumber));
1557
+ if (params.pageSize) queryParams.set("pageSize", String(params.pageSize));
1558
+ const qs = queryParams.toString();
1559
+ return await this.fetchJson(
1560
+ `${this.baseUrl}/audit${qs ? `?${qs}` : ""}`,
1561
+ {
1562
+ method: "GET",
1563
+ errorContext: "Get Audit Log"
1564
+ }
1565
+ );
1566
+ }
1567
+ /**
1568
+ * Lists all users in the workspace with optional filtering and pagination (admin).
1569
+ *
1570
+ * @param params - Optional `active` flag, `q` (name/email search), `userType`,
1571
+ * `page`, and `size`.
1572
+ * @returns Paginated list of user accounts.
1573
+ * @throws ToolError if the request fails.
1574
+ */
1575
+ async listAdminUsers(params) {
1576
+ const queryParams = new URLSearchParams();
1577
+ if (params.active !== void 0)
1578
+ queryParams.set("active", String(params.active));
1579
+ if (params.q) queryParams.set("q", params.q);
1580
+ if (params.userType !== void 0)
1581
+ queryParams.set("userType", String(params.userType));
1582
+ if (params.page) queryParams.set("page", String(params.page));
1583
+ if (params.size) queryParams.set("size", String(params.size));
1584
+ const qs = queryParams.toString();
1585
+ return await this.fetchJson(
1586
+ `${this.baseUrl}/admin/users${qs ? `?${qs}` : ""}`,
1587
+ {
1588
+ method: "GET",
1589
+ errorContext: "List Admin Users"
1590
+ }
1591
+ );
1592
+ }
1593
+ /**
1594
+ * Retrieves a user's full profile by UUID (admin).
1595
+ *
1596
+ * @param params - `userId`: UUID of the user.
1597
+ * @returns User profile including roles and active status.
1598
+ * @throws ToolError if the user is not found or the request fails.
1599
+ */
1600
+ async getAdminUser({
1601
+ userId
1602
+ }) {
1603
+ return await this.fetchJson(
1604
+ `${this.baseUrl}/admin/users/${encodeURIComponent(userId)}`,
1605
+ {
1606
+ method: "GET",
1607
+ errorContext: "Get Admin User"
1608
+ }
1609
+ );
1610
+ }
1611
+ /**
1612
+ * Creates a new user account in the workspace (admin).
1613
+ *
1614
+ * @param body - User name, email, and optional SSO identity fields.
1615
+ * @returns The created user resource.
1616
+ * @throws ToolError if the request fails.
1617
+ */
1618
+ async createAdminUser({
1619
+ ...body
1620
+ }) {
1621
+ return await this.fetchJson(`${this.baseUrl}/admin/users`, {
1622
+ method: "POST",
1623
+ body,
1624
+ errorContext: "Create Admin User"
1625
+ });
1626
+ }
1627
+ /**
1628
+ * Replaces a user's profile (admin). Can also deactivate the user.
1629
+ *
1630
+ * @param params - `userId` (UUID) plus updated name, email, active flag, and SSO fields.
1631
+ * @returns The updated user resource.
1632
+ * @throws ToolError if the user is not found or the request fails.
1633
+ */
1634
+ async updateAdminUser({
1635
+ userId,
1636
+ ...body
1637
+ }) {
1638
+ return await this.fetchJson(
1639
+ `${this.baseUrl}/admin/users/${encodeURIComponent(userId)}`,
1640
+ {
1641
+ method: "PUT",
1642
+ body,
1643
+ errorContext: "Update Admin User"
1644
+ }
1645
+ );
1646
+ }
1647
+ /**
1648
+ * Permanently deletes a user account from the workspace (admin).
1649
+ *
1650
+ * @param params - `userId`: UUID of the user to delete.
1651
+ * @throws ToolError if the user is not found or the request fails.
1652
+ */
1653
+ async deleteAdminUser({
1654
+ userId
1655
+ }) {
1656
+ return await this.fetchJson(
1657
+ `${this.baseUrl}/admin/users/${encodeURIComponent(userId)}`,
1658
+ {
1659
+ method: "DELETE",
1660
+ errorContext: "Delete Admin User"
1661
+ }
1662
+ );
1663
+ }
1664
+ /**
1665
+ * Sends invitation emails to one or more new users (admin).
1666
+ *
1667
+ * @param params - `users`: Array of objects with email and optional name.
1668
+ * @throws ToolError if the request fails.
1669
+ */
1670
+ async inviteUsers({
1671
+ users
1672
+ }) {
1673
+ return await this.fetchJson(
1674
+ `${this.baseUrl}/admin/users/invite-users`,
1675
+ {
1676
+ method: "POST",
1677
+ body: { users },
1678
+ errorContext: "Invite Users"
1679
+ }
1680
+ );
1681
+ }
1682
+ /**
1683
+ * Fully replaces the roles assigned to a user (admin).
1684
+ * All existing roles are removed; the provided list becomes the new set.
1685
+ *
1686
+ * @param params - `userId` (UUID) and `roles` array of role UUIDs.
1687
+ * @throws ToolError if the user is not found or the request fails.
1688
+ */
1689
+ async setUserRoles({
1690
+ userId,
1691
+ roles
1692
+ }) {
1693
+ return await this.fetchJson(
1694
+ `${this.baseUrl}/admin/users/${encodeURIComponent(userId)}/roles`,
1695
+ {
1696
+ method: "PUT",
1697
+ body: { roles },
1698
+ errorContext: "Set User Roles"
1699
+ }
1700
+ );
1701
+ }
1702
+ /**
1703
+ * Grants a single additional role to a user without affecting their existing roles (admin).
1704
+ *
1705
+ * @param params - `userId` and `roleId` UUIDs.
1706
+ * @throws ToolError if the user or role is not found, or the request fails.
1707
+ */
1708
+ async addRoleToUser({
1709
+ userId,
1710
+ roleId
1711
+ }) {
1712
+ return await this.fetchJson(
1713
+ `${this.baseUrl}/admin/users/${encodeURIComponent(userId)}/roles/${encodeURIComponent(roleId)}`,
1714
+ { method: "PUT", body: {}, errorContext: "Add Role to User" }
1715
+ );
1716
+ }
1717
+ /**
1718
+ * Revokes a specific role from a user without affecting their other roles (admin).
1719
+ *
1720
+ * @param params - `userId` and `roleId` UUIDs.
1721
+ * @throws ToolError if the user or role is not found, or the request fails.
1722
+ */
1723
+ async removeRoleFromUser({
1724
+ userId,
1725
+ roleId
1726
+ }) {
1727
+ return await this.fetchJson(
1728
+ `${this.baseUrl}/admin/users/${encodeURIComponent(userId)}/roles/${encodeURIComponent(roleId)}`,
1729
+ { method: "DELETE", errorContext: "Remove Role from User" }
1730
+ );
1731
+ }
1732
+ /**
1733
+ * Lists all teams in the workspace with optional name filtering and pagination (admin).
1734
+ *
1735
+ * @param params - Optional `q` (name search), `page`, and `size`.
1736
+ * @returns Paginated list of teams.
1737
+ * @throws ToolError if the request fails.
1738
+ */
1739
+ async listAdminTeams(params) {
1740
+ const queryParams = new URLSearchParams();
1741
+ if (params.q) queryParams.set("q", params.q);
1742
+ if (params.page) queryParams.set("page", String(params.page));
1743
+ if (params.size) queryParams.set("size", String(params.size));
1744
+ const qs = queryParams.toString();
1745
+ return await this.fetchJson(
1746
+ `${this.baseUrl}/admin/teams${qs ? `?${qs}` : ""}`,
1747
+ {
1748
+ method: "GET",
1749
+ errorContext: "List Admin Teams"
1750
+ }
1751
+ );
1752
+ }
1753
+ /**
1754
+ * Retrieves the full configuration of a team by UUID (admin).
1755
+ *
1756
+ * @param params - `teamId`: UUID of the team.
1757
+ * @returns Team details including name, members, environments, and pacticipants.
1758
+ * @throws ToolError if the team is not found or the request fails.
1759
+ */
1760
+ async getAdminTeam({
1761
+ teamId
1762
+ }) {
1763
+ return await this.fetchJson(
1764
+ `${this.baseUrl}/admin/teams/${encodeURIComponent(teamId)}`,
1765
+ {
1766
+ method: "GET",
1767
+ errorContext: "Get Admin Team"
1768
+ }
1769
+ );
1770
+ }
1771
+ /**
1772
+ * Creates a new team in the workspace (admin).
1773
+ *
1774
+ * @param body - Team name and optional administrators, environments, and pacticipants.
1775
+ * @returns The created team resource.
1776
+ * @throws ToolError if the request fails.
1777
+ */
1778
+ async createAdminTeam({
1779
+ ...body
1780
+ }) {
1781
+ return await this.fetchJson(`${this.baseUrl}/admin/teams`, {
1782
+ method: "POST",
1783
+ body,
1784
+ errorContext: "Create Admin Team"
1785
+ });
1786
+ }
1787
+ /**
1788
+ * Fully replaces a team's configuration (admin).
1789
+ *
1790
+ * @param params - `teamId` (UUID) plus updated name, administrators, environments,
1791
+ * and pacticipant assignments.
1792
+ * @throws ToolError if the team is not found or the request fails.
1793
+ */
1794
+ async updateAdminTeam({
1795
+ teamId,
1796
+ ...body
1797
+ }) {
1798
+ return await this.fetchJson(
1799
+ `${this.baseUrl}/admin/teams/${encodeURIComponent(teamId)}`,
1800
+ {
1801
+ method: "PUT",
1802
+ body,
1803
+ errorContext: "Update Admin Team"
1804
+ }
1805
+ );
1806
+ }
1807
+ /**
1808
+ * Permanently deletes a team from the workspace (admin). Members are not deleted.
1809
+ *
1810
+ * @param params - `teamId`: UUID of the team to delete.
1811
+ * @throws ToolError if the team is not found or the request fails.
1812
+ */
1813
+ async deleteAdminTeam({
1814
+ teamId
1815
+ }) {
1816
+ return await this.fetchJson(
1817
+ `${this.baseUrl}/admin/teams/${encodeURIComponent(teamId)}`,
1818
+ {
1819
+ method: "DELETE",
1820
+ errorContext: "Delete Admin Team"
1821
+ }
1822
+ );
1823
+ }
1824
+ /**
1825
+ * Lists all user members of a specific team (admin).
1826
+ *
1827
+ * @param params - `teamId`: UUID of the team.
1828
+ * @returns List of users in the team.
1829
+ * @throws ToolError if the team is not found or the request fails.
1830
+ */
1831
+ async listTeamUsers({
1832
+ teamId
1833
+ }) {
1834
+ return await this.fetchJson(
1835
+ `${this.baseUrl}/admin/teams/${encodeURIComponent(teamId)}/users`,
1836
+ {
1837
+ method: "GET",
1838
+ errorContext: "List Team Users"
1839
+ }
1840
+ );
1841
+ }
1842
+ /**
1843
+ * Verifies whether a specific user is a member of a team (admin).
1844
+ * Returns 404 if the user is not in the team.
1845
+ *
1846
+ * @param params - `teamId` and `userId` UUIDs.
1847
+ * @throws ToolError if not found or the request fails.
1848
+ */
1849
+ async getTeamUser({
1850
+ teamId,
1851
+ userId
1852
+ }) {
1853
+ return await this.fetchJson(
1854
+ `${this.baseUrl}/admin/teams/${encodeURIComponent(teamId)}/users/${encodeURIComponent(userId)}`,
1855
+ { method: "GET", errorContext: "Get Team User" }
1856
+ );
1857
+ }
1858
+ /**
1859
+ * Fully replaces the members of a team (admin).
1860
+ * All existing members are removed; the provided UUID list becomes the new membership.
1861
+ *
1862
+ * @param params - `teamId` (UUID) and `uuids` array of user UUIDs.
1863
+ * @throws ToolError if the team is not found or the request fails.
1864
+ */
1865
+ async setTeamUsers({
1866
+ teamId,
1867
+ uuids
1868
+ }) {
1869
+ return await this.fetchJson(
1870
+ `${this.baseUrl}/admin/teams/${encodeURIComponent(teamId)}/users`,
1871
+ {
1872
+ method: "PUT",
1873
+ body: { uuids },
1874
+ errorContext: "Set Team Users"
1875
+ }
1876
+ );
1877
+ }
1878
+ /**
1879
+ * Adds or removes individual users from a team using JSON Patch semantics (admin).
1880
+ *
1881
+ * @param params - `teamId` (UUID) and `operations` array of JSON Patch ops (add/remove).
1882
+ * @throws ToolError if the team is not found or the request fails.
1883
+ */
1884
+ async patchTeamUsers({
1885
+ teamId,
1886
+ operations
1887
+ }) {
1888
+ return await this.fetchJson(
1889
+ `${this.baseUrl}/admin/teams/${encodeURIComponent(teamId)}/users`,
1890
+ {
1891
+ method: "PATCH",
1892
+ body: operations,
1893
+ errorContext: "Patch Team Users"
1894
+ }
1895
+ );
1896
+ }
1897
+ /**
1898
+ * Removes a specific user from a team (admin).
1899
+ *
1900
+ * @param params - `teamId` and `userId` UUIDs.
1901
+ * @throws ToolError if not found or the request fails.
1902
+ */
1903
+ async removeUserFromTeam({
1904
+ teamId,
1905
+ userId
1906
+ }) {
1907
+ return await this.fetchJson(
1908
+ `${this.baseUrl}/admin/teams/${encodeURIComponent(teamId)}/users/${encodeURIComponent(userId)}`,
1909
+ { method: "DELETE", errorContext: "Remove User from Team" }
1910
+ );
1911
+ }
1912
+ /**
1913
+ * Lists all roles defined in the workspace (admin).
1914
+ *
1915
+ * @returns All role definitions and their associated permission scopes.
1916
+ * @throws ToolError if the request fails.
1917
+ */
1918
+ async listAdminRoles() {
1919
+ return await this.fetchJson(`${this.baseUrl}/admin/roles`, {
1920
+ method: "GET",
1921
+ errorContext: "List Admin Roles"
1922
+ });
1923
+ }
1924
+ /**
1925
+ * Retrieves a role's name, description, and full permission set by UUID (admin).
1926
+ *
1927
+ * @param params - `roleId`: UUID of the role.
1928
+ * @throws ToolError if the role is not found or the request fails.
1929
+ */
1930
+ async getAdminRole({
1931
+ roleId
1932
+ }) {
1933
+ return await this.fetchJson(
1934
+ `${this.baseUrl}/admin/roles/${encodeURIComponent(roleId)}`,
1935
+ {
1936
+ method: "GET",
1937
+ errorContext: "Get Admin Role"
1938
+ }
1939
+ );
1940
+ }
1941
+ /**
1942
+ * Creates a custom role with a tailored set of permission scopes (admin).
1943
+ *
1944
+ * @param body - Role name, optional description, and array of permission scope strings.
1945
+ * @returns The created role resource.
1946
+ * @throws ToolError if the request fails.
1947
+ */
1948
+ async createAdminRole({
1949
+ ...body
1950
+ }) {
1951
+ return await this.fetchJson(`${this.baseUrl}/admin/roles`, {
1952
+ method: "POST",
1953
+ body,
1954
+ errorContext: "Create Admin Role"
1955
+ });
1956
+ }
1957
+ /**
1958
+ * Updates an existing role's name and/or permission set (admin).
1959
+ * Changes affect all users currently assigned the role.
1960
+ *
1961
+ * @param params - `roleId` (UUID) plus updated name, description, and permissions.
1962
+ * @throws ToolError if the role is not found or the request fails.
1963
+ */
1964
+ async updateAdminRole({
1965
+ roleId,
1966
+ ...body
1967
+ }) {
1968
+ return await this.fetchJson(
1969
+ `${this.baseUrl}/admin/roles/${encodeURIComponent(roleId)}`,
1970
+ {
1971
+ method: "PUT",
1972
+ body,
1973
+ errorContext: "Update Admin Role"
1974
+ }
1975
+ );
1976
+ }
1977
+ /**
1978
+ * Permanently deletes a role (admin). Users assigned this role will lose its permissions.
1979
+ *
1980
+ * @param params - `roleId`: UUID of the role to delete.
1981
+ * @throws ToolError if the role is not found or the request fails.
1982
+ */
1983
+ async deleteAdminRole({
1984
+ roleId
1985
+ }) {
1986
+ return await this.fetchJson(
1987
+ `${this.baseUrl}/admin/roles/${encodeURIComponent(roleId)}`,
1988
+ {
1989
+ method: "DELETE",
1990
+ errorContext: "Delete Admin Role"
1991
+ }
1992
+ );
1993
+ }
1994
+ /**
1995
+ * Resets all roles to factory defaults (admin).
1996
+ * Custom roles are removed; built-in roles are restored to their original permissions.
1997
+ *
1998
+ * @throws ToolError if the request fails.
1999
+ */
2000
+ async resetAdminRoles() {
2001
+ return await this.fetchJson(`${this.baseUrl}/admin/roles/reset`, {
2002
+ method: "POST",
2003
+ body: {},
2004
+ errorContext: "Reset Admin Roles"
2005
+ });
2006
+ }
2007
+ /**
2008
+ * Lists all permission scopes available to assign to roles (admin).
2009
+ *
2010
+ * @returns All permission scope definitions.
2011
+ * @throws ToolError if the request fails.
2012
+ */
2013
+ async listAdminPermissions() {
2014
+ return await this.fetchJson(`${this.baseUrl}/admin/permissions`, {
2015
+ method: "GET",
2016
+ errorContext: "List Admin Permissions"
2017
+ });
2018
+ }
2019
+ /**
2020
+ * Creates a machine/service account that authenticates via API token (admin).
2021
+ *
2022
+ * @param body - Account name and optional description.
2023
+ * @returns The created system account resource.
2024
+ * @throws ToolError if the request fails.
2025
+ */
2026
+ async createSystemAccount({
2027
+ ...body
2028
+ }) {
2029
+ return await this.fetchJson(`${this.baseUrl}/admin/system-accounts`, {
2030
+ method: "POST",
2031
+ body,
2032
+ errorContext: "Create System Account"
2033
+ });
2034
+ }
2035
+ /**
2036
+ * Retrieves the API tokens associated with a system account (admin).
2037
+ *
2038
+ * @param params - `accountId`: UUID of the system account.
2039
+ * @returns Token list for use in CI/CD pipelines.
2040
+ * @throws ToolError if the account is not found or the request fails.
2041
+ */
2042
+ async getSystemAccountTokens({
2043
+ accountId
2044
+ }) {
2045
+ return await this.fetchJson(
2046
+ `${this.baseUrl}/admin/system-accounts/${encodeURIComponent(accountId)}/tokens`,
2047
+ {
2048
+ method: "GET",
2049
+ errorContext: "Get System Account Tokens"
2050
+ }
2051
+ );
2052
+ }
374
2053
  /**
375
2054
  * Registers tools with the provided register function.
376
2055
  *