portkey-admin-mcp 0.6.2 → 0.7.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/build/server.js CHANGED
@@ -136,6 +136,7 @@ var Logger = {
136
136
 
137
137
  // src/services/base.service.ts
138
138
  var DEFAULT_BASE_URL = "https://api.portkey.ai/v1";
139
+ var DEFAULT_PUBLIC_BASE_URL = "https://api.portkey.ai";
139
140
  var PRIVATE_BASE_URL_OVERRIDE_HINT = "Set PORTKEY_ALLOW_PRIVATE_BASE_URL=true to allow self-hosted gateways on loopback or private networks.";
140
141
  var INSECURE_HTTP_OVERRIDE_HINT = "Set PORTKEY_ALLOW_INSECURE_HTTP=true only for a trusted self-hosted gateway when TLS is unavailable.";
141
142
  function isPrivateOrLocalHost(hostname) {
@@ -230,14 +231,12 @@ var BaseService = class {
230
231
  encodePathSegment(value) {
231
232
  return encodeURIComponent(value);
232
233
  }
233
- buildUrl(path, params) {
234
- return `${this.baseUrl}${path}${buildQueryString(params)}`;
234
+ buildUrl(path, params, baseUrl = this.baseUrl) {
235
+ return `${baseUrl}${path}${buildQueryString(params)}`;
235
236
  }
236
- buildHeaders(method) {
237
- const headers = {
238
- "x-portkey-api-key": this.apiKey,
239
- Accept: "application/json"
240
- };
237
+ buildHeaders(method, authenticate = true) {
238
+ const headers = { Accept: "application/json" };
239
+ if (authenticate) headers["x-portkey-api-key"] = this.apiKey;
241
240
  if (method === "POST" || method === "PUT") {
242
241
  headers["Content-Type"] = "application/json";
243
242
  }
@@ -248,7 +247,7 @@ var BaseService = class {
248
247
  }
249
248
  async executeRequest(method, path, options = {}) {
250
249
  const requestId = crypto.randomUUID();
251
- const url = this.buildUrl(path, options.params);
250
+ const url = this.buildUrl(path, options.params, options.baseUrl);
252
251
  const startTime = Date.now();
253
252
  Logger.debug("HTTP request started", {
254
253
  requestId,
@@ -262,7 +261,7 @@ var BaseService = class {
262
261
  const response = await fetchWithTimeout(url, {
263
262
  method,
264
263
  redirect: "manual",
265
- headers: this.buildHeaders(method),
264
+ headers: this.buildHeaders(method, options.authenticate),
266
265
  body: this.serializeBody(options.body),
267
266
  timeout: this.timeout
268
267
  });
@@ -307,14 +306,25 @@ var BaseService = class {
307
306
  async get(path, params) {
308
307
  return this.executeRequest("GET", path, { params });
309
308
  }
309
+ /** Read an unauthenticated Portkey public-catalog endpoint outside /v1. */
310
+ async getPublic(path, params) {
311
+ return this.executeRequest("GET", path, {
312
+ params,
313
+ baseUrl: DEFAULT_PUBLIC_BASE_URL,
314
+ authenticate: false
315
+ });
316
+ }
310
317
  async post(path, body) {
311
318
  return this.executeRequest("POST", path, { body });
312
319
  }
313
320
  async put(path, body) {
314
321
  return this.executeRequest("PUT", path, { body });
315
322
  }
316
- async delete(path) {
317
- return this.executeRequest("DELETE", path, { allowNoContent: true });
323
+ async delete(path, params) {
324
+ return this.executeRequest("DELETE", path, {
325
+ params,
326
+ allowNoContent: true
327
+ });
318
328
  }
319
329
  };
320
330
 
@@ -581,6 +591,33 @@ var ConfigsService = class extends BaseService {
581
591
 
582
592
  // src/services/guardrails.service.ts
583
593
  var GuardrailsService = class extends BaseService {
594
+ /** Get the organisation-wide input and output guardrail defaults. */
595
+ async getOrganisationDefaults() {
596
+ return this.get(
597
+ "/admin/organisation/defaults"
598
+ );
599
+ }
600
+ /** Replace either or both organisation-wide guardrail default lists. */
601
+ async updateOrganisationDefaults(data) {
602
+ return this.put(
603
+ "/admin/organisation/defaults",
604
+ data
605
+ );
606
+ }
607
+ /** List workspace exclusions for input or output organisation guardrails. */
608
+ async listWorkspaceExclusions(direction, params) {
609
+ return this.get(
610
+ `/workspace-exclusions/${direction}-guardrails`,
611
+ params
612
+ );
613
+ }
614
+ /** Update workspace exclusions for input or output organisation guardrails. */
615
+ async updateWorkspaceExclusions(direction, data) {
616
+ return this.put(
617
+ `/workspace-exclusions/${direction}-guardrails`,
618
+ data
619
+ );
620
+ }
584
621
  /**
585
622
  * List all guardrails with optional filtering
586
623
  */
@@ -667,6 +704,12 @@ var HealthService = class extends BaseService {
667
704
 
668
705
  // src/services/integrations.service.ts
669
706
  var IntegrationsService = class extends BaseService {
707
+ // Get current public catalog pricing (USD cents per token/unit).
708
+ async getModelPricing(provider, model) {
709
+ return this.getPublic(
710
+ `/model-configs/pricing/${this.encodePathSegment(provider)}/${this.encodePathSegment(model)}`
711
+ );
712
+ }
670
713
  // List all integrations
671
714
  async listIntegrations(params) {
672
715
  return this.get("/integrations", {
@@ -698,13 +741,16 @@ var IntegrationsService = class extends BaseService {
698
741
  }
699
742
  // List models for an integration
700
743
  async listIntegrationModels(slug, params) {
701
- return this.get(
702
- `/integrations/${this.encodePathSegment(slug)}/models`,
703
- {
704
- current_page: params?.current_page,
705
- page_size: params?.page_size
706
- }
707
- );
744
+ const response = await this.get(`/integrations/${this.encodePathSegment(slug)}/models`, {
745
+ current_page: params?.current_page,
746
+ page_size: params?.page_size
747
+ });
748
+ const data = response.data ?? response.models ?? [];
749
+ return {
750
+ object: response.object ?? "list",
751
+ total: response.total ?? data.length,
752
+ data
753
+ };
708
754
  }
709
755
  // Update models for an integration
710
756
  async updateIntegrationModels(slug, data) {
@@ -723,13 +769,16 @@ var IntegrationsService = class extends BaseService {
723
769
  }
724
770
  // List workspaces for an integration
725
771
  async listIntegrationWorkspaces(slug, params) {
726
- return this.get(
727
- `/integrations/${this.encodePathSegment(slug)}/workspaces`,
728
- {
729
- current_page: params?.current_page,
730
- page_size: params?.page_size
731
- }
732
- );
772
+ const response = await this.get(`/integrations/${this.encodePathSegment(slug)}/workspaces`, {
773
+ current_page: params?.current_page,
774
+ page_size: params?.page_size
775
+ });
776
+ const data = response.data ?? response.workspaces ?? [];
777
+ return {
778
+ object: response.object ?? "list",
779
+ total: response.total ?? data.length,
780
+ data
781
+ };
733
782
  }
734
783
  // Update workspaces for an integration
735
784
  async updateIntegrationWorkspaces(slug, data) {
@@ -930,6 +979,20 @@ var LimitsService = class extends BaseService {
930
979
 
931
980
  // src/services/logging.service.ts
932
981
  var LoggingService = class extends BaseService {
982
+ /** Get one gateway log by ID. */
983
+ async getLog(logId, params) {
984
+ return this.get(
985
+ `/logs/${this.encodePathSegment(logId)}`,
986
+ params
987
+ );
988
+ }
989
+ /** Get organisation-managed export field restrictions for a workspace. */
990
+ async getLogExportFieldRestrictions(params) {
991
+ return this.get(
992
+ "/logs/exports/field-restrictions",
993
+ params
994
+ );
995
+ }
933
996
  /**
934
997
  * Insert a log entry (or multiple entries) into Portkey
935
998
  */
@@ -1049,6 +1112,19 @@ var McpIntegrationsService = class extends BaseService {
1049
1112
 
1050
1113
  // src/services/mcp-servers.service.ts
1051
1114
  var McpServersService = class extends BaseService {
1115
+ async listMcpServerConnections(id, params) {
1116
+ return this.get(
1117
+ `/mcp-servers/${this.encodePathSegment(id)}/connections`,
1118
+ params
1119
+ );
1120
+ }
1121
+ async disconnectMcpServerConnection(id, params) {
1122
+ await this.delete(
1123
+ `/mcp-servers/${this.encodePathSegment(id)}/connections`,
1124
+ params
1125
+ );
1126
+ return { success: true };
1127
+ }
1052
1128
  async listMcpServers(params) {
1053
1129
  return this.get("/mcp-servers", {
1054
1130
  current_page: params?.current_page,
@@ -1626,6 +1702,22 @@ var UsersService = class extends BaseService {
1626
1702
 
1627
1703
  // src/services/workspaces.service.ts
1628
1704
  var WorkspacesService = class extends BaseService {
1705
+ async listScimWorkspaceMappings(params) {
1706
+ return this.get(
1707
+ "/scim/workspaces",
1708
+ params
1709
+ );
1710
+ }
1711
+ async createScimWorkspaceMapping(data) {
1712
+ return this.post("/scim/workspaces", data);
1713
+ }
1714
+ async deleteScimWorkspaceMapping(mappingId) {
1715
+ await this.delete(`/scim/workspaces/${this.encodePathSegment(mappingId)}`);
1716
+ return { success: true };
1717
+ }
1718
+ async listScimGroups(params) {
1719
+ return this.get("/scim/groups", params);
1720
+ }
1629
1721
  async listWorkspaces(params) {
1630
1722
  return this.get("/admin/workspaces", params);
1631
1723
  }
@@ -1772,7 +1864,7 @@ function getSharedPortkeyService(apiKey) {
1772
1864
  }
1773
1865
 
1774
1866
  // src/tools/index.ts
1775
- import { z as z22 } from "zod";
1867
+ import { z as z23 } from "zod";
1776
1868
 
1777
1869
  // src/lib/type-guards.ts
1778
1870
  function isRecord(value) {
@@ -2701,6 +2793,12 @@ function registerCollectionsTools(server, service) {
2701
2793
 
2702
2794
  // src/tools/configs.tools.ts
2703
2795
  import { z as z5 } from "zod";
2796
+ var configTargetSchema = z5.object({
2797
+ provider: z5.string().optional().describe("Provider slug to route requests to"),
2798
+ virtual_key: z5.string().optional().describe("Virtual key slug to use for this routing target")
2799
+ }).refine((target) => target.provider || target.virtual_key, {
2800
+ message: "Each target must have at least provider or virtual_key"
2801
+ });
2704
2802
  var CONFIGS_TOOL_SCHEMAS = {
2705
2803
  listConfigs: {
2706
2804
  current_page: z5.coerce.number().int().positive().optional().describe("Page number for pagination"),
@@ -2719,14 +2817,7 @@ var CONFIGS_TOOL_SCHEMAS = {
2719
2817
  retry_attempts: z5.coerce.number().positive().max(5).optional().describe("Number of retry attempts (1-5)"),
2720
2818
  retry_on_status_codes: z5.array(z5.coerce.number()).optional().describe("HTTP status codes to retry on (e.g., [429, 500, 502, 503])"),
2721
2819
  strategy_mode: z5.enum(["loadbalance", "fallback"]).optional().describe("Routing strategy: 'loadbalance' or 'fallback'"),
2722
- targets: z5.array(
2723
- z5.object({
2724
- provider: z5.string().optional(),
2725
- virtual_key: z5.string().optional()
2726
- }).refine((t) => t.provider || t.virtual_key, {
2727
- message: "Each target must have at least provider or virtual_key"
2728
- })
2729
- ).optional().describe("Array of target providers with virtual keys")
2820
+ targets: z5.array(configTargetSchema).optional().describe("Array of target providers with virtual keys")
2730
2821
  },
2731
2822
  updateConfig: {
2732
2823
  slug: z5.string().describe("Configuration slug to update"),
@@ -2737,14 +2828,7 @@ var CONFIGS_TOOL_SCHEMAS = {
2737
2828
  retry_attempts: z5.coerce.number().positive().max(5).optional().describe("Number of retry attempts (1-5)"),
2738
2829
  retry_on_status_codes: z5.array(z5.coerce.number()).optional().describe("HTTP status codes to retry on"),
2739
2830
  strategy_mode: z5.enum(["loadbalance", "fallback"]).optional().describe("Routing strategy"),
2740
- targets: z5.array(
2741
- z5.object({
2742
- provider: z5.string().optional(),
2743
- virtual_key: z5.string().optional()
2744
- }).refine((t) => t.provider || t.virtual_key, {
2745
- message: "Each target must have at least provider or virtual_key"
2746
- })
2747
- ).optional().describe("Array of target providers")
2831
+ targets: z5.array(configTargetSchema).optional().describe("Array of target providers")
2748
2832
  },
2749
2833
  deleteConfig: {
2750
2834
  slug: z5.string().describe("Configuration slug to delete")
@@ -2759,12 +2843,7 @@ var configPayloadSchema = z5.object({
2759
2843
  retry_attempts: z5.coerce.number().positive().max(5).optional(),
2760
2844
  retry_on_status_codes: z5.array(z5.coerce.number()).optional(),
2761
2845
  strategy_mode: z5.enum(["loadbalance", "fallback"]).optional(),
2762
- targets: z5.array(
2763
- z5.object({
2764
- provider: z5.string().optional(),
2765
- virtual_key: z5.string().optional()
2766
- })
2767
- ).optional()
2846
+ targets: z5.array(configTargetSchema).optional()
2768
2847
  });
2769
2848
  function buildConfigPayload(params) {
2770
2849
  const cache = params.cache_mode !== void 0 || params.cache_max_age !== void 0 ? {
@@ -2999,7 +3078,12 @@ var guardrailActionSchema = z6.object({
2999
3078
  on_fail_action: z6.string().optional().describe("Simple action on failure (e.g., 'block')"),
3000
3079
  message: z6.string().optional().describe("Message to return when guardrail triggers")
3001
3080
  });
3081
+ var workspaceGuardrailExclusionSchema = z6.object({
3082
+ workspace_id: z6.string().describe("Workspace ID whose exclusion state changes"),
3083
+ excluded: z6.boolean().describe("True to exclude this workspace; false to restore enforcement")
3084
+ });
3002
3085
  var GUARDRAILS_TOOL_SCHEMAS = {
3086
+ getOrganisationDefaults: {},
3003
3087
  listGuardrails: {
3004
3088
  workspace_id: z6.string().optional().describe("Filter guardrails by workspace ID"),
3005
3089
  organisation_id: z6.string().optional().describe("Filter guardrails by organization ID"),
@@ -3026,9 +3110,157 @@ var GUARDRAILS_TOOL_SCHEMAS = {
3026
3110
  },
3027
3111
  deleteGuardrail: {
3028
3112
  guardrail_id: z6.string().describe("The guardrail UUID or slug to delete")
3113
+ },
3114
+ updateOrganisationDefaults: {
3115
+ input_guardrails: z6.array(z6.string()).optional().describe("Ordered guardrail IDs or slugs to enforce on model input"),
3116
+ output_guardrails: z6.array(z6.string()).optional().describe("Ordered guardrail IDs or slugs to enforce on model output")
3117
+ },
3118
+ listWorkspaceExclusions: {
3119
+ organisation_id: z6.string().describe("Organisation ID whose workspace exclusions should be listed")
3120
+ },
3121
+ updateWorkspaceExclusions: {
3122
+ organisation_id: z6.string().describe("Organisation ID whose workspace exclusions should be updated"),
3123
+ workspaces: z6.array(workspaceGuardrailExclusionSchema).min(1).describe("Workspace exclusion states to apply"),
3124
+ override_existing: z6.boolean().optional().describe("Replace existing exclusion states instead of merging changes")
3029
3125
  }
3030
3126
  };
3127
+ var GET_ORGANISATION_DEFAULTS_ANNOTATIONS = {
3128
+ title: "Get Organisation Guardrail Defaults",
3129
+ readOnlyHint: true,
3130
+ destructiveHint: false,
3131
+ idempotentHint: true,
3132
+ openWorldHint: true
3133
+ };
3031
3134
  function registerGuardrailsTools(server, service) {
3135
+ server.tool(
3136
+ "get_organisation_defaults",
3137
+ "Get the organisation-wide input and output guardrails that workspaces inherit by default. Use this before update_organisation_defaults or when auditing baseline enforcement; it does not include per-workspace exclusions, which are available from the directional exclusion list tools. Requires an organisation service API key with organisation_settings.read scope.",
3138
+ GUARDRAILS_TOOL_SCHEMAS.getOrganisationDefaults,
3139
+ GET_ORGANISATION_DEFAULTS_ANNOTATIONS,
3140
+ async () => ({
3141
+ content: [
3142
+ {
3143
+ type: "text",
3144
+ text: JSON.stringify(
3145
+ await service.guardrails.getOrganisationDefaults()
3146
+ )
3147
+ }
3148
+ ]
3149
+ })
3150
+ );
3151
+ server.tool(
3152
+ "update_organisation_defaults",
3153
+ "Replace the organisation-wide default input and/or output guardrail lists inherited by workspaces. Only supplied directions change, but enforcement updates immediately across non-excluded workspaces; inspect get_organisation_defaults and the directional workspace exclusions first. Repeating the same lists is safe. Requires an organisation service API key with organisation_settings.update scope.",
3154
+ GUARDRAILS_TOOL_SCHEMAS.updateOrganisationDefaults,
3155
+ {
3156
+ title: "Update Organisation Guardrail Defaults",
3157
+ readOnlyHint: false,
3158
+ destructiveHint: false,
3159
+ idempotentHint: true,
3160
+ openWorldHint: true
3161
+ },
3162
+ async (params) => ({
3163
+ content: [
3164
+ {
3165
+ type: "text",
3166
+ text: JSON.stringify(
3167
+ await service.guardrails.updateOrganisationDefaults(params)
3168
+ )
3169
+ }
3170
+ ]
3171
+ })
3172
+ );
3173
+ server.tool(
3174
+ "list_input_guardrail_workspace_exclusions",
3175
+ "List workspaces excluded from organisation-wide input guardrails for one organisation. Use this to audit exceptions or establish the current state before the matching update tool; it reads input exclusions only and does not return the organisation's default guardrail list. Requires an organisation service API key with organisation_exclusions.list scope.",
3176
+ GUARDRAILS_TOOL_SCHEMAS.listWorkspaceExclusions,
3177
+ {
3178
+ title: "List Input Guardrail Workspace Exclusions",
3179
+ readOnlyHint: true,
3180
+ destructiveHint: false,
3181
+ idempotentHint: true,
3182
+ openWorldHint: true
3183
+ },
3184
+ async (params) => ({
3185
+ content: [
3186
+ {
3187
+ type: "text",
3188
+ text: JSON.stringify(
3189
+ await service.guardrails.listWorkspaceExclusions("input", params)
3190
+ )
3191
+ }
3192
+ ]
3193
+ })
3194
+ );
3195
+ server.tool(
3196
+ "update_input_guardrail_workspace_exclusions",
3197
+ "Set workspace exclusions from organisation-wide input guardrails. Each entry excludes or restores one workspace; override_existing replaces prior states while the default merge behavior preserves unmentioned workspaces. Review the matching list tool first because enforcement changes immediately. Repeating the same states is safe. Requires an organisation service API key with organisation_exclusions.update scope.",
3198
+ GUARDRAILS_TOOL_SCHEMAS.updateWorkspaceExclusions,
3199
+ {
3200
+ title: "Update Input Guardrail Workspace Exclusions",
3201
+ readOnlyHint: false,
3202
+ destructiveHint: true,
3203
+ idempotentHint: true,
3204
+ openWorldHint: true
3205
+ },
3206
+ async (params) => ({
3207
+ content: [
3208
+ {
3209
+ type: "text",
3210
+ text: JSON.stringify(
3211
+ await service.guardrails.updateWorkspaceExclusions("input", params)
3212
+ )
3213
+ }
3214
+ ]
3215
+ })
3216
+ );
3217
+ server.tool(
3218
+ "list_output_guardrail_workspace_exclusions",
3219
+ "List workspaces excluded from organisation-wide output guardrails for one organisation. Use this to audit exceptions or establish the current state before the matching update tool; it reads output exclusions only and does not return the organisation's default guardrail list. Requires an organisation service API key with organisation_exclusions.list scope.",
3220
+ GUARDRAILS_TOOL_SCHEMAS.listWorkspaceExclusions,
3221
+ {
3222
+ title: "List Output Guardrail Workspace Exclusions",
3223
+ readOnlyHint: true,
3224
+ destructiveHint: false,
3225
+ idempotentHint: true,
3226
+ openWorldHint: true
3227
+ },
3228
+ async (params) => ({
3229
+ content: [
3230
+ {
3231
+ type: "text",
3232
+ text: JSON.stringify(
3233
+ await service.guardrails.listWorkspaceExclusions("output", params)
3234
+ )
3235
+ }
3236
+ ]
3237
+ })
3238
+ );
3239
+ server.tool(
3240
+ "update_output_guardrail_workspace_exclusions",
3241
+ "Set workspace exclusions from organisation-wide output guardrails. Each entry excludes or restores one workspace; override_existing replaces prior states while the default merge behavior preserves unmentioned workspaces. Review the matching list tool first because enforcement changes immediately. Repeating the same states is safe. Requires an organisation service API key with organisation_exclusions.update scope.",
3242
+ GUARDRAILS_TOOL_SCHEMAS.updateWorkspaceExclusions,
3243
+ {
3244
+ title: "Update Output Guardrail Workspace Exclusions",
3245
+ readOnlyHint: false,
3246
+ destructiveHint: true,
3247
+ idempotentHint: true,
3248
+ openWorldHint: true
3249
+ },
3250
+ async (params) => ({
3251
+ content: [
3252
+ {
3253
+ type: "text",
3254
+ text: JSON.stringify(
3255
+ await service.guardrails.updateWorkspaceExclusions(
3256
+ "output",
3257
+ params
3258
+ )
3259
+ )
3260
+ }
3261
+ ]
3262
+ })
3263
+ );
3032
3264
  server.tool(
3033
3265
  "list_guardrails",
3034
3266
  "List guardrails in the org with id, slug, status, ownership, and optional workspace/org filters. Use this to find IDs and slugs before get_guardrail, update_guardrail, or delete_guardrail.",
@@ -3175,7 +3407,7 @@ function registerGuardrailsTools(server, service) {
3175
3407
  }
3176
3408
 
3177
3409
  // src/tools/integrations.tools.ts
3178
- import { z as z7 } from "zod";
3410
+ import { z as z8 } from "zod";
3179
3411
 
3180
3412
  // src/lib/limits.ts
3181
3413
  var PERIODIC_RESET_DEFAULT = "monthly";
@@ -3217,96 +3449,257 @@ function buildRateLimits(params) {
3217
3449
  ];
3218
3450
  }
3219
3451
 
3452
+ // src/tools/secret-mapping.schemas.ts
3453
+ import { z as z7 } from "zod";
3454
+ function createSecretMappingSchema({
3455
+ allowKeyTarget,
3456
+ targetFieldDescription,
3457
+ secretReferenceDescription,
3458
+ valueFormatDescription
3459
+ }) {
3460
+ return z7.object({
3461
+ target_field: z7.string().refine(
3462
+ (value) => allowKeyTarget && value === "key" || value.startsWith("configurations."),
3463
+ allowKeyTarget ? "target_field must be 'key' or start with 'configurations.'" : "target_field must start with 'configurations.'"
3464
+ ).describe(targetFieldDescription),
3465
+ secret_reference_id: z7.string().describe(secretReferenceDescription),
3466
+ secret_key: z7.string().nullable().optional().describe("Optional key to select from a multi-value secret"),
3467
+ value_format: z7.enum(["string", "json"]).nullable().optional().describe(valueFormatDescription)
3468
+ });
3469
+ }
3470
+ function uniqueSecretMappingsSchema(itemSchema) {
3471
+ return z7.array(itemSchema).superRefine((mappings, context) => {
3472
+ const firstIndexByTarget = /* @__PURE__ */ new Map();
3473
+ for (const [index, mapping] of mappings.entries()) {
3474
+ const firstIndex = firstIndexByTarget.get(mapping.target_field);
3475
+ if (firstIndex !== void 0) {
3476
+ context.addIssue({
3477
+ code: "custom",
3478
+ path: [index, "target_field"],
3479
+ message: `target_field must be unique; also used at index ${firstIndex}`
3480
+ });
3481
+ } else {
3482
+ firstIndexByTarget.set(mapping.target_field, index);
3483
+ }
3484
+ }
3485
+ });
3486
+ }
3487
+
3220
3488
  // src/tools/integrations.tools.ts
3489
+ var integrationSecretMappingSchema = createSecretMappingSchema({
3490
+ allowKeyTarget: true,
3491
+ targetFieldDescription: "Integration field populated at runtime: key or configurations.<field>",
3492
+ secretReferenceDescription: "Secret Reference UUID or slug accessible to the workspace",
3493
+ valueFormatDescription: "Treat the resolved value as a plain string or parsed JSON"
3494
+ });
3495
+ var integrationSecretMappingsSchema = uniqueSecretMappingsSchema(
3496
+ integrationSecretMappingSchema
3497
+ );
3498
+ var nullableMultiplier = (description) => z8.coerce.number().nonnegative().nullable().optional().describe(description);
3499
+ var pricingMultiplierSchema = z8.object({
3500
+ default: nullableMultiplier(
3501
+ "Fallback multiplier for pricing units; 1 is unchanged, 0.8 is a 20% discount"
3502
+ ),
3503
+ request_token: nullableMultiplier("Input token price multiplier"),
3504
+ response_token: nullableMultiplier("Output token price multiplier"),
3505
+ cache_read_input_token: nullableMultiplier(
3506
+ "Cache-read input token price multiplier"
3507
+ ),
3508
+ cache_write_input_token: nullableMultiplier(
3509
+ "Cache-write input token price multiplier"
3510
+ ),
3511
+ cache_read_audio_input_token: nullableMultiplier(
3512
+ "Cache-read audio input token price multiplier"
3513
+ ),
3514
+ request_audio_token: nullableMultiplier("Audio input token price multiplier"),
3515
+ response_audio_token: nullableMultiplier(
3516
+ "Audio output token price multiplier"
3517
+ ),
3518
+ reasoning_token: nullableMultiplier("Reasoning token price multiplier"),
3519
+ prediction_accepted_token: nullableMultiplier(
3520
+ "Accepted predicted-output token price multiplier"
3521
+ ),
3522
+ prediction_rejected_token: nullableMultiplier(
3523
+ "Rejected predicted-output token price multiplier"
3524
+ ),
3525
+ request_image_token: nullableMultiplier("Image input token price multiplier"),
3526
+ response_image_token: nullableMultiplier(
3527
+ "Image output token price multiplier"
3528
+ ),
3529
+ request_text_token: nullableMultiplier("Text input token price multiplier"),
3530
+ response_text_token: nullableMultiplier("Text output token price multiplier"),
3531
+ cache_read_image_input_token: nullableMultiplier(
3532
+ "Cache-read image input token price multiplier"
3533
+ ),
3534
+ cache_read_text_input_token: nullableMultiplier(
3535
+ "Cache-read text input token price multiplier"
3536
+ ),
3537
+ cache_write_text_input_token: nullableMultiplier(
3538
+ "Cache-write text input token price multiplier"
3539
+ ),
3540
+ cache_write_image_input_token: nullableMultiplier(
3541
+ "Cache-write image input token price multiplier"
3542
+ ),
3543
+ image: z8.object({
3544
+ default: nullableMultiplier("Default image-generation price multiplier")
3545
+ }).nullable().optional().describe("Image-generation pricing multipliers"),
3546
+ additional_units: z8.record(z8.string(), z8.coerce.number().nonnegative().nullable()).nullable().optional().describe(
3547
+ "Multipliers keyed by Portkey pricing unit, such as web_search or file_search"
3548
+ )
3549
+ });
3550
+ var pricingAdjustmentsSchema = z8.object({
3551
+ multiplier: pricingMultiplierSchema.optional().describe("Per-unit multipliers applied over Portkey catalog pricing")
3552
+ }).nullable();
3553
+ var modelConfigurationsSchema = z8.object({
3554
+ custom_host: z8.string().url().optional().describe("Custom upstream URL used only for this model"),
3555
+ custom_headers: z8.record(z8.string(), z8.string()).optional().describe("Headers sent only for this model; values may contain secrets")
3556
+ });
3557
+ var tokenPricingSchema = z8.object({
3558
+ price: z8.coerce.number().nonnegative().describe("Static price per token in the integration pricing unit")
3559
+ });
3560
+ var integrationModelPricingSchema = z8.object({
3561
+ type: z8.literal("static").describe("Static per-token pricing configuration"),
3562
+ pay_as_you_go: z8.object({
3563
+ request_token: tokenPricingSchema.optional().describe("Input token pricing"),
3564
+ response_token: tokenPricingSchema.optional().describe("Output token pricing")
3565
+ }).optional().describe("Pay-as-you-go rates for this integration model")
3566
+ });
3221
3567
  var INTEGRATIONS_TOOL_SCHEMAS = {
3568
+ getModelPricing: {
3569
+ provider: z8.string().describe(
3570
+ "Lowercase Portkey provider identifier, such as openai, anthropic, bedrock, or x-ai"
3571
+ ),
3572
+ model: z8.string().describe("Exact provider model identifier, such as gpt-4o")
3573
+ },
3222
3574
  listIntegrations: {
3223
- current_page: z7.coerce.number().int().positive().optional().describe("Page number for pagination"),
3224
- page_size: z7.coerce.number().int().positive().max(100).optional().describe("Number of results per page (default 100, max 100)"),
3225
- workspace_id: z7.string().optional().describe("Filter integrations accessible by a specific workspace"),
3226
- type: z7.enum(["workspace", "organisation", "all"]).optional().describe(
3575
+ current_page: z8.coerce.number().int().positive().optional().describe("Page number for pagination"),
3576
+ page_size: z8.coerce.number().int().positive().max(100).optional().describe("Number of results per page (default 100, max 100)"),
3577
+ workspace_id: z8.string().optional().describe("Filter integrations accessible by a specific workspace"),
3578
+ type: z8.enum(["workspace", "organisation", "all"]).optional().describe(
3227
3579
  "Filter by integration type: 'workspace', 'organisation', or 'all' (default)"
3228
3580
  )
3229
3581
  },
3230
3582
  createIntegration: {
3231
- name: z7.string().describe("Human-readable name for the integration"),
3232
- ai_provider_id: z7.string().describe(
3583
+ name: z8.string().describe("Human-readable name for the integration"),
3584
+ ai_provider_id: z8.string().describe(
3233
3585
  "ID of the AI provider (e.g., 'openai', 'anthropic', 'azure-openai', 'aws-bedrock', 'vertex-ai')"
3234
3586
  ),
3235
- slug: z7.string().optional().describe(
3587
+ slug: z8.string().optional().describe(
3236
3588
  "URL-friendly identifier (auto-generated from name if not provided)"
3237
3589
  ),
3238
- key: z7.string().optional().describe("API key for the provider (if required)"),
3239
- description: z7.string().optional().describe("Optional description of the integration"),
3240
- workspace_id: z7.string().optional().describe("Workspace ID for workspace-scoped integrations"),
3241
- api_version: z7.string().optional().describe("API version (for Azure OpenAI)"),
3242
- resource_name: z7.string().optional().describe("Resource name (for Azure OpenAI)"),
3243
- deployment_name: z7.string().optional().describe("Deployment name (for Azure OpenAI)"),
3244
- aws_region: z7.string().optional().describe("AWS region (for AWS Bedrock)"),
3245
- aws_access_key_id: z7.string().optional().describe("AWS access key ID (for AWS Bedrock)"),
3246
- aws_secret_access_key: z7.string().optional().describe("AWS secret access key (for AWS Bedrock)"),
3247
- vertex_project_id: z7.string().optional().describe("GCP project ID (for Vertex AI)"),
3248
- vertex_region: z7.string().optional().describe("GCP region (for Vertex AI)"),
3249
- custom_host: z7.string().optional().describe("Custom base URL for the provider")
3590
+ key: z8.string().optional().describe("API key for the provider (if required)"),
3591
+ description: z8.string().optional().describe("Optional description of the integration"),
3592
+ workspace_id: z8.string().optional().describe("Workspace ID for workspace-scoped integrations"),
3593
+ api_version: z8.string().optional().describe("API version (for Azure OpenAI)"),
3594
+ resource_name: z8.string().optional().describe("Resource name (for Azure OpenAI)"),
3595
+ deployment_name: z8.string().optional().describe("Deployment name (for Azure OpenAI)"),
3596
+ aws_region: z8.string().optional().describe("AWS region (for AWS Bedrock)"),
3597
+ aws_access_key_id: z8.string().optional().describe("AWS access key ID (for AWS Bedrock)"),
3598
+ aws_secret_access_key: z8.string().optional().describe("AWS secret access key (for AWS Bedrock)"),
3599
+ vertex_project_id: z8.string().optional().describe("GCP project ID (for Vertex AI)"),
3600
+ vertex_region: z8.string().optional().describe("GCP region (for Vertex AI)"),
3601
+ custom_host: z8.string().optional().describe("Custom base URL for the provider"),
3602
+ create_default_provider: z8.boolean().optional().describe(
3603
+ "Create a provider automatically for a workspace-scoped integration; defaults to true"
3604
+ ),
3605
+ default_provider_slug: z8.string().max(255).regex(/^[a-zA-Z0-9_-]+$/).optional().describe("Custom slug for the automatically created workspace provider"),
3606
+ secret_mappings: integrationSecretMappingsSchema.optional().describe(
3607
+ "Unique runtime Secret Reference mappings; mapping key allows the key field to be omitted"
3608
+ ),
3609
+ pricing_adjustments: pricingAdjustmentsSchema.optional().describe(
3610
+ "Negotiated discount or markup multipliers for cost accounting"
3611
+ )
3250
3612
  },
3251
3613
  getIntegration: {
3252
- slug: z7.string().describe("The unique slug identifier of the integration to retrieve")
3614
+ slug: z8.string().describe("The unique slug identifier of the integration to retrieve")
3253
3615
  },
3254
3616
  updateIntegration: {
3255
- slug: z7.string().describe("The slug of the integration to update"),
3256
- name: z7.string().optional().describe("New human-readable name for the integration"),
3257
- key: z7.string().optional().describe("New API key for the provider"),
3258
- description: z7.string().optional().describe("New description for the integration"),
3259
- api_version: z7.string().optional().describe("New API version (for Azure OpenAI)"),
3260
- resource_name: z7.string().optional().describe("New resource name (for Azure OpenAI)"),
3261
- deployment_name: z7.string().optional().describe("New deployment name (for Azure OpenAI)"),
3262
- aws_region: z7.string().optional().describe("New AWS region (for AWS Bedrock)"),
3263
- aws_access_key_id: z7.string().optional().describe("New AWS access key ID (for AWS Bedrock)"),
3264
- aws_secret_access_key: z7.string().optional().describe("New AWS secret access key (for AWS Bedrock)"),
3265
- vertex_project_id: z7.string().optional().describe("New GCP project ID (for Vertex AI)"),
3266
- vertex_region: z7.string().optional().describe("New GCP region (for Vertex AI)"),
3267
- custom_host: z7.string().optional().describe("New custom base URL for the provider")
3617
+ slug: z8.string().describe("The slug of the integration to update"),
3618
+ name: z8.string().optional().describe("New human-readable name for the integration"),
3619
+ key: z8.string().optional().describe("New API key for the provider"),
3620
+ description: z8.string().optional().describe("New description for the integration"),
3621
+ api_version: z8.string().optional().describe("New API version (for Azure OpenAI)"),
3622
+ resource_name: z8.string().optional().describe("New resource name (for Azure OpenAI)"),
3623
+ deployment_name: z8.string().optional().describe("New deployment name (for Azure OpenAI)"),
3624
+ aws_region: z8.string().optional().describe("New AWS region (for AWS Bedrock)"),
3625
+ aws_access_key_id: z8.string().optional().describe("New AWS access key ID (for AWS Bedrock)"),
3626
+ aws_secret_access_key: z8.string().optional().describe("New AWS secret access key (for AWS Bedrock)"),
3627
+ vertex_project_id: z8.string().optional().describe("New GCP project ID (for Vertex AI)"),
3628
+ vertex_region: z8.string().optional().describe("New GCP region (for Vertex AI)"),
3629
+ custom_host: z8.string().optional().describe("New custom base URL for the provider"),
3630
+ secret_mappings: integrationSecretMappingsSchema.optional().describe(
3631
+ "Replacement runtime Secret Reference mappings; each target_field must be unique"
3632
+ ),
3633
+ pricing_adjustments: pricingAdjustmentsSchema.optional().describe(
3634
+ "Replacement cost multiplier configuration, or null to clear adjustments"
3635
+ )
3268
3636
  },
3269
3637
  deleteIntegration: {
3270
- slug: z7.string().describe("The slug of the integration to delete")
3638
+ slug: z8.string().describe("The slug of the integration to delete")
3271
3639
  },
3272
3640
  listIntegrationModels: {
3273
- slug: z7.string().describe("The slug of the integration"),
3274
- current_page: z7.coerce.number().int().positive().optional().describe("Page number for pagination"),
3275
- page_size: z7.coerce.number().int().positive().max(100).optional().describe("Number of results per page")
3641
+ slug: z8.string().describe("The slug of the integration"),
3642
+ current_page: z8.coerce.number().int().positive().optional().describe("Page number for pagination"),
3643
+ page_size: z8.coerce.number().int().positive().max(100).optional().describe("Number of results per page")
3276
3644
  },
3277
3645
  updateIntegrationModels: {
3278
- slug: z7.string().describe("The slug of the integration"),
3279
- models: z7.array(
3280
- z7.object({
3281
- slug: z7.string().describe("The model slug identifier"),
3282
- model_name: z7.string().optional().describe(
3646
+ slug: z8.string().describe("The slug of the integration"),
3647
+ allow_all_models: z8.boolean().optional().describe(
3648
+ "Whether newly available provider models are enabled by default"
3649
+ ),
3650
+ models: z8.array(
3651
+ z8.object({
3652
+ slug: z8.string().describe("The model slug identifier"),
3653
+ model_name: z8.string().optional().describe(
3283
3654
  "Display name for the model (required for custom models)"
3284
3655
  ),
3285
- enabled: z7.boolean().describe("Whether the model is enabled"),
3286
- is_custom: z7.boolean().optional().describe("Whether this is a custom model (default: false)")
3656
+ enabled: z8.boolean().describe("Whether the model is enabled"),
3657
+ is_custom: z8.boolean().optional().describe("Whether this is a custom model (default: false)"),
3658
+ is_finetune: z8.boolean().optional().describe("Whether this entry is a fine-tuned model"),
3659
+ base_model_slug: z8.string().optional().describe("Base model slug for a fine-tuned model"),
3660
+ configurations: modelConfigurationsSchema.optional().describe("Per-model custom upstream host and headers"),
3661
+ pricing_config: integrationModelPricingSchema.optional().describe("Static custom pricing for this integration model")
3287
3662
  })
3288
3663
  ).describe("Array of model configurations to update")
3289
3664
  },
3290
3665
  deleteIntegrationModel: {
3291
- slug: z7.string().describe("The slug of the integration"),
3292
- model_slug: z7.string().describe("The slug of the model to delete")
3666
+ slug: z8.string().describe("The slug of the integration"),
3667
+ model_slug: z8.string().describe("The slug of the model to delete")
3293
3668
  },
3294
3669
  listIntegrationWorkspaces: {
3295
- slug: z7.string().describe("The slug of the integration"),
3296
- current_page: z7.coerce.number().int().positive().optional().describe("Page number for pagination"),
3297
- page_size: z7.coerce.number().int().positive().max(100).optional().describe("Number of results per page")
3670
+ slug: z8.string().describe("The slug of the integration"),
3671
+ current_page: z8.coerce.number().int().positive().optional().describe("Page number for pagination"),
3672
+ page_size: z8.coerce.number().int().positive().max(100).optional().describe("Number of results per page")
3298
3673
  },
3299
3674
  updateIntegrationWorkspaces: {
3300
- slug: z7.string().describe("The slug of the integration"),
3301
- workspaces: z7.array(
3302
- z7.object({
3303
- id: z7.string().describe("The workspace ID"),
3304
- enabled: z7.boolean().describe("Whether the workspace has access to this integration"),
3305
- credit_limit: z7.coerce.number().positive().optional().describe("Credit limit for this workspace"),
3306
- alert_threshold: z7.coerce.number().min(0).max(100).optional().describe("Alert threshold percentage (0-100)"),
3307
- rate_limit_rpm: z7.coerce.number().positive().optional().describe("Rate limit in requests per minute")
3675
+ slug: z8.string().describe("The slug of the integration"),
3676
+ workspaces: z8.array(
3677
+ z8.object({
3678
+ id: z8.string().describe("The workspace ID"),
3679
+ enabled: z8.boolean().describe("Whether the workspace has access to this integration"),
3680
+ credit_limit: z8.coerce.number().positive().optional().describe("Credit limit for this workspace"),
3681
+ alert_threshold: z8.coerce.number().min(0).max(100).optional().describe("Alert threshold percentage (0-100)"),
3682
+ rate_limit_rpm: z8.coerce.number().positive().optional().describe("Rate limit in requests per minute"),
3683
+ reset_usage: z8.boolean().optional().describe("Reset exhausted usage status to active"),
3684
+ create_default_provider: z8.boolean().optional().describe(
3685
+ "Override whether a provider is auto-created for this workspace"
3686
+ ),
3687
+ default_provider_slug: z8.string().optional().describe(
3688
+ "Override the auto-created provider slug for this workspace"
3689
+ )
3308
3690
  })
3309
- ).describe("Array of workspace configurations to update")
3691
+ ).describe("Array of workspace configurations to update"),
3692
+ global_workspace_access_enabled: z8.boolean().optional().describe(
3693
+ "Enable or disable access for all current and future workspaces"
3694
+ ),
3695
+ global_credit_limit: z8.coerce.number().positive().optional().describe(
3696
+ "Global cost credit limit applied with global workspace access"
3697
+ ),
3698
+ global_alert_threshold: z8.coerce.number().nonnegative().max(100).optional().describe("Global cost alert threshold applied to workspace access"),
3699
+ global_rate_limit_rpm: z8.coerce.number().positive().optional().describe("Global requests-per-minute limit for workspace access"),
3700
+ override_existing_workspace_access: z8.boolean().optional().describe("Apply global settings over existing per-workspace access"),
3701
+ create_default_provider: z8.boolean().optional().describe("Auto-create providers when granting workspace access"),
3702
+ default_provider_slug: z8.string().optional().describe("Default slug for providers auto-created in workspaces")
3310
3703
  }
3311
3704
  };
3312
3705
  function buildIntegrationConfigurations(params) {
@@ -3332,6 +3725,31 @@ function buildIntegrationConfigurations(params) {
3332
3725
  return Object.keys(configurations).length > 0 ? configurations : void 0;
3333
3726
  }
3334
3727
  function registerIntegrationsTools(server, service) {
3728
+ server.tool(
3729
+ "get_model_pricing",
3730
+ "Get Portkey's current public pricing configuration for one exact provider/model pair. Prices are returned in USD cents per token or provider-specific unit and may include cache, audio, image, fine-tuning, and calculation metadata. Use this read-only catalog lookup before setting integration pricing_adjustments or custom-model pricing; it does not return your negotiated integration multiplier or require Portkey authentication.",
3731
+ INTEGRATIONS_TOOL_SCHEMAS.getModelPricing,
3732
+ {
3733
+ title: "Get Model Pricing",
3734
+ readOnlyHint: true,
3735
+ destructiveHint: false,
3736
+ idempotentHint: true,
3737
+ openWorldHint: true
3738
+ },
3739
+ async (params) => ({
3740
+ content: [
3741
+ {
3742
+ type: "text",
3743
+ text: JSON.stringify(
3744
+ await service.integrations.getModelPricing(
3745
+ params.provider,
3746
+ params.model
3747
+ )
3748
+ )
3749
+ }
3750
+ ]
3751
+ })
3752
+ );
3335
3753
  server.tool(
3336
3754
  "list_integrations",
3337
3755
  "List org-level AI provider connections with optional workspace or type filters. Use this to find integration slugs before model or workspace updates. Returns total plus id, name, slug, provider, status, description, workspace counts, and config summary.",
@@ -3368,13 +3786,14 @@ function registerIntegrationsTools(server, service) {
3368
3786
  );
3369
3787
  server.tool(
3370
3788
  "create_integration",
3371
- "Create an org-level provider integration that stores an AI provider's API key and becomes the source workspace providers (create_provider) build on. ai_provider_id takes a provider identifier such as 'openai' or 'anthropic'; some backends (azure-openai, aws-bedrock, vertex-ai) need provider-specific fields, and the key is write-only afterwards (get_integration shows it masked). Provision models and workspace access afterwards with update_integration_models and update_integration_workspaces. Returns the new integration id and slug.",
3789
+ "Create an AI-provider integration that becomes the source for workspace providers. ai_provider_id identifies the backend; provider-specific fields configure Azure, Bedrock, Vertex, or custom hosts. For workspace-scoped integrations, create_default_provider controls automatic provider creation. key is write-only, but secret_mappings can resolve it or configuration fields from Secret References at runtime. pricing_adjustments apply negotiated discounts or markups to cost accounting. Use update_integration_models and update_integration_workspaces after creation; returns the new integration id and slug.",
3372
3790
  INTEGRATIONS_TOOL_SCHEMAS.createIntegration,
3373
3791
  {
3792
+ title: "Create AI Provider Integration",
3374
3793
  readOnlyHint: false,
3375
3794
  destructiveHint: false,
3376
3795
  idempotentHint: false,
3377
- openWorldHint: false
3796
+ openWorldHint: true
3378
3797
  },
3379
3798
  async (params) => {
3380
3799
  const result = await service.integrations.createIntegration({
@@ -3384,7 +3803,11 @@ function registerIntegrationsTools(server, service) {
3384
3803
  key: params.key,
3385
3804
  description: params.description,
3386
3805
  workspace_id: params.workspace_id,
3387
- configurations: buildIntegrationConfigurations(params)
3806
+ configurations: buildIntegrationConfigurations(params),
3807
+ ...params.create_default_provider !== void 0 ? { create_default_provider: params.create_default_provider } : {},
3808
+ ...params.default_provider_slug !== void 0 ? { default_provider_slug: params.default_provider_slug } : {},
3809
+ ...params.secret_mappings !== void 0 ? { secret_mappings: params.secret_mappings } : {},
3810
+ ...params.pricing_adjustments !== void 0 ? { pricing_adjustments: params.pricing_adjustments } : {}
3388
3811
  });
3389
3812
  return {
3390
3813
  content: [
@@ -3425,6 +3848,8 @@ function registerIntegrationsTools(server, service) {
3425
3848
  global_workspace_access_settings: integration.global_workspace_access_settings,
3426
3849
  allow_all_models: integration.allow_all_models,
3427
3850
  workspace_count: integration.workspace_count,
3851
+ secret_mappings: integration.secret_mappings,
3852
+ pricing_adjustments: integration.pricing_adjustments,
3428
3853
  created_at: integration.created_at,
3429
3854
  last_updated_at: integration.last_updated_at
3430
3855
  })
@@ -3435,20 +3860,23 @@ function registerIntegrationsTools(server, service) {
3435
3860
  );
3436
3861
  server.tool(
3437
3862
  "update_integration",
3438
- "Update an org-level integration's name, description, API key, or provider-specific config by slug. Only provided fields change and the update is in place (no version history); key and config changes take effect immediately and can disrupt dependent providers or live requests, so review current settings with get_integration first. Get the slug from list_integrations; model provisioning and workspace access are managed separately via update_integration_models and update_integration_workspaces. Returns a success flag.",
3863
+ "Update an integration's name, description, API key, provider config, Secret Reference mappings, or pricing adjustments by slug. Only provided fields change; key, secret mapping, and config changes take effect immediately and can disrupt dependent providers or live requests, while pricing multipliers change cost analytics and budget accounting. Review get_integration first. Model availability and workspace access remain separate in update_integration_models and update_integration_workspaces.",
3439
3864
  INTEGRATIONS_TOOL_SCHEMAS.updateIntegration,
3440
3865
  {
3866
+ title: "Update AI Provider Integration",
3441
3867
  readOnlyHint: false,
3442
3868
  destructiveHint: true,
3443
3869
  idempotentHint: true,
3444
- openWorldHint: false
3870
+ openWorldHint: true
3445
3871
  },
3446
3872
  async (params) => {
3447
3873
  const result = await service.integrations.updateIntegration(params.slug, {
3448
3874
  name: params.name,
3449
3875
  key: params.key,
3450
3876
  description: params.description,
3451
- configurations: buildIntegrationConfigurations(params)
3877
+ configurations: buildIntegrationConfigurations(params),
3878
+ secret_mappings: params.secret_mappings,
3879
+ pricing_adjustments: params.pricing_adjustments
3452
3880
  });
3453
3881
  return {
3454
3882
  content: [
@@ -3503,10 +3931,14 @@ function registerIntegrationsTools(server, service) {
3503
3931
  integration_slug: params.slug,
3504
3932
  models: models.data.map((model) => ({
3505
3933
  id: model.id,
3506
- model_id: model.model_id,
3507
- model_name: model.model_name,
3934
+ slug: model.slug ?? model.model_id,
3935
+ name: model.name ?? model.model_name,
3508
3936
  enabled: model.enabled,
3509
- custom: model.custom,
3937
+ is_custom: model.is_custom ?? model.custom,
3938
+ is_finetune: model.is_finetune,
3939
+ base_model_slug: model.base_model_slug,
3940
+ configurations: model.configurations,
3941
+ pricing_config: model.pricing_config,
3510
3942
  created_at: model.created_at,
3511
3943
  last_updated_at: model.last_updated_at
3512
3944
  }))
@@ -3518,13 +3950,21 @@ function registerIntegrationsTools(server, service) {
3518
3950
  );
3519
3951
  server.tool(
3520
3952
  "update_integration_models",
3521
- "Enable, disable, or register custom models for an integration. This changes model availability for every workspace using it, so confirm the downstream impact first. Returns success and the number of models updated.",
3953
+ "Bulk enable or disable integration models, register custom or fine-tuned models, set per-model hosts and headers, and attach static token pricing. allow_all_models controls whether future provider models start enabled. These changes affect every workspace using the integration; inspect list_integration_models first and use get_model_pricing when deriving custom rates. Returns success and the number of models updated.",
3522
3954
  INTEGRATIONS_TOOL_SCHEMAS.updateIntegrationModels,
3955
+ {
3956
+ title: "Update Integration Models",
3957
+ readOnlyHint: false,
3958
+ destructiveHint: true,
3959
+ idempotentHint: true,
3960
+ openWorldHint: true
3961
+ },
3523
3962
  async (params) => {
3524
3963
  const result = await service.integrations.updateIntegrationModels(
3525
3964
  params.slug,
3526
3965
  {
3527
- models: params.models
3966
+ models: params.models,
3967
+ allow_all_models: params.allow_all_models
3528
3968
  }
3529
3969
  );
3530
3970
  return {
@@ -3584,7 +4024,7 @@ function registerIntegrationsTools(server, service) {
3584
4024
  integration_slug: params.slug,
3585
4025
  workspaces: workspaces.data.map((ws) => ({
3586
4026
  id: ws.id,
3587
- workspace_id: ws.workspace_id,
4027
+ workspace_id: ws.workspace_id ?? ws.id,
3588
4028
  workspace_name: ws.workspace_name,
3589
4029
  enabled: ws.enabled,
3590
4030
  usage_limits: ws.usage_limits,
@@ -3600,9 +4040,41 @@ function registerIntegrationsTools(server, service) {
3600
4040
  );
3601
4041
  server.tool(
3602
4042
  "update_integration_workspaces",
3603
- "Control which workspaces can use an integration and set per-workspace limits, unlike update_integration which edits the org-level connection. Call list_integration_workspaces first to review current state; access changes and new limits apply to downstream usage immediately, and the call returns success plus the number of workspaces updated.",
4043
+ "Control per-workspace and global access to an integration, including cost/rate limits, usage resets, and automatic default-provider creation. global_workspace_access_enabled affects current and future workspaces; override_existing_workspace_access determines whether it replaces explicit workspace settings. Per-workspace default-provider fields override top-level values. Review list_integration_workspaces first because access and limits change downstream usage immediately.",
3604
4044
  INTEGRATIONS_TOOL_SCHEMAS.updateIntegrationWorkspaces,
4045
+ {
4046
+ title: "Update Integration Workspace Access",
4047
+ readOnlyHint: false,
4048
+ destructiveHint: true,
4049
+ idempotentHint: true,
4050
+ openWorldHint: true
4051
+ },
3605
4052
  async (params) => {
4053
+ const hasGlobalLimits = params.global_credit_limit !== void 0 || params.global_alert_threshold !== void 0 || params.global_rate_limit_rpm !== void 0;
4054
+ if (hasGlobalLimits && params.global_workspace_access_enabled === void 0) {
4055
+ return {
4056
+ content: [
4057
+ {
4058
+ type: "text",
4059
+ text: "global_workspace_access_enabled is required when setting global limits."
4060
+ }
4061
+ ],
4062
+ isError: true
4063
+ };
4064
+ }
4065
+ const globalUsageLimits = params.global_credit_limit !== void 0 || params.global_alert_threshold !== void 0 ? [
4066
+ {
4067
+ type: "cost",
4068
+ credit_limit: params.global_credit_limit,
4069
+ alert_threshold: params.global_alert_threshold
4070
+ }
4071
+ ] : void 0;
4072
+ const globalRateLimits = buildRateLimitsRpm(params.global_rate_limit_rpm);
4073
+ const globalWorkspaceAccess = params.global_workspace_access_enabled !== void 0 ? {
4074
+ enabled: params.global_workspace_access_enabled,
4075
+ usage_limits: globalUsageLimits,
4076
+ rate_limits: globalRateLimits
4077
+ } : void 0;
3606
4078
  const result = await service.integrations.updateIntegrationWorkspaces(
3607
4079
  params.slug,
3608
4080
  {
@@ -3615,9 +4087,16 @@ function registerIntegrationsTools(server, service) {
3615
4087
  id: ws.id,
3616
4088
  enabled: ws.enabled,
3617
4089
  usage_limits: usageLimits ? [usageLimits] : void 0,
3618
- rate_limits: buildRateLimitsRpm(ws.rate_limit_rpm)
4090
+ rate_limits: buildRateLimitsRpm(ws.rate_limit_rpm),
4091
+ reset_usage: ws.reset_usage,
4092
+ create_default_provider: ws.create_default_provider,
4093
+ default_provider_slug: ws.default_provider_slug
3619
4094
  };
3620
- })
4095
+ }),
4096
+ global_workspace_access: globalWorkspaceAccess,
4097
+ override_existing_workspace_access: params.override_existing_workspace_access,
4098
+ create_default_provider: params.create_default_provider,
4099
+ default_provider_slug: params.default_provider_slug
3621
4100
  }
3622
4101
  );
3623
4102
  return {
@@ -3637,110 +4116,110 @@ function registerIntegrationsTools(server, service) {
3637
4116
  }
3638
4117
 
3639
4118
  // src/tools/keys.tools.ts
3640
- import { z as z8 } from "zod";
4119
+ import { z as z9 } from "zod";
3641
4120
  var KEYS_TOOL_SCHEMAS = {
3642
4121
  listVirtualKeys: {
3643
- current_page: z8.coerce.number().int().positive().optional().describe("Page number for pagination"),
3644
- page_size: z8.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
4122
+ current_page: z9.coerce.number().int().positive().optional().describe("Page number for pagination"),
4123
+ page_size: z9.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
3645
4124
  },
3646
4125
  createVirtualKey: {
3647
- name: z8.string().describe("Display name for the virtual key"),
3648
- provider: z8.string().describe(
4126
+ name: z9.string().describe("Display name for the virtual key"),
4127
+ provider: z9.string().describe(
3649
4128
  "Provider slug (e.g., 'openai', 'anthropic', 'azure-openai', 'google')"
3650
4129
  ),
3651
- key: z8.string().describe("The actual provider API key to store"),
3652
- note: z8.string().optional().describe("Optional note or description for this key"),
3653
- workspace_id: z8.string().optional().describe("Workspace ID to create the key in"),
3654
- api_version: z8.string().optional().describe("API version (for Azure OpenAI)"),
3655
- resource_name: z8.string().optional().describe("Resource name (for Azure OpenAI)"),
3656
- deployment_name: z8.string().optional().describe("Deployment name (for Azure OpenAI)"),
3657
- credit_limit: z8.coerce.number().positive().optional().describe("Maximum usage cost threshold"),
3658
- alert_threshold: z8.coerce.number().min(0).max(100).optional().describe(
4130
+ key: z9.string().describe("The actual provider API key to store"),
4131
+ note: z9.string().optional().describe("Optional note or description for this key"),
4132
+ workspace_id: z9.string().optional().describe("Workspace ID to create the key in"),
4133
+ api_version: z9.string().optional().describe("API version (for Azure OpenAI)"),
4134
+ resource_name: z9.string().optional().describe("Resource name (for Azure OpenAI)"),
4135
+ deployment_name: z9.string().optional().describe("Deployment name (for Azure OpenAI)"),
4136
+ credit_limit: z9.coerce.number().positive().optional().describe("Maximum usage cost threshold"),
4137
+ alert_threshold: z9.coerce.number().min(0).max(100).optional().describe(
3659
4138
  "Percentage of credit_limit at which to send alert emails (0-100)"
3660
4139
  ),
3661
- rate_limit_rpm: z8.coerce.number().positive().optional().describe("Requests per minute limit")
4140
+ rate_limit_rpm: z9.coerce.number().positive().optional().describe("Requests per minute limit")
3662
4141
  },
3663
4142
  getVirtualKey: {
3664
- slug: z8.string().describe("The unique slug identifier of the virtual key to retrieve")
4143
+ slug: z9.string().describe("The unique slug identifier of the virtual key to retrieve")
3665
4144
  },
3666
4145
  updateVirtualKey: {
3667
- slug: z8.string().describe("The slug of the virtual key to update"),
3668
- name: z8.string().optional().describe("New display name for the key"),
3669
- key: z8.string().optional().describe("New provider API key value"),
3670
- note: z8.string().optional().describe("New note or description"),
3671
- credit_limit: z8.coerce.number().positive().optional().describe("New credit limit for usage"),
3672
- alert_threshold: z8.coerce.number().min(0).max(100).optional().describe("New alert threshold percentage (0-100)"),
3673
- rate_limit_rpm: z8.coerce.number().positive().optional().describe("New rate limit in requests per minute")
4146
+ slug: z9.string().describe("The slug of the virtual key to update"),
4147
+ name: z9.string().optional().describe("New display name for the key"),
4148
+ key: z9.string().optional().describe("New provider API key value"),
4149
+ note: z9.string().optional().describe("New note or description"),
4150
+ credit_limit: z9.coerce.number().positive().optional().describe("New credit limit for usage"),
4151
+ alert_threshold: z9.coerce.number().min(0).max(100).optional().describe("New alert threshold percentage (0-100)"),
4152
+ rate_limit_rpm: z9.coerce.number().positive().optional().describe("New rate limit in requests per minute")
3674
4153
  },
3675
4154
  deleteVirtualKey: {
3676
- slug: z8.string().describe("The slug of the virtual key to delete")
4155
+ slug: z9.string().describe("The slug of the virtual key to delete")
3677
4156
  },
3678
4157
  createApiKey: {
3679
- type: z8.enum(["organisation", "workspace"]).describe(
4158
+ type: z9.enum(["organisation", "workspace"]).describe(
3680
4159
  "Key type: 'organisation' for org-wide access or 'workspace' for workspace-scoped"
3681
4160
  ),
3682
- sub_type: z8.enum(["user", "service"]).describe(
4161
+ sub_type: z9.enum(["user", "service"]).describe(
3683
4162
  "Sub-type: 'user' for user-associated keys or 'service' for service accounts"
3684
4163
  ),
3685
- name: z8.string().describe("Display name for the API key"),
3686
- description: z8.string().optional().describe("Optional description for the key"),
3687
- workspace_id: z8.string().optional().describe("Workspace ID (required for workspace-type keys)"),
3688
- user_id: z8.string().optional().describe("User ID (required for user sub-type keys)"),
3689
- scopes: z8.array(z8.string()).describe(
4164
+ name: z9.string().describe("Display name for the API key"),
4165
+ description: z9.string().optional().describe("Optional description for the key"),
4166
+ workspace_id: z9.string().optional().describe("Workspace ID (required for workspace-type keys)"),
4167
+ user_id: z9.string().optional().describe("User ID (required for user sub-type keys)"),
4168
+ scopes: z9.array(z9.string()).describe(
3690
4169
  "Permission scopes for the key (e.g., ['logs.read', 'analytics.read'])"
3691
4170
  ),
3692
- credit_limit: z8.coerce.number().positive().optional().describe("Credit limit for usage"),
3693
- alert_threshold: z8.coerce.number().min(0).max(100).optional().describe("Alert threshold percentage (0-100)"),
3694
- rate_limit_rpm: z8.coerce.number().positive().optional().describe("Rate limit in requests per minute"),
3695
- default_config_id: z8.string().optional().describe("Default configuration ID to use with this key"),
3696
- default_metadata: z8.record(z8.string(), z8.string()).optional().describe("Default metadata key-value pairs"),
3697
- alert_emails: z8.array(z8.string()).optional().describe("Email addresses for alerts"),
3698
- expires_at: z8.string().optional().describe("Expiration date in ISO 8601 format")
4171
+ credit_limit: z9.coerce.number().positive().optional().describe("Credit limit for usage"),
4172
+ alert_threshold: z9.coerce.number().min(0).max(100).optional().describe("Alert threshold percentage (0-100)"),
4173
+ rate_limit_rpm: z9.coerce.number().positive().optional().describe("Rate limit in requests per minute"),
4174
+ default_config_id: z9.string().optional().describe("Default configuration ID to use with this key"),
4175
+ default_metadata: z9.record(z9.string(), z9.string()).optional().describe("Default metadata key-value pairs"),
4176
+ alert_emails: z9.array(z9.string()).optional().describe("Email addresses for alerts"),
4177
+ expires_at: z9.string().optional().describe("Expiration date in ISO 8601 format")
3699
4178
  },
3700
4179
  listApiKeys: {
3701
- page_size: z8.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)"),
3702
- current_page: z8.coerce.number().int().positive().optional().describe("Page number for pagination"),
3703
- workspace_id: z8.string().optional().describe("Filter by workspace ID")
4180
+ page_size: z9.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)"),
4181
+ current_page: z9.coerce.number().int().positive().optional().describe("Page number for pagination"),
4182
+ workspace_id: z9.string().optional().describe("Filter by workspace ID")
3704
4183
  },
3705
4184
  getApiKey: {
3706
- id: z8.string().uuid().describe("The UUID of the API key to retrieve")
4185
+ id: z9.string().uuid().describe("The UUID of the API key to retrieve")
3707
4186
  },
3708
4187
  updateApiKey: {
3709
- id: z8.string().uuid().describe("The UUID of the API key to update"),
3710
- name: z8.string().optional().describe("New display name for the key"),
3711
- description: z8.string().optional().describe("New description for the key"),
3712
- scopes: z8.array(z8.string()).optional().describe("New permission scopes for the key"),
3713
- credit_limit: z8.coerce.number().positive().optional().describe("New credit limit for usage"),
3714
- alert_threshold: z8.coerce.number().min(0).max(100).optional().describe("New alert threshold percentage (0-100)"),
3715
- rate_limit_rpm: z8.coerce.number().positive().optional().describe("New rate limit in requests per minute"),
3716
- default_config_id: z8.string().optional().describe("New default configuration ID"),
3717
- default_metadata: z8.record(z8.string(), z8.string()).optional().describe("New default metadata key-value pairs"),
3718
- alert_emails: z8.array(z8.string()).optional().describe("New email addresses for alerts"),
3719
- expires_at: z8.string().nullable().optional().describe(
4188
+ id: z9.string().uuid().describe("The UUID of the API key to update"),
4189
+ name: z9.string().optional().describe("New display name for the key"),
4190
+ description: z9.string().optional().describe("New description for the key"),
4191
+ scopes: z9.array(z9.string()).optional().describe("New permission scopes for the key"),
4192
+ credit_limit: z9.coerce.number().positive().optional().describe("New credit limit for usage"),
4193
+ alert_threshold: z9.coerce.number().min(0).max(100).optional().describe("New alert threshold percentage (0-100)"),
4194
+ rate_limit_rpm: z9.coerce.number().positive().optional().describe("New rate limit in requests per minute"),
4195
+ default_config_id: z9.string().optional().describe("New default configuration ID"),
4196
+ default_metadata: z9.record(z9.string(), z9.string()).optional().describe("New default metadata key-value pairs"),
4197
+ alert_emails: z9.array(z9.string()).optional().describe("New email addresses for alerts"),
4198
+ expires_at: z9.string().nullable().optional().describe(
3720
4199
  "New expiration date in ISO 8601 format, or null to remove expiration"
3721
4200
  )
3722
4201
  },
3723
4202
  rotateApiKey: {
3724
- id: z8.string().uuid().describe("API key UUID obtained from list_api_keys"),
3725
- key_transition_period_ms: z8.coerce.number().int().min(18e5).optional().describe(
4203
+ id: z9.string().uuid().describe("API key UUID obtained from list_api_keys"),
4204
+ key_transition_period_ms: z9.coerce.number().int().min(18e5).optional().describe(
3726
4205
  "Overlap in milliseconds while the previous key remains valid; minimum 1,800,000 (30 minutes), for example 3,600,000 for 1 hour"
3727
4206
  )
3728
4207
  },
3729
4208
  deleteApiKey: {
3730
- id: z8.string().uuid().describe("The UUID of the API key to delete")
4209
+ id: z9.string().uuid().describe("The UUID of the API key to delete")
3731
4210
  }
3732
4211
  };
3733
- var createApiKeySchema = z8.object(KEYS_TOOL_SCHEMAS.createApiKey).superRefine((value, ctx) => {
4212
+ var createApiKeySchema = z9.object(KEYS_TOOL_SCHEMAS.createApiKey).superRefine((value, ctx) => {
3734
4213
  if (value.type === "workspace" && !value.workspace_id) {
3735
4214
  ctx.addIssue({
3736
- code: z8.ZodIssueCode.custom,
4215
+ code: z9.ZodIssueCode.custom,
3737
4216
  path: ["workspace_id"],
3738
4217
  message: "workspace_id is required when type is 'workspace'"
3739
4218
  });
3740
4219
  }
3741
4220
  if (value.sub_type === "user" && !value.user_id) {
3742
4221
  ctx.addIssue({
3743
- code: z8.ZodIssueCode.custom,
4222
+ code: z9.ZodIssueCode.custom,
3744
4223
  path: ["user_id"],
3745
4224
  message: "user_id is required when sub_type is 'user'"
3746
4225
  });
@@ -4130,37 +4609,37 @@ function registerKeysTools(server, service) {
4130
4609
  }
4131
4610
 
4132
4611
  // src/tools/labels.tools.ts
4133
- import { z as z9 } from "zod";
4612
+ import { z as z10 } from "zod";
4134
4613
  var LABELS_TOOL_SCHEMAS = {
4135
4614
  createPromptLabel: {
4136
- name: z9.string().describe("Name of the label"),
4137
- organisation_id: z9.string().optional().describe("Organisation ID to create the label in"),
4138
- workspace_id: z9.string().optional().describe("Workspace ID to create the label in"),
4139
- description: z9.string().optional().describe("Description of the label"),
4140
- color_code: z9.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe(
4615
+ name: z10.string().describe("Name of the label"),
4616
+ organisation_id: z10.string().optional().describe("Organisation ID to create the label in"),
4617
+ workspace_id: z10.string().optional().describe("Workspace ID to create the label in"),
4618
+ description: z10.string().optional().describe("Description of the label"),
4619
+ color_code: z10.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe(
4141
4620
  "Hex format, e.g. '#FF5733'. Optional \u2014 omit for default color."
4142
4621
  )
4143
4622
  },
4144
4623
  listPromptLabels: {
4145
- organisation_id: z9.string().optional().describe("Filter by organisation ID"),
4146
- workspace_id: z9.string().optional().describe("Filter by workspace ID"),
4147
- search: z9.string().optional().describe("Search labels by name"),
4148
- current_page: z9.coerce.number().int().positive().optional().describe("Page number for pagination"),
4149
- page_size: z9.coerce.number().int().positive().max(100).optional().describe("Results per page (max 100)")
4624
+ organisation_id: z10.string().optional().describe("Filter by organisation ID"),
4625
+ workspace_id: z10.string().optional().describe("Filter by workspace ID"),
4626
+ search: z10.string().optional().describe("Search labels by name"),
4627
+ current_page: z10.coerce.number().int().positive().optional().describe("Page number for pagination"),
4628
+ page_size: z10.coerce.number().int().positive().max(100).optional().describe("Results per page (max 100)")
4150
4629
  },
4151
4630
  getPromptLabel: {
4152
- label_id: z9.string().describe("Label ID to retrieve"),
4153
- organisation_id: z9.string().optional().describe("Organisation ID for filtering"),
4154
- workspace_id: z9.string().optional().describe("Workspace ID for filtering")
4631
+ label_id: z10.string().describe("Label ID to retrieve"),
4632
+ organisation_id: z10.string().optional().describe("Organisation ID for filtering"),
4633
+ workspace_id: z10.string().optional().describe("Workspace ID for filtering")
4155
4634
  },
4156
4635
  updatePromptLabel: {
4157
- label_id: z9.string().describe("Label ID to update"),
4158
- name: z9.string().optional().describe("New name for the label"),
4159
- description: z9.string().optional().describe("New description"),
4160
- color_code: z9.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("New hex color code (e.g., '#FF5733')")
4636
+ label_id: z10.string().describe("Label ID to update"),
4637
+ name: z10.string().optional().describe("New name for the label"),
4638
+ description: z10.string().optional().describe("New description"),
4639
+ color_code: z10.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("New hex color code (e.g., '#FF5733')")
4161
4640
  },
4162
4641
  deletePromptLabel: {
4163
- label_id: z9.string().describe("Label ID to delete")
4642
+ label_id: z10.string().describe("Label ID to delete")
4164
4643
  }
4165
4644
  };
4166
4645
  function registerLabelsTools(server, service) {
@@ -4300,86 +4779,86 @@ function registerLabelsTools(server, service) {
4300
4779
  }
4301
4780
 
4302
4781
  // src/tools/limits.tools.ts
4303
- import { z as z10 } from "zod";
4304
- var conditionSchema = z10.object({
4305
- field: z10.string().describe(
4782
+ import { z as z11 } from "zod";
4783
+ var conditionSchema = z11.object({
4784
+ field: z11.string().describe(
4306
4785
  "The field to match on (e.g., 'virtual_key', 'api_key', 'user_id', 'metadata.key')"
4307
4786
  ),
4308
- operator: z10.string().describe("The comparison operator (e.g., 'is', 'contains', 'is_not')"),
4309
- value: z10.string().describe("The value to match against")
4787
+ operator: z11.string().describe("The comparison operator (e.g., 'is', 'contains', 'is_not')"),
4788
+ value: z11.string().describe("The value to match against")
4310
4789
  });
4311
4790
  var LIMITS_TOOL_SCHEMAS = {
4312
4791
  listRateLimits: {
4313
- workspace_id: z10.string().optional().describe("Filter rate limits by workspace ID")
4792
+ workspace_id: z11.string().optional().describe("Filter rate limits by workspace ID")
4314
4793
  },
4315
4794
  getRateLimit: {
4316
- id: z10.string().describe("The unique identifier of the rate limit")
4795
+ id: z11.string().describe("The unique identifier of the rate limit")
4317
4796
  },
4318
4797
  createRateLimit: {
4319
- conditions: z10.array(conditionSchema).describe(
4798
+ conditions: z11.array(conditionSchema).describe(
4320
4799
  "Array of conditions that determine which requests this rate limit applies to"
4321
4800
  ),
4322
- group_by: z10.array(z10.string()).describe(
4801
+ group_by: z11.array(z11.string()).describe(
4323
4802
  "Array of fields to group the rate limit by (e.g., ['virtual_key'], ['api_key', 'user_id'])"
4324
4803
  ),
4325
- type: z10.enum(["requests", "tokens"]).describe("What to rate limit: 'requests' or 'tokens'"),
4326
- unit: z10.enum(["rpm", "rph", "rpd"]).describe(
4804
+ type: z11.enum(["requests", "tokens"]).describe("What to rate limit: 'requests' or 'tokens'"),
4805
+ unit: z11.enum(["rpm", "rph", "rpd"]).describe(
4327
4806
  "Time unit: 'rpm' (per minute), 'rph' (per hour), or 'rpd' (per day)"
4328
4807
  ),
4329
- value: z10.coerce.number().positive().describe("The maximum allowed value per unit (e.g., 100 rpm)"),
4330
- name: z10.string().optional().describe("Optional name for the rate limit"),
4331
- workspace_id: z10.string().optional().describe("Workspace ID to scope the limit to"),
4332
- organisation_id: z10.string().optional().describe("Organisation ID to scope the limit to")
4808
+ value: z11.coerce.number().positive().describe("The maximum allowed value per unit (e.g., 100 rpm)"),
4809
+ name: z11.string().optional().describe("Optional name for the rate limit"),
4810
+ workspace_id: z11.string().optional().describe("Workspace ID to scope the limit to"),
4811
+ organisation_id: z11.string().optional().describe("Organisation ID to scope the limit to")
4333
4812
  },
4334
4813
  updateRateLimit: {
4335
- id: z10.string().describe("The unique identifier of the rate limit"),
4336
- name: z10.string().optional().describe("New name for the rate limit"),
4337
- unit: z10.enum(["rpm", "rph", "rpd"]).optional().describe(
4814
+ id: z11.string().describe("The unique identifier of the rate limit"),
4815
+ name: z11.string().optional().describe("New name for the rate limit"),
4816
+ unit: z11.enum(["rpm", "rph", "rpd"]).optional().describe(
4338
4817
  "New time unit: 'rpm' (per minute), 'rph' (per hour), or 'rpd' (per day)"
4339
4818
  ),
4340
- value: z10.coerce.number().positive().optional().describe("New maximum allowed value per unit")
4819
+ value: z11.coerce.number().positive().optional().describe("New maximum allowed value per unit")
4341
4820
  },
4342
4821
  deleteRateLimit: {
4343
- id: z10.string().describe("The unique identifier of the rate limit")
4822
+ id: z11.string().describe("The unique identifier of the rate limit")
4344
4823
  },
4345
4824
  listUsageLimits: {
4346
- workspace_id: z10.string().optional().describe("Filter usage limits by workspace ID")
4825
+ workspace_id: z11.string().optional().describe("Filter usage limits by workspace ID")
4347
4826
  },
4348
4827
  getUsageLimit: {
4349
- id: z10.string().describe("The unique identifier of the usage limit")
4828
+ id: z11.string().describe("The unique identifier of the usage limit")
4350
4829
  },
4351
4830
  createUsageLimit: {
4352
- conditions: z10.array(conditionSchema).describe(
4831
+ conditions: z11.array(conditionSchema).describe(
4353
4832
  "Array of conditions that determine which requests this usage limit applies to"
4354
4833
  ),
4355
- group_by: z10.array(z10.string()).describe(
4834
+ group_by: z11.array(z11.string()).describe(
4356
4835
  "Array of fields to group the usage limit by (e.g., ['virtual_key'], ['api_key', 'user_id'])"
4357
4836
  ),
4358
- type: z10.enum(["cost", "tokens"]).describe("What to limit: 'cost' (in dollars) or 'tokens'"),
4359
- credit_limit: z10.coerce.number().positive().describe("The maximum allowed usage (cost in dollars or token count)"),
4360
- name: z10.string().optional().describe("Optional name for the usage limit"),
4361
- alert_threshold: z10.coerce.number().optional().describe("Percentage threshold (0-100) at which to send an alert"),
4362
- periodic_reset: z10.enum(["monthly", "weekly"]).optional().describe("Automatically reset usage counters on this schedule"),
4363
- workspace_id: z10.string().optional().describe("Workspace ID to scope the limit to"),
4364
- organisation_id: z10.string().optional().describe("Organisation ID to scope the limit to")
4837
+ type: z11.enum(["cost", "tokens"]).describe("What to limit: 'cost' (in dollars) or 'tokens'"),
4838
+ credit_limit: z11.coerce.number().positive().describe("The maximum allowed usage (cost in dollars or token count)"),
4839
+ name: z11.string().optional().describe("Optional name for the usage limit"),
4840
+ alert_threshold: z11.coerce.number().optional().describe("Percentage threshold (0-100) at which to send an alert"),
4841
+ periodic_reset: z11.enum(["monthly", "weekly"]).optional().describe("Automatically reset usage counters on this schedule"),
4842
+ workspace_id: z11.string().optional().describe("Workspace ID to scope the limit to"),
4843
+ organisation_id: z11.string().optional().describe("Organisation ID to scope the limit to")
4365
4844
  },
4366
4845
  updateUsageLimit: {
4367
- id: z10.string().describe("The unique identifier of the usage limit"),
4368
- name: z10.string().optional().describe("New name for the usage limit"),
4369
- credit_limit: z10.coerce.number().positive().optional().describe("New maximum allowed usage value"),
4370
- alert_threshold: z10.coerce.number().optional().describe("New alert threshold percentage (0-100)"),
4371
- periodic_reset: z10.enum(["monthly", "weekly"]).optional().describe("New periodic reset schedule"),
4372
- reset_usage_for_value: z10.string().optional().describe("Reset usage counters for a specific group_by value")
4846
+ id: z11.string().describe("The unique identifier of the usage limit"),
4847
+ name: z11.string().optional().describe("New name for the usage limit"),
4848
+ credit_limit: z11.coerce.number().positive().optional().describe("New maximum allowed usage value"),
4849
+ alert_threshold: z11.coerce.number().optional().describe("New alert threshold percentage (0-100)"),
4850
+ periodic_reset: z11.enum(["monthly", "weekly"]).optional().describe("New periodic reset schedule"),
4851
+ reset_usage_for_value: z11.string().optional().describe("Reset usage counters for a specific group_by value")
4373
4852
  },
4374
4853
  deleteUsageLimit: {
4375
- id: z10.string().describe("The unique identifier of the usage limit")
4854
+ id: z11.string().describe("The unique identifier of the usage limit")
4376
4855
  },
4377
4856
  listUsageLimitEntities: {
4378
- limit_id: z10.string().describe("Usage limit policy ID")
4857
+ limit_id: z11.string().describe("Usage limit policy ID")
4379
4858
  },
4380
4859
  resetUsageLimitEntity: {
4381
- limit_id: z10.string().describe("Usage limit policy ID"),
4382
- entity_id: z10.string().describe("Entity ID to reset usage for")
4860
+ limit_id: z11.string().describe("Usage limit policy ID"),
4861
+ entity_id: z11.string().describe("Entity ID to reset usage for")
4383
4862
  }
4384
4863
  };
4385
4864
  function formatRateLimit(limit) {
@@ -4685,8 +5164,8 @@ function registerLimitsTools(server, service) {
4685
5164
  }
4686
5165
 
4687
5166
  // src/tools/logging.tools.ts
4688
- import { z as z11 } from "zod";
4689
- var logExportFieldSchema = z11.enum([
5167
+ import { z as z12 } from "zod";
5168
+ var logExportFieldSchema = z12.enum([
4690
5169
  "id",
4691
5170
  "trace_id",
4692
5171
  "created_at",
@@ -4708,71 +5187,132 @@ var logExportFieldSchema = z11.enum([
4708
5187
  "prompt_slug",
4709
5188
  "metadata"
4710
5189
  ]);
5190
+ var getLogInputSchema = z12.object({
5191
+ log_id: z12.string().describe("Gateway log ID to retrieve"),
5192
+ path_format: z12.enum(["v1", "v2"]).optional().describe("Log storage path format; defaults to v1"),
5193
+ created_at: z12.iso.datetime({ offset: true }).optional().describe("Log creation timestamp in ISO 8601 format; required for v2"),
5194
+ type: z12.enum(["hooks"]).optional().describe("Set to hooks when retrieving a hook execution log")
5195
+ }).superRefine((input, context) => {
5196
+ if (input.path_format === "v2" && input.created_at === void 0) {
5197
+ context.addIssue({
5198
+ code: "custom",
5199
+ path: ["created_at"],
5200
+ message: "created_at is required when path_format is v2"
5201
+ });
5202
+ }
5203
+ });
4711
5204
  var LOGGING_TOOL_SCHEMAS = {
5205
+ getLogExportFieldRestrictions: {
5206
+ workspace_id: z12.string().describe("Workspace ID whose export field restrictions should be read")
5207
+ },
4712
5208
  insertLog: {
4713
- request_url: z11.string().optional().describe("The endpoint URL being called"),
4714
- request_provider: z11.string().optional().describe("AI provider name (e.g., 'openai', 'anthropic')"),
4715
- request_method: z11.string().optional().default("post").describe("HTTP method used (defaults to 'post')"),
4716
- request_headers: z11.record(z11.string(), z11.string()).optional().describe("Request headers as key-value pairs"),
4717
- request_body: z11.record(z11.string(), z11.unknown()).optional().describe("Request payload/body"),
4718
- response_status: z11.coerce.number().optional().default(200).describe("HTTP response status code (defaults to 200)"),
4719
- response_headers: z11.record(z11.string(), z11.string()).optional().describe("Response headers as key-value pairs"),
4720
- response_body: z11.record(z11.string(), z11.unknown()).optional().describe("Response payload/body"),
4721
- response_time: z11.coerce.number().optional().describe("Response latency in milliseconds"),
4722
- streaming_mode: z11.boolean().optional().default(false).describe("Whether the response was streamed"),
4723
- metadata_organization: z11.string().optional().describe("Organization identifier for the log"),
4724
- metadata_user: z11.string().optional().describe("User identifier for the log"),
4725
- metadata_trace_id: z11.string().optional().describe("Trace ID for distributed tracing"),
4726
- metadata_span_id: z11.string().optional().describe("Span ID for tracing"),
4727
- metadata_span_name: z11.string().optional().describe("Span name for tracing"),
4728
- metadata_parent_span_id: z11.string().optional().describe("Parent span ID for tracing"),
4729
- metadata_custom: z11.record(z11.string(), z11.unknown()).optional().describe("Additional custom metadata key-value pairs")
5209
+ request_url: z12.string().optional().describe("The endpoint URL being called"),
5210
+ request_provider: z12.string().optional().describe("AI provider name (e.g., 'openai', 'anthropic')"),
5211
+ request_method: z12.string().optional().default("post").describe("HTTP method used (defaults to 'post')"),
5212
+ request_headers: z12.record(z12.string(), z12.string()).optional().describe("Request headers as key-value pairs"),
5213
+ request_body: z12.record(z12.string(), z12.unknown()).optional().describe("Request payload/body"),
5214
+ response_status: z12.coerce.number().optional().default(200).describe("HTTP response status code (defaults to 200)"),
5215
+ response_headers: z12.record(z12.string(), z12.string()).optional().describe("Response headers as key-value pairs"),
5216
+ response_body: z12.record(z12.string(), z12.unknown()).optional().describe("Response payload/body"),
5217
+ response_time: z12.coerce.number().optional().describe("Response latency in milliseconds"),
5218
+ streaming_mode: z12.boolean().optional().default(false).describe("Whether the response was streamed"),
5219
+ metadata_organization: z12.string().optional().describe("Organization identifier for the log"),
5220
+ metadata_user: z12.string().optional().describe("User identifier for the log"),
5221
+ metadata_trace_id: z12.string().optional().describe("Trace ID for distributed tracing"),
5222
+ metadata_span_id: z12.string().optional().describe("Span ID for tracing"),
5223
+ metadata_span_name: z12.string().optional().describe("Span name for tracing"),
5224
+ metadata_parent_span_id: z12.string().optional().describe("Parent span ID for tracing"),
5225
+ metadata_custom: z12.record(z12.string(), z12.unknown()).optional().describe("Additional custom metadata key-value pairs")
4730
5226
  },
4731
5227
  createLogExport: {
4732
- workspace_id: z11.string().optional().describe("Workspace ID for the export"),
4733
- description: z11.string().optional().describe("Human-readable description for the export job"),
4734
- time_min: z11.string().describe(
5228
+ workspace_id: z12.string().optional().describe("Workspace ID for the export"),
5229
+ description: z12.string().optional().describe("Human-readable description for the export job"),
5230
+ time_min: z12.string().describe(
4735
5231
  "Minimum time filter in date format (e.g., '2024-01-01' or ISO 8601)"
4736
5232
  ),
4737
- time_max: z11.string().describe(
5233
+ time_max: z12.string().describe(
4738
5234
  "Maximum time filter in date format (e.g., '2024-01-31' or ISO 8601)"
4739
5235
  ),
4740
- cost_min: z11.coerce.number().optional().describe("Minimum cost filter"),
4741
- cost_max: z11.coerce.number().optional().describe("Maximum cost filter"),
4742
- total_units_min: z11.coerce.number().optional().describe("Minimum total units (tokens) filter"),
4743
- total_units_max: z11.coerce.number().optional().describe("Maximum total units (tokens) filter"),
4744
- ai_model: z11.array(z11.string()).optional().describe("Filter by specific AI model names"),
4745
- requested_fields: z11.array(logExportFieldSchema).describe(
5236
+ cost_min: z12.coerce.number().optional().describe("Minimum cost filter"),
5237
+ cost_max: z12.coerce.number().optional().describe("Maximum cost filter"),
5238
+ total_units_min: z12.coerce.number().optional().describe("Minimum total units (tokens) filter"),
5239
+ total_units_max: z12.coerce.number().optional().describe("Maximum total units (tokens) filter"),
5240
+ ai_model: z12.array(z12.string()).optional().describe("Filter by specific AI model names"),
5241
+ requested_fields: z12.array(logExportFieldSchema).describe(
4746
5242
  "Fields to include in export: id, trace_id, created_at, request, response, is_success, ai_org, ai_model, req_units, res_units, total_units, request_url, cost, cost_currency, response_time, response_status_code, mode, config, prompt_slug, metadata"
4747
5243
  )
4748
5244
  },
4749
5245
  listLogExports: {
4750
- workspace_id: z11.string().describe("Workspace ID to list exports for (required)")
5246
+ workspace_id: z12.string().describe("Workspace ID to list exports for (required)")
4751
5247
  },
4752
5248
  getLogExport: {
4753
- export_id: z11.string().describe("The unique ID of the log export")
5249
+ export_id: z12.string().describe("The unique ID of the log export")
4754
5250
  },
4755
5251
  startLogExport: {
4756
- export_id: z11.string().describe("The unique ID of the log export to start")
5252
+ export_id: z12.string().describe("The unique ID of the log export to start")
4757
5253
  },
4758
5254
  cancelLogExport: {
4759
- export_id: z11.string().describe("The unique ID of the log export to cancel")
5255
+ export_id: z12.string().describe("The unique ID of the log export to cancel")
4760
5256
  },
4761
5257
  downloadLogExport: {
4762
- export_id: z11.string().describe("The unique ID of the log export to download")
5258
+ export_id: z12.string().describe("The unique ID of the log export to download")
4763
5259
  },
4764
5260
  updateLogExport: {
4765
- export_id: z11.string().describe("The unique ID of the log export to update"),
4766
- workspace_id: z11.string().optional().describe("Workspace ID for the export"),
4767
- time_of_generation_max: z11.string().optional().describe(
5261
+ export_id: z12.string().describe("The unique ID of the log export to update"),
5262
+ workspace_id: z12.string().optional().describe("Workspace ID for the export"),
5263
+ time_of_generation_max: z12.string().optional().describe(
4768
5264
  "Maximum time filter in date format (e.g., '2024-07-25' or ISO 8601)"
4769
5265
  ),
4770
- requested_fields: z11.array(logExportFieldSchema).optional().describe(
5266
+ requested_fields: z12.array(logExportFieldSchema).optional().describe(
4771
5267
  "Fields to include in export: id, trace_id, created_at, request, response, is_success, ai_org, ai_model, req_units, res_units, total_units, request_url, cost, cost_currency, response_time, response_status_code, mode, config, prompt_slug, metadata"
4772
5268
  )
4773
5269
  }
4774
5270
  };
4775
5271
  function registerLoggingTools(server, service) {
5272
+ server.registerTool(
5273
+ "get_log",
5274
+ {
5275
+ description: "Get one gateway request log by ID, including its request, response, usage, cost, and metadata payload when available. For path_format v2, also provide the log's created_at timestamp.",
5276
+ inputSchema: getLogInputSchema,
5277
+ annotations: {
5278
+ title: "Get Gateway Log",
5279
+ readOnlyHint: true,
5280
+ destructiveHint: false,
5281
+ idempotentHint: true,
5282
+ openWorldHint: true
5283
+ }
5284
+ },
5285
+ async (params) => {
5286
+ const result = await service.logging.getLog(params.log_id, {
5287
+ path_format: params.path_format,
5288
+ created_at: params.created_at,
5289
+ type: params.type
5290
+ });
5291
+ return {
5292
+ content: [{ type: "text", text: JSON.stringify(result) }]
5293
+ };
5294
+ }
5295
+ );
5296
+ server.tool(
5297
+ "get_log_export_field_restrictions",
5298
+ "Get the organisation-managed fields that a workspace is restricted from including in log exports. Use before create_log_export or update_log_export to avoid requesting disallowed fields. Requires an API key with logs.export scope; completion-log fields may additionally require completion scope.",
5299
+ LOGGING_TOOL_SCHEMAS.getLogExportFieldRestrictions,
5300
+ {
5301
+ title: "Get Log Export Field Restrictions",
5302
+ readOnlyHint: true,
5303
+ destructiveHint: false,
5304
+ idempotentHint: true,
5305
+ openWorldHint: true
5306
+ },
5307
+ async (params) => {
5308
+ const result = await service.logging.getLogExportFieldRestrictions({
5309
+ workspace_id: params.workspace_id
5310
+ });
5311
+ return {
5312
+ content: [{ type: "text", text: JSON.stringify(result) }]
5313
+ };
5314
+ }
5315
+ );
4776
5316
  server.tool(
4777
5317
  "insert_log",
4778
5318
  "Insert log records for requests that bypassed the gateway. This writes request, response, and trace metadata into Portkey immediately, and the call will fail if request_provider does not match a configured integration. Use the span fields to stitch trace hierarchies together.",
@@ -5008,73 +5548,88 @@ function registerLoggingTools(server, service) {
5008
5548
  }
5009
5549
 
5010
5550
  // src/tools/mcp-integrations.tools.ts
5011
- import { z as z12 } from "zod";
5551
+ import { z as z13 } from "zod";
5552
+ var mcpSecretMappingSchema = createSecretMappingSchema({
5553
+ allowKeyTarget: false,
5554
+ targetFieldDescription: "Configuration field resolved at runtime, such as configurations.oauth_metadata",
5555
+ secretReferenceDescription: "Secret Reference UUID or slug accessible to this integration",
5556
+ valueFormatDescription: "Use json when the target configuration field expects a structured object"
5557
+ });
5558
+ var mcpSecretMappingsSchema = uniqueSecretMappingsSchema(
5559
+ mcpSecretMappingSchema
5560
+ );
5012
5561
  var MCP_INTEGRATIONS_TOOL_SCHEMAS = {
5013
5562
  listMcpIntegrations: {
5014
- current_page: z12.coerce.number().int().positive().optional().describe("Page number for pagination"),
5015
- page_size: z12.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)"),
5016
- workspace_id: z12.string().optional().describe("Filter by workspace ID")
5563
+ current_page: z13.coerce.number().int().positive().optional().describe("Page number for pagination"),
5564
+ page_size: z13.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)"),
5565
+ workspace_id: z13.string().optional().describe("Filter by workspace ID")
5017
5566
  },
5018
5567
  createMcpIntegration: {
5019
- name: z12.string().describe("Display name for the MCP integration"),
5020
- url: z12.string().describe("URL endpoint of the MCP server to integrate"),
5021
- auth_type: z12.enum(["oauth_auto", "headers", "none"]).describe(
5568
+ name: z13.string().describe("Display name for the MCP integration"),
5569
+ url: z13.string().describe("URL endpoint of the MCP server to integrate"),
5570
+ auth_type: z13.enum(["oauth_auto", "headers", "none"]).describe(
5022
5571
  "Authentication type: 'none', 'headers' (custom headers), or 'oauth_auto' (OAuth)"
5023
5572
  ),
5024
- transport: z12.enum(["http", "sse"]).describe(
5573
+ transport: z13.enum(["http", "sse"]).describe(
5025
5574
  "MCP transport protocol: 'http' (streamable HTTP) or 'sse' (server-sent events)"
5026
5575
  ),
5027
- slug: z12.string().optional().describe("Custom slug. Auto-generated if omitted"),
5028
- description: z12.string().optional().describe("Description of the MCP integration"),
5029
- custom_headers: z12.record(z12.string(), z12.string()).optional().describe(
5576
+ slug: z13.string().optional().describe("Custom slug. Auto-generated if omitted"),
5577
+ description: z13.string().optional().describe("Description of the MCP integration"),
5578
+ custom_headers: z13.record(z13.string(), z13.string()).optional().describe(
5030
5579
  'Custom headers for authentication (e.g. { "Authorization": "Bearer xxx" }). Sent via configurations.custom_headers'
5031
5580
  ),
5032
- workspace_id: z12.string().optional().describe(
5581
+ workspace_id: z13.string().optional().describe(
5033
5582
  "Workspace ID \u2014 required when using organization admin API keys"
5583
+ ),
5584
+ secret_mappings: mcpSecretMappingsSchema.optional().describe(
5585
+ "Runtime Secret Reference mappings; every configurations.<field> target must be unique"
5034
5586
  )
5035
5587
  },
5036
5588
  getMcpIntegration: {
5037
- id: z12.string().describe("The MCP integration ID or slug to retrieve")
5589
+ id: z13.string().describe("The MCP integration ID or slug to retrieve")
5038
5590
  },
5039
5591
  updateMcpIntegration: {
5040
- id: z12.string().describe("The MCP integration ID or slug to update"),
5041
- name: z12.string().optional().describe("New display name"),
5042
- description: z12.string().optional().describe("New description"),
5043
- url: z12.string().optional().describe("New URL endpoint"),
5044
- auth_type: z12.enum(["oauth_auto", "headers", "none"]).optional().describe("New authentication type"),
5045
- transport: z12.enum(["http", "sse"]).optional().describe("New transport protocol"),
5046
- custom_headers: z12.record(z12.string(), z12.string()).optional().describe(
5592
+ id: z13.string().describe("The MCP integration ID or slug to update"),
5593
+ name: z13.string().optional().describe("New display name"),
5594
+ description: z13.string().optional().describe("New description"),
5595
+ url: z13.string().optional().describe("New URL endpoint"),
5596
+ auth_type: z13.enum(["oauth_auto", "headers", "none"]).optional().describe("New authentication type"),
5597
+ transport: z13.enum(["http", "sse"]).optional().describe("New transport protocol"),
5598
+ custom_headers: z13.record(z13.string(), z13.string()).optional().describe(
5047
5599
  "New custom headers for authentication. Sent via configurations.custom_headers"
5600
+ ),
5601
+ secret_mappings: mcpSecretMappingsSchema.optional().describe(
5602
+ "Replacement runtime Secret Reference mappings; each target_field must be unique"
5048
5603
  )
5049
5604
  },
5050
5605
  deleteMcpIntegration: {
5051
- id: z12.string().describe("The MCP integration ID or slug to delete")
5606
+ id: z13.string().describe("The MCP integration ID or slug to delete")
5052
5607
  },
5053
5608
  getMcpIntegrationMetadata: {
5054
- id: z12.string().describe("The MCP integration ID or slug")
5609
+ id: z13.string().describe("The MCP integration ID or slug")
5055
5610
  },
5056
5611
  listMcpIntegrationCapabilities: {
5057
- id: z12.string().describe("The MCP integration ID or slug")
5612
+ id: z13.string().describe("The MCP integration ID or slug")
5058
5613
  },
5059
5614
  updateMcpIntegrationCapabilities: {
5060
- id: z12.string().describe("The MCP integration ID or slug"),
5061
- capabilities: z12.array(
5062
- z12.object({
5063
- name: z12.string().describe("Capability name"),
5064
- type: z12.enum(["tool", "prompt", "resource"]).describe("Capability type"),
5065
- enabled: z12.boolean().describe("Whether to enable the capability")
5615
+ id: z13.string().describe("The MCP integration ID or slug"),
5616
+ capabilities: z13.array(
5617
+ z13.object({
5618
+ name: z13.string().describe("Capability name"),
5619
+ type: z13.enum(["tool", "prompt", "resource"]).describe("Capability type"),
5620
+ enabled: z13.boolean().describe("Whether to enable the capability")
5066
5621
  })
5067
5622
  ).min(1).describe("Array of capability updates")
5068
5623
  },
5069
5624
  listMcpIntegrationWorkspaces: {
5070
- id: z12.string().describe("The MCP integration ID or slug")
5625
+ id: z13.string().describe("The MCP integration ID or slug")
5071
5626
  },
5072
5627
  updateMcpIntegrationWorkspaces: {
5073
- id: z12.string().describe("The MCP integration ID or slug"),
5074
- workspaces: z12.array(
5075
- z12.object({
5076
- id: z12.string().describe("Workspace ID"),
5077
- enabled: z12.boolean().describe("Whether workspace has access")
5628
+ id: z13.string().describe("The MCP integration ID or slug"),
5629
+ workspaces: z13.array(
5630
+ z13.object({
5631
+ id: z13.string().describe("Workspace ID"),
5632
+ enabled: z13.boolean().describe("Whether workspace has access")
5078
5633
  })
5079
5634
  ).min(1).describe("Array of workspace access updates")
5080
5635
  }
@@ -5102,6 +5657,7 @@ function formatMcpIntegration(integration) {
5102
5657
  global_workspace_access: integration.global_workspace_access,
5103
5658
  configuration_keys: integration.configurations ? Object.keys(integration.configurations) : void 0,
5104
5659
  custom_header_names: getCustomHeaderNames(integration.configurations),
5660
+ secret_mappings: integration.secret_mappings,
5105
5661
  created_at: integration.created_at,
5106
5662
  last_updated_at: integration.last_updated_at
5107
5663
  };
@@ -5154,10 +5710,19 @@ function registerMcpIntegrationsTools(server, service) {
5154
5710
  );
5155
5711
  server.tool(
5156
5712
  "create_mcp_integration",
5157
- "Create an MCP integration from an external server URL. Registers the Portkey-side connection and returns the new id and slug; if auth_type is headers, custom_headers are required, and you usually follow with create_mcp_server and capability updates.",
5713
+ "Create a Portkey integration for an external MCP server URL. For headers auth, provide custom_headers or a Secret Reference mapping targeting configurations.custom_headers; secret_mappings resolve protected values at runtime without storing them in the tool call. Organisation admin keys normally need workspace_id. After creation, create_mcp_server and configure capabilities/access; returns the integration id and slug.",
5158
5714
  MCP_INTEGRATIONS_TOOL_SCHEMAS.createMcpIntegration,
5715
+ {
5716
+ title: "Create MCP Integration",
5717
+ readOnlyHint: false,
5718
+ destructiveHint: false,
5719
+ idempotentHint: false,
5720
+ openWorldHint: true
5721
+ },
5159
5722
  async (params) => {
5160
- if (params.auth_type === "headers" && (!params.custom_headers || Object.keys(params.custom_headers).length === 0)) {
5723
+ if (params.auth_type === "headers" && (!params.custom_headers || Object.keys(params.custom_headers).length === 0) && !params.secret_mappings?.some(
5724
+ (mapping) => mapping.target_field === "configurations.custom_headers"
5725
+ )) {
5161
5726
  return {
5162
5727
  content: [
5163
5728
  {
@@ -5207,8 +5772,15 @@ function registerMcpIntegrationsTools(server, service) {
5207
5772
  );
5208
5773
  server.tool(
5209
5774
  "update_mcp_integration",
5210
- "Update an MCP integration's name, description, URL, auth, or transport. Changes apply immediately and altering url or auth_type can break connected clients; use update_mcp_server when you only need to rename or re-describe a server.",
5775
+ "Update an MCP integration's name, description, URL, auth, transport, headers, or runtime Secret Reference mappings. Only supplied fields change; URL, auth, header, and secret changes apply immediately and can break active clients, so inspect get_mcp_integration first. Use update_mcp_server when changing only a Portkey server instance's display metadata.",
5211
5776
  MCP_INTEGRATIONS_TOOL_SCHEMAS.updateMcpIntegration,
5777
+ {
5778
+ title: "Update MCP Integration",
5779
+ readOnlyHint: false,
5780
+ destructiveHint: true,
5781
+ idempotentHint: true,
5782
+ openWorldHint: true
5783
+ },
5212
5784
  async (params) => {
5213
5785
  const { id, custom_headers, ...rest } = params;
5214
5786
  await service.mcpIntegrations.updateMcpIntegration(id, {
@@ -5366,7 +5938,7 @@ function registerMcpIntegrationsTools(server, service) {
5366
5938
  }
5367
5939
 
5368
5940
  // src/tools/mcp-servers.tools.ts
5369
- import { z as z13 } from "zod";
5941
+ import { z as z14 } from "zod";
5370
5942
 
5371
5943
  // src/tools/utils.ts
5372
5944
  function formatFullName(firstName, lastName) {
@@ -5376,58 +5948,78 @@ function formatFullName(firstName, lastName) {
5376
5948
  // src/tools/mcp-servers.tools.ts
5377
5949
  var MCP_SERVERS_TOOL_SCHEMAS = {
5378
5950
  listMcpServers: {
5379
- current_page: z13.coerce.number().int().positive().optional().describe("Page number for pagination"),
5380
- page_size: z13.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)"),
5381
- workspace_id: z13.string().optional().describe("Filter by workspace ID")
5951
+ current_page: z14.coerce.number().int().positive().optional().describe("Page number for pagination"),
5952
+ page_size: z14.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)"),
5953
+ workspace_id: z14.string().optional().describe("Filter by workspace ID")
5382
5954
  },
5383
5955
  createMcpServer: {
5384
- name: z13.string().describe("Display name for the MCP server"),
5385
- mcp_integration_id: z13.string().describe("ID or slug of the MCP integration this server belongs to"),
5386
- slug: z13.string().optional().describe("Custom slug. Auto-generated if omitted"),
5387
- description: z13.string().optional().describe("Description of the MCP server")
5956
+ name: z14.string().describe("Display name for the MCP server"),
5957
+ mcp_integration_id: z14.string().describe("ID or slug of the MCP integration this server belongs to"),
5958
+ slug: z14.string().optional().describe("Custom slug. Auto-generated if omitted"),
5959
+ description: z14.string().optional().describe("Description of the MCP server")
5388
5960
  },
5389
5961
  getMcpServer: {
5390
- id: z13.string().describe("The MCP server ID or slug to retrieve")
5962
+ id: z14.string().describe("The MCP server ID or slug to retrieve")
5391
5963
  },
5392
5964
  updateMcpServer: {
5393
- id: z13.string().describe("The MCP server ID or slug to update"),
5394
- name: z13.string().optional().describe("New display name"),
5395
- description: z13.string().optional().describe("New description")
5965
+ id: z14.string().describe("The MCP server ID or slug to update"),
5966
+ name: z14.string().optional().describe("New display name"),
5967
+ description: z14.string().optional().describe("New description")
5396
5968
  },
5397
5969
  deleteMcpServer: {
5398
- id: z13.string().describe("The MCP server ID or slug to delete")
5970
+ id: z14.string().describe("The MCP server ID or slug to delete")
5399
5971
  },
5400
5972
  testMcpServer: {
5401
- id: z13.string().describe("The MCP server ID or slug to test")
5973
+ id: z14.string().describe("The MCP server ID or slug to test")
5402
5974
  },
5403
5975
  listMcpServerCapabilities: {
5404
- id: z13.string().describe("The MCP server ID or slug"),
5405
- current_page: z13.coerce.number().int().positive().optional().describe("Page number for pagination"),
5406
- page_size: z13.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
5976
+ id: z14.string().describe("The MCP server ID or slug"),
5977
+ current_page: z14.coerce.number().int().positive().optional().describe("Page number for pagination"),
5978
+ page_size: z14.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
5407
5979
  },
5408
5980
  updateMcpServerCapabilities: {
5409
- id: z13.string().describe("The MCP server ID or slug"),
5410
- capabilities: z13.array(
5411
- z13.object({
5412
- name: z13.string().describe("Capability name"),
5413
- type: z13.enum(["tool", "prompt", "resource"]).describe("Capability type"),
5414
- enabled: z13.boolean().describe("Whether to enable the capability")
5981
+ id: z14.string().describe("The MCP server ID or slug"),
5982
+ capabilities: z14.array(
5983
+ z14.object({
5984
+ name: z14.string().describe("Capability name"),
5985
+ type: z14.enum(["tool", "prompt", "resource"]).describe("Capability type"),
5986
+ enabled: z14.boolean().describe("Whether to enable the capability")
5415
5987
  })
5416
5988
  ).min(1).describe("Array of capability updates")
5417
5989
  },
5418
5990
  listMcpServerUserAccess: {
5419
- id: z13.string().describe("The MCP server ID or slug"),
5420
- current_page: z13.coerce.number().int().positive().optional().describe("Page number for pagination"),
5421
- page_size: z13.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
5991
+ id: z14.string().describe("The MCP server ID or slug"),
5992
+ current_page: z14.coerce.number().int().positive().optional().describe("Page number for pagination"),
5993
+ page_size: z14.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
5422
5994
  },
5423
5995
  updateMcpServerUserAccess: {
5424
- id: z13.string().describe("The MCP server ID or slug"),
5425
- users: z13.array(
5426
- z13.object({
5427
- user_id: z13.string().describe("User ID"),
5428
- enabled: z13.boolean().describe("Whether user has access")
5996
+ id: z14.string().describe("The MCP server ID or slug"),
5997
+ users: z14.array(
5998
+ z14.object({
5999
+ user_id: z14.string().describe("User ID"),
6000
+ enabled: z14.boolean().describe("Whether user has access")
5429
6001
  })
5430
6002
  ).min(1).describe("Array of user access updates")
6003
+ },
6004
+ listMcpServerConnections: {
6005
+ id: z14.string().describe("MCP server ID or slug whose connections to list"),
6006
+ user_id: z14.string().uuid().optional().describe(
6007
+ "User UUID to filter; user-scoped keys default to their own user when omitted"
6008
+ ),
6009
+ workspace_id: z14.string().optional().describe(
6010
+ "Workspace ID or slug; required with an organisation admin API key"
6011
+ ),
6012
+ current_page: z14.coerce.number().int().min(0).optional().describe("Zero-based results page; defaults to 0"),
6013
+ page_size: z14.coerce.number().int().min(1).max(500).optional().describe("Connections per page, from 1 through 500; defaults to 100")
6014
+ },
6015
+ disconnectMcpServerConnection: {
6016
+ id: z14.string().describe("MCP server ID or slug containing the active connection"),
6017
+ user_id: z14.string().uuid().optional().describe(
6018
+ "User UUID to disconnect; required with service keys and derived from user keys when omitted"
6019
+ ),
6020
+ workspace_id: z14.string().optional().describe(
6021
+ "Workspace ID or slug; required with an organisation admin API key"
6022
+ )
5431
6023
  }
5432
6024
  };
5433
6025
  function formatMcpServer(server) {
@@ -5461,6 +6053,73 @@ function formatMcpServerUserAccess(user) {
5461
6053
  };
5462
6054
  }
5463
6055
  function registerMcpServersTools(server, service) {
6056
+ server.tool(
6057
+ "list_mcp_server_connections",
6058
+ "List active connection records for one Portkey-managed MCP server, including user, connected state, and connection timestamps. Use it to audit sessions or identify the user/workspace before disconnect_mcp_server_connection; service keys can list all users, while user keys default to their own user. Organisation admin keys must provide workspace_id. This reads live connection state and does not test upstream server reachability (use test_mcp_server for that).",
6059
+ MCP_SERVERS_TOOL_SCHEMAS.listMcpServerConnections,
6060
+ {
6061
+ title: "List MCP Server Connections",
6062
+ readOnlyHint: true,
6063
+ destructiveHint: false,
6064
+ idempotentHint: true,
6065
+ openWorldHint: true
6066
+ },
6067
+ async (params) => {
6068
+ const result = await service.mcpServers.listMcpServerConnections(
6069
+ params.id,
6070
+ {
6071
+ user_id: params.user_id,
6072
+ workspace_id: params.workspace_id,
6073
+ current_page: params.current_page,
6074
+ page_size: params.page_size
6075
+ }
6076
+ );
6077
+ return {
6078
+ content: [
6079
+ {
6080
+ type: "text",
6081
+ text: JSON.stringify({
6082
+ total: result.total,
6083
+ has_more: result.has_more,
6084
+ connections: result.data
6085
+ })
6086
+ }
6087
+ ]
6088
+ };
6089
+ }
6090
+ );
6091
+ server.tool(
6092
+ "disconnect_mcp_server_connection",
6093
+ "Disconnect one user's active session from a Portkey-managed MCP server. This immediately ends that connection but does not revoke future access; use update_mcp_server_user_access when access itself should be removed. Provide user_id with service keys (user keys derive it), and workspace_id with organisation admin keys. Inspect list_mcp_server_connections first when the target is uncertain.",
6094
+ MCP_SERVERS_TOOL_SCHEMAS.disconnectMcpServerConnection,
6095
+ {
6096
+ title: "Disconnect MCP Server Connection",
6097
+ readOnlyHint: false,
6098
+ destructiveHint: true,
6099
+ idempotentHint: true,
6100
+ openWorldHint: true
6101
+ },
6102
+ async (params) => {
6103
+ const result = await service.mcpServers.disconnectMcpServerConnection(
6104
+ params.id,
6105
+ {
6106
+ user_id: params.user_id,
6107
+ workspace_id: params.workspace_id
6108
+ }
6109
+ );
6110
+ return {
6111
+ content: [
6112
+ {
6113
+ type: "text",
6114
+ text: JSON.stringify({
6115
+ message: `Disconnected MCP server connection for "${params.id}"`,
6116
+ ...result
6117
+ })
6118
+ }
6119
+ ]
6120
+ };
6121
+ }
6122
+ );
5464
6123
  server.tool(
5465
6124
  "list_mcp_servers",
5466
6125
  "List MCP servers in the organization. Returns paginated server records plus total for discovering server IDs; use get_mcp_server for one server's details and list_mcp_integrations for the parent integration.",
@@ -5669,40 +6328,40 @@ function registerMcpServersTools(server, service) {
5669
6328
  }
5670
6329
 
5671
6330
  // src/tools/partials.tools.ts
5672
- import { z as z14 } from "zod";
6331
+ import { z as z15 } from "zod";
5673
6332
  var PARTIALS_TOOL_SCHEMAS = {
5674
6333
  createPromptPartial: {
5675
- name: z14.string().describe("Display name for the partial"),
5676
- string: z14.string().describe("The partial content/template string"),
5677
- workspace_id: z14.string().optional().describe(
6334
+ name: z15.string().describe("Display name for the partial"),
6335
+ string: z15.string().describe("The partial content/template string"),
6336
+ workspace_id: z15.string().optional().describe(
5678
6337
  "Workspace ID to create partial in (required for org-level API keys)"
5679
6338
  ),
5680
- version_description: z14.string().optional().describe("Description for this version")
6339
+ version_description: z15.string().optional().describe("Description for this version")
5681
6340
  },
5682
6341
  listPromptPartials: {
5683
- collection_id: z14.string().optional().describe(
6342
+ collection_id: z15.string().optional().describe(
5684
6343
  "Filter by collection ID. Optional \u2014 omit to list all partials across collections"
5685
6344
  )
5686
6345
  },
5687
6346
  getPromptPartial: {
5688
- prompt_partial_id: z14.string().describe("Prompt partial ID or slug to retrieve")
6347
+ prompt_partial_id: z15.string().describe("Prompt partial ID or slug to retrieve")
5689
6348
  },
5690
6349
  updatePromptPartial: {
5691
- prompt_partial_id: z14.string().describe("Prompt partial ID or slug to update"),
5692
- name: z14.string().optional().describe("New display name for the partial"),
5693
- string: z14.string().optional().describe("New content for the partial"),
5694
- description: z14.string().optional().describe("Description for this version"),
5695
- status: z14.enum(["active", "archived"]).optional().describe("New status for the partial")
6350
+ prompt_partial_id: z15.string().describe("Prompt partial ID or slug to update"),
6351
+ name: z15.string().optional().describe("New display name for the partial"),
6352
+ string: z15.string().optional().describe("New content for the partial"),
6353
+ description: z15.string().optional().describe("Description for this version"),
6354
+ status: z15.enum(["active", "archived"]).optional().describe("New status for the partial")
5696
6355
  },
5697
6356
  deletePromptPartial: {
5698
- prompt_partial_id: z14.string().describe("Prompt partial ID or slug to delete")
6357
+ prompt_partial_id: z15.string().describe("Prompt partial ID or slug to delete")
5699
6358
  },
5700
6359
  listPartialVersions: {
5701
- prompt_partial_id: z14.string().describe("Prompt partial ID or slug to list versions for")
6360
+ prompt_partial_id: z15.string().describe("Prompt partial ID or slug to list versions for")
5702
6361
  },
5703
6362
  publishPartial: {
5704
- prompt_partial_id: z14.string().describe("Prompt partial ID or slug"),
5705
- version: z14.coerce.number().positive().describe("Version number to publish as default")
6363
+ prompt_partial_id: z15.string().describe("Prompt partial ID or slug"),
6364
+ version: z15.coerce.number().positive().describe("Version number to publish as default")
5706
6365
  }
5707
6366
  };
5708
6367
  function registerPartialsTools(server, service) {
@@ -5888,57 +6547,57 @@ function registerPartialsTools(server, service) {
5888
6547
  }
5889
6548
 
5890
6549
  // src/tools/prompts.tools.ts
5891
- import { z as z16 } from "zod";
6550
+ import { z as z17 } from "zod";
5892
6551
 
5893
6552
  // src/lib/schemas.ts
5894
- import { z as z15 } from "zod";
5895
- var PromptFunctionSchema = z15.object({
5896
- name: z15.string().describe("Function name"),
5897
- description: z15.string().optional().describe("Function description"),
5898
- parameters: z15.record(z15.string(), z15.unknown()).optional().describe("Function parameters schema")
6553
+ import { z as z16 } from "zod";
6554
+ var PromptFunctionSchema = z16.object({
6555
+ name: z16.string().describe("Function name"),
6556
+ description: z16.string().optional().describe("Function description"),
6557
+ parameters: z16.record(z16.string(), z16.unknown()).optional().describe("Function parameters schema")
5899
6558
  });
5900
- var PromptToolSchema = z15.object({
5901
- type: z15.literal("function").describe("Tool type"),
6559
+ var PromptToolSchema = z16.object({
6560
+ type: z16.literal("function").describe("Tool type"),
5902
6561
  function: PromptFunctionSchema.describe("Function definition")
5903
6562
  });
5904
- var HyperparametersSchema = z15.object({
5905
- max_tokens: z15.coerce.number().positive().optional().describe("Maximum tokens to generate"),
5906
- temperature: z15.coerce.number().min(0).max(2).optional().describe("Sampling temperature (0-2)"),
5907
- top_p: z15.coerce.number().min(0).max(1).optional().describe("Top-p sampling (0-1)"),
5908
- top_k: z15.coerce.number().positive().optional().describe("Top-k sampling"),
5909
- presence_penalty: z15.coerce.number().min(-2).max(2).optional().describe("Presence penalty (-2 to 2)"),
5910
- frequency_penalty: z15.coerce.number().min(-2).max(2).optional().describe("Frequency penalty (-2 to 2)"),
5911
- stop: z15.array(z15.string()).optional().describe("Stop sequences")
6563
+ var HyperparametersSchema = z16.object({
6564
+ max_tokens: z16.coerce.number().positive().optional().describe("Maximum tokens to generate"),
6565
+ temperature: z16.coerce.number().min(0).max(2).optional().describe("Sampling temperature (0-2)"),
6566
+ top_p: z16.coerce.number().min(0).max(1).optional().describe("Top-p sampling (0-1)"),
6567
+ top_k: z16.coerce.number().positive().optional().describe("Top-k sampling"),
6568
+ presence_penalty: z16.coerce.number().min(-2).max(2).optional().describe("Presence penalty (-2 to 2)"),
6569
+ frequency_penalty: z16.coerce.number().min(-2).max(2).optional().describe("Frequency penalty (-2 to 2)"),
6570
+ stop: z16.array(z16.string()).optional().describe("Stop sequences")
5912
6571
  });
5913
- var PromptAppIdentifierSchema = z15.string().min(1).describe(
6572
+ var PromptAppIdentifierSchema = z16.string().min(1).describe(
5914
6573
  "App identifier (REQUIRED). Use your deployed app name, for example 'hourlink' or 'support-console'."
5915
6574
  );
5916
- var PromptEnvironmentIdentifierSchema = z15.string().min(1).describe(
6575
+ var PromptEnvironmentIdentifierSchema = z16.string().min(1).describe(
5917
6576
  "Environment identifier (REQUIRED). Use your environment name, for example 'dev', 'staging', 'prod', or 'qa'."
5918
6577
  );
5919
- var BillingMetadataSchema = z15.object({
5920
- client_id: z15.string().describe("Client ID for billing attribution (REQUIRED)"),
6578
+ var BillingMetadataSchema = z16.object({
6579
+ client_id: z16.string().describe("Client ID for billing attribution (REQUIRED)"),
5921
6580
  app: PromptAppIdentifierSchema,
5922
6581
  env: PromptEnvironmentIdentifierSchema,
5923
- project_id: z15.string().optional().describe("Project ID for granular billing"),
5924
- feature: z15.string().optional().describe("Feature name for tracking")
6582
+ project_id: z16.string().optional().describe("Project ID for granular billing"),
6583
+ feature: z16.string().optional().describe("Feature name for tracking")
5925
6584
  });
5926
- var ToolChoiceSchema = z15.object({
5927
- mode: z15.enum(["auto", "none", "function"]).describe(
6585
+ var ToolChoiceSchema = z16.object({
6586
+ mode: z16.enum(["auto", "none", "function"]).describe(
5928
6587
  "Tool choice mode: auto lets the model decide, none disables tool use, function forces one function by name"
5929
6588
  ),
5930
- function_name: z15.string().optional().describe("Required when mode is 'function'; ignored otherwise")
6589
+ function_name: z16.string().optional().describe("Required when mode is 'function'; ignored otherwise")
5931
6590
  }).superRefine((value, ctx) => {
5932
6591
  if (value.mode === "function" && !value.function_name) {
5933
6592
  ctx.addIssue({
5934
- code: z15.ZodIssueCode.custom,
6593
+ code: z16.ZodIssueCode.custom,
5935
6594
  path: ["function_name"],
5936
6595
  message: "function_name is required when mode is 'function'"
5937
6596
  });
5938
6597
  }
5939
6598
  if (value.mode !== "function" && value.function_name !== void 0) {
5940
6599
  ctx.addIssue({
5941
- code: z15.ZodIssueCode.custom,
6600
+ code: z16.ZodIssueCode.custom,
5942
6601
  path: ["function_name"],
5943
6602
  message: "function_name is only allowed when mode is 'function'"
5944
6603
  });
@@ -5960,98 +6619,98 @@ function toPromptToolChoice(toolChoice) {
5960
6619
  }
5961
6620
 
5962
6621
  // src/tools/prompts.tools.ts
5963
- var PROMPT_VARIABLES_SCHEMA = z16.record(z16.string(), z16.union([z16.string(), z16.coerce.number(), z16.boolean()])).describe("Variable values to substitute into the template");
5964
- var PROMPT_TEMPLATE_CONTENT_BLOCK_SCHEMA = z16.object({
5965
- type: z16.string().describe("Content block type"),
5966
- text: z16.string().optional().describe("Text content for text-based blocks")
6622
+ var PROMPT_VARIABLES_SCHEMA = z17.record(z17.string(), z17.union([z17.string(), z17.coerce.number(), z17.boolean()])).describe("Variable values to substitute into the template");
6623
+ var PROMPT_TEMPLATE_CONTENT_BLOCK_SCHEMA = z17.object({
6624
+ type: z17.string().describe("Content block type"),
6625
+ text: z17.string().optional().describe("Text content for text-based blocks")
5967
6626
  }).passthrough().describe("Content block within a structured chat message");
5968
- var PROMPT_TEMPLATE_MESSAGE_SCHEMA = z16.object({
5969
- role: z16.enum(["system", "user", "assistant"]).describe("Message role in the chat template"),
5970
- content: z16.array(PROMPT_TEMPLATE_CONTENT_BLOCK_SCHEMA).describe("Message content blocks")
6627
+ var PROMPT_TEMPLATE_MESSAGE_SCHEMA = z17.object({
6628
+ role: z17.enum(["system", "user", "assistant"]).describe("Message role in the chat template"),
6629
+ content: z17.array(PROMPT_TEMPLATE_CONTENT_BLOCK_SCHEMA).describe("Message content blocks")
5971
6630
  }).passthrough().describe("Structured chat message in a prompt template");
5972
6631
  var PROMPTS_TOOL_SCHEMAS = {
5973
6632
  createPrompt: {
5974
- name: z16.string().describe("Display name for the prompt"),
5975
- collection_id: z16.string().describe(
6633
+ name: z17.string().describe("Display name for the prompt"),
6634
+ collection_id: z17.string().describe(
5976
6635
  "Collection ID to organize the prompt in (use list_collections to find)"
5977
6636
  ),
5978
- string: z16.string().optional().describe(
6637
+ string: z17.string().optional().describe(
5979
6638
  "Legacy prompt template string. Use plain text for single-message prompts, or a JSON-encoded messages array string for multi-message chat prompts."
5980
6639
  ),
5981
- messages: z16.array(PROMPT_TEMPLATE_MESSAGE_SCHEMA).optional().describe(
6640
+ messages: z17.array(PROMPT_TEMPLATE_MESSAGE_SCHEMA).optional().describe(
5982
6641
  "Structured chat template alias. Serialized to the legacy string format before creation."
5983
6642
  ),
5984
- parameters: z16.record(z16.string(), z16.unknown()).describe("Default values for template variables"),
5985
- virtual_key: z16.string().describe("Virtual key slug for model access"),
5986
- model: z16.string().optional().describe(
6643
+ parameters: z17.record(z17.string(), z17.unknown()).describe("Default values for template variables"),
6644
+ virtual_key: z17.string().describe("Virtual key slug for model access"),
6645
+ model: z17.string().optional().describe(
5987
6646
  "Model identifier (e.g., 'gpt-4', 'claude-3-opus'). Required unless ai_model_id or finetune_id is provided"
5988
6647
  ),
5989
- ai_model_id: z16.string().optional().describe(
6648
+ ai_model_id: z17.string().optional().describe(
5990
6649
  "AI model ID (alternative to model). Required unless model or finetune_id is provided"
5991
6650
  ),
5992
- finetune_id: z16.string().optional().describe(
6651
+ finetune_id: z17.string().optional().describe(
5993
6652
  "Fine-tune ID (alternative to model). Required unless model or ai_model_id is provided"
5994
6653
  ),
5995
- version_description: z16.string().optional().describe("Description for this prompt version"),
5996
- template_metadata: z16.record(z16.string(), z16.unknown()).optional().describe("Custom metadata (app, env, source_file, etc.)"),
5997
- functions: z16.array(PromptFunctionSchema).optional().describe("Function definitions for function calling"),
5998
- tools: z16.array(PromptToolSchema).optional().describe("Tool definitions for tool use"),
6654
+ version_description: z17.string().optional().describe("Description for this prompt version"),
6655
+ template_metadata: z17.record(z17.string(), z17.unknown()).optional().describe("Custom metadata (app, env, source_file, etc.)"),
6656
+ functions: z17.array(PromptFunctionSchema).optional().describe("Function definitions for function calling"),
6657
+ tools: z17.array(PromptToolSchema).optional().describe("Tool definitions for tool use"),
5999
6658
  tool_choice: ToolChoiceSchema.optional().describe("Tool choice strategy"),
6000
- dry_run: z16.boolean().optional().describe("When true, validate without creating")
6659
+ dry_run: z17.boolean().optional().describe("When true, validate without creating")
6001
6660
  },
6002
6661
  listPrompts: {
6003
- collection_id: z16.string().optional().describe(
6662
+ collection_id: z17.string().optional().describe(
6004
6663
  "Filter by collection ID (recommended for app-specific prompts)"
6005
6664
  ),
6006
- workspace_id: z16.string().optional().describe("Filter by workspace ID"),
6007
- search: z16.string().optional().describe("Search prompts by name"),
6008
- current_page: z16.coerce.number().int().positive().optional().describe("Page number for pagination"),
6009
- page_size: z16.coerce.number().int().positive().max(100).optional().describe("Results per page (max 100)")
6665
+ workspace_id: z17.string().optional().describe("Filter by workspace ID"),
6666
+ search: z17.string().optional().describe("Search prompts by name"),
6667
+ current_page: z17.coerce.number().int().positive().optional().describe("Page number for pagination"),
6668
+ page_size: z17.coerce.number().int().positive().max(100).optional().describe("Results per page (max 100)")
6010
6669
  },
6011
6670
  getPrompt: {
6012
- prompt_id: z16.string().describe("Prompt ID or slug to retrieve")
6671
+ prompt_id: z17.string().describe("Prompt ID or slug to retrieve")
6013
6672
  },
6014
6673
  updatePrompt: {
6015
- prompt_id: z16.string().describe("Prompt ID or slug to update"),
6016
- name: z16.string().optional().describe("New display name for the prompt"),
6017
- collection_id: z16.string().optional().describe("Move to a different collection"),
6018
- string: z16.string().optional().describe(
6674
+ prompt_id: z17.string().describe("Prompt ID or slug to update"),
6675
+ name: z17.string().optional().describe("New display name for the prompt"),
6676
+ collection_id: z17.string().optional().describe("Move to a different collection"),
6677
+ string: z17.string().optional().describe(
6019
6678
  "Legacy prompt template string. Use plain text for single-message prompts, or a JSON-encoded messages array string for multi-message chat prompts."
6020
6679
  ),
6021
- messages: z16.array(PROMPT_TEMPLATE_MESSAGE_SCHEMA).optional().describe(
6680
+ messages: z17.array(PROMPT_TEMPLATE_MESSAGE_SCHEMA).optional().describe(
6022
6681
  "Structured chat template alias for updates. Serialized to the legacy string format before the prompt is updated."
6023
6682
  ),
6024
- parameters: z16.record(z16.string(), z16.unknown()).optional().describe("New default values for template variables"),
6025
- model: z16.string().optional().describe("New model identifier"),
6026
- virtual_key: z16.string().optional().describe("New virtual key slug"),
6027
- version_description: z16.string().optional().describe("Description for this version"),
6028
- template_metadata: z16.record(z16.string(), z16.unknown()).optional().describe("New metadata"),
6029
- functions: z16.array(PromptFunctionSchema).optional().describe("New function definitions"),
6030
- tools: z16.array(PromptToolSchema).optional().describe("New tool definitions"),
6683
+ parameters: z17.record(z17.string(), z17.unknown()).optional().describe("New default values for template variables"),
6684
+ model: z17.string().optional().describe("New model identifier"),
6685
+ virtual_key: z17.string().optional().describe("New virtual key slug"),
6686
+ version_description: z17.string().optional().describe("Description for this version"),
6687
+ template_metadata: z17.record(z17.string(), z17.unknown()).optional().describe("New metadata"),
6688
+ functions: z17.array(PromptFunctionSchema).optional().describe("New function definitions"),
6689
+ tools: z17.array(PromptToolSchema).optional().describe("New tool definitions"),
6031
6690
  tool_choice: ToolChoiceSchema.optional().describe(
6032
6691
  "New tool choice strategy"
6033
6692
  ),
6034
- dry_run: z16.boolean().optional().describe("When true, validate without updating")
6693
+ dry_run: z17.boolean().optional().describe("When true, validate without updating")
6035
6694
  },
6036
6695
  deletePrompt: {
6037
- prompt_id: z16.string().describe("Prompt ID or slug to delete")
6696
+ prompt_id: z17.string().describe("Prompt ID or slug to delete")
6038
6697
  },
6039
6698
  publishPrompt: {
6040
- prompt_id: z16.string().describe("Prompt ID or slug to publish"),
6041
- version: z16.coerce.number().positive().describe("Version number to publish as the default")
6699
+ prompt_id: z17.string().describe("Prompt ID or slug to publish"),
6700
+ version: z17.coerce.number().positive().describe("Version number to publish as the default")
6042
6701
  },
6043
6702
  listPromptVersions: {
6044
- prompt_id: z16.string().describe("Prompt ID or slug to list versions for")
6703
+ prompt_id: z17.string().describe("Prompt ID or slug to list versions for")
6045
6704
  },
6046
6705
  renderPrompt: {
6047
- prompt_id: z16.string().describe("Prompt ID or slug to render"),
6706
+ prompt_id: z17.string().describe("Prompt ID or slug to render"),
6048
6707
  variables: PROMPT_VARIABLES_SCHEMA,
6049
6708
  hyperparameters: HyperparametersSchema.optional().describe(
6050
6709
  "Override default hyperparameters"
6051
6710
  )
6052
6711
  },
6053
6712
  runPromptCompletion: {
6054
- prompt_id: z16.string().describe("Prompt ID or slug to execute"),
6713
+ prompt_id: z17.string().describe("Prompt ID or slug to execute"),
6055
6714
  variables: PROMPT_VARIABLES_SCHEMA,
6056
6715
  metadata: BillingMetadataSchema.describe(
6057
6716
  "Billing metadata - client_id, app, env are REQUIRED for cost attribution"
@@ -6061,54 +6720,54 @@ var PROMPTS_TOOL_SCHEMAS = {
6061
6720
  )
6062
6721
  },
6063
6722
  migratePrompt: {
6064
- name: z16.string().describe("Prompt name to create or find for update"),
6723
+ name: z17.string().describe("Prompt name to create or find for update"),
6065
6724
  app: PromptAppIdentifierSchema,
6066
6725
  env: PromptEnvironmentIdentifierSchema,
6067
- collection_id: z16.string().describe("Collection ID to search in and create under"),
6068
- string: z16.string().optional().describe(
6726
+ collection_id: z17.string().describe("Collection ID to search in and create under"),
6727
+ string: z17.string().optional().describe(
6069
6728
  "Legacy prompt template string with {{variable}} mustache syntax."
6070
6729
  ),
6071
- messages: z16.array(PROMPT_TEMPLATE_MESSAGE_SCHEMA).optional().describe(
6730
+ messages: z17.array(PROMPT_TEMPLATE_MESSAGE_SCHEMA).optional().describe(
6072
6731
  "Structured chat template alias for migrations. Serialized to the legacy string format before the prompt is created or updated."
6073
6732
  ),
6074
- parameters: z16.record(z16.string(), z16.unknown()).describe("Default values for template variables"),
6075
- virtual_key: z16.string().describe("Virtual key slug for model access"),
6076
- model: z16.string().optional().describe("Model identifier"),
6077
- version_description: z16.string().optional().describe("Description for this version"),
6078
- template_metadata: z16.record(z16.string(), z16.unknown()).optional().describe("Additional custom metadata"),
6079
- functions: z16.array(PromptFunctionSchema).optional().describe("Function definitions"),
6080
- tools: z16.array(PromptToolSchema).optional().describe("Tool definitions"),
6733
+ parameters: z17.record(z17.string(), z17.unknown()).describe("Default values for template variables"),
6734
+ virtual_key: z17.string().describe("Virtual key slug for model access"),
6735
+ model: z17.string().optional().describe("Model identifier"),
6736
+ version_description: z17.string().optional().describe("Description for this version"),
6737
+ template_metadata: z17.record(z17.string(), z17.unknown()).optional().describe("Additional custom metadata"),
6738
+ functions: z17.array(PromptFunctionSchema).optional().describe("Function definitions"),
6739
+ tools: z17.array(PromptToolSchema).optional().describe("Tool definitions"),
6081
6740
  tool_choice: ToolChoiceSchema.optional().describe("Tool choice strategy"),
6082
- dry_run: z16.boolean().optional().describe(
6741
+ dry_run: z17.boolean().optional().describe(
6083
6742
  "When true, only check what action would be taken without making changes"
6084
6743
  )
6085
6744
  },
6086
6745
  promotePrompt: {
6087
- source_prompt_id: z16.string().describe("Source prompt ID or slug (e.g., staging prompt)"),
6088
- target_collection_id: z16.string().describe("Target collection ID for the promoted prompt"),
6089
- target_name: z16.string().optional().describe(
6746
+ source_prompt_id: z17.string().describe("Source prompt ID or slug (e.g., staging prompt)"),
6747
+ target_collection_id: z17.string().describe("Target collection ID for the promoted prompt"),
6748
+ target_name: z17.string().optional().describe(
6090
6749
  "Target prompt name (defaults to source name with env suffix replaced)"
6091
6750
  ),
6092
6751
  target_env: PromptEnvironmentIdentifierSchema,
6093
- virtual_key: z16.string().optional().describe(
6752
+ virtual_key: z17.string().optional().describe(
6094
6753
  "Virtual key ID to use (defaults to source prompt's virtual_key)"
6095
6754
  )
6096
6755
  },
6097
6756
  validateCompletionMetadata: {
6098
- client_id: z16.string().optional().describe("Client ID for billing attribution"),
6757
+ client_id: z17.string().optional().describe("Client ID for billing attribution"),
6099
6758
  app: PromptAppIdentifierSchema.optional(),
6100
6759
  env: PromptEnvironmentIdentifierSchema.optional(),
6101
- project_id: z16.string().optional().describe("Project ID for granular billing"),
6102
- feature: z16.string().optional().describe("Feature name for tracking")
6760
+ project_id: z17.string().optional().describe("Project ID for granular billing"),
6761
+ feature: z17.string().optional().describe("Feature name for tracking")
6103
6762
  },
6104
6763
  getPromptVersion: {
6105
- prompt_id: z16.string().describe("Prompt ID or slug"),
6106
- version_id: z16.string().describe("Version UUID to retrieve")
6764
+ prompt_id: z17.string().describe("Prompt ID or slug"),
6765
+ version_id: z17.string().describe("Version UUID to retrieve")
6107
6766
  },
6108
6767
  updatePromptVersion: {
6109
- prompt_id: z16.string().describe("Prompt ID or slug"),
6110
- version_id: z16.string().describe("Version UUID to update"),
6111
- label_id: z16.string().nullable().describe(
6768
+ prompt_id: z17.string().describe("Prompt ID or slug"),
6769
+ version_id: z17.string().describe("Version UUID to update"),
6770
+ label_id: z17.string().nullable().describe(
6112
6771
  "Label ID to assign to this version, or null to remove the label"
6113
6772
  )
6114
6773
  }
@@ -6698,68 +7357,68 @@ function registerPromptsTools(server, service) {
6698
7357
  }
6699
7358
 
6700
7359
  // src/tools/providers.tools.ts
6701
- import { z as z17 } from "zod";
7360
+ import { z as z18 } from "zod";
6702
7361
  var PROVIDERS_TOOL_SCHEMAS = {
6703
7362
  listProviders: {
6704
- current_page: z17.coerce.number().int().positive().optional().describe("Page number for pagination"),
6705
- page_size: z17.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100, default 50)"),
6706
- workspace_id: z17.string().optional().describe(
7363
+ current_page: z18.coerce.number().int().positive().optional().describe("Page number for pagination"),
7364
+ page_size: z18.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100, default 50)"),
7365
+ workspace_id: z18.string().optional().describe(
6707
7366
  "Workspace ID - required when using organization admin keys, optional with workspace API keys"
6708
7367
  )
6709
7368
  },
6710
7369
  createProvider: {
6711
- name: z17.string().describe("Display name for the provider"),
6712
- integration_id: z17.string().describe(
7370
+ name: z18.string().describe("Display name for the provider"),
7371
+ integration_id: z18.string().describe(
6713
7372
  "Integration slug for the provider (e.g., 'openai', 'anthropic', 'azure-openai')"
6714
7373
  ),
6715
- workspace_id: z17.string().optional().describe(
7374
+ workspace_id: z18.string().optional().describe(
6716
7375
  "Workspace ID - required when using organization admin API keys"
6717
7376
  ),
6718
- slug: z17.string().optional().describe(
7377
+ slug: z18.string().optional().describe(
6719
7378
  "Custom slug for the provider. Auto-generated with random suffix if omitted"
6720
7379
  ),
6721
- note: z17.string().optional().describe("Optional note or description for the provider"),
6722
- credit_limit: z17.coerce.number().positive().optional().describe("Credit limit for usage"),
6723
- alert_threshold: z17.coerce.number().min(0).max(100).optional().describe("Alert threshold percentage (0-100)"),
6724
- usage_limit_type: z17.enum(["cost", "tokens"]).optional().describe(
7380
+ note: z18.string().optional().describe("Optional note or description for the provider"),
7381
+ credit_limit: z18.coerce.number().positive().optional().describe("Credit limit for usage"),
7382
+ alert_threshold: z18.coerce.number().min(0).max(100).optional().describe("Alert threshold percentage (0-100)"),
7383
+ usage_limit_type: z18.enum(["cost", "tokens"]).optional().describe(
6725
7384
  "Type of usage limit: 'cost' (monetary) or 'tokens' (token count). Defaults to 'cost'."
6726
7385
  ),
6727
- periodic_reset: z17.enum(["monthly", "weekly"]).optional().describe(
7386
+ periodic_reset: z18.enum(["monthly", "weekly"]).optional().describe(
6728
7387
  "Period for resetting usage limits: 'monthly' or 'weekly'. Defaults to 'monthly'."
6729
7388
  ),
6730
- rate_limit_value: z17.coerce.number().positive().optional().describe("Must be provided together with rate_limit_unit."),
6731
- rate_limit_unit: z17.enum(["rpm", "rph", "rpd"]).optional().describe(
7389
+ rate_limit_value: z18.coerce.number().positive().optional().describe("Must be provided together with rate_limit_unit."),
7390
+ rate_limit_unit: z18.enum(["rpm", "rph", "rpd"]).optional().describe(
6732
7391
  "Must be provided together with rate_limit_value. Values: 'rpm' (requests/min), 'rph' (requests/hour), or 'rpd' (requests/day)."
6733
7392
  ),
6734
- expires_at: z17.string().optional().describe("Expiration date in ISO 8601 format")
7393
+ expires_at: z18.string().optional().describe("Expiration date in ISO 8601 format")
6735
7394
  },
6736
7395
  getProvider: {
6737
- slug: z17.string().describe("The unique slug identifier of the provider to retrieve"),
6738
- workspace_id: z17.string().optional().describe("Workspace ID - required when using organization admin keys")
7396
+ slug: z18.string().describe("The unique slug identifier of the provider to retrieve"),
7397
+ workspace_id: z18.string().optional().describe("Workspace ID - required when using organization admin keys")
6739
7398
  },
6740
7399
  updateProvider: {
6741
- slug: z17.string().describe("The slug of the provider to update"),
6742
- workspace_id: z17.string().optional().describe("Workspace ID - required when using organization admin keys"),
6743
- name: z17.string().optional().describe("New display name for the provider"),
6744
- note: z17.string().optional().describe("New note or description for the provider"),
6745
- credit_limit: z17.coerce.number().positive().optional().describe("New credit limit for usage"),
6746
- alert_threshold: z17.coerce.number().min(0).max(100).optional().describe("New alert threshold percentage (0-100)"),
6747
- usage_limit_type: z17.enum(["cost", "tokens"]).optional().describe(
7400
+ slug: z18.string().describe("The slug of the provider to update"),
7401
+ workspace_id: z18.string().optional().describe("Workspace ID - required when using organization admin keys"),
7402
+ name: z18.string().optional().describe("New display name for the provider"),
7403
+ note: z18.string().optional().describe("New note or description for the provider"),
7404
+ credit_limit: z18.coerce.number().positive().optional().describe("New credit limit for usage"),
7405
+ alert_threshold: z18.coerce.number().min(0).max(100).optional().describe("New alert threshold percentage (0-100)"),
7406
+ usage_limit_type: z18.enum(["cost", "tokens"]).optional().describe(
6748
7407
  "Type of usage limit: 'cost' (monetary) or 'tokens' (token count). Defaults to 'cost'."
6749
7408
  ),
6750
- periodic_reset: z17.enum(["monthly", "weekly"]).optional().describe(
7409
+ periodic_reset: z18.enum(["monthly", "weekly"]).optional().describe(
6751
7410
  "Period for resetting usage limits: 'monthly' or 'weekly'. Defaults to 'monthly'."
6752
7411
  ),
6753
- rate_limit_value: z17.coerce.number().positive().optional().describe("New rate limit value"),
6754
- rate_limit_unit: z17.enum(["rpm", "rph", "rpd"]).optional().describe(
7412
+ rate_limit_value: z18.coerce.number().positive().optional().describe("New rate limit value"),
7413
+ rate_limit_unit: z18.enum(["rpm", "rph", "rpd"]).optional().describe(
6755
7414
  "Rate limit unit: 'rpm' (requests per minute), 'rph' (requests per hour), or 'rpd' (requests per day)"
6756
7415
  ),
6757
- expires_at: z17.string().optional().describe("New expiration date in ISO 8601 format"),
6758
- reset_usage: z17.boolean().optional().describe("Set to true to reset accumulated usage metrics")
7416
+ expires_at: z18.string().optional().describe("New expiration date in ISO 8601 format"),
7417
+ reset_usage: z18.boolean().optional().describe("Set to true to reset accumulated usage metrics")
6759
7418
  },
6760
7419
  deleteProvider: {
6761
- slug: z17.string().describe("The slug of the provider to delete"),
6762
- workspace_id: z17.string().optional().describe("Workspace ID - required when using organization admin keys")
7420
+ slug: z18.string().describe("The slug of the provider to delete"),
7421
+ workspace_id: z18.string().optional().describe("Workspace ID - required when using organization admin keys")
6763
7422
  }
6764
7423
  };
6765
7424
  function registerProvidersTools(server, service) {
@@ -6941,73 +7600,73 @@ function registerProvidersTools(server, service) {
6941
7600
  }
6942
7601
 
6943
7602
  // src/tools/secret-references.tools.ts
6944
- import { z as z18 } from "zod";
7603
+ import { z as z19 } from "zod";
6945
7604
  var authFields = {
6946
- aws_auth_type: z18.enum(["accessKey", "assumedRole", "serviceRole"]).describe(
7605
+ aws_auth_type: z19.enum(["accessKey", "assumedRole", "serviceRole"]).describe(
6947
7606
  "AWS authentication mode: accessKey uses a key pair, assumedRole uses an IAM role, and serviceRole uses the runtime workload identity"
6948
7607
  ),
6949
- aws_access_key_id: z18.string().min(1).describe("AWS access key ID; required when aws_auth_type is accessKey"),
6950
- aws_secret_access_key: z18.string().min(1).describe(
7608
+ aws_access_key_id: z19.string().min(1).describe("AWS access key ID; required when aws_auth_type is accessKey"),
7609
+ aws_secret_access_key: z19.string().min(1).describe(
6951
7610
  "AWS secret access key; required when aws_auth_type is accessKey and exposed to the MCP transcript"
6952
7611
  ),
6953
- aws_region: z18.string().min(1).describe("AWS region containing the secret, for example us-east-1"),
6954
- aws_role_arn: z18.string().min(1).describe(
7612
+ aws_region: z19.string().min(1).describe("AWS region containing the secret, for example us-east-1"),
7613
+ aws_role_arn: z19.string().min(1).describe(
6955
7614
  "IAM role ARN to assume; required when aws_auth_type is assumedRole"
6956
7615
  ),
6957
- aws_external_id: z18.string().nullable().describe("Optional external ID required by the target IAM role"),
6958
- azure_auth_mode: z18.enum(["entra", "managed", "default"]).describe(
7616
+ aws_external_id: z19.string().nullable().describe("Optional external ID required by the target IAM role"),
7617
+ azure_auth_mode: z19.enum(["entra", "managed", "default"]).describe(
6959
7618
  "Azure authentication mode: entra uses a client secret, managed uses managed identity, and default uses the runtime credential chain"
6960
7619
  ),
6961
- azure_entra_tenant_id: z18.string().min(1).describe("Microsoft Entra tenant ID; required for entra authentication"),
6962
- azure_entra_client_id: z18.string().min(1).describe(
7620
+ azure_entra_tenant_id: z19.string().min(1).describe("Microsoft Entra tenant ID; required for entra authentication"),
7621
+ azure_entra_client_id: z19.string().min(1).describe(
6963
7622
  "Microsoft Entra application client ID; required for entra authentication"
6964
7623
  ),
6965
- azure_entra_client_secret: z18.string().min(1).describe(
7624
+ azure_entra_client_secret: z19.string().min(1).describe(
6966
7625
  "Microsoft Entra client secret; required for entra authentication and exposed to the MCP transcript"
6967
7626
  ),
6968
- azure_managed_client_id: z18.string().min(1).describe(
7627
+ azure_managed_client_id: z19.string().min(1).describe(
6969
7628
  "Optional client ID of a user-assigned managed identity; omit for the system-assigned identity"
6970
7629
  ),
6971
- azure_vault_url: z18.url().describe(
7630
+ azure_vault_url: z19.url().describe(
6972
7631
  "Azure Key Vault URL, for example https://example.vault.azure.net"
6973
7632
  ),
6974
- vault_auth_type: z18.enum(["token", "approle", "kubernetes"]).describe(
7633
+ vault_auth_type: z19.enum(["token", "approle", "kubernetes"]).describe(
6975
7634
  "HashiCorp Vault authentication mode: token, AppRole, or Kubernetes"
6976
7635
  ),
6977
- vault_addr: z18.url().describe("Base URL of the HashiCorp Vault server"),
6978
- vault_token: z18.string().min(1).describe(
7636
+ vault_addr: z19.url().describe("Base URL of the HashiCorp Vault server"),
7637
+ vault_token: z19.string().min(1).describe(
6979
7638
  "HashiCorp Vault token; required for token authentication and exposed to the MCP transcript"
6980
7639
  ),
6981
- vault_namespace: z18.string().min(1).describe("Optional HashiCorp Vault Enterprise namespace"),
6982
- vault_role_id: z18.string().min(1).describe(
7640
+ vault_namespace: z19.string().min(1).describe("Optional HashiCorp Vault Enterprise namespace"),
7641
+ vault_role_id: z19.string().min(1).describe(
6983
7642
  "HashiCorp Vault AppRole role ID; required for approle authentication"
6984
7643
  ),
6985
- vault_secret_id: z18.string().min(1).describe(
7644
+ vault_secret_id: z19.string().min(1).describe(
6986
7645
  "HashiCorp Vault AppRole secret ID; required for approle authentication and exposed to the MCP transcript"
6987
7646
  ),
6988
- vault_role: z18.string().min(1).describe("HashiCorp Vault Kubernetes auth role name")
7647
+ vault_role: z19.string().min(1).describe("HashiCorp Vault Kubernetes auth role name")
6989
7648
  };
6990
- var authConfigSchema = z18.union([
6991
- z18.object({
6992
- aws_auth_type: z18.literal("accessKey").describe("Use an AWS access key ID and secret access key"),
7649
+ var authConfigSchema = z19.union([
7650
+ z19.object({
7651
+ aws_auth_type: z19.literal("accessKey").describe("Use an AWS access key ID and secret access key"),
6993
7652
  aws_access_key_id: authFields.aws_access_key_id,
6994
7653
  aws_secret_access_key: authFields.aws_secret_access_key,
6995
7654
  aws_region: authFields.aws_region
6996
7655
  }).strict(),
6997
- z18.object({
6998
- aws_auth_type: z18.literal("assumedRole").describe("Assume the specified AWS IAM role"),
7656
+ z19.object({
7657
+ aws_auth_type: z19.literal("assumedRole").describe("Assume the specified AWS IAM role"),
6999
7658
  aws_role_arn: authFields.aws_role_arn,
7000
7659
  aws_external_id: authFields.aws_external_id.optional(),
7001
7660
  aws_region: authFields.aws_region
7002
7661
  }).strict(),
7003
- z18.object({
7004
- aws_auth_type: z18.literal("serviceRole").describe("Use the AWS workload or service role available at runtime"),
7005
- aws_region: z18.string().optional().describe(
7662
+ z19.object({
7663
+ aws_auth_type: z19.literal("serviceRole").describe("Use the AWS workload or service role available at runtime"),
7664
+ aws_region: z19.string().optional().describe(
7006
7665
  "Optional AWS region containing the secret, for example us-east-1"
7007
7666
  )
7008
7667
  }).strict(),
7009
- z18.object({
7010
- azure_auth_mode: z18.literal("entra").describe(
7668
+ z19.object({
7669
+ azure_auth_mode: z19.literal("entra").describe(
7011
7670
  "Authenticate with a Microsoft Entra application client secret"
7012
7671
  ),
7013
7672
  azure_entra_tenant_id: authFields.azure_entra_tenant_id,
@@ -7015,30 +7674,30 @@ var authConfigSchema = z18.union([
7015
7674
  azure_entra_client_secret: authFields.azure_entra_client_secret,
7016
7675
  azure_vault_url: authFields.azure_vault_url
7017
7676
  }).strict(),
7018
- z18.object({
7019
- azure_auth_mode: z18.literal("managed").describe("Authenticate with an Azure managed identity"),
7677
+ z19.object({
7678
+ azure_auth_mode: z19.literal("managed").describe("Authenticate with an Azure managed identity"),
7020
7679
  azure_managed_client_id: authFields.azure_managed_client_id.optional(),
7021
7680
  azure_vault_url: authFields.azure_vault_url
7022
7681
  }).strict(),
7023
- z18.object({
7024
- azure_auth_mode: z18.literal("default").describe("Use Azure's default runtime credential chain"),
7682
+ z19.object({
7683
+ azure_auth_mode: z19.literal("default").describe("Use Azure's default runtime credential chain"),
7025
7684
  azure_vault_url: authFields.azure_vault_url
7026
7685
  }).strict(),
7027
- z18.object({
7028
- vault_auth_type: z18.literal("token").describe("Authenticate to HashiCorp Vault with a token"),
7686
+ z19.object({
7687
+ vault_auth_type: z19.literal("token").describe("Authenticate to HashiCorp Vault with a token"),
7029
7688
  vault_addr: authFields.vault_addr,
7030
7689
  vault_token: authFields.vault_token,
7031
7690
  vault_namespace: authFields.vault_namespace.optional()
7032
7691
  }).strict(),
7033
- z18.object({
7034
- vault_auth_type: z18.literal("approle").describe("Authenticate to HashiCorp Vault with AppRole credentials"),
7692
+ z19.object({
7693
+ vault_auth_type: z19.literal("approle").describe("Authenticate to HashiCorp Vault with AppRole credentials"),
7035
7694
  vault_addr: authFields.vault_addr,
7036
7695
  vault_role_id: authFields.vault_role_id,
7037
7696
  vault_secret_id: authFields.vault_secret_id,
7038
7697
  vault_namespace: authFields.vault_namespace.optional()
7039
7698
  }).strict(),
7040
- z18.object({
7041
- vault_auth_type: z18.literal("kubernetes").describe(
7699
+ z19.object({
7700
+ vault_auth_type: z19.literal("kubernetes").describe(
7042
7701
  "Authenticate to HashiCorp Vault with a Kubernetes service account"
7043
7702
  ),
7044
7703
  vault_addr: authFields.vault_addr,
@@ -7046,61 +7705,61 @@ var authConfigSchema = z18.union([
7046
7705
  vault_namespace: authFields.vault_namespace.optional()
7047
7706
  }).strict()
7048
7707
  ]);
7049
- var updateAuthConfigSchema = z18.union([
7050
- z18.object({
7708
+ var updateAuthConfigSchema = z19.union([
7709
+ z19.object({
7051
7710
  aws_auth_type: authFields.aws_auth_type.optional(),
7052
7711
  aws_access_key_id: authFields.aws_access_key_id.optional(),
7053
7712
  aws_secret_access_key: authFields.aws_secret_access_key.optional(),
7054
- aws_region: z18.string().optional().describe("AWS region containing the secret, for example us-east-1"),
7713
+ aws_region: z19.string().optional().describe("AWS region containing the secret, for example us-east-1"),
7055
7714
  aws_role_arn: authFields.aws_role_arn.optional(),
7056
7715
  aws_external_id: authFields.aws_external_id.optional()
7057
7716
  }).strict(),
7058
- z18.object({
7717
+ z19.object({
7059
7718
  azure_auth_mode: authFields.azure_auth_mode.optional(),
7060
7719
  azure_entra_tenant_id: authFields.azure_entra_tenant_id.optional(),
7061
7720
  azure_entra_client_id: authFields.azure_entra_client_id.optional(),
7062
7721
  azure_entra_client_secret: authFields.azure_entra_client_secret.optional(),
7063
- azure_managed_client_id: z18.string().optional().describe(
7722
+ azure_managed_client_id: z19.string().optional().describe(
7064
7723
  "Optional client ID of a user-assigned managed identity; omit for the system-assigned identity"
7065
7724
  ),
7066
7725
  azure_vault_url: authFields.azure_vault_url.optional()
7067
7726
  }).strict(),
7068
- z18.object({
7727
+ z19.object({
7069
7728
  vault_auth_type: authFields.vault_auth_type.optional(),
7070
7729
  vault_addr: authFields.vault_addr.optional(),
7071
7730
  vault_token: authFields.vault_token.optional(),
7072
- vault_namespace: z18.string().optional().describe("Optional HashiCorp Vault Enterprise namespace"),
7731
+ vault_namespace: z19.string().optional().describe("Optional HashiCorp Vault Enterprise namespace"),
7073
7732
  vault_role_id: authFields.vault_role_id.optional(),
7074
7733
  vault_secret_id: authFields.vault_secret_id.optional(),
7075
7734
  vault_role: authFields.vault_role.optional()
7076
7735
  }).strict()
7077
7736
  ]);
7078
- var managerTypeSchema = z18.enum(["aws_sm", "azure_kv", "hashicorp_vault"]).describe(
7737
+ var managerTypeSchema = z19.enum(["aws_sm", "azure_kv", "hashicorp_vault"]).describe(
7079
7738
  "External secret manager: aws_sm for AWS Secrets Manager, azure_kv for Azure Key Vault, or hashicorp_vault for HashiCorp Vault; must match the auth_config field family"
7080
7739
  );
7081
- var tagsSchema = z18.record(z18.string(), z18.string()).describe("Tag filters or metadata as string key-value pairs");
7740
+ var tagsSchema = z19.record(z19.string(), z19.string()).describe("Tag filters or metadata as string key-value pairs");
7082
7741
  var SECRET_REFERENCE_TOOL_SCHEMAS = {
7083
7742
  create: {
7084
- name: z18.string().min(1).max(255).describe("Human-readable name"),
7743
+ name: z19.string().min(1).max(255).describe("Human-readable name"),
7085
7744
  manager_type: managerTypeSchema,
7086
7745
  auth_config: authConfigSchema.describe(
7087
7746
  "Choose exactly one documented authentication shape matching manager_type. Credentials are sent to Portkey and visible in the MCP transcript; prefer workload identity or short-lived credentials when available."
7088
7747
  ),
7089
- secret_path: z18.string().max(1024).describe("Path of the secret in the external secret manager"),
7090
- organisation_id: z18.string().uuid().optional().describe(
7748
+ secret_path: z19.string().max(1024).describe("Path of the secret in the external secret manager"),
7749
+ organisation_id: z19.string().uuid().optional().describe(
7091
7750
  "Organisation UUID; required when the MCP server is not authenticated with a Portkey API key"
7092
7751
  ),
7093
- slug: z18.string().max(255).regex(/^[a-zA-Z0-9_-]+$/).optional().describe(
7752
+ slug: z19.string().max(255).regex(/^[a-zA-Z0-9_-]+$/).optional().describe(
7094
7753
  "Optional stable slug containing only letters, numbers, underscores, or hyphens; Portkey generates one when omitted"
7095
7754
  ),
7096
- description: z18.string().max(1024).nullable().optional().describe("Optional description; use null to leave it empty"),
7097
- secret_key: z18.string().max(255).nullable().optional().describe(
7755
+ description: z19.string().max(1024).nullable().optional().describe("Optional description; use null to leave it empty"),
7756
+ secret_key: z19.string().max(255).nullable().optional().describe(
7098
7757
  "Optional key within a structured external secret; null uses the whole secret value"
7099
7758
  ),
7100
- allow_all_workspaces: z18.boolean().optional().describe(
7759
+ allow_all_workspaces: z19.boolean().optional().describe(
7101
7760
  "Whether every workspace may use this reference; defaults to true and cannot be true with allowed_workspaces"
7102
7761
  ),
7103
- allowed_workspaces: z18.array(z18.string()).min(1).optional().describe(
7762
+ allowed_workspaces: z19.array(z19.string()).min(1).optional().describe(
7104
7763
  "Workspace UUIDs or slugs allowed to use this reference; omit when allow_all_workspaces is true"
7105
7764
  ),
7106
7765
  tags: tagsSchema.nullable().optional().describe(
@@ -7112,34 +7771,34 @@ var SECRET_REFERENCE_TOOL_SCHEMAS = {
7112
7771
  "Filter by external secret manager: aws_sm, azure_kv, or hashicorp_vault"
7113
7772
  ),
7114
7773
  tags: tagsSchema.optional().describe("Return references matching these tags"),
7115
- search: z18.string().min(1).max(255).optional().describe("Search references by name"),
7116
- current_page: z18.coerce.number().int().nonnegative().optional().describe("Zero-based page number; defaults to 0"),
7117
- page_size: z18.coerce.number().int().min(1).max(100).optional().describe("References per page, from 1 to 100; defaults to 20")
7774
+ search: z19.string().min(1).max(255).optional().describe("Search references by name"),
7775
+ current_page: z19.coerce.number().int().nonnegative().optional().describe("Zero-based page number; defaults to 0"),
7776
+ page_size: z19.coerce.number().int().min(1).max(100).optional().describe("References per page, from 1 to 100; defaults to 20")
7118
7777
  },
7119
7778
  get: {
7120
- id: z18.string().min(1).describe("Secret Reference UUID or slug")
7779
+ id: z19.string().min(1).describe("Secret Reference UUID or slug")
7121
7780
  },
7122
7781
  update: {
7123
- id: z18.string().min(1).describe("Secret Reference UUID or slug"),
7124
- name: z18.string().min(1).max(255).optional().describe("New human-readable name"),
7125
- description: z18.string().max(1024).nullable().optional().describe("New description, or null to clear it"),
7782
+ id: z19.string().min(1).describe("Secret Reference UUID or slug"),
7783
+ name: z19.string().min(1).max(255).optional().describe("New human-readable name"),
7784
+ description: z19.string().max(1024).nullable().optional().describe("New description, or null to clear it"),
7126
7785
  auth_config: updateAuthConfigSchema.optional().describe(
7127
7786
  "Provide at least one changed authentication field to merge into the existing configuration; choose one AWS, Azure, or HashiCorp field family and do not mix families"
7128
7787
  ),
7129
- secret_path: z18.string().max(1024).optional().describe("New path of the secret in the external secret manager"),
7130
- secret_key: z18.string().max(255).nullable().optional().describe(
7788
+ secret_path: z19.string().max(1024).optional().describe("New path of the secret in the external secret manager"),
7789
+ secret_key: z19.string().max(255).nullable().optional().describe(
7131
7790
  "New key within a structured secret, or null to use the whole value"
7132
7791
  ),
7133
- allow_all_workspaces: z18.boolean().optional().describe(
7792
+ allow_all_workspaces: z19.boolean().optional().describe(
7134
7793
  "Whether every workspace may use this reference; cannot be true with allowed_workspaces"
7135
7794
  ),
7136
- allowed_workspaces: z18.array(z18.string()).min(1).optional().describe(
7795
+ allowed_workspaces: z19.array(z19.string()).min(1).optional().describe(
7137
7796
  "Replacement list of workspace UUIDs or slugs allowed to use this reference; supplying it sets allow_all_workspaces=false"
7138
7797
  ),
7139
7798
  tags: tagsSchema.nullable().optional().describe("Replacement string key-value tags, or null to clear them")
7140
7799
  },
7141
7800
  delete: {
7142
- id: z18.string().min(1).describe("Secret Reference UUID or slug")
7801
+ id: z19.string().min(1).describe("Secret Reference UUID or slug")
7143
7802
  }
7144
7803
  };
7145
7804
  function validateWorkspaceAccess(value) {
@@ -7338,29 +7997,29 @@ function registerSecretReferencesTools(server, service) {
7338
7997
  }
7339
7998
 
7340
7999
  // src/tools/tracing.tools.ts
7341
- import { z as z19 } from "zod";
8000
+ import { z as z20 } from "zod";
7342
8001
  var TRACING_TOOL_SCHEMAS = {
7343
8002
  createFeedback: {
7344
- trace_id: z19.string().describe(
8003
+ trace_id: z20.string().describe(
7345
8004
  "The trace ID to associate the feedback with. This links feedback to a specific request/generation."
7346
8005
  ),
7347
- value: z19.coerce.number().describe(
8006
+ value: z20.coerce.number().describe(
7348
8007
  "Feedback value/rating. Common patterns: 1 for positive (thumbs up), 0 for negative (thumbs down), or use a scale like 1-5."
7349
8008
  ),
7350
- weight: z19.coerce.number().positive().optional().describe(
8009
+ weight: z20.coerce.number().positive().optional().describe(
7351
8010
  "Optional weighting factor for the feedback. Use to give more importance to certain feedback."
7352
8011
  ),
7353
- metadata: z19.record(z19.string(), z19.unknown()).optional().describe(
8012
+ metadata: z20.record(z20.string(), z20.unknown()).optional().describe(
7354
8013
  "Optional custom metadata for categorization and analysis (e.g., feedback_source, category, user_segment)."
7355
8014
  )
7356
8015
  },
7357
8016
  updateFeedback: {
7358
- id: z19.string().describe("The unique identifier of the feedback to update"),
7359
- value: z19.coerce.number().optional().describe(
8017
+ id: z20.string().describe("The unique identifier of the feedback to update"),
8018
+ value: z20.coerce.number().optional().describe(
7360
8019
  "New feedback value/rating. Common patterns: 1 for positive, 0 for negative."
7361
8020
  ),
7362
- weight: z19.coerce.number().positive().optional().describe("New weighting factor for the feedback"),
7363
- metadata: z19.record(z19.string(), z19.unknown()).optional().describe("New or updated custom metadata for the feedback")
8021
+ weight: z20.coerce.number().positive().optional().describe("New weighting factor for the feedback"),
8022
+ metadata: z20.record(z20.string(), z20.unknown()).optional().describe("New or updated custom metadata for the feedback")
7364
8023
  }
7365
8024
  };
7366
8025
  function registerTracingTools(server, service) {
@@ -7416,77 +8075,77 @@ function registerTracingTools(server, service) {
7416
8075
  }
7417
8076
 
7418
8077
  // src/tools/users.tools.ts
7419
- import { z as z20 } from "zod";
8078
+ import { z as z21 } from "zod";
7420
8079
  var USERS_TOOL_SCHEMAS = {
7421
8080
  listAllUsers: {
7422
- current_page: z20.coerce.number().int().positive().optional().describe("Page number for pagination"),
7423
- page_size: z20.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
8081
+ current_page: z21.coerce.number().int().positive().optional().describe("Page number for pagination"),
8082
+ page_size: z21.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
7424
8083
  },
7425
8084
  inviteUser: {
7426
- email: z20.string().email().describe("Email address of the user to invite"),
7427
- role: z20.enum(["admin", "member"]).describe(
8085
+ email: z21.string().email().describe("Email address of the user to invite"),
8086
+ role: z21.enum(["admin", "member"]).describe(
7428
8087
  "Organization-level role: 'admin' for full access, 'member' for limited access"
7429
8088
  ),
7430
- first_name: z20.string().optional().describe("User's first name"),
7431
- last_name: z20.string().optional().describe("User's last name"),
7432
- workspaces: z20.array(
7433
- z20.object({
7434
- id: z20.string().describe(
8089
+ first_name: z21.string().optional().describe("User's first name"),
8090
+ last_name: z21.string().optional().describe("User's last name"),
8091
+ workspaces: z21.array(
8092
+ z21.object({
8093
+ id: z21.string().describe(
7435
8094
  "Workspace ID/slug where the user will be granted access"
7436
8095
  ),
7437
- role: z20.enum(["admin", "member", "manager"]).describe(
8096
+ role: z21.enum(["admin", "member", "manager"]).describe(
7438
8097
  "Workspace-level role: 'admin' for full access, 'manager' for workspace management, 'member' for basic access"
7439
8098
  )
7440
8099
  })
7441
8100
  ).describe(
7442
8101
  "List of workspaces and corresponding roles to grant to the user"
7443
8102
  ),
7444
- workspace_api_key_details: z20.object({
7445
- name: z20.string().optional().describe("Name of the API key to be created"),
7446
- expiry: z20.string().optional().describe("Expiration date for the API key (ISO8601 format)"),
7447
- metadata: z20.record(z20.string(), z20.string()).optional().describe("Additional metadata key-value pairs for the API key"),
7448
- scopes: z20.array(z20.string()).describe("List of permission scopes for the API key")
8103
+ workspace_api_key_details: z21.object({
8104
+ name: z21.string().optional().describe("Name of the API key to be created"),
8105
+ expiry: z21.string().optional().describe("Expiration date for the API key (ISO8601 format)"),
8106
+ metadata: z21.record(z21.string(), z21.string()).optional().describe("Additional metadata key-value pairs for the API key"),
8107
+ scopes: z21.array(z21.string()).describe("List of permission scopes for the API key")
7449
8108
  }).optional().describe("Optional API key to be created for the user")
7450
8109
  },
7451
8110
  getUserStats: {
7452
- time_of_generation_min: z20.string().describe(
8111
+ time_of_generation_min: z21.string().describe(
7453
8112
  "Start time for the analytics period (ISO8601 format, e.g., '2024-01-01T00:00:00Z')"
7454
8113
  ),
7455
- time_of_generation_max: z20.string().describe(
8114
+ time_of_generation_max: z21.string().describe(
7456
8115
  "End time for the analytics period (ISO8601 format, e.g., '2024-02-01T00:00:00Z')"
7457
8116
  ),
7458
- total_units_min: z20.coerce.number().positive().optional().describe("Minimum number of total tokens to filter by"),
7459
- total_units_max: z20.coerce.number().positive().optional().describe("Maximum number of total tokens to filter by"),
7460
- cost_min: z20.coerce.number().positive().optional().describe("Minimum cost in cents to filter by"),
7461
- cost_max: z20.coerce.number().positive().optional().describe("Maximum cost in cents to filter by"),
7462
- status_code: z20.string().optional().describe("Filter by specific HTTP status codes (comma-separated)"),
7463
- virtual_keys: z20.string().optional().describe("Filter by specific virtual key slugs (comma-separated)"),
7464
- page_size: z20.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
8117
+ total_units_min: z21.coerce.number().positive().optional().describe("Minimum number of total tokens to filter by"),
8118
+ total_units_max: z21.coerce.number().positive().optional().describe("Maximum number of total tokens to filter by"),
8119
+ cost_min: z21.coerce.number().positive().optional().describe("Minimum cost in cents to filter by"),
8120
+ cost_max: z21.coerce.number().positive().optional().describe("Maximum cost in cents to filter by"),
8121
+ status_code: z21.string().optional().describe("Filter by specific HTTP status codes (comma-separated)"),
8122
+ virtual_keys: z21.string().optional().describe("Filter by specific virtual key slugs (comma-separated)"),
8123
+ page_size: z21.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
7465
8124
  },
7466
8125
  getUser: {
7467
- user_id: z20.string().describe("The user ID to retrieve")
8126
+ user_id: z21.string().describe("The user ID to retrieve")
7468
8127
  },
7469
8128
  updateUser: {
7470
- user_id: z20.string().describe("The user ID to update"),
7471
- first_name: z20.string().optional().describe("New first name"),
7472
- last_name: z20.string().optional().describe("New last name"),
7473
- role: z20.enum(["admin", "member"]).optional().describe("New organization-level role")
8129
+ user_id: z21.string().describe("The user ID to update"),
8130
+ first_name: z21.string().optional().describe("New first name"),
8131
+ last_name: z21.string().optional().describe("New last name"),
8132
+ role: z21.enum(["admin", "member"]).optional().describe("New organization-level role")
7474
8133
  },
7475
8134
  deleteUser: {
7476
- user_id: z20.string().describe("The user ID to delete")
8135
+ user_id: z21.string().describe("The user ID to delete")
7477
8136
  },
7478
8137
  listUserInvites: {
7479
- current_page: z20.coerce.number().int().positive().optional().describe("Page number for pagination"),
7480
- page_size: z20.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
8138
+ current_page: z21.coerce.number().int().positive().optional().describe("Page number for pagination"),
8139
+ page_size: z21.coerce.number().int().positive().max(100).optional().describe("Number of results per page (max 100)")
7481
8140
  },
7482
8141
  getUserInvite: {
7483
- invite_id: z20.string().describe("The invite ID to retrieve")
8142
+ invite_id: z21.string().describe("The invite ID to retrieve")
7484
8143
  },
7485
8144
  deleteUserInvite: {
7486
- invite_id: z20.string().describe("The invite ID to delete")
8145
+ invite_id: z21.string().describe("The invite ID to delete")
7487
8146
  },
7488
8147
  resendUserInvite: {
7489
- invite_id: z20.string().describe("The invite ID to resend")
8148
+ invite_id: z21.string().describe("The invite ID to resend")
7490
8149
  }
7491
8150
  };
7492
8151
  function formatUser(user) {
@@ -7712,59 +8371,97 @@ function registerUsersTools(server, service) {
7712
8371
  }
7713
8372
 
7714
8373
  // src/tools/workspaces.tools.ts
7715
- import { z as z21 } from "zod";
8374
+ import { z as z22 } from "zod";
8375
+ var scimWorkspaceMappingBaseShape = {
8376
+ workspace_id: z22.string().describe("Portkey workspace ID that the SCIM group should access"),
8377
+ role: z22.enum(["admin", "member", "manager"]).describe("Workspace role automatically granted to group members")
8378
+ };
8379
+ var createScimWorkspaceMappingInputSchema = z22.object({
8380
+ ...scimWorkspaceMappingBaseShape,
8381
+ scim_group_id: z22.string().min(1).optional().describe(
8382
+ "Existing identity-provider SCIM group ID; provide this or scim_group_name, but not both"
8383
+ ),
8384
+ scim_group_name: z22.string().min(1).optional().describe(
8385
+ "Existing SCIM group display name; provide this or scim_group_id, but not both"
8386
+ )
8387
+ }).superRefine((input, context) => {
8388
+ if (Boolean(input.scim_group_id) === Boolean(input.scim_group_name)) {
8389
+ context.addIssue({
8390
+ code: "custom",
8391
+ path: ["scim_group_id"],
8392
+ message: "Provide exactly one of scim_group_id or scim_group_name"
8393
+ });
8394
+ }
8395
+ });
7716
8396
  var WORKSPACES_TOOL_SCHEMAS = {
7717
8397
  listWorkspaces: {
7718
- page_size: z21.coerce.number().int().positive().max(100).optional().describe("Number of workspaces to return per page (max 100)"),
7719
- current_page: z21.coerce.number().int().positive().optional().describe("Page number to retrieve when results are paginated")
8398
+ page_size: z22.coerce.number().int().positive().max(100).optional().describe("Number of workspaces to return per page (max 100)"),
8399
+ current_page: z22.coerce.number().int().positive().optional().describe("Page number to retrieve when results are paginated")
7720
8400
  },
7721
8401
  getWorkspace: {
7722
- workspace_id: z21.string().describe(
8402
+ workspace_id: z22.string().describe(
7723
8403
  "The unique identifier of the workspace to retrieve. This can be found in the workspace's URL or from the list_workspaces tool response"
7724
8404
  )
7725
8405
  },
7726
8406
  createWorkspace: {
7727
- name: z21.string().describe("Name of the workspace"),
7728
- slug: z21.string().optional().describe("URL-friendly slug (auto-generated if not provided)"),
7729
- description: z21.string().optional().describe("Description of the workspace"),
7730
- is_default: z21.coerce.number().optional().describe("Set as default workspace (1 = yes, 0 = no)"),
7731
- metadata: z21.record(z21.string(), z21.string()).optional().describe("Custom metadata key-value pairs")
8407
+ name: z22.string().describe("Name of the workspace"),
8408
+ slug: z22.string().optional().describe("URL-friendly slug (auto-generated if not provided)"),
8409
+ description: z22.string().optional().describe("Description of the workspace"),
8410
+ is_default: z22.coerce.number().optional().describe("Set as default workspace (1 = yes, 0 = no)"),
8411
+ metadata: z22.record(z22.string(), z22.string()).optional().describe("Custom metadata key-value pairs")
7732
8412
  },
7733
8413
  updateWorkspace: {
7734
- workspace_id: z21.string().describe("The workspace ID to update"),
7735
- name: z21.string().optional().describe("New name for the workspace"),
7736
- slug: z21.string().optional().describe("New slug for the workspace"),
7737
- description: z21.string().optional().describe("New description"),
7738
- is_default: z21.coerce.number().optional().describe("Set as default workspace (1 = yes, 0 = no)"),
7739
- metadata: z21.record(z21.string(), z21.string()).optional().describe("New metadata key-value pairs")
8414
+ workspace_id: z22.string().describe("The workspace ID to update"),
8415
+ name: z22.string().optional().describe("New name for the workspace"),
8416
+ slug: z22.string().optional().describe("New slug for the workspace"),
8417
+ description: z22.string().optional().describe("New description"),
8418
+ is_default: z22.coerce.number().optional().describe("Set as default workspace (1 = yes, 0 = no)"),
8419
+ metadata: z22.record(z22.string(), z22.string()).optional().describe("New metadata key-value pairs")
7740
8420
  },
7741
8421
  deleteWorkspace: {
7742
- workspace_id: z21.string().describe("The workspace ID to delete")
8422
+ workspace_id: z22.string().describe("The workspace ID to delete")
7743
8423
  },
7744
8424
  addWorkspaceMember: {
7745
- workspace_id: z21.string().describe("The workspace ID to add the member to"),
7746
- user_id: z21.string().uuid(
8425
+ workspace_id: z22.string().describe("The workspace ID to add the member to"),
8426
+ user_id: z22.string().uuid(
7747
8427
  "user_id must be a valid UUID (use list_all_users to find user IDs)"
7748
8428
  ).describe(
7749
8429
  "The user ID to add (must be a valid UUID from list_all_users, not an email address)"
7750
8430
  ),
7751
- role: z21.enum(["admin", "member", "manager"]).describe("Role in the workspace")
8431
+ role: z22.enum(["admin", "member", "manager"]).describe("Role in the workspace")
7752
8432
  },
7753
8433
  listWorkspaceMembers: {
7754
- workspace_id: z21.string().describe("The workspace ID to list members for")
8434
+ workspace_id: z22.string().describe("The workspace ID to list members for")
7755
8435
  },
7756
8436
  getWorkspaceMember: {
7757
- workspace_id: z21.string().describe("The workspace ID"),
7758
- user_id: z21.string().describe("The user ID to retrieve")
8437
+ workspace_id: z22.string().describe("The workspace ID"),
8438
+ user_id: z22.string().describe("The user ID to retrieve")
7759
8439
  },
7760
8440
  updateWorkspaceMember: {
7761
- workspace_id: z21.string().describe("The workspace ID"),
7762
- user_id: z21.string().describe("The user ID to update"),
7763
- role: z21.enum(["admin", "member", "manager"]).describe("New role in the workspace")
8441
+ workspace_id: z22.string().describe("The workspace ID"),
8442
+ user_id: z22.string().describe("The user ID to update"),
8443
+ role: z22.enum(["admin", "member", "manager"]).describe("New role in the workspace")
7764
8444
  },
7765
8445
  removeWorkspaceMember: {
7766
- workspace_id: z21.string().describe("The workspace ID"),
7767
- user_id: z21.string().describe("The user ID to remove")
8446
+ workspace_id: z22.string().describe("The workspace ID"),
8447
+ user_id: z22.string().describe("The user ID to remove")
8448
+ },
8449
+ listScimWorkspaceMappings: {
8450
+ workspace_id: z22.string().optional().describe("Return only mappings for this Portkey workspace ID"),
8451
+ scim_group_id: z22.string().optional().describe(
8452
+ "Return only mappings for this identity-provider SCIM group ID"
8453
+ ),
8454
+ role: z22.enum(["admin", "member", "manager"]).optional().describe("Return only mappings that grant this workspace role"),
8455
+ page: z22.coerce.number().int().nonnegative().optional().describe("Zero-based results page to retrieve; the first page is 0"),
8456
+ page_size: z22.coerce.number().int().positive().max(100).optional().describe("Mappings per page, from 1 through 100")
8457
+ },
8458
+ deleteScimWorkspaceMapping: {
8459
+ mapping_id: z22.string().describe("SCIM workspace mapping ID from list_scim_workspace_mappings")
8460
+ },
8461
+ listScimGroups: {
8462
+ search: z22.string().optional().describe("Case-insensitive text to match against SCIM group names"),
8463
+ page: z22.coerce.number().int().nonnegative().optional().describe("Zero-based results page to retrieve; the first page is 0"),
8464
+ page_size: z22.coerce.number().int().positive().max(100).optional().describe("SCIM groups per page, from 1 through 100")
7768
8465
  }
7769
8466
  };
7770
8467
  function formatWorkspaceDefaults(defaults) {
@@ -7811,6 +8508,114 @@ function formatWorkspaceDetail(workspace) {
7811
8508
  };
7812
8509
  }
7813
8510
  function registerWorkspacesTools(server, service) {
8511
+ server.tool(
8512
+ "list_scim_workspace_mappings",
8513
+ "List identity-provider SCIM group mappings that automatically grant Portkey workspace roles. Use it to audit provisioned access or obtain mapping_id before delete_scim_workspace_mapping; filter by workspace, group, or role and page through large directories. This reads mappings only and does not query individual workspace members.",
8514
+ WORKSPACES_TOOL_SCHEMAS.listScimWorkspaceMappings,
8515
+ {
8516
+ title: "List SCIM Workspace Mappings",
8517
+ readOnlyHint: true,
8518
+ destructiveHint: false,
8519
+ idempotentHint: true,
8520
+ openWorldHint: true
8521
+ },
8522
+ async (params) => ({
8523
+ content: [
8524
+ {
8525
+ type: "text",
8526
+ text: JSON.stringify(
8527
+ await service.workspaces.listScimWorkspaceMappings(params)
8528
+ )
8529
+ }
8530
+ ]
8531
+ })
8532
+ );
8533
+ server.registerTool(
8534
+ "create_scim_workspace_mapping",
8535
+ {
8536
+ description: "Map one identity-provider SCIM group to a Portkey workspace role so current and future group members receive access automatically. Provide exactly one of scim_group_id or scim_group_name; a name can pre-create the Portkey SCIM group before the IdP provisions it. Use list_scim_groups to discover existing groups and list_workspaces for the workspace ID. This changes access provisioning and is distinct from add_workspace_member, which grants one user directly.",
8537
+ inputSchema: createScimWorkspaceMappingInputSchema,
8538
+ annotations: {
8539
+ title: "Create SCIM Workspace Mapping",
8540
+ readOnlyHint: false,
8541
+ destructiveHint: false,
8542
+ idempotentHint: false,
8543
+ openWorldHint: true
8544
+ }
8545
+ },
8546
+ async (params) => {
8547
+ let request;
8548
+ if (params.scim_group_id !== void 0) {
8549
+ request = {
8550
+ workspace_id: params.workspace_id,
8551
+ role: params.role,
8552
+ scim_group_id: params.scim_group_id
8553
+ };
8554
+ } else if (params.scim_group_name !== void 0) {
8555
+ request = {
8556
+ workspace_id: params.workspace_id,
8557
+ role: params.role,
8558
+ scim_group_name: params.scim_group_name
8559
+ };
8560
+ } else {
8561
+ throw new Error(
8562
+ "Provide exactly one of scim_group_id or scim_group_name"
8563
+ );
8564
+ }
8565
+ const result = await service.workspaces.createScimWorkspaceMapping(request);
8566
+ return {
8567
+ content: [{ type: "text", text: JSON.stringify(result) }]
8568
+ };
8569
+ }
8570
+ );
8571
+ server.tool(
8572
+ "delete_scim_workspace_mapping",
8573
+ "Delete a SCIM group-to-workspace mapping by mapping_id and stop future group updates from affecting that workspace. Existing provisioned members remain in the workspace and must be managed separately. Inspect list_scim_workspace_mappings first; this does not delete the identity-provider group or the Portkey workspace.",
8574
+ WORKSPACES_TOOL_SCHEMAS.deleteScimWorkspaceMapping,
8575
+ {
8576
+ title: "Delete SCIM Workspace Mapping",
8577
+ readOnlyHint: false,
8578
+ destructiveHint: true,
8579
+ idempotentHint: true,
8580
+ openWorldHint: true
8581
+ },
8582
+ async (params) => {
8583
+ const result = await service.workspaces.deleteScimWorkspaceMapping(
8584
+ params.mapping_id
8585
+ );
8586
+ return {
8587
+ content: [
8588
+ {
8589
+ type: "text",
8590
+ text: JSON.stringify({
8591
+ message: `Deleted SCIM workspace mapping "${params.mapping_id}"`,
8592
+ ...result
8593
+ })
8594
+ }
8595
+ ]
8596
+ };
8597
+ }
8598
+ );
8599
+ server.tool(
8600
+ "list_scim_groups",
8601
+ "Search and page through identity-provider groups synchronized to Portkey over SCIM. Use this to resolve a group ID or exact display name before create_scim_workspace_mapping; it reads directory groups only and does not show their workspace mappings or individual members.",
8602
+ WORKSPACES_TOOL_SCHEMAS.listScimGroups,
8603
+ {
8604
+ title: "List SCIM Groups",
8605
+ readOnlyHint: true,
8606
+ destructiveHint: false,
8607
+ idempotentHint: true,
8608
+ openWorldHint: true
8609
+ },
8610
+ async (params) => ({
8611
+ content: [
8612
+ {
8613
+ type: "text",
8614
+ text: JSON.stringify(await service.workspaces.listScimGroups(params))
8615
+ }
8616
+ ]
8617
+ })
8618
+ );
7814
8619
  server.tool(
7815
8620
  "list_workspaces",
7816
8621
  "List workspaces with id, name, slug, default settings, and timestamps. Use this to find a workspace_id before get_workspace, update_workspace, add_workspace_member, or remove_workspace_member.",
@@ -8117,7 +8922,25 @@ var ENTERPRISE_GATED_TOOL_NAMES = /* @__PURE__ */ new Set([
8117
8922
  "list_all_users",
8118
8923
  "get_user",
8119
8924
  "list_user_invites",
8120
- "get_user_stats"
8925
+ "get_user_stats",
8926
+ "get_organisation_defaults",
8927
+ "update_organisation_defaults",
8928
+ "list_input_guardrail_workspace_exclusions",
8929
+ "update_input_guardrail_workspace_exclusions",
8930
+ "list_output_guardrail_workspace_exclusions",
8931
+ "update_output_guardrail_workspace_exclusions",
8932
+ "create_log_export",
8933
+ "list_log_exports",
8934
+ "get_log_export",
8935
+ "start_log_export",
8936
+ "cancel_log_export",
8937
+ "download_log_export",
8938
+ "update_log_export",
8939
+ "get_log_export_field_restrictions",
8940
+ "list_scim_workspace_mappings",
8941
+ "create_scim_workspace_mapping",
8942
+ "delete_scim_workspace_mapping",
8943
+ "list_scim_groups"
8121
8944
  ]);
8122
8945
  var ENTERPRISE_GATED_DESCRIPTION_NOTE = "Enterprise-gated. Returns 403 on non-Enterprise Portkey plans.";
8123
8946
  function isToolAnnotationsLike(value) {
@@ -8174,71 +8997,71 @@ function getToolErrorMessage(error) {
8174
8997
  return String(error);
8175
8998
  }
8176
8999
  var STANDARD_TOOL_OUTPUT_SCHEMA = {
8177
- ok: z22.boolean().describe("Whether the tool call succeeded and returned structured data"),
8178
- data: z22.unknown().optional().describe("Structured success payload when ok is true"),
8179
- error: z22.object({
8180
- message: z22.string().describe("Human-readable error message"),
8181
- details: z22.unknown().optional().describe("Optional structured error details")
9000
+ ok: z23.boolean().describe("Whether the tool call succeeded and returned structured data"),
9001
+ data: z23.unknown().optional().describe("Structured success payload when ok is true"),
9002
+ error: z23.object({
9003
+ message: z23.string().describe("Human-readable error message"),
9004
+ details: z23.unknown().optional().describe("Optional structured error details")
8182
9005
  }).optional().describe("Structured error payload when ok is false")
8183
9006
  };
8184
9007
  var TOOL_SUCCESS_DATA_SCHEMAS = {
8185
- rotate_api_key: z22.object({
8186
- message: z22.string().describe("Rotation confirmation"),
8187
- warning: z22.string().describe("Required handling guidance for the one-time secret"),
8188
- id: z22.string().uuid().describe("Rotated API key UUID"),
8189
- key: z22.string().describe("New API key secret, returned only once"),
8190
- key_transition_expires_at: z22.iso.datetime().describe("Time when the previous key stops working")
9008
+ rotate_api_key: z23.object({
9009
+ message: z23.string().describe("Rotation confirmation"),
9010
+ warning: z23.string().describe("Required handling guidance for the one-time secret"),
9011
+ id: z23.string().uuid().describe("Rotated API key UUID"),
9012
+ key: z23.string().describe("New API key secret, returned only once"),
9013
+ key_transition_expires_at: z23.iso.datetime().describe("Time when the previous key stops working")
8191
9014
  }),
8192
- create_secret_reference: z22.object({
8193
- message: z22.string().describe("Creation confirmation"),
8194
- id: z22.string().uuid().describe("New Secret Reference UUID"),
8195
- slug: z22.string().describe("New Secret Reference slug")
9015
+ create_secret_reference: z23.object({
9016
+ message: z23.string().describe("Creation confirmation"),
9017
+ id: z23.string().uuid().describe("New Secret Reference UUID"),
9018
+ slug: z23.string().describe("New Secret Reference slug")
8196
9019
  }),
8197
- list_secret_references: z22.object({
8198
- total: z22.number().int().nonnegative().describe("Total matching references"),
8199
- secret_references: z22.array(
8200
- z22.object({
8201
- id: z22.string().uuid().describe("Secret Reference UUID"),
8202
- name: z22.string().describe("Human-readable name"),
8203
- slug: z22.string().describe("Stable Secret Reference slug"),
9020
+ list_secret_references: z23.object({
9021
+ total: z23.number().int().nonnegative().describe("Total matching references"),
9022
+ secret_references: z23.array(
9023
+ z23.object({
9024
+ id: z23.string().uuid().describe("Secret Reference UUID"),
9025
+ name: z23.string().describe("Human-readable name"),
9026
+ slug: z23.string().describe("Stable Secret Reference slug"),
8204
9027
  manager_type: SecretManagerTypeSchema.describe(
8205
9028
  "External secret manager type"
8206
9029
  ),
8207
- status: z22.literal("ACTIVE").describe("Current reference status"),
8208
- created_at: z22.iso.datetime().describe("ISO 8601 creation timestamp"),
8209
- last_updated_at: z22.iso.datetime().describe("ISO 8601 last-update timestamp")
9030
+ status: z23.literal("ACTIVE").describe("Current reference status"),
9031
+ created_at: z23.iso.datetime().describe("ISO 8601 creation timestamp"),
9032
+ last_updated_at: z23.iso.datetime().describe("ISO 8601 last-update timestamp")
8210
9033
  })
8211
9034
  ).describe(
8212
9035
  "Current page of Secret References without authentication values"
8213
9036
  )
8214
9037
  }),
8215
- get_secret_reference: z22.object({
8216
- id: z22.string().uuid().describe("Secret Reference UUID"),
8217
- organisation_id: z22.string().uuid().describe("Owning organisation UUID"),
8218
- name: z22.string().describe("Human-readable name"),
8219
- slug: z22.string().describe("Stable Secret Reference slug"),
8220
- description: z22.string().nullable().describe("Reference description"),
9038
+ get_secret_reference: z23.object({
9039
+ id: z23.string().uuid().describe("Secret Reference UUID"),
9040
+ organisation_id: z23.string().uuid().describe("Owning organisation UUID"),
9041
+ name: z23.string().describe("Human-readable name"),
9042
+ slug: z23.string().describe("Stable Secret Reference slug"),
9043
+ description: z23.string().nullable().describe("Reference description"),
8221
9044
  manager_type: SecretManagerTypeSchema.describe(
8222
9045
  "External secret manager type"
8223
9046
  ),
8224
- secret_path: z22.string().describe("Path in the external secret manager"),
8225
- secret_key: z22.string().nullable().describe("Selected key within a structured secret"),
8226
- allow_all_workspaces: z22.boolean().describe("Whether all workspaces may use the reference"),
8227
- tags: z22.record(z22.string(), z22.string()).nullable().describe("String metadata tags"),
8228
- status: z22.literal("ACTIVE").describe("Current reference status"),
8229
- created_by: z22.string().describe("Creator identifier"),
8230
- created_at: z22.iso.datetime().describe("ISO 8601 creation timestamp"),
8231
- last_updated_at: z22.iso.datetime().describe("ISO 8601 last-update timestamp"),
8232
- auth_config: z22.record(z22.string(), z22.unknown()).describe("Authentication configuration with sensitive values redacted"),
8233
- object: z22.literal("secret-reference").describe("Portkey object type")
9047
+ secret_path: z23.string().describe("Path in the external secret manager"),
9048
+ secret_key: z23.string().nullable().describe("Selected key within a structured secret"),
9049
+ allow_all_workspaces: z23.boolean().describe("Whether all workspaces may use the reference"),
9050
+ tags: z23.record(z23.string(), z23.string()).nullable().describe("String metadata tags"),
9051
+ status: z23.literal("ACTIVE").describe("Current reference status"),
9052
+ created_by: z23.string().describe("Creator identifier"),
9053
+ created_at: z23.iso.datetime().describe("ISO 8601 creation timestamp"),
9054
+ last_updated_at: z23.iso.datetime().describe("ISO 8601 last-update timestamp"),
9055
+ auth_config: z23.record(z23.string(), z23.unknown()).describe("Authentication configuration with sensitive values redacted"),
9056
+ object: z23.literal("secret-reference").describe("Portkey object type")
8234
9057
  }),
8235
- update_secret_reference: z22.object({
8236
- message: z22.string().describe("Update confirmation"),
8237
- success: z22.literal(true).describe("Whether the update succeeded")
9058
+ update_secret_reference: z23.object({
9059
+ message: z23.string().describe("Update confirmation"),
9060
+ success: z23.literal(true).describe("Whether the update succeeded")
8238
9061
  }),
8239
- delete_secret_reference: z22.object({
8240
- message: z22.string().describe("Deletion confirmation"),
8241
- success: z22.literal(true).describe("Whether the deletion succeeded")
9062
+ delete_secret_reference: z23.object({
9063
+ message: z23.string().describe("Deletion confirmation"),
9064
+ success: z23.literal(true).describe("Whether the deletion succeeded")
8242
9065
  })
8243
9066
  };
8244
9067
  function getToolOutputSchema(toolName) {
@@ -8383,6 +9206,36 @@ function createSafeToolServer(server) {
8383
9206
  args
8384
9207
  );
8385
9208
  };
9209
+ safeServer.registerTool = ((name, config, callback) => {
9210
+ const description = augmentToolDescription(
9211
+ name,
9212
+ typeof config.description === "string" ? config.description : void 0
9213
+ );
9214
+ const annotations = {
9215
+ ...inferToolAnnotations(name),
9216
+ ...isToolAnnotationsLike(config.annotations) ? config.annotations : {}
9217
+ };
9218
+ const wrappedCallback = wrapToolCallback(name, callback);
9219
+ if (originalRegisterTool) {
9220
+ return callOriginalRegisterTool(
9221
+ name,
9222
+ {
9223
+ ...config,
9224
+ ...description === void 0 ? {} : { description },
9225
+ outputSchema: config.outputSchema ?? getToolOutputSchema(name),
9226
+ annotations
9227
+ },
9228
+ wrappedCallback
9229
+ );
9230
+ }
9231
+ const legacyArguments = [
9232
+ ...description === void 0 ? [] : [description],
9233
+ ...config.inputSchema === void 0 ? [] : [config.inputSchema],
9234
+ annotations,
9235
+ wrappedCallback
9236
+ ];
9237
+ return callOriginalTool(name, ...legacyArguments);
9238
+ });
8386
9239
  safeServer.tool = ((name, ...rest) => {
8387
9240
  const maybeCallback = rest.at(-1);
8388
9241
  if (typeof maybeCallback !== "function") {
@@ -9314,7 +10167,7 @@ function createManagedEventStore(config) {
9314
10167
  // src/lib/mcp-server.ts
9315
10168
  import { readFileSync } from "node:fs";
9316
10169
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9317
- import { z as z23 } from "zod";
10170
+ import { z as z24 } from "zod";
9318
10171
  var PACKAGE_JSON_URL_CANDIDATES = [
9319
10172
  new URL("../../package.json", import.meta.url),
9320
10173
  new URL("../package.json", import.meta.url)
@@ -9387,8 +10240,8 @@ function registerServerPromptsAndResources(server) {
9387
10240
  title: "Plan Portkey Admin Workflow",
9388
10241
  description: "Create a concise, safe plan for a Portkey Admin API task using this MCP server.",
9389
10242
  argsSchema: {
9390
- task: z23.string().min(1).max(500).describe("Portkey admin task to plan, such as promoting a prompt"),
9391
- area: z23.string().max(80).optional().describe(
10243
+ task: z24.string().min(1).max(500).describe("Portkey admin task to plan, such as promoting a prompt"),
10244
+ area: z24.string().max(80).optional().describe(
9392
10245
  "Optional Portkey area, such as prompts, analytics, configs, or users"
9393
10246
  )
9394
10247
  }