@mastra/connect 1.0.4-alpha.0 → 1.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.
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { MCPClient } from "@mastra/mcp";
2
2
  import { z } from "zod";
3
3
  import { SpanType, resolveCurrentSpan } from "@mastra/core/observability";
4
4
  import { createTool } from "@mastra/core/tools";
5
+ import { hkdfSync } from "crypto";
5
6
  //#region src/errors.ts
6
7
  const MAX_DETAIL_LENGTH = 2e3;
7
8
  var MastraConnectError = class extends Error {
@@ -244,6 +245,8 @@ function resolveClient(options) {
244
245
  };
245
246
  const orgId = options?.orgId?.trim() || process.env.MASTRA_ORG_ID?.trim();
246
247
  if (orgId) headers["x-organization-id"] = orgId;
248
+ const projectId = options?.projectId?.trim() || process.env.MASTRA_PROJECT_ID?.trim();
249
+ if (projectId) headers["x-mastra-project-id"] = projectId;
247
250
  return {
248
251
  baseUrl,
249
252
  headers,
@@ -1026,7 +1029,6 @@ const CHANNELS$1 = [
1026
1029
  integrationId: "microsoft-teams",
1027
1030
  async create(options, runtime) {
1028
1031
  const mod = await import("@mastra/teams");
1029
- if (!process.env.MASTRA_ENCRYPTION_KEY) throw new MastraConnectError("invalid_options", "Microsoft Teams channel: MASTRA_ENCRYPTION_KEY is not set. The Teams install store persists per-agent bot secrets and requires an at-rest encryption key (a 32-byte value, base64-encoded).");
1030
1032
  const safeOptions = stripReservedOptions("microsoft-teams", options);
1031
1033
  const tokenResolver = async (scope) => {
1032
1034
  const fresh = await runtime.getCredential();
@@ -1035,10 +1037,22 @@ const CHANNELS$1 = [
1035
1037
  if (!token) throw new MastraConnectError("no_active_connection", `Teams connection ${runtime.getConnectionId()} has no Dev Portal token on its credential. Reconnect with an integration that requests the ${mod.TEAMS_DEV_PORTAL_SCOPE} scope.`);
1036
1038
  return token;
1037
1039
  };
1038
- return { provider: new mod.TeamsProvider({
1040
+ const config = {
1039
1041
  tokenResolver,
1040
1042
  ...safeOptions ?? {}
1041
- }) };
1043
+ };
1044
+ const usingDerivedKey = !process.env.MASTRA_ENCRYPTION_KEY;
1045
+ if (usingDerivedKey) config.encryptionKey = Buffer.from(hkdfSync("sha256", runtime.client.accessToken, "mastra-connect", "microsoft-teams-install-store", 32)).toString("base64");
1046
+ let warnedDerivedKey = false;
1047
+ return {
1048
+ provider: new mod.TeamsProvider(config),
1049
+ async sync() {
1050
+ if (usingDerivedKey && !warnedDerivedKey) {
1051
+ warnedDerivedKey = true;
1052
+ console.warn("[@mastra/connect] MASTRA_ENCRYPTION_KEY is not set: encrypting the Microsoft Teams install store with a key derived from the platform access token. Set MASTRA_ENCRYPTION_KEY to use a dedicated key — otherwise rotating the platform access token makes stored bot credentials unreadable (disconnect and reconnect the channel to re-provision).");
1053
+ }
1054
+ }
1055
+ };
1042
1056
  }
1043
1057
  }
1044
1058
  ];
@@ -75094,7 +75108,11 @@ function tools(options = {}) {
75094
75108
  if (!projectId) throw new MastraConnectError("missing_project_id", "Missing project id: set MASTRA_PROJECT_ID or pass projectId.");
75095
75109
  if (options.ttlMs !== void 0 && (!Number.isFinite(options.ttlMs) || options.ttlMs < 0)) throw new MastraConnectError("invalid_options", `Invalid ttlMs (${options.ttlMs}): expected a finite number of milliseconds >= 0.`);
75096
75110
  const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS$1;
75097
- const client = resolveClient(options.client);
75111
+ const clientOptions = {
75112
+ ...options.client,
75113
+ projectId
75114
+ };
75115
+ const client = resolveClient(clientOptions);
75098
75116
  const resolverId = ++nextResolverId;
75099
75117
  const mcpClients = /* @__PURE__ */ new Map();
75100
75118
  const normalizedProviders = normalizeProviderOverrides(options.providers);
@@ -75142,7 +75160,7 @@ function tools(options = {}) {
75142
75160
  if (!inflight) inflight = (async () => {
75143
75161
  try {
75144
75162
  const { connections, catalog, catalogAvailable } = await loadSnapshotInputs();
75145
- const snapshot = await mapTools(connections, buildRequests(normalizedProviders, catalog, catalogAvailable), options, client, mcpClients, resolverId);
75163
+ const snapshot = await mapTools(connections, buildRequests(normalizedProviders, catalog, catalogAvailable), options, clientOptions, client, mcpClients, resolverId);
75146
75164
  cache = {
75147
75165
  snapshot,
75148
75166
  fetchedAt: Date.now()
@@ -75323,7 +75341,7 @@ function buildRequests(providers, catalog, catalogAvailable) {
75323
75341
  return requests;
75324
75342
  }
75325
75343
  /** Maps one platform connection list snapshot to a flat tool record without allowing ambiguous tool ownership. */
75326
- async function mapTools(connections, requests, options, client, mcpClients, resolverId) {
75344
+ async function mapTools(connections, requests, options, clientOptions, client, mcpClients, resolverId) {
75327
75345
  const byIntegrationId = groupByIntegrationId(connections);
75328
75346
  const activeMcpKeys = /* @__PURE__ */ new Set();
75329
75347
  const result = {};
@@ -75356,7 +75374,7 @@ async function mapTools(connections, requests, options, client, mcpClients, reso
75356
75374
  } else {
75357
75375
  providerTools = request.registration.createTools({
75358
75376
  connectionId: resolution.connectionId,
75359
- client: options.client,
75377
+ client: clientOptions,
75360
75378
  ...providerFilterOptions(request.options)
75361
75379
  });
75362
75380
  applyProxyRequireApproval(providerTools, integrationId, request.options.requireApproval);
@@ -75379,7 +75397,7 @@ async function mapTools(connections, requests, options, client, mcpClients, reso
75379
75397
  connections: resolution.connections,
75380
75398
  allowTools: request.options.allowTools,
75381
75399
  disallowTools: request.options.disallowTools,
75382
- client: options.client
75400
+ client: clientOptions
75383
75401
  });
75384
75402
  applyProxyRequireApproval(providerTools, integrationId, request.options.requireApproval, [listConnectionsToolKey(integrationId)]);
75385
75403
  }
@@ -75581,7 +75599,10 @@ async function channels(options = {}) {
75581
75599
  const unknownChannelIds = Object.keys(providerOverrides).filter((integrationId) => !knownChannelIds.has(integrationId) && !providerOverrides[integrationId]?.disabled);
75582
75600
  if (unknownChannelIds.length > 0) throw new MastraConnectError("invalid_options", `Unknown channel${unknownChannelIds.length > 1 ? "s" : ""} in the providers option: ${unknownChannelIds.map((id) => `'${id}'`).join(", ")}. Known channels: ${[...knownChannelIds].join(", ")}.`);
75583
75601
  const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
75584
- const client = resolveClient(options.client);
75602
+ const client = resolveClient({
75603
+ ...options.client,
75604
+ projectId
75605
+ });
75585
75606
  const states = [];
75586
75607
  for (const registration of CHANNELS) {
75587
75608
  if (only !== void 0 && !only.has(registration.integrationId)) continue;