@zuora/agent-toolkit 0.0.1-alpha.0 → 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { d as ZuoraToolkitEvent, e as ZuoraAgentToolkitConfig, f as ZuoraMcpClient, T as ToolSelection, Z as ZuoraToolDefinition, g as ZuoraBundleDefinition, h as ZuoraBundleName, b as ZuoraToolExecutionResult, c as ZuoraAsyncJobResult, i as ZuoraWaitForJobOptions } from '../async-jobs-Dd8Jafv0.js';
1
+ import { d as ZuoraToolkitEvent, e as ZuoraAgentToolkitConfig, f as ZuoraMcpClient, T as ToolSelection, Z as ZuoraToolDefinition, g as ZuoraBundleDefinition, h as ZuoraBundleName, b as ZuoraToolExecutionResult, c as ZuoraAsyncJobResult, i as ZuoraWaitForJobOptions } from '../async-jobs-DJ_GygII.js';
2
2
 
3
3
  type InternalToolkitEvent = Omit<ZuoraToolkitEvent, "type" | "timestamp"> & Partial<Pick<ZuoraToolkitEvent, "type" | "timestamp">>;
4
4
 
@@ -19,6 +19,10 @@ var ZuoraAgentToolkitError = class extends Error {
19
19
  };
20
20
 
21
21
  // src/shared/types.ts
22
+ var SafetyMode = {
23
+ ReadOnly: "readOnly",
24
+ WriteEnabled: "writeEnabled"
25
+ };
22
26
  var ApprovalPolicyPreset = {
23
27
  Off: "off",
24
28
  AllWrites: "all_writes",
@@ -114,15 +118,15 @@ var evaluatePreset = (preset, request) => {
114
118
  const isProduction = environment === "production";
115
119
  switch (preset) {
116
120
  case ApprovalPolicyPreset.Off:
117
- return "not_required";
121
+ return "allow";
118
122
  case ApprovalPolicyPreset.AllWrites:
119
- return isWrite ? "deny" : "not_required";
123
+ return isWrite ? "deny" : "allow";
120
124
  case ApprovalPolicyPreset.HighRisk:
121
- return isHighRisk ? "deny" : "not_required";
125
+ return isHighRisk ? "deny" : "allow";
122
126
  case ApprovalPolicyPreset.ProductionWrites:
123
- return isProduction && isWrite ? "deny" : "not_required";
127
+ return isProduction && isWrite ? "deny" : "allow";
124
128
  case ApprovalPolicyPreset.ProductionHighRisk:
125
- return isProduction && isHighRisk ? "deny" : "not_required";
129
+ return isProduction && isHighRisk ? "deny" : "allow";
126
130
  }
127
131
  };
128
132
  var throwApprovalRejected = (tool) => {
@@ -2589,26 +2593,11 @@ var readEnvAllowedHosts = () => {
2589
2593
  const hosts = raw.split(",").map((host) => host.trim()).filter(Boolean);
2590
2594
  return hosts.length > 0 ? hosts : void 0;
2591
2595
  };
2592
- var isQueryBundleConfigured = (configuration) => {
2593
- const bundles = configuration?.bundles;
2594
- if (!bundles) {
2595
- return false;
2596
- }
2597
- const query = bundles.query;
2598
- if (query === true) {
2599
- return true;
2600
- }
2601
- return typeof query === "object" && query !== null;
2602
- };
2603
2596
  var resolveNativeFileToolsInput = (config) => {
2604
2597
  const explicit = config.nativeFileTools;
2605
2598
  if (explicit?.enabled === false) {
2606
2599
  return { enabled: false };
2607
2600
  }
2608
- const autoEnable = isQueryBundleConfigured(config.configuration);
2609
- if (!autoEnable && explicit?.enabled !== true) {
2610
- return explicit;
2611
- }
2612
2601
  const rootDir = nonEmptyString(explicit?.rootDir) ?? nonEmptyString(process.env["ZUORA_NATIVE_FILE_ROOT"]) ?? DEFAULT_NATIVE_ARTIFACT_ROOT;
2613
2602
  const allowedHosts = explicit?.allowedHosts ?? readEnvAllowedHosts() ?? DEFAULT_NATIVE_ALLOWED_HOSTS;
2614
2603
  return {
@@ -3430,21 +3419,10 @@ var OAuthTokenProvider = class {
3430
3419
  category: "auth"
3431
3420
  });
3432
3421
  }
3433
- if (this.config.auth.type === "accessToken" && this.config.auth.accessToken) {
3434
- this.accessToken = this.config.auth.accessToken;
3435
- return this.config.auth.accessToken;
3436
- }
3437
3422
  const now = Date.now();
3438
3423
  if (this.accessToken && this.isAccessTokenFresh(now)) {
3439
3424
  return this.accessToken;
3440
3425
  }
3441
- if (this.config.auth.type !== "oauthClientCredentials") {
3442
- throw new ZuoraAgentToolkitError({
3443
- code: "UNSUPPORTED_AUTH",
3444
- message: "Unsupported auth configuration for Zuora HTTP MCP client.",
3445
- category: "auth"
3446
- });
3447
- }
3448
3426
  const token = await this.fetchOAuthToken();
3449
3427
  this.accessToken = token.access_token;
3450
3428
  this.tokenIssuedAt = now;
@@ -3463,10 +3441,8 @@ var OAuthTokenProvider = class {
3463
3441
  sensitiveValues() {
3464
3442
  const values = [this.accessToken];
3465
3443
  const auth = this.config.auth;
3466
- if (auth?.type === "oauthClientCredentials") {
3444
+ if (auth?.clientSecret) {
3467
3445
  values.push(auth.clientSecret);
3468
- } else if (auth?.type === "accessToken") {
3469
- values.push(auth.accessToken);
3470
3446
  }
3471
3447
  return values.filter(
3472
3448
  (value) => typeof value === "string" && value.length > 0
@@ -3530,11 +3506,8 @@ var OAuthTokenProvider = class {
3530
3506
  });
3531
3507
  }
3532
3508
  async resolveTokenEndpoints() {
3533
- if (this.config.tokenEndpoint) {
3534
- return [this.config.tokenEndpoint];
3535
- }
3536
3509
  const restEndpoint = `${this.restBaseUrl}/oauth/token`;
3537
- const oneIdEndpoint = await this.resolveOneIdTokenEndpoint();
3510
+ const oneIdEndpoint = isStagingZuoraBaseUrl(this.restBaseUrl) ? "https://one.stg.na.zuora.com/oauth2/token" : "https://one.zuora.com/oauth2/token";
3538
3511
  const endpoints = [restEndpoint, oneIdEndpoint];
3539
3512
  const uniqueEndpoints = [...new Set(endpoints)];
3540
3513
  if (!this.preferredTokenEndpoint) {
@@ -3547,29 +3520,8 @@ var OAuthTokenProvider = class {
3547
3520
  )
3548
3521
  ];
3549
3522
  }
3550
- async resolveOneIdTokenEndpoint() {
3551
- const fallback = isStagingZuoraBaseUrl(this.restBaseUrl) ? "https://one.stg.na.zuora.com/oauth2/token" : "https://one.zuora.com/oauth2/token";
3552
- try {
3553
- return await this.discoverTokenEndpoint() ?? fallback;
3554
- } catch {
3555
- return fallback;
3556
- }
3557
- }
3558
- async discoverTokenEndpoint() {
3559
- const metadataUrl = new URL(this.restBaseUrl);
3560
- metadataUrl.pathname = "/.well-known/oauth-authorization-server";
3561
- metadataUrl.search = "";
3562
- const response = await fetch(metadataUrl, {
3563
- headers: { accept: "application/json" }
3564
- });
3565
- if (!response.ok) {
3566
- return void 0;
3567
- }
3568
- const metadata = await response.json().catch(() => ({}));
3569
- return metadata.token_endpoint;
3570
- }
3571
3523
  async requestOAuthToken(tokenEndpoint) {
3572
- if (!this.config.auth || this.config.auth.type !== "oauthClientCredentials") {
3524
+ if (!this.config.auth) {
3573
3525
  throw new ZuoraAgentToolkitError({
3574
3526
  code: "UNSUPPORTED_AUTH",
3575
3527
  message: "Unsupported auth configuration for Zuora HTTP MCP client.",
@@ -3582,17 +3534,8 @@ var OAuthTokenProvider = class {
3582
3534
  accept: "application/json"
3583
3535
  };
3584
3536
  const auth = this.config.auth;
3585
- if (this.config.tokenAuthMethod === "client_secret_basic") {
3586
- headers.authorization = `Basic ${base64Encode(
3587
- `${auth.clientId}:${auth.clientSecret}`
3588
- )}`;
3589
- } else {
3590
- body.set("client_id", auth.clientId);
3591
- body.set("client_secret", auth.clientSecret);
3592
- }
3593
- if (auth.scope) {
3594
- body.set("scope", auth.scope);
3595
- }
3537
+ body.set("client_id", auth.clientId);
3538
+ body.set("client_secret", auth.clientSecret);
3596
3539
  const response = await fetch(tokenEndpoint, {
3597
3540
  method: "POST",
3598
3541
  headers,
@@ -3634,7 +3577,6 @@ var extractTenantId = (scope) => {
3634
3577
  const tenantMatch = scope?.match(/tenant\.(\d+)/);
3635
3578
  return tenantMatch?.[1];
3636
3579
  };
3637
- var base64Encode = (value) => Buffer.from(value).toString("base64");
3638
3580
 
3639
3581
  // src/shared/transport/request-headers.ts
3640
3582
  var RESERVED_HEADER_NAMES = /* @__PURE__ */ new Set([
@@ -3706,10 +3648,8 @@ var resolveZuoraConnectionConfig = (config, mcpUrl) => ({
3706
3648
  clientName: config.clientName ?? "zuora-agent-toolkit",
3707
3649
  clientVersion: config.clientVersion ?? "0.1.0",
3708
3650
  protocolVersion: config.protocolVersion ?? "2025-03-26",
3709
- tokenAuthMethod: config.tokenAuthMethod ?? "client_secret_post",
3710
3651
  url: mcpUrl,
3711
3652
  ...config.auth ? { auth: config.auth } : {},
3712
- ...config.tokenEndpoint ? { tokenEndpoint: config.tokenEndpoint } : {},
3713
3653
  ...config.headers ? { headers: config.headers } : {},
3714
3654
  ...config.tenantAuth ? { tenantAuth: config.tenantAuth } : {},
3715
3655
  ...config.entityIds ? { entityIds: config.entityIds } : {},
@@ -3890,7 +3830,7 @@ var resolveToolSelectionPolicy = (configuration, selection) => ({
3890
3830
  ...selection?.exclude ?? []
3891
3831
  ])
3892
3832
  });
3893
- var resolveToolMode = (configuration, selection) => selection?.mode ?? configuration?.mode ?? "readOnly";
3833
+ var resolveToolMode = (configuration, selection) => selection?.mode ?? configuration?.mode ?? SafetyMode.ReadOnly;
3894
3834
  var resolveExcludedToolNames = (configuration) => /* @__PURE__ */ new Set([
3895
3835
  ...resolveConfiguredExcludedToolNames(configuration),
3896
3836
  ...resolveBundleExcludedToolNames(configuration)
@@ -4152,11 +4092,19 @@ var ZuoraHttpMcpClient = class _ZuoraHttpMcpClient extends ZuoraClient {
4152
4092
 
4153
4093
  // src/shared/toolkit-core.ts
4154
4094
  var createHttpMcpClientConfig = (config) => {
4155
- if (isTenantAuthConnection(config.connection)) {
4095
+ const contextEntityIds = config.configuration?.context?.entityIds;
4096
+ const contextOrgIds = config.configuration?.context?.orgIds;
4097
+ const contextOverrides = {
4098
+ ...contextEntityIds ? { entityIds: contextEntityIds } : {},
4099
+ ...contextOrgIds ? { orgIds: contextOrgIds } : {}
4100
+ };
4101
+ const connection = "connection" in config ? config.connection : void 0;
4102
+ if (isTenantAuthConnection(connection)) {
4156
4103
  return {
4157
4104
  url: config.baseUrl,
4158
4105
  ...config.auth ? { auth: config.auth } : {},
4159
- ...config.connection
4106
+ ...connection,
4107
+ ...contextOverrides
4160
4108
  };
4161
4109
  }
4162
4110
  if (!config.auth) {
@@ -4169,13 +4117,23 @@ var createHttpMcpClientConfig = (config) => {
4169
4117
  return {
4170
4118
  url: config.baseUrl,
4171
4119
  auth: config.auth,
4172
- ...config.connection
4120
+ ...connection ?? {},
4121
+ ...contextOverrides
4173
4122
  };
4174
4123
  };
4175
4124
  var isTenantAuthConnection = (connection) => connection?.tenantAuth?.enabled === true;
4176
4125
  var filterCatalogTools = (tools, policy) => tools.filter((tool) => {
4177
- if (policy.mode === "readOnly" && tool.meta.access === "write") {
4178
- return false;
4126
+ if (policy.mode === SafetyMode.ReadOnly) {
4127
+ if (tool.meta.operationAccess) {
4128
+ const hasReadOperation = Object.values(tool.meta.operationAccess).some(
4129
+ (access) => access === "read"
4130
+ );
4131
+ if (!hasReadOperation) {
4132
+ return false;
4133
+ }
4134
+ } else if (tool.meta.access === "write") {
4135
+ return false;
4136
+ }
4179
4137
  }
4180
4138
  if (policy.bundles.size > 0 && !policy.bundles.has(tool.meta.bundle)) {
4181
4139
  return false;
@@ -4336,19 +4294,19 @@ var ToolkitCore = class {
4336
4294
  category: "configuration"
4337
4295
  });
4338
4296
  }
4339
- const mode = this.config.configuration?.mode ?? "readOnly";
4340
- if (mode === "readOnly" && tool.meta.access === "write") {
4341
- throw new ZuoraAgentToolkitError({
4342
- code: "TOOL_EXECUTION_ERROR",
4343
- message: `Write tool "${operationName}" is disabled in readOnly mode.`,
4344
- category: "tool_execution"
4345
- });
4346
- }
4297
+ const mode = this.config.configuration?.mode ?? SafetyMode.ReadOnly;
4347
4298
  const nativeRuntimeTool = this.nativeToolRegistry?.get(operationName);
4348
4299
  const nativeApprovalMetadata = nativeRuntimeTool?.approvalMetadata(input);
4349
4300
  const invokedOperation = tool.meta.operationSelector ? String(input[tool.meta.operationSelector] ?? "") : void 0;
4350
4301
  const effectiveAccess = (invokedOperation ? tool.meta.operationAccess?.[invokedOperation] : void 0) ?? tool.meta.access;
4351
4302
  const effectiveRiskLevel = (invokedOperation ? tool.meta.operationRiskLevel?.[invokedOperation] : void 0) ?? tool.meta.riskLevel;
4303
+ if (mode === SafetyMode.ReadOnly && effectiveAccess === "write") {
4304
+ throw new ZuoraAgentToolkitError({
4305
+ code: "TOOL_EXECUTION_ERROR",
4306
+ message: `Write operation "${invokedOperation ?? operationName}" is disabled in readOnly mode.`,
4307
+ category: "tool_execution"
4308
+ });
4309
+ }
4352
4310
  const effectiveTool = effectiveAccess === tool.meta.access && effectiveRiskLevel === tool.meta.riskLevel ? tool : { ...tool, meta: { ...tool.meta, access: effectiveAccess, riskLevel: effectiveRiskLevel } };
4353
4311
  await enforceApproval(
4354
4312
  effectiveTool,
@@ -4582,7 +4540,7 @@ var ToolkitCore = class {
4582
4540
  return this.catalogTools ?? [];
4583
4541
  }
4584
4542
  resolveSplitOperations() {
4585
- return this.config.configuration?.splitOperations ?? true;
4543
+ return this.config.configuration?.splitOperations ?? false;
4586
4544
  }
4587
4545
  warnIfNotInitialized() {
4588
4546
  if (!this._initialized) {
@@ -4651,13 +4609,11 @@ var ToolkitCore = class {
4651
4609
  }
4652
4610
  createEventContext() {
4653
4611
  const configurationContext = this.config.configuration?.context ?? {};
4654
- const tenantId = nonEmptyString(configurationContext.tenantId) ?? nonEmptyString(configurationContext.tenant_id);
4655
4612
  const entityIds = normalizeIdList(configurationContext.entityIds) ?? normalizeIdList(configurationContext.entityId);
4656
4613
  const orgIds = normalizeIdList(configurationContext.orgIds) ?? normalizeIdList(configurationContext.orgId);
4657
4614
  const environment = inferZuoraEnvironment(this.config.baseUrl) ?? "sandbox";
4658
4615
  return {
4659
4616
  environment,
4660
- ...tenantId ? { tenantId } : {},
4661
4617
  ...entityIds ? { entityIds } : {},
4662
4618
  ...orgIds ? { orgIds } : {}
4663
4619
  };