@mastra/connect 0.7.0-alpha.1 → 1.0.0-alpha.4
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/README.md +47 -42
- package/dist/channels.d.ts +40 -22
- package/dist/channels.d.ts.map +1 -1
- package/dist/client.d.ts +21 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/errors.d.ts +23 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.cjs +821 -465
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +822 -458
- package/dist/index.js.map +1 -1
- package/dist/instrumentation.d.ts +48 -0
- package/dist/instrumentation.d.ts.map +1 -0
- package/dist/multi-connection.d.ts +1 -1
- package/dist/multi-connection.d.ts.map +1 -1
- package/dist/providers/channels.d.ts +5 -1
- package/dist/providers/channels.d.ts.map +1 -1
- package/dist/providers/clerk/tools/create-organization-domain.d.ts +9 -9
- package/dist/providers/clerk/tools/create-organization-domain.d.ts.map +1 -1
- package/dist/providers/clerk/tools/create-organization-invitation.d.ts +3 -3
- package/dist/providers/clerk/tools/create-user.d.ts.map +1 -1
- package/dist/providers/clerk/tools/delete-email-address.d.ts.map +1 -1
- package/dist/providers/clerk/tools/delete-organization-domain.d.ts.map +1 -1
- package/dist/providers/clerk/tools/delete-organization-membership.d.ts.map +1 -1
- package/dist/providers/clerk/tools/delete-organization-role.d.ts.map +1 -1
- package/dist/providers/clerk/tools/delete-phone-number.d.ts.map +1 -1
- package/dist/providers/clerk/tools/get-email-address.d.ts.map +1 -1
- package/dist/providers/clerk/tools/get-organization-invitation.d.ts +3 -3
- package/dist/providers/clerk/tools/get-organization-role.d.ts.map +1 -1
- package/dist/providers/clerk/tools/get-phone-number.d.ts.map +1 -1
- package/dist/providers/clerk/tools/get-session.d.ts +3 -3
- package/dist/providers/clerk/tools/get-session.d.ts.map +1 -1
- package/dist/providers/clerk/tools/list-organization-domains.d.ts +9 -9
- package/dist/providers/clerk/tools/list-organization-domains.d.ts.map +1 -1
- package/dist/providers/clerk/tools/list-organization-invitations.d.ts +3 -3
- package/dist/providers/clerk/tools/list-organization-invitations.d.ts.map +1 -1
- package/dist/providers/clerk/tools/list-organization-memberships.d.ts.map +1 -1
- package/dist/providers/clerk/tools/list-organization-roles.d.ts.map +1 -1
- package/dist/providers/clerk/tools/list-organizations.d.ts.map +1 -1
- package/dist/providers/clerk/tools/list-sessions.d.ts +3 -5
- package/dist/providers/clerk/tools/list-sessions.d.ts.map +1 -1
- package/dist/providers/clerk/tools/list-users.d.ts +12 -0
- package/dist/providers/clerk/tools/list-users.d.ts.map +1 -1
- package/dist/providers/clerk/tools/revoke-organization-invitation.d.ts +3 -3
- package/dist/providers/clerk/tools/revoke-session.d.ts +3 -3
- package/dist/providers/clerk/tools/revoke-session.d.ts.map +1 -1
- package/dist/providers/clerk/tools/update-organization-domain.d.ts +9 -9
- package/dist/providers/clerk/tools/update-organization-domain.d.ts.map +1 -1
- package/dist/providers/clerk/tools/update-organization-role.d.ts.map +1 -1
- package/dist/providers/clerk/tools/update-organization.d.ts +2 -0
- package/dist/providers/clerk/tools/update-organization.d.ts.map +1 -1
- package/dist/providers/clerk/tools/update-user.d.ts +10 -10
- package/dist/providers/clerk/tools/verify-organization-domain.d.ts +12 -7
- package/dist/providers/clerk/tools/verify-organization-domain.d.ts.map +1 -1
- package/dist/providers/discord/tools/list-channels.d.ts +2 -2
- package/dist/providers/discord/tools/list-channels.d.ts.map +1 -1
- package/dist/providers/jira/tools/get-create-issue-metadata.d.ts +42 -0
- package/dist/providers/jira/tools/get-create-issue-metadata.d.ts.map +1 -1
- package/dist/providers/jira/tools/list-issue-types.d.ts +6 -2
- package/dist/providers/jira/tools/list-issue-types.d.ts.map +1 -1
- package/dist/providers/resend/tools/cancel-email.d.ts +2 -2
- package/dist/providers/resend/tools/get-email.d.ts +2 -2
- package/dist/providers/resend/tools/get-received-email.d.ts +2 -2
- package/dist/providers/resend/tools/get-template.d.ts +2 -2
- package/dist/providers/resend/tools/list-emails.d.ts +2 -2
- package/dist/providers/resend/tools/list-received-emails.d.ts +2 -2
- package/dist/providers/resend/tools/update-contact-topics.d.ts.map +1 -1
- package/dist/registry.d.ts +1 -8
- package/dist/registry.d.ts.map +1 -1
- package/dist/resolution.d.ts +3 -11
- package/dist/resolution.d.ts.map +1 -1
- package/dist/runtime/platform-proxy.d.ts.map +1 -1
- package/dist/tools.d.ts +94 -33
- package/dist/tools.d.ts.map +1 -1
- package/dist/toolset.d.ts +39 -13
- package/dist/toolset.d.ts.map +1 -1
- package/package.json +12 -8
- package/dist/connect.d.ts +0 -22
- package/dist/connect.d.ts.map +0 -1
- package/dist/environment.d.ts +0 -48
- package/dist/environment.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let _mastra_mcp = require("@mastra/mcp");
|
|
3
3
|
let zod = require("zod");
|
|
4
|
+
let _mastra_core_observability = require("@mastra/core/observability");
|
|
4
5
|
let _mastra_core_tools = require("@mastra/core/tools");
|
|
5
6
|
//#region src/errors.ts
|
|
6
7
|
const MAX_DETAIL_LENGTH = 2e3;
|
|
@@ -8,18 +9,56 @@ var MastraConnectError = class extends Error {
|
|
|
8
9
|
code;
|
|
9
10
|
status;
|
|
10
11
|
detail;
|
|
12
|
+
/**
|
|
13
|
+
* Axios-compatible alias for {@link status}. Generated provider tools come
|
|
14
|
+
* from upstream Nango templates whose error handlers check
|
|
15
|
+
* `error.response.status` (the axios/Nango SDK shape). Exposing the HTTP
|
|
16
|
+
* status under `response.status` as well lets that generated code work
|
|
17
|
+
* unchanged against the errors this package throws. Only set when the error
|
|
18
|
+
* carries an HTTP status.
|
|
19
|
+
*/
|
|
20
|
+
response;
|
|
11
21
|
constructor(code, message, options) {
|
|
12
22
|
super(message);
|
|
13
23
|
this.name = "MastraConnectError";
|
|
14
24
|
this.code = code;
|
|
15
25
|
this.status = options?.status;
|
|
16
26
|
this.detail = options?.detail ? truncate(options.detail) : void 0;
|
|
27
|
+
if (typeof options?.status === "number") this.response = { status: options.status };
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* A caller configuration mistake (for example an unknown tool name in
|
|
32
|
+
* `requireApproval`) that must fail resolution instead of being downgraded
|
|
33
|
+
* to the resolver's warn-and-skip path, which exists for provider-side
|
|
34
|
+
* failures. Internal to the package: callers observe it as a regular
|
|
35
|
+
* `MastraConnectError` with code `invalid_options`.
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
var MastraConnectConfigError = class extends MastraConnectError {
|
|
40
|
+
constructor(message) {
|
|
41
|
+
super("invalid_options", message);
|
|
17
42
|
}
|
|
18
43
|
};
|
|
19
44
|
function truncate(text) {
|
|
20
45
|
return text.length > MAX_DETAIL_LENGTH ? `${text.slice(0, MAX_DETAIL_LENGTH)}…` : text;
|
|
21
46
|
}
|
|
22
47
|
/**
|
|
48
|
+
* Pulls the first human-readable message from an array of error entries. Many
|
|
49
|
+
* providers (Clerk, Linear's GraphQL envelope, Nango v2) return
|
|
50
|
+
* `{ errors: [{ message, long_message, code }] }`; surfacing the first message
|
|
51
|
+
* is the most useful detail without echoing the whole payload.
|
|
52
|
+
*/
|
|
53
|
+
function extractFirstArrayMessage(errors) {
|
|
54
|
+
for (const entry of errors) {
|
|
55
|
+
if (!entry || typeof entry !== "object") continue;
|
|
56
|
+
const record = entry;
|
|
57
|
+
const message = typeof record.long_message === "string" ? record.long_message : record.message;
|
|
58
|
+
if (typeof message === "string" && message) return message;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
23
62
|
* Extracts a human-readable detail string from an RFC-7807 problem JSON body
|
|
24
63
|
* (or a plain `{ error }` body) without echoing anything else from the response.
|
|
25
64
|
* Returns undefined when the body is not parseable JSON.
|
|
@@ -50,6 +89,14 @@ async function extractProblemDetail(response) {
|
|
|
50
89
|
};
|
|
51
90
|
}
|
|
52
91
|
}
|
|
92
|
+
if (Array.isArray(data.errors)) {
|
|
93
|
+
const message = extractFirstArrayMessage(data.errors);
|
|
94
|
+
if (message) return {
|
|
95
|
+
detail: truncate(message),
|
|
96
|
+
code,
|
|
97
|
+
isProblemJson
|
|
98
|
+
};
|
|
99
|
+
}
|
|
53
100
|
return {
|
|
54
101
|
code,
|
|
55
102
|
isProblemJson
|
|
@@ -59,6 +106,98 @@ async function extractProblemDetail(response) {
|
|
|
59
106
|
return { isProblemJson };
|
|
60
107
|
}
|
|
61
108
|
//#endregion
|
|
109
|
+
//#region src/instrumentation.ts
|
|
110
|
+
const ID_SEGMENT_ROUTES = [{
|
|
111
|
+
prefix: "/v2/connections/",
|
|
112
|
+
placeholder: "{connectionId}",
|
|
113
|
+
key: "connectionId"
|
|
114
|
+
}, {
|
|
115
|
+
prefix: "/v2/projects/",
|
|
116
|
+
placeholder: "{projectId}",
|
|
117
|
+
key: "projectId"
|
|
118
|
+
}];
|
|
119
|
+
const PROXY_SEGMENT = "/proxy/";
|
|
120
|
+
/** Describes a platform request for span naming without leaking query params, ids, or vendor path segments. */
|
|
121
|
+
function describePlatformCall(method, rawPath) {
|
|
122
|
+
const path = rawPath.split("?")[0];
|
|
123
|
+
let route = path;
|
|
124
|
+
const descriptor = {
|
|
125
|
+
method,
|
|
126
|
+
route,
|
|
127
|
+
isProxy: false
|
|
128
|
+
};
|
|
129
|
+
for (const idRoute of ID_SEGMENT_ROUTES) {
|
|
130
|
+
if (!path.startsWith(idRoute.prefix)) continue;
|
|
131
|
+
const rest = path.slice(idRoute.prefix.length);
|
|
132
|
+
const slash = rest.indexOf("/");
|
|
133
|
+
const id = slash === -1 ? rest : rest.slice(0, slash);
|
|
134
|
+
const tail = slash === -1 ? "" : rest.slice(slash);
|
|
135
|
+
descriptor[idRoute.key] = safeDecode(id);
|
|
136
|
+
route = `${idRoute.prefix}${idRoute.placeholder}${tail}`;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
const proxyIndex = route.indexOf(PROXY_SEGMENT);
|
|
140
|
+
if (proxyIndex !== -1) {
|
|
141
|
+
descriptor.isProxy = true;
|
|
142
|
+
route = `${route.slice(0, proxyIndex + 7)}*`;
|
|
143
|
+
}
|
|
144
|
+
descriptor.route = route;
|
|
145
|
+
return descriptor;
|
|
146
|
+
}
|
|
147
|
+
function safeDecode(segment) {
|
|
148
|
+
try {
|
|
149
|
+
return decodeURIComponent(segment);
|
|
150
|
+
} catch {
|
|
151
|
+
return segment;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Starts a GENERIC child span for an outbound connect HTTP call, or returns
|
|
156
|
+
* `undefined` when no ambient span is active. Span creation failures are
|
|
157
|
+
* swallowed: instrumentation must never break a request.
|
|
158
|
+
*/
|
|
159
|
+
function startPlatformCallSpan(descriptor) {
|
|
160
|
+
let parent;
|
|
161
|
+
try {
|
|
162
|
+
parent = (0, _mastra_core_observability.resolveCurrentSpan)();
|
|
163
|
+
if (!parent) return void 0;
|
|
164
|
+
return parent.createChildSpan({
|
|
165
|
+
type: _mastra_core_observability.SpanType.GENERIC,
|
|
166
|
+
name: `connect.${descriptor.isProxy ? "proxy" : "platform"} ${descriptor.method} ${descriptor.route}`,
|
|
167
|
+
metadata: {
|
|
168
|
+
method: descriptor.method,
|
|
169
|
+
route: descriptor.route,
|
|
170
|
+
...descriptor.connectionId ? { connectionId: descriptor.connectionId } : {},
|
|
171
|
+
...descriptor.projectId ? { projectId: descriptor.projectId } : {}
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
} catch {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** Ends a platform-call span with the response status. Never throws. */
|
|
179
|
+
function endPlatformCallSpan(span, status) {
|
|
180
|
+
if (!span) return;
|
|
181
|
+
try {
|
|
182
|
+
span.end({ metadata: { status } });
|
|
183
|
+
} catch {}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Records a transport-level failure on a platform-call span. Nothing from the
|
|
187
|
+
* original error is recorded — fetch failures can embed the request URL in
|
|
188
|
+
* both `message` and `name`, which may carry secret query params — so the
|
|
189
|
+
* span gets a fixed, constant error. Never throws.
|
|
190
|
+
*/
|
|
191
|
+
function errorPlatformCallSpan(span, _error) {
|
|
192
|
+
if (!span) return;
|
|
193
|
+
try {
|
|
194
|
+
span.error({
|
|
195
|
+
error: /* @__PURE__ */ new Error("connect request failed"),
|
|
196
|
+
endSpan: true
|
|
197
|
+
});
|
|
198
|
+
} catch {}
|
|
199
|
+
}
|
|
200
|
+
//#endregion
|
|
62
201
|
//#region src/client.ts
|
|
63
202
|
const DEFAULT_INTEGRATIONS_URL = "https://integrations.mastra.ai";
|
|
64
203
|
const REGIONAL_INTEGRATIONS_URLS = {
|
|
@@ -101,20 +240,25 @@ function redact(message, accessToken) {
|
|
|
101
240
|
return message.split(accessToken).join("[REDACTED]");
|
|
102
241
|
}
|
|
103
242
|
async function platformFetch(client, path, init) {
|
|
243
|
+
const span = startPlatformCallSpan(describePlatformCall(init?.method ?? "GET", path));
|
|
104
244
|
try {
|
|
105
|
-
|
|
245
|
+
const response = await client.fetch(`${client.baseUrl}${path}`, {
|
|
106
246
|
...init,
|
|
107
247
|
headers: {
|
|
108
248
|
...client.headers,
|
|
109
249
|
...init?.headers
|
|
110
250
|
}
|
|
111
251
|
});
|
|
252
|
+
endPlatformCallSpan(span, response.status);
|
|
253
|
+
return response;
|
|
112
254
|
} catch (error) {
|
|
113
255
|
if (error instanceof Error && error.message.includes(client.accessToken)) {
|
|
114
256
|
const redacted = new Error(redact(error.message, client.accessToken));
|
|
115
257
|
redacted.name = error.name;
|
|
258
|
+
errorPlatformCallSpan(span, redacted);
|
|
116
259
|
throw redacted;
|
|
117
260
|
}
|
|
261
|
+
errorPlatformCallSpan(span, error);
|
|
118
262
|
throw error;
|
|
119
263
|
}
|
|
120
264
|
}
|
|
@@ -189,14 +333,35 @@ const integrationCatalogEntrySchema = zod.z.object({
|
|
|
189
333
|
capabilities: zod.z.object({ mcp: zod.z.boolean().optional() })
|
|
190
334
|
});
|
|
191
335
|
const integrationCatalogResponseSchema = zod.z.object({ integrations: zod.z.array(integrationCatalogEntrySchema) });
|
|
192
|
-
|
|
193
|
-
|
|
336
|
+
/**
|
|
337
|
+
* Secondary access token minted by the vendor alongside the primary oauth2
|
|
338
|
+
* credential (e.g. `devPortalAccessToken` on Microsoft Teams connections).
|
|
339
|
+
* Keyed by the vendor's connection-config field name. Treat this like any
|
|
340
|
+
* other bearer credential — it authenticates second-audience API calls
|
|
341
|
+
* (Teams Dev Portal, etc.) and must not be logged or forwarded to code that
|
|
342
|
+
* shouldn't hold connection secrets.
|
|
343
|
+
*/
|
|
344
|
+
const secondaryAccessTokenSchema = zod.z.object({
|
|
194
345
|
accessToken: zod.z.string(),
|
|
195
346
|
expiresAt: zod.z.string().nullable()
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
347
|
+
});
|
|
348
|
+
const credentialSchema = zod.z.discriminatedUnion("type", [
|
|
349
|
+
zod.z.object({
|
|
350
|
+
type: zod.z.literal("oauth2"),
|
|
351
|
+
accessToken: zod.z.string(),
|
|
352
|
+
expiresAt: zod.z.string().nullable(),
|
|
353
|
+
secondaryAccessTokens: zod.z.record(zod.z.string(), secondaryAccessTokenSchema).optional()
|
|
354
|
+
}),
|
|
355
|
+
zod.z.object({
|
|
356
|
+
type: zod.z.literal("api_key"),
|
|
357
|
+
apiKey: zod.z.string()
|
|
358
|
+
}),
|
|
359
|
+
zod.z.object({
|
|
360
|
+
type: zod.z.literal("two_step"),
|
|
361
|
+
token: zod.z.string(),
|
|
362
|
+
expiresAt: zod.z.string().nullable()
|
|
363
|
+
})
|
|
364
|
+
]);
|
|
200
365
|
const connectionContextSchema = zod.z.object({
|
|
201
366
|
connection_config: zod.z.record(zod.z.string(), zod.z.unknown()).nullable(),
|
|
202
367
|
metadata: zod.z.record(zod.z.string(), zod.z.unknown()).nullable()
|
|
@@ -272,9 +437,6 @@ function assertValidBaseUrlOverride(baseUrlOverride) {
|
|
|
272
437
|
if (parsed.protocol !== "https:") throw new MastraConnectError("invalid_options", `Invalid baseUrlOverride '${baseUrlOverride}': only https:// URLs are allowed.`);
|
|
273
438
|
if (parsed.username || parsed.password) throw new MastraConnectError("invalid_options", `Invalid baseUrlOverride '${baseUrlOverride}': embedded credentials are not allowed.`);
|
|
274
439
|
}
|
|
275
|
-
async function proxyRequest(client, connectionId, options) {
|
|
276
|
-
return (await proxyRequestWithResponse(client, connectionId, options)).data;
|
|
277
|
-
}
|
|
278
440
|
/** Preserves HTTP metadata for tools with status-dependent provider contracts. */
|
|
279
441
|
async function proxyRequestWithResponse(client, connectionId, options) {
|
|
280
442
|
const cleanPath = options.path.replace(/^\/+/, "");
|
|
@@ -287,7 +449,12 @@ async function proxyRequestWithResponse(client, connectionId, options) {
|
|
|
287
449
|
}
|
|
288
450
|
const queryString = search.size > 0 ? `?${search.toString()}` : "";
|
|
289
451
|
const url = `/v2/connections/${encodeURIComponent(connectionId)}/proxy/${cleanPath}${queryString}`;
|
|
290
|
-
const headers = {
|
|
452
|
+
const headers = {};
|
|
453
|
+
for (const [name, value] of Object.entries(options.headers ?? {})) {
|
|
454
|
+
const lower = name.toLowerCase();
|
|
455
|
+
if (lower === "authorization" || lower === "proxy-authorization") continue;
|
|
456
|
+
headers[name] = value;
|
|
457
|
+
}
|
|
291
458
|
if (options.baseUrlOverride !== void 0) {
|
|
292
459
|
assertValidBaseUrlOverride(options.baseUrlOverride);
|
|
293
460
|
headers["base-url-override"] = options.baseUrlOverride;
|
|
@@ -356,37 +523,64 @@ async function proxyRequestWithResponse(client, connectionId, options) {
|
|
|
356
523
|
}
|
|
357
524
|
//#endregion
|
|
358
525
|
//#region src/toolset.ts
|
|
359
|
-
/**
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
526
|
+
/**
|
|
527
|
+
* Compiles a tool-filter entry containing `*` wildcards into an anchored
|
|
528
|
+
* regex; every other character matches literally.
|
|
529
|
+
*/
|
|
530
|
+
function compileToolPattern(pattern) {
|
|
531
|
+
const escaped = pattern.split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join(".*");
|
|
532
|
+
return new RegExp(`^${escaped}$`);
|
|
364
533
|
}
|
|
365
534
|
/**
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
535
|
+
* Returns a predicate testing tool keys against filter `entries`, where an
|
|
536
|
+
* entry containing `*` is a glob and anything else matches literally. Used
|
|
537
|
+
* where keys are only known later (MCP approval predicates); list-shaped
|
|
538
|
+
* call sites expand eagerly with {@link expandToolPatterns} instead.
|
|
369
539
|
*/
|
|
370
|
-
function
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
540
|
+
function compileToolMatcher(entries) {
|
|
541
|
+
const literals = /* @__PURE__ */ new Set();
|
|
542
|
+
const patterns = [];
|
|
543
|
+
for (const entry of entries) if (entry.includes("*")) patterns.push(compileToolPattern(entry));
|
|
544
|
+
else literals.add(entry);
|
|
545
|
+
return (toolKey) => literals.has(toolKey) || patterns.some((pattern) => pattern.test(toolKey));
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Expands `*` glob entries against the known tool keys, preserving order and
|
|
549
|
+
* de-duplicating. Literal entries pass through untouched (callers validate
|
|
550
|
+
* those against their own key sets). A glob that matches nothing throws:
|
|
551
|
+
* like an unknown literal name, a dead pattern in access-limiting config is
|
|
552
|
+
* a typo that must surface instead of silently filtering nothing.
|
|
553
|
+
*/
|
|
554
|
+
function expandToolPatterns(entries, knownKeys, label) {
|
|
555
|
+
const expanded = [];
|
|
556
|
+
const seen = /* @__PURE__ */ new Set();
|
|
557
|
+
const push = (key) => {
|
|
558
|
+
if (seen.has(key)) return;
|
|
559
|
+
seen.add(key);
|
|
560
|
+
expanded.push(key);
|
|
561
|
+
};
|
|
562
|
+
for (const entry of entries) {
|
|
563
|
+
if (!entry.includes("*")) {
|
|
564
|
+
push(entry);
|
|
565
|
+
continue;
|
|
380
566
|
}
|
|
381
|
-
|
|
567
|
+
const pattern = compileToolPattern(entry);
|
|
568
|
+
const matches = knownKeys.filter((key) => pattern.test(key));
|
|
569
|
+
if (matches.length === 0) throw new MastraConnectConfigError(`Pattern '${entry}' in ${label} matched no tools. Known tools: ${knownKeys.join(", ")}.`);
|
|
570
|
+
for (const match of matches) push(match);
|
|
571
|
+
}
|
|
572
|
+
return expanded;
|
|
382
573
|
}
|
|
383
574
|
/**
|
|
384
|
-
* Filters a toolset by tool key.
|
|
385
|
-
*
|
|
575
|
+
* Filters a toolset by tool key. Entries containing `*` are globs expanded
|
|
576
|
+
* against the toolset's keys. Throws at build time on unknown names and on
|
|
577
|
+
* globs that match nothing, so typos in access-limiting config surface
|
|
578
|
+
* immediately.
|
|
386
579
|
*/
|
|
387
|
-
function applyAllowTools(tools,
|
|
388
|
-
if (!
|
|
580
|
+
function applyAllowTools(tools, allowToolsInput) {
|
|
581
|
+
if (!allowToolsInput) return tools;
|
|
389
582
|
const known = Object.keys(tools);
|
|
583
|
+
const allowTools = expandToolPatterns(allowToolsInput, known, "allowTools");
|
|
390
584
|
const unknown = allowTools.filter((name) => !known.includes(name));
|
|
391
585
|
if (unknown.length > 0) throw new Error(`Unknown tool name(s) in allowTools: ${unknown.join(", ")}. Known tools: ${known.join(", ")}.`);
|
|
392
586
|
const filtered = {};
|
|
@@ -394,13 +588,15 @@ function applyAllowTools(tools, allowTools) {
|
|
|
394
588
|
return filtered;
|
|
395
589
|
}
|
|
396
590
|
/**
|
|
397
|
-
* Removes tool keys from a toolset.
|
|
398
|
-
*
|
|
399
|
-
*
|
|
591
|
+
* Removes tool keys from a toolset. Entries containing `*` are globs
|
|
592
|
+
* expanded against the toolset's keys. Throws at build time on unknown names
|
|
593
|
+
* and on globs that match nothing, so typos in access-limiting config
|
|
594
|
+
* surface immediately instead of silently removing nothing.
|
|
400
595
|
*/
|
|
401
|
-
function applyDisallowTools(tools,
|
|
402
|
-
if (!
|
|
596
|
+
function applyDisallowTools(tools, disallowToolsInput) {
|
|
597
|
+
if (!disallowToolsInput || disallowToolsInput.length === 0) return tools;
|
|
403
598
|
const known = Object.keys(tools);
|
|
599
|
+
const disallowTools = expandToolPatterns(disallowToolsInput, known, "disallowTools");
|
|
404
600
|
const unknown = disallowTools.filter((name) => !known.includes(name));
|
|
405
601
|
if (unknown.length > 0) throw new Error(`Unknown tool name(s) in disallowTools: ${unknown.join(", ")}. Known tools: ${known.join(", ")}.`);
|
|
406
602
|
const remove = new Set(disallowTools);
|
|
@@ -637,8 +833,8 @@ function buildProxyMultiConnectionTools(input) {
|
|
|
637
833
|
* client cache so stale clients can be reaped elsewhere.
|
|
638
834
|
*/
|
|
639
835
|
async function buildMcpMultiConnectionTools(input) {
|
|
640
|
-
const { registration, connections, allowTools, disallowTools,
|
|
641
|
-
const
|
|
836
|
+
const { registration, connections, allowTools, disallowTools, requireApproval, client, mcpClients, resolverId } = input;
|
|
837
|
+
const requireApprovalFor = Array.isArray(requireApproval) ? compileToolMatcher(requireApproval) : void 0;
|
|
642
838
|
const listToolKey = listConnectionsToolKey(registration.integrationId);
|
|
643
839
|
const innerAllowTools = allowTools?.filter((name) => name !== listToolKey);
|
|
644
840
|
const innerDisallowTools = disallowTools?.filter((name) => name !== listToolKey);
|
|
@@ -662,7 +858,7 @@ async function buildMcpMultiConnectionTools(input) {
|
|
|
662
858
|
id: `mastra-connect-${resolverId}-${registration.integrationId}-${connection.id}`,
|
|
663
859
|
servers: { [registration.integrationId]: {
|
|
664
860
|
...transport,
|
|
665
|
-
requireToolApproval: ({ toolName }) =>
|
|
861
|
+
...requireApproval === true ? { requireToolApproval: true } : requireApprovalFor ? { requireToolApproval: ({ toolName }) => requireApprovalFor(`${registration.integrationId}_${String(toolName)}`) } : {}
|
|
666
862
|
} }
|
|
667
863
|
})
|
|
668
864
|
};
|
|
@@ -679,8 +875,10 @@ async function buildMcpMultiConnectionTools(input) {
|
|
|
679
875
|
}
|
|
680
876
|
const catalogUnion = /* @__PURE__ */ new Set();
|
|
681
877
|
for (const catalog of rawInnerCatalogs.values()) for (const key of Object.keys(catalog)) catalogUnion.add(key);
|
|
682
|
-
|
|
683
|
-
|
|
878
|
+
if (Array.isArray(requireApproval)) {
|
|
879
|
+
const unknown = expandToolPatterns(requireApproval, [...catalogUnion], `requireApproval for '${registration.integrationId}'`).filter((name) => !catalogUnion.has(name));
|
|
880
|
+
if (unknown.length > 0) throw new MastraConnectConfigError(`Unknown tool name(s) in requireApproval for '${registration.integrationId}': ${unknown.join(", ")}. Known tools: ${[...catalogUnion].join(", ")}.`);
|
|
881
|
+
}
|
|
684
882
|
innerToolsByConnectionId = /* @__PURE__ */ new Map();
|
|
685
883
|
for (const [connectionId, catalog] of rawInnerCatalogs) {
|
|
686
884
|
const filtered = applyToolFilter(catalog, {
|
|
@@ -708,11 +906,15 @@ async function buildMcpMultiConnectionTools(input) {
|
|
|
708
906
|
}
|
|
709
907
|
//#endregion
|
|
710
908
|
//#region src/providers/channels.ts
|
|
711
|
-
function credentialToken
|
|
712
|
-
|
|
909
|
+
function credentialToken(credential) {
|
|
910
|
+
switch (credential.type) {
|
|
911
|
+
case "oauth2": return credential.accessToken;
|
|
912
|
+
case "two_step": return credential.token;
|
|
913
|
+
default: return credential.apiKey;
|
|
914
|
+
}
|
|
713
915
|
}
|
|
714
916
|
const RESERVED_OPTION_KEYS = {
|
|
715
|
-
slack: [
|
|
917
|
+
"slack-channels": [
|
|
716
918
|
"baseUrl",
|
|
717
919
|
"refreshToken",
|
|
718
920
|
"token",
|
|
@@ -726,7 +928,14 @@ const RESERVED_OPTION_KEYS = {
|
|
|
726
928
|
"tokenResolver",
|
|
727
929
|
"encryptionKey"
|
|
728
930
|
],
|
|
729
|
-
discord: ["baseUrl", "encryptionKey"]
|
|
931
|
+
discord: ["baseUrl", "encryptionKey"],
|
|
932
|
+
"microsoft-teams": [
|
|
933
|
+
"baseUrl",
|
|
934
|
+
"appId",
|
|
935
|
+
"appPassword",
|
|
936
|
+
"tokenResolver",
|
|
937
|
+
"encryptionKey"
|
|
938
|
+
]
|
|
730
939
|
};
|
|
731
940
|
function stripReservedOptions(integrationId, options) {
|
|
732
941
|
if (!options) return options;
|
|
@@ -746,12 +955,12 @@ function stripReservedOptions(integrationId, options) {
|
|
|
746
955
|
}
|
|
747
956
|
const CHANNELS$1 = [
|
|
748
957
|
{
|
|
749
|
-
integrationId: "slack",
|
|
958
|
+
integrationId: "slack-channels",
|
|
750
959
|
async create(options, runtime) {
|
|
751
960
|
const mod = await import("@mastra/slack");
|
|
752
|
-
const safeOptions = stripReservedOptions("slack", options);
|
|
961
|
+
const safeOptions = stripReservedOptions("slack-channels", options);
|
|
753
962
|
const tokenResolver = async () => {
|
|
754
|
-
return credentialToken
|
|
963
|
+
return credentialToken(await runtime.getCredential());
|
|
755
964
|
};
|
|
756
965
|
return { provider: new mod.SlackProvider({
|
|
757
966
|
tokenResolver,
|
|
@@ -765,7 +974,7 @@ const CHANNELS$1 = [
|
|
|
765
974
|
const mod = await import("@mastra/telegram");
|
|
766
975
|
const safeOptions = stripReservedOptions("telegram", options);
|
|
767
976
|
const tokenResolver = async () => {
|
|
768
|
-
return credentialToken
|
|
977
|
+
return credentialToken(await runtime.getCredential());
|
|
769
978
|
};
|
|
770
979
|
return { provider: new mod.TelegramProvider({
|
|
771
980
|
tokenResolver,
|
|
@@ -797,17 +1006,42 @@ const CHANNELS$1 = [
|
|
|
797
1006
|
}
|
|
798
1007
|
};
|
|
799
1008
|
}
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
integrationId: "microsoft-teams",
|
|
1012
|
+
async create(options, runtime) {
|
|
1013
|
+
const mod = await import("@mastra/teams");
|
|
1014
|
+
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).");
|
|
1015
|
+
const safeOptions = stripReservedOptions("microsoft-teams", options);
|
|
1016
|
+
const tokenResolver = async (scope) => {
|
|
1017
|
+
const fresh = await runtime.getCredential();
|
|
1018
|
+
if (!(Array.isArray(scope) ? scope : [scope]).includes(mod.TEAMS_DEV_PORTAL_SCOPE)) return credentialToken(fresh);
|
|
1019
|
+
const token = fresh.type === "oauth2" ? fresh.secondaryAccessTokens?.devPortalAccessToken?.accessToken : void 0;
|
|
1020
|
+
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.`);
|
|
1021
|
+
return token;
|
|
1022
|
+
};
|
|
1023
|
+
return { provider: new mod.TeamsProvider({
|
|
1024
|
+
tokenResolver,
|
|
1025
|
+
...safeOptions ?? {}
|
|
1026
|
+
}) };
|
|
1027
|
+
}
|
|
800
1028
|
}
|
|
801
1029
|
];
|
|
802
1030
|
//#endregion
|
|
803
1031
|
//#region src/runtime/platform-proxy.ts
|
|
804
1032
|
/** Maps the platform credential to the field names templates are written against. */
|
|
805
1033
|
function toTemplateCredentials(credential) {
|
|
806
|
-
|
|
1034
|
+
if (credential.type === "oauth2") return {
|
|
807
1035
|
type: "OAUTH2",
|
|
808
1036
|
access_token: credential.accessToken,
|
|
809
1037
|
expires_at: credential.expiresAt
|
|
810
|
-
}
|
|
1038
|
+
};
|
|
1039
|
+
if (credential.type === "two_step") return {
|
|
1040
|
+
type: "TWO_STEP",
|
|
1041
|
+
token: credential.token,
|
|
1042
|
+
expires_at: credential.expiresAt
|
|
1043
|
+
};
|
|
1044
|
+
return {
|
|
811
1045
|
type: "API_KEY",
|
|
812
1046
|
apiKey: credential.apiKey
|
|
813
1047
|
};
|
|
@@ -1735,8 +1969,8 @@ const anthropicProvider = {
|
|
|
1735
1969
|
//#endregion
|
|
1736
1970
|
//#region src/providers/clerk/tools/assign-organization-role-permission.ts
|
|
1737
1971
|
const assignOrganizationRolePermissionInputSchema = zod.z.object({
|
|
1738
|
-
organization_role_id: zod.z.string(),
|
|
1739
|
-
permission_id: zod.z.string()
|
|
1972
|
+
organization_role_id: zod.z.string().min(1),
|
|
1973
|
+
permission_id: zod.z.string().min(1)
|
|
1740
1974
|
});
|
|
1741
1975
|
const ResourceSchema$49 = zod.z.object({
|
|
1742
1976
|
id: zod.z.string(),
|
|
@@ -1772,8 +2006,8 @@ function assignOrganizationRolePermissionTool(proxy) {
|
|
|
1772
2006
|
//#endregion
|
|
1773
2007
|
//#region src/providers/clerk/tools/create-email-address.ts
|
|
1774
2008
|
const createEmailAddressInputSchema = zod.z.object({
|
|
1775
|
-
user_id: zod.z.string(),
|
|
1776
|
-
email_address: zod.z.string(),
|
|
2009
|
+
user_id: zod.z.string().min(1),
|
|
2010
|
+
email_address: zod.z.string().email(),
|
|
1777
2011
|
verified: zod.z.boolean().optional(),
|
|
1778
2012
|
primary: zod.z.boolean().optional(),
|
|
1779
2013
|
notify_primary_email_address_changed: zod.z.boolean().optional()
|
|
@@ -1818,16 +2052,22 @@ function createEmailAddressTool(proxy) {
|
|
|
1818
2052
|
}
|
|
1819
2053
|
//#endregion
|
|
1820
2054
|
//#region src/providers/clerk/tools/create-organization-domain.ts
|
|
1821
|
-
const EnrollmentModeSchema$
|
|
2055
|
+
const EnrollmentModeSchema$3 = zod.z.enum([
|
|
1822
2056
|
"manual_invitation",
|
|
1823
2057
|
"automatic_invitation",
|
|
1824
2058
|
"automatic_suggestion",
|
|
1825
2059
|
"enterprise_sso"
|
|
1826
2060
|
]);
|
|
2061
|
+
const EnrollmentModeSchemaWidened$2 = zod.z.enum([
|
|
2062
|
+
"manual_invitation",
|
|
2063
|
+
"automatic_invitation",
|
|
2064
|
+
"automatic_suggestion",
|
|
2065
|
+
"enterprise_sso"
|
|
2066
|
+
]).or(zod.z.string());
|
|
1827
2067
|
const createOrganizationDomainInputSchema$1 = zod.z.object({
|
|
1828
|
-
organization_id: zod.z.string(),
|
|
2068
|
+
organization_id: zod.z.string().min(1),
|
|
1829
2069
|
name: zod.z.string(),
|
|
1830
|
-
enrollment_mode: EnrollmentModeSchema$
|
|
2070
|
+
enrollment_mode: EnrollmentModeSchema$3,
|
|
1831
2071
|
verified: zod.z.boolean().optional()
|
|
1832
2072
|
});
|
|
1833
2073
|
const ResourceSchema$47 = zod.z.object({
|
|
@@ -1835,15 +2075,15 @@ const ResourceSchema$47 = zod.z.object({
|
|
|
1835
2075
|
object: zod.z.string().optional(),
|
|
1836
2076
|
organization_id: zod.z.string().optional(),
|
|
1837
2077
|
name: zod.z.string(),
|
|
1838
|
-
enrollment_mode:
|
|
2078
|
+
enrollment_mode: EnrollmentModeSchemaWidened$2.optional(),
|
|
1839
2079
|
affiliation_verification: zod.z.object({
|
|
1840
2080
|
attempts: zod.z.number().optional(),
|
|
1841
2081
|
status: zod.z.string().optional()
|
|
1842
|
-
}).passthrough().optional(),
|
|
2082
|
+
}).passthrough().nullable().optional(),
|
|
1843
2083
|
verification: zod.z.object({
|
|
1844
2084
|
attempts: zod.z.number().optional(),
|
|
1845
2085
|
status: zod.z.string().optional()
|
|
1846
|
-
}).passthrough().optional(),
|
|
2086
|
+
}).passthrough().nullable().optional(),
|
|
1847
2087
|
verified: zod.z.boolean().optional(),
|
|
1848
2088
|
created_at: zod.z.number().optional(),
|
|
1849
2089
|
updated_at: zod.z.number().optional()
|
|
@@ -1872,7 +2112,7 @@ function createOrganizationDomainTool$1(proxy) {
|
|
|
1872
2112
|
//#endregion
|
|
1873
2113
|
//#region src/providers/clerk/tools/create-organization-invitation.ts
|
|
1874
2114
|
const createOrganizationInvitationInputSchema = zod.z.object({
|
|
1875
|
-
organization_id: zod.z.string(),
|
|
2115
|
+
organization_id: zod.z.string().min(1),
|
|
1876
2116
|
email_address: zod.z.string().email(),
|
|
1877
2117
|
role: zod.z.string(),
|
|
1878
2118
|
inviter_user_id: zod.z.string().optional(),
|
|
@@ -1893,7 +2133,7 @@ const ResourceSchema$46 = zod.z.object({
|
|
|
1893
2133
|
"accepted",
|
|
1894
2134
|
"revoked",
|
|
1895
2135
|
"expired"
|
|
1896
|
-
]).optional(),
|
|
2136
|
+
]).or(zod.z.string()).optional(),
|
|
1897
2137
|
created_at: zod.z.number().optional(),
|
|
1898
2138
|
updated_at: zod.z.number().optional()
|
|
1899
2139
|
}).passthrough();
|
|
@@ -1926,8 +2166,8 @@ function createOrganizationInvitationTool(proxy) {
|
|
|
1926
2166
|
//#endregion
|
|
1927
2167
|
//#region src/providers/clerk/tools/create-organization-membership.ts
|
|
1928
2168
|
const createOrganizationMembershipInputSchema$1 = zod.z.object({
|
|
1929
|
-
organization_id: zod.z.string(),
|
|
1930
|
-
user_id: zod.z.string(),
|
|
2169
|
+
organization_id: zod.z.string().min(1),
|
|
2170
|
+
user_id: zod.z.string().min(1),
|
|
1931
2171
|
role: zod.z.string(),
|
|
1932
2172
|
public_metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
1933
2173
|
private_metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
@@ -2063,7 +2303,7 @@ function createOrganizationTool$1(proxy) {
|
|
|
2063
2303
|
//#endregion
|
|
2064
2304
|
//#region src/providers/clerk/tools/create-phone-number.ts
|
|
2065
2305
|
const createPhoneNumberInputSchema = zod.z.object({
|
|
2066
|
-
user_id: zod.z.string(),
|
|
2306
|
+
user_id: zod.z.string().min(1),
|
|
2067
2307
|
phone_number: zod.z.string(),
|
|
2068
2308
|
verified: zod.z.boolean().optional(),
|
|
2069
2309
|
primary: zod.z.boolean().optional(),
|
|
@@ -2126,7 +2366,7 @@ const createUserInputSchema$2 = zod.z.object({
|
|
|
2126
2366
|
public_metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
2127
2367
|
private_metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
2128
2368
|
unsafe_metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
2129
|
-
});
|
|
2369
|
+
}).refine((value) => (value.email_address?.length ?? 0) > 0 || (value.phone_number?.length ?? 0) > 0 || value.username !== void 0 || value.password !== void 0, { message: "Provide at least one of email_address, phone_number, username, or password." });
|
|
2130
2370
|
const UserSchema$27 = zod.z.object({
|
|
2131
2371
|
id: zod.z.string(),
|
|
2132
2372
|
object: zod.z.string().optional(),
|
|
@@ -2178,7 +2418,7 @@ function createUserTool$2(proxy) {
|
|
|
2178
2418
|
}
|
|
2179
2419
|
//#endregion
|
|
2180
2420
|
//#region src/providers/clerk/tools/delete-email-address.ts
|
|
2181
|
-
const deleteEmailAddressInputSchema = zod.z.object({ email_address_id: zod.z.string() });
|
|
2421
|
+
const deleteEmailAddressInputSchema = zod.z.object({ email_address_id: zod.z.string().min(1) });
|
|
2182
2422
|
const deleteEmailAddressOutputSchema = zod.z.object({
|
|
2183
2423
|
id: zod.z.string(),
|
|
2184
2424
|
success: zod.z.boolean()
|
|
@@ -2204,8 +2444,8 @@ function deleteEmailAddressTool(proxy) {
|
|
|
2204
2444
|
//#endregion
|
|
2205
2445
|
//#region src/providers/clerk/tools/delete-organization-domain.ts
|
|
2206
2446
|
const deleteOrganizationDomainInputSchema$1 = zod.z.object({
|
|
2207
|
-
organization_id: zod.z.string(),
|
|
2208
|
-
domain_id: zod.z.string()
|
|
2447
|
+
organization_id: zod.z.string().min(1),
|
|
2448
|
+
domain_id: zod.z.string().min(1)
|
|
2209
2449
|
});
|
|
2210
2450
|
const deleteOrganizationDomainOutputSchema$1 = zod.z.object({
|
|
2211
2451
|
id: zod.z.string(),
|
|
@@ -2232,8 +2472,8 @@ function deleteOrganizationDomainTool$1(proxy) {
|
|
|
2232
2472
|
//#endregion
|
|
2233
2473
|
//#region src/providers/clerk/tools/delete-organization-membership.ts
|
|
2234
2474
|
const deleteOrganizationMembershipInputSchema$1 = zod.z.object({
|
|
2235
|
-
organization_id: zod.z.string(),
|
|
2236
|
-
user_id: zod.z.string()
|
|
2475
|
+
organization_id: zod.z.string().min(1),
|
|
2476
|
+
user_id: zod.z.string().min(1)
|
|
2237
2477
|
});
|
|
2238
2478
|
const deleteOrganizationMembershipOutputSchema$1 = zod.z.object({
|
|
2239
2479
|
id: zod.z.string(),
|
|
@@ -2259,7 +2499,7 @@ function deleteOrganizationMembershipTool$1(proxy) {
|
|
|
2259
2499
|
}
|
|
2260
2500
|
//#endregion
|
|
2261
2501
|
//#region src/providers/clerk/tools/delete-organization-role.ts
|
|
2262
|
-
const deleteOrganizationRoleInputSchema = zod.z.object({ organization_role_id: zod.z.string() });
|
|
2502
|
+
const deleteOrganizationRoleInputSchema = zod.z.object({ organization_role_id: zod.z.string().min(1) });
|
|
2263
2503
|
const deleteOrganizationRoleOutputSchema = zod.z.object({
|
|
2264
2504
|
id: zod.z.string(),
|
|
2265
2505
|
success: zod.z.boolean()
|
|
@@ -2309,7 +2549,7 @@ function deleteOrganizationTool$1(proxy) {
|
|
|
2309
2549
|
}
|
|
2310
2550
|
//#endregion
|
|
2311
2551
|
//#region src/providers/clerk/tools/delete-phone-number.ts
|
|
2312
|
-
const deletePhoneNumberInputSchema = zod.z.object({ phone_number_id: zod.z.string() });
|
|
2552
|
+
const deletePhoneNumberInputSchema = zod.z.object({ phone_number_id: zod.z.string().min(1) });
|
|
2313
2553
|
const deletePhoneNumberOutputSchema = zod.z.object({
|
|
2314
2554
|
id: zod.z.string(),
|
|
2315
2555
|
success: zod.z.boolean()
|
|
@@ -2359,7 +2599,7 @@ function deleteUserTool$2(proxy) {
|
|
|
2359
2599
|
}
|
|
2360
2600
|
//#endregion
|
|
2361
2601
|
//#region src/providers/clerk/tools/get-email-address.ts
|
|
2362
|
-
const getEmailAddressInputSchema = zod.z.object({ email_address_id: zod.z.string() });
|
|
2602
|
+
const getEmailAddressInputSchema = zod.z.object({ email_address_id: zod.z.string().min(1) });
|
|
2363
2603
|
const ResourceSchema$42 = zod.z.object({
|
|
2364
2604
|
id: zod.z.string(),
|
|
2365
2605
|
object: zod.z.string().optional(),
|
|
@@ -2394,8 +2634,8 @@ function getEmailAddressTool(proxy) {
|
|
|
2394
2634
|
//#endregion
|
|
2395
2635
|
//#region src/providers/clerk/tools/get-organization-invitation.ts
|
|
2396
2636
|
const getOrganizationInvitationInputSchema = zod.z.object({
|
|
2397
|
-
organization_id: zod.z.string(),
|
|
2398
|
-
invitation_id: zod.z.string()
|
|
2637
|
+
organization_id: zod.z.string().min(1),
|
|
2638
|
+
invitation_id: zod.z.string().min(1)
|
|
2399
2639
|
});
|
|
2400
2640
|
const ResourceSchema$41 = zod.z.object({
|
|
2401
2641
|
id: zod.z.string(),
|
|
@@ -2408,7 +2648,7 @@ const ResourceSchema$41 = zod.z.object({
|
|
|
2408
2648
|
"accepted",
|
|
2409
2649
|
"revoked",
|
|
2410
2650
|
"expired"
|
|
2411
|
-
]).optional(),
|
|
2651
|
+
]).or(zod.z.string()).optional(),
|
|
2412
2652
|
created_at: zod.z.number().optional(),
|
|
2413
2653
|
updated_at: zod.z.number().optional()
|
|
2414
2654
|
}).passthrough();
|
|
@@ -2430,7 +2670,7 @@ function getOrganizationInvitationTool(proxy) {
|
|
|
2430
2670
|
}
|
|
2431
2671
|
//#endregion
|
|
2432
2672
|
//#region src/providers/clerk/tools/get-organization-role.ts
|
|
2433
|
-
const getOrganizationRoleInputSchema = zod.z.object({ organization_role_id: zod.z.string() });
|
|
2673
|
+
const getOrganizationRoleInputSchema = zod.z.object({ organization_role_id: zod.z.string().min(1) });
|
|
2434
2674
|
const ResourceSchema$40 = zod.z.object({
|
|
2435
2675
|
id: zod.z.string(),
|
|
2436
2676
|
object: zod.z.string().optional(),
|
|
@@ -2502,7 +2742,7 @@ function getOrganizationTool$1(proxy) {
|
|
|
2502
2742
|
}
|
|
2503
2743
|
//#endregion
|
|
2504
2744
|
//#region src/providers/clerk/tools/get-phone-number.ts
|
|
2505
|
-
const getPhoneNumberInputSchema = zod.z.object({ phone_number_id: zod.z.string() });
|
|
2745
|
+
const getPhoneNumberInputSchema = zod.z.object({ phone_number_id: zod.z.string().min(1) });
|
|
2506
2746
|
const ResourceSchema$39 = zod.z.object({
|
|
2507
2747
|
id: zod.z.string(),
|
|
2508
2748
|
object: zod.z.string().optional(),
|
|
@@ -2537,7 +2777,7 @@ function getPhoneNumberTool(proxy) {
|
|
|
2537
2777
|
}
|
|
2538
2778
|
//#endregion
|
|
2539
2779
|
//#region src/providers/clerk/tools/get-session.ts
|
|
2540
|
-
const getSessionInputSchema = zod.z.object({ session_id: zod.z.string() });
|
|
2780
|
+
const getSessionInputSchema = zod.z.object({ session_id: zod.z.string().min(1) });
|
|
2541
2781
|
const ResourceSchema$38 = zod.z.object({
|
|
2542
2782
|
id: zod.z.string(),
|
|
2543
2783
|
object: zod.z.string().optional(),
|
|
@@ -2551,7 +2791,7 @@ const ResourceSchema$38 = zod.z.object({
|
|
|
2551
2791
|
"removed",
|
|
2552
2792
|
"replaced",
|
|
2553
2793
|
"revoked"
|
|
2554
|
-
]).optional(),
|
|
2794
|
+
]).or(zod.z.string()).optional(),
|
|
2555
2795
|
last_active_at: zod.z.number().optional(),
|
|
2556
2796
|
expire_at: zod.z.number().optional(),
|
|
2557
2797
|
abandon_at: zod.z.number().optional(),
|
|
@@ -2611,33 +2851,39 @@ function getUserTool$7(proxy) {
|
|
|
2611
2851
|
}
|
|
2612
2852
|
//#endregion
|
|
2613
2853
|
//#region src/providers/clerk/tools/list-organization-domains.ts
|
|
2614
|
-
const EnrollmentModeSchema$
|
|
2854
|
+
const EnrollmentModeSchema$2 = zod.z.enum([
|
|
2615
2855
|
"manual_invitation",
|
|
2616
2856
|
"automatic_invitation",
|
|
2617
2857
|
"automatic_suggestion",
|
|
2618
2858
|
"enterprise_sso"
|
|
2619
2859
|
]);
|
|
2860
|
+
const EnrollmentModeSchemaWidened$1 = zod.z.enum([
|
|
2861
|
+
"manual_invitation",
|
|
2862
|
+
"automatic_invitation",
|
|
2863
|
+
"automatic_suggestion",
|
|
2864
|
+
"enterprise_sso"
|
|
2865
|
+
]).or(zod.z.string());
|
|
2620
2866
|
const listOrganizationDomainsInputSchema = zod.z.object({
|
|
2621
|
-
cursor: zod.z.string().optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2867
|
+
cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2622
2868
|
limit: zod.z.number().int().min(1).max(500).optional(),
|
|
2623
|
-
organization_id: zod.z.string(),
|
|
2869
|
+
organization_id: zod.z.string().min(1),
|
|
2624
2870
|
verified: zod.z.boolean().optional(),
|
|
2625
|
-
enrollment_mode: EnrollmentModeSchema$
|
|
2871
|
+
enrollment_mode: EnrollmentModeSchema$2.optional()
|
|
2626
2872
|
});
|
|
2627
2873
|
const ResourceSchema$37 = zod.z.object({
|
|
2628
2874
|
id: zod.z.string(),
|
|
2629
2875
|
object: zod.z.string().optional(),
|
|
2630
2876
|
organization_id: zod.z.string().optional(),
|
|
2631
2877
|
name: zod.z.string(),
|
|
2632
|
-
enrollment_mode:
|
|
2878
|
+
enrollment_mode: EnrollmentModeSchemaWidened$1.optional(),
|
|
2633
2879
|
affiliation_verification: zod.z.object({
|
|
2634
2880
|
attempts: zod.z.number().optional(),
|
|
2635
2881
|
status: zod.z.string().optional()
|
|
2636
|
-
}).passthrough().optional(),
|
|
2882
|
+
}).passthrough().nullable().optional(),
|
|
2637
2883
|
verification: zod.z.object({
|
|
2638
2884
|
attempts: zod.z.number().optional(),
|
|
2639
2885
|
status: zod.z.string().optional()
|
|
2640
|
-
}).passthrough().optional(),
|
|
2886
|
+
}).passthrough().nullable().optional(),
|
|
2641
2887
|
verified: zod.z.boolean().optional(),
|
|
2642
2888
|
created_at: zod.z.number().optional(),
|
|
2643
2889
|
updated_at: zod.z.number().optional()
|
|
@@ -2648,7 +2894,7 @@ const ProviderResponseSchema$244 = zod.z.object({
|
|
|
2648
2894
|
});
|
|
2649
2895
|
const listOrganizationDomainsOutputSchema = zod.z.object({
|
|
2650
2896
|
items: zod.z.array(ResourceSchema$37),
|
|
2651
|
-
next_cursor: zod.z.string().optional(),
|
|
2897
|
+
next_cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2652
2898
|
total: zod.z.number()
|
|
2653
2899
|
});
|
|
2654
2900
|
function listOrganizationDomainsTool(proxy) {
|
|
@@ -2659,11 +2905,7 @@ function listOrganizationDomainsTool(proxy) {
|
|
|
2659
2905
|
outputSchema: listOrganizationDomainsOutputSchema,
|
|
2660
2906
|
execute: async (input, { requestContext }) => {
|
|
2661
2907
|
const platformProxy = proxy.withRequestContext(requestContext);
|
|
2662
|
-
const offset = input.cursor === void 0 ? 0 : Number
|
|
2663
|
-
if (!Number.isInteger(offset) || offset < 0) throw new platformProxy.ActionError({
|
|
2664
|
-
type: "invalid_cursor",
|
|
2665
|
-
message: "Cursor must be a non-negative integer."
|
|
2666
|
-
});
|
|
2908
|
+
const offset = input.cursor === void 0 ? 0 : Number(input.cursor);
|
|
2667
2909
|
const response = await platformProxy.get({
|
|
2668
2910
|
endpoint: `/v1/organizations/${encodeURIComponent(input.organization_id)}/domains`,
|
|
2669
2911
|
params: {
|
|
@@ -2687,9 +2929,9 @@ function listOrganizationDomainsTool(proxy) {
|
|
|
2687
2929
|
//#endregion
|
|
2688
2930
|
//#region src/providers/clerk/tools/list-organization-invitations.ts
|
|
2689
2931
|
const listOrganizationInvitationsInputSchema = zod.z.object({
|
|
2690
|
-
cursor: zod.z.string().optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2932
|
+
cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2691
2933
|
limit: zod.z.number().int().min(1).max(500).optional(),
|
|
2692
|
-
organization_id: zod.z.string(),
|
|
2934
|
+
organization_id: zod.z.string().min(1),
|
|
2693
2935
|
status: zod.z.enum([
|
|
2694
2936
|
"pending",
|
|
2695
2937
|
"accepted",
|
|
@@ -2710,7 +2952,7 @@ const ResourceSchema$36 = zod.z.object({
|
|
|
2710
2952
|
"accepted",
|
|
2711
2953
|
"revoked",
|
|
2712
2954
|
"expired"
|
|
2713
|
-
]).optional(),
|
|
2955
|
+
]).or(zod.z.string()).optional(),
|
|
2714
2956
|
created_at: zod.z.number().optional(),
|
|
2715
2957
|
updated_at: zod.z.number().optional()
|
|
2716
2958
|
}).passthrough();
|
|
@@ -2720,7 +2962,7 @@ const ProviderResponseSchema$243 = zod.z.object({
|
|
|
2720
2962
|
});
|
|
2721
2963
|
const listOrganizationInvitationsOutputSchema = zod.z.object({
|
|
2722
2964
|
items: zod.z.array(ResourceSchema$36),
|
|
2723
|
-
next_cursor: zod.z.string().optional(),
|
|
2965
|
+
next_cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2724
2966
|
total: zod.z.number()
|
|
2725
2967
|
});
|
|
2726
2968
|
function listOrganizationInvitationsTool(proxy) {
|
|
@@ -2731,11 +2973,7 @@ function listOrganizationInvitationsTool(proxy) {
|
|
|
2731
2973
|
outputSchema: listOrganizationInvitationsOutputSchema,
|
|
2732
2974
|
execute: async (input, { requestContext }) => {
|
|
2733
2975
|
const platformProxy = proxy.withRequestContext(requestContext);
|
|
2734
|
-
const offset = input.cursor === void 0 ? 0 : Number
|
|
2735
|
-
if (!Number.isInteger(offset) || offset < 0) throw new platformProxy.ActionError({
|
|
2736
|
-
type: "invalid_cursor",
|
|
2737
|
-
message: "Cursor must be a non-negative integer."
|
|
2738
|
-
});
|
|
2976
|
+
const offset = input.cursor === void 0 ? 0 : Number(input.cursor);
|
|
2739
2977
|
const response = await platformProxy.get({
|
|
2740
2978
|
endpoint: `/v1/organizations/${encodeURIComponent(input.organization_id)}/invitations`,
|
|
2741
2979
|
params: {
|
|
@@ -2760,9 +2998,9 @@ function listOrganizationInvitationsTool(proxy) {
|
|
|
2760
2998
|
//#endregion
|
|
2761
2999
|
//#region src/providers/clerk/tools/list-organization-memberships.ts
|
|
2762
3000
|
const listOrganizationMembershipsInputSchema$1 = zod.z.object({
|
|
2763
|
-
cursor: zod.z.string().optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
3001
|
+
cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2764
3002
|
limit: zod.z.number().int().min(1).max(500).optional(),
|
|
2765
|
-
organization_id: zod.z.string(),
|
|
3003
|
+
organization_id: zod.z.string().min(1),
|
|
2766
3004
|
user_id: zod.z.array(zod.z.string()).optional(),
|
|
2767
3005
|
email_address: zod.z.array(zod.z.string()).optional(),
|
|
2768
3006
|
phone_number: zod.z.array(zod.z.string()).optional(),
|
|
@@ -2796,7 +3034,7 @@ const ProviderResponseSchema$242 = zod.z.object({
|
|
|
2796
3034
|
});
|
|
2797
3035
|
const listOrganizationMembershipsOutputSchema$1 = zod.z.object({
|
|
2798
3036
|
items: zod.z.array(ResourceSchema$35),
|
|
2799
|
-
next_cursor: zod.z.string().optional(),
|
|
3037
|
+
next_cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2800
3038
|
total: zod.z.number()
|
|
2801
3039
|
});
|
|
2802
3040
|
function listOrganizationMembershipsTool$1(proxy) {
|
|
@@ -2807,11 +3045,7 @@ function listOrganizationMembershipsTool$1(proxy) {
|
|
|
2807
3045
|
outputSchema: listOrganizationMembershipsOutputSchema$1,
|
|
2808
3046
|
execute: async (input, { requestContext }) => {
|
|
2809
3047
|
const platformProxy = proxy.withRequestContext(requestContext);
|
|
2810
|
-
const offset = input.cursor === void 0 ? 0 : Number
|
|
2811
|
-
if (!Number.isInteger(offset) || offset < 0) throw new platformProxy.ActionError({
|
|
2812
|
-
type: "invalid_cursor",
|
|
2813
|
-
message: "Cursor must be a non-negative integer."
|
|
2814
|
-
});
|
|
3048
|
+
const offset = input.cursor === void 0 ? 0 : Number(input.cursor);
|
|
2815
3049
|
const response = await platformProxy.get({
|
|
2816
3050
|
endpoint: `/v1/organizations/${encodeURIComponent(input.organization_id)}/memberships`,
|
|
2817
3051
|
params: {
|
|
@@ -2849,7 +3083,7 @@ function listOrganizationMembershipsTool$1(proxy) {
|
|
|
2849
3083
|
//#endregion
|
|
2850
3084
|
//#region src/providers/clerk/tools/list-organization-roles.ts
|
|
2851
3085
|
const listOrganizationRolesInputSchema = zod.z.object({
|
|
2852
|
-
cursor: zod.z.string().optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
3086
|
+
cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2853
3087
|
limit: zod.z.number().int().min(1).max(500).optional(),
|
|
2854
3088
|
query: zod.z.string().optional(),
|
|
2855
3089
|
order_by: zod.z.string().optional()
|
|
@@ -2874,7 +3108,7 @@ const ProviderResponseSchema$241 = zod.z.object({
|
|
|
2874
3108
|
});
|
|
2875
3109
|
const listOrganizationRolesOutputSchema = zod.z.object({
|
|
2876
3110
|
items: zod.z.array(ResourceSchema$34),
|
|
2877
|
-
next_cursor: zod.z.string().optional(),
|
|
3111
|
+
next_cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2878
3112
|
total: zod.z.number()
|
|
2879
3113
|
});
|
|
2880
3114
|
function listOrganizationRolesTool(proxy) {
|
|
@@ -2885,11 +3119,7 @@ function listOrganizationRolesTool(proxy) {
|
|
|
2885
3119
|
outputSchema: listOrganizationRolesOutputSchema,
|
|
2886
3120
|
execute: async (input, { requestContext }) => {
|
|
2887
3121
|
const platformProxy = proxy.withRequestContext(requestContext);
|
|
2888
|
-
const offset = input.cursor === void 0 ? 0 : Number
|
|
2889
|
-
if (!Number.isInteger(offset) || offset < 0) throw new platformProxy.ActionError({
|
|
2890
|
-
type: "invalid_cursor",
|
|
2891
|
-
message: "Cursor must be a non-negative integer."
|
|
2892
|
-
});
|
|
3122
|
+
const offset = input.cursor === void 0 ? 0 : Number(input.cursor);
|
|
2893
3123
|
const response = await platformProxy.get({
|
|
2894
3124
|
endpoint: "/v1/organization_roles",
|
|
2895
3125
|
params: {
|
|
@@ -2913,7 +3143,7 @@ function listOrganizationRolesTool(proxy) {
|
|
|
2913
3143
|
//#endregion
|
|
2914
3144
|
//#region src/providers/clerk/tools/list-organizations.ts
|
|
2915
3145
|
const listOrganizationsInputSchema$1 = zod.z.object({
|
|
2916
|
-
cursor: zod.z.string().optional(),
|
|
3146
|
+
cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2917
3147
|
limit: zod.z.number().int().min(1).max(500).optional(),
|
|
2918
3148
|
query: zod.z.string().optional(),
|
|
2919
3149
|
order_by: zod.z.string().optional().describe("Sort by name, created_at, or members_count, prefixed with + or -."),
|
|
@@ -2953,11 +3183,7 @@ function listOrganizationsTool$1(proxy) {
|
|
|
2953
3183
|
outputSchema: listOrganizationsOutputSchema$1,
|
|
2954
3184
|
execute: async (input, { requestContext }) => {
|
|
2955
3185
|
const platformProxy = proxy.withRequestContext(requestContext);
|
|
2956
|
-
const offset = input.cursor === void 0 ? 0 : Number
|
|
2957
|
-
if (!Number.isInteger(offset) || offset < 0) throw new platformProxy.ActionError({
|
|
2958
|
-
type: "invalid_cursor",
|
|
2959
|
-
message: "Cursor must be a non-negative integer."
|
|
2960
|
-
});
|
|
3186
|
+
const offset = input.cursor === void 0 ? 0 : Number(input.cursor);
|
|
2961
3187
|
const response = await platformProxy.get({
|
|
2962
3188
|
endpoint: "/v1/organizations",
|
|
2963
3189
|
params: {
|
|
@@ -2983,10 +3209,10 @@ function listOrganizationsTool$1(proxy) {
|
|
|
2983
3209
|
//#endregion
|
|
2984
3210
|
//#region src/providers/clerk/tools/list-sessions.ts
|
|
2985
3211
|
const listSessionsInputSchema = zod.z.object({
|
|
2986
|
-
cursor: zod.z.string().optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
3212
|
+
cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
2987
3213
|
limit: zod.z.number().int().min(1).max(500).optional(),
|
|
2988
|
-
client_id: zod.z.string().optional(),
|
|
2989
|
-
user_id: zod.z.string().optional(),
|
|
3214
|
+
client_id: zod.z.string().min(1).optional(),
|
|
3215
|
+
user_id: zod.z.string().min(1).optional(),
|
|
2990
3216
|
status: zod.z.enum([
|
|
2991
3217
|
"abandoned",
|
|
2992
3218
|
"active",
|
|
@@ -2996,7 +3222,7 @@ const listSessionsInputSchema = zod.z.object({
|
|
|
2996
3222
|
"replaced",
|
|
2997
3223
|
"revoked"
|
|
2998
3224
|
]).optional()
|
|
2999
|
-
});
|
|
3225
|
+
}).refine((value) => value.client_id !== void 0 || value.user_id !== void 0, { message: "Provide at least one of client_id or user_id." });
|
|
3000
3226
|
const ResourceSchema$33 = zod.z.object({
|
|
3001
3227
|
id: zod.z.string(),
|
|
3002
3228
|
object: zod.z.string().optional(),
|
|
@@ -3010,21 +3236,17 @@ const ResourceSchema$33 = zod.z.object({
|
|
|
3010
3236
|
"removed",
|
|
3011
3237
|
"replaced",
|
|
3012
3238
|
"revoked"
|
|
3013
|
-
]).optional(),
|
|
3239
|
+
]).or(zod.z.string()).optional(),
|
|
3014
3240
|
last_active_at: zod.z.number().optional(),
|
|
3015
3241
|
expire_at: zod.z.number().optional(),
|
|
3016
3242
|
abandon_at: zod.z.number().optional(),
|
|
3017
3243
|
created_at: zod.z.number().optional(),
|
|
3018
3244
|
updated_at: zod.z.number().optional()
|
|
3019
3245
|
}).passthrough();
|
|
3020
|
-
const ProviderResponseSchema$239 = zod.z.
|
|
3021
|
-
data: zod.z.array(ResourceSchema$33),
|
|
3022
|
-
total_count: zod.z.number()
|
|
3023
|
-
});
|
|
3246
|
+
const ProviderResponseSchema$239 = zod.z.array(ResourceSchema$33);
|
|
3024
3247
|
const listSessionsOutputSchema = zod.z.object({
|
|
3025
3248
|
items: zod.z.array(ResourceSchema$33),
|
|
3026
|
-
next_cursor: zod.z.string().optional()
|
|
3027
|
-
total: zod.z.number()
|
|
3249
|
+
next_cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page.")
|
|
3028
3250
|
});
|
|
3029
3251
|
function listSessionsTool(proxy) {
|
|
3030
3252
|
return (0, _mastra_core_tools.createTool)({
|
|
@@ -3034,28 +3256,23 @@ function listSessionsTool(proxy) {
|
|
|
3034
3256
|
outputSchema: listSessionsOutputSchema,
|
|
3035
3257
|
execute: async (input, { requestContext }) => {
|
|
3036
3258
|
const platformProxy = proxy.withRequestContext(requestContext);
|
|
3037
|
-
const offset = input.cursor === void 0 ? 0 : Number
|
|
3038
|
-
|
|
3039
|
-
type: "invalid_cursor",
|
|
3040
|
-
message: "Cursor must be a non-negative integer."
|
|
3041
|
-
});
|
|
3259
|
+
const offset = input.cursor === void 0 ? 0 : Number(input.cursor);
|
|
3260
|
+
const limit = input.limit ?? 10;
|
|
3042
3261
|
const response = await platformProxy.get({
|
|
3043
3262
|
endpoint: "/v1/sessions",
|
|
3044
3263
|
params: {
|
|
3045
3264
|
offset: String(offset),
|
|
3046
|
-
|
|
3265
|
+
limit: String(limit),
|
|
3047
3266
|
...input.client_id !== void 0 && { client_id: input.client_id },
|
|
3048
3267
|
...input.user_id !== void 0 && { user_id: input.user_id },
|
|
3049
3268
|
...input.status !== void 0 && { status: input.status }
|
|
3050
3269
|
},
|
|
3051
3270
|
retries: 3
|
|
3052
3271
|
});
|
|
3053
|
-
const
|
|
3054
|
-
const nextOffset = offset + provider.data.length;
|
|
3272
|
+
const sessions = ProviderResponseSchema$239.parse(response.data);
|
|
3055
3273
|
return {
|
|
3056
|
-
items:
|
|
3057
|
-
...
|
|
3058
|
-
total: provider.total_count
|
|
3274
|
+
items: sessions,
|
|
3275
|
+
...sessions.length === limit && { next_cursor: String(offset + sessions.length) }
|
|
3059
3276
|
};
|
|
3060
3277
|
}
|
|
3061
3278
|
});
|
|
@@ -3063,13 +3280,19 @@ function listSessionsTool(proxy) {
|
|
|
3063
3280
|
//#endregion
|
|
3064
3281
|
//#region src/providers/clerk/tools/list-users.ts
|
|
3065
3282
|
const listUsersInputSchema$9 = zod.z.object({
|
|
3066
|
-
cursor: zod.z.string().optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
3283
|
+
cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
3067
3284
|
limit: zod.z.number().int().min(1).max(500).optional().describe("Maximum number of users to return. Maximum 500."),
|
|
3068
3285
|
query: zod.z.string().optional().describe("Search across names, identifiers, email addresses, phone numbers, and usernames."),
|
|
3069
3286
|
email_address: zod.z.array(zod.z.string()).max(100).optional().describe("Filter by email addresses."),
|
|
3287
|
+
phone_number: zod.z.array(zod.z.string()).max(100).optional().describe("Filter by phone numbers."),
|
|
3288
|
+
username: zod.z.array(zod.z.string()).max(100).optional().describe("Filter by usernames."),
|
|
3070
3289
|
user_id: zod.z.array(zod.z.string()).max(100).optional().describe("Filter by Clerk user IDs."),
|
|
3071
3290
|
external_id: zod.z.array(zod.z.string()).max(100).optional().describe("Filter by external user IDs."),
|
|
3072
3291
|
organization_id: zod.z.array(zod.z.string()).max(100).optional().describe("Filter by organization IDs."),
|
|
3292
|
+
last_active_at_before: zod.z.number().int().optional().describe("Filter users last active before this Unix timestamp in milliseconds."),
|
|
3293
|
+
last_active_at_after: zod.z.number().int().optional().describe("Filter users last active after this Unix timestamp in milliseconds."),
|
|
3294
|
+
created_at_before: zod.z.number().int().optional().describe("Filter users created before this Unix timestamp in milliseconds."),
|
|
3295
|
+
created_at_after: zod.z.number().int().optional().describe("Filter users created after this Unix timestamp in milliseconds."),
|
|
3073
3296
|
order_by: zod.z.string().optional().describe("Sort field prefixed with + for ascending or - for descending. Example: \"-created_at\"")
|
|
3074
3297
|
});
|
|
3075
3298
|
const UserSchema$25 = zod.z.object({
|
|
@@ -3088,13 +3311,11 @@ const UserSchema$25 = zod.z.object({
|
|
|
3088
3311
|
updated_at: zod.z.number().optional(),
|
|
3089
3312
|
locale: zod.z.string().nullable().optional()
|
|
3090
3313
|
}).passthrough();
|
|
3091
|
-
const ProviderResponseSchema$238 = zod.z.
|
|
3092
|
-
|
|
3093
|
-
total_count: zod.z.number()
|
|
3094
|
-
});
|
|
3314
|
+
const ProviderResponseSchema$238 = zod.z.array(UserSchema$25);
|
|
3315
|
+
const ProviderCountSchema = zod.z.object({ total_count: zod.z.number() }).passthrough();
|
|
3095
3316
|
const listUsersOutputSchema$9 = zod.z.object({
|
|
3096
3317
|
items: zod.z.array(UserSchema$25),
|
|
3097
|
-
next_cursor: zod.z.string().optional(),
|
|
3318
|
+
next_cursor: zod.z.string().regex(/^\d+$/, "Cursor must be a non-negative integer.").refine((value) => Number.isSafeInteger(Number(value)), "Cursor must be a non-negative integer.").optional().describe("Pagination cursor returned by a previous request. Omit for the first page."),
|
|
3098
3319
|
total: zod.z.number()
|
|
3099
3320
|
});
|
|
3100
3321
|
function listUsersTool$9(proxy) {
|
|
@@ -3105,31 +3326,42 @@ function listUsersTool$9(proxy) {
|
|
|
3105
3326
|
outputSchema: listUsersOutputSchema$9,
|
|
3106
3327
|
execute: async (input, { requestContext }) => {
|
|
3107
3328
|
const platformProxy = proxy.withRequestContext(requestContext);
|
|
3108
|
-
const offset = input.cursor === void 0 ? 0 : Number
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3329
|
+
const offset = input.cursor === void 0 ? 0 : Number(input.cursor);
|
|
3330
|
+
const filterParams = {
|
|
3331
|
+
...input.query !== void 0 && { query: input.query },
|
|
3332
|
+
...input.email_address !== void 0 && { email_address: input.email_address },
|
|
3333
|
+
...input.phone_number !== void 0 && { phone_number: input.phone_number },
|
|
3334
|
+
...input.username !== void 0 && { username: input.username },
|
|
3335
|
+
...input.user_id !== void 0 && { user_id: input.user_id },
|
|
3336
|
+
...input.external_id !== void 0 && { external_id: input.external_id },
|
|
3337
|
+
...input.organization_id !== void 0 && { organization_id: input.organization_id },
|
|
3338
|
+
...input.last_active_at_before !== void 0 && { last_active_at_before: String(input.last_active_at_before) },
|
|
3339
|
+
...input.last_active_at_after !== void 0 && { last_active_at_after: String(input.last_active_at_after) },
|
|
3340
|
+
...input.created_at_before !== void 0 && { created_at_before: String(input.created_at_before) },
|
|
3341
|
+
...input.created_at_after !== void 0 && { created_at_after: String(input.created_at_after) }
|
|
3342
|
+
};
|
|
3113
3343
|
const response = await platformProxy.get({
|
|
3114
3344
|
endpoint: "/v1/users",
|
|
3115
3345
|
params: {
|
|
3116
3346
|
offset: String(offset),
|
|
3117
3347
|
...input.limit !== void 0 && { limit: String(input.limit) },
|
|
3118
|
-
...input.
|
|
3119
|
-
...
|
|
3120
|
-
...input.user_id !== void 0 && { user_id: input.user_id },
|
|
3121
|
-
...input.external_id !== void 0 && { external_id: input.external_id },
|
|
3122
|
-
...input.organization_id !== void 0 && { organization_id: input.organization_id },
|
|
3123
|
-
...input.order_by !== void 0 && { order_by: input.order_by }
|
|
3348
|
+
...input.order_by !== void 0 && { order_by: input.order_by },
|
|
3349
|
+
...filterParams
|
|
3124
3350
|
},
|
|
3125
3351
|
retries: 3
|
|
3126
3352
|
});
|
|
3127
|
-
const
|
|
3128
|
-
const
|
|
3353
|
+
const users = ProviderResponseSchema$238.parse(response.data);
|
|
3354
|
+
const countResponse = await platformProxy.get({
|
|
3355
|
+
endpoint: "/v1/users/count",
|
|
3356
|
+
params: filterParams,
|
|
3357
|
+
retries: 3
|
|
3358
|
+
});
|
|
3359
|
+
const total = ProviderCountSchema.parse(countResponse.data).total_count;
|
|
3360
|
+
const nextOffset = offset + users.length;
|
|
3129
3361
|
return {
|
|
3130
|
-
items:
|
|
3131
|
-
...nextOffset <
|
|
3132
|
-
total
|
|
3362
|
+
items: users,
|
|
3363
|
+
...users.length > 0 && nextOffset < total && { next_cursor: String(nextOffset) },
|
|
3364
|
+
total
|
|
3133
3365
|
};
|
|
3134
3366
|
}
|
|
3135
3367
|
});
|
|
@@ -3137,8 +3369,8 @@ function listUsersTool$9(proxy) {
|
|
|
3137
3369
|
//#endregion
|
|
3138
3370
|
//#region src/providers/clerk/tools/remove-organization-role-permission.ts
|
|
3139
3371
|
const removeOrganizationRolePermissionInputSchema = zod.z.object({
|
|
3140
|
-
organization_role_id: zod.z.string(),
|
|
3141
|
-
permission_id: zod.z.string()
|
|
3372
|
+
organization_role_id: zod.z.string().min(1),
|
|
3373
|
+
permission_id: zod.z.string().min(1)
|
|
3142
3374
|
});
|
|
3143
3375
|
const removeOrganizationRolePermissionOutputSchema = zod.z.object({
|
|
3144
3376
|
id: zod.z.string(),
|
|
@@ -3165,8 +3397,8 @@ function removeOrganizationRolePermissionTool(proxy) {
|
|
|
3165
3397
|
//#endregion
|
|
3166
3398
|
//#region src/providers/clerk/tools/revoke-organization-invitation.ts
|
|
3167
3399
|
const revokeOrganizationInvitationInputSchema = zod.z.object({
|
|
3168
|
-
organization_id: zod.z.string(),
|
|
3169
|
-
invitation_id: zod.z.string(),
|
|
3400
|
+
organization_id: zod.z.string().min(1),
|
|
3401
|
+
invitation_id: zod.z.string().min(1),
|
|
3170
3402
|
requesting_user_id: zod.z.string().optional()
|
|
3171
3403
|
});
|
|
3172
3404
|
const ResourceSchema$32 = zod.z.object({
|
|
@@ -3180,7 +3412,7 @@ const ResourceSchema$32 = zod.z.object({
|
|
|
3180
3412
|
"accepted",
|
|
3181
3413
|
"revoked",
|
|
3182
3414
|
"expired"
|
|
3183
|
-
]).optional(),
|
|
3415
|
+
]).or(zod.z.string()).optional(),
|
|
3184
3416
|
created_at: zod.z.number().optional(),
|
|
3185
3417
|
updated_at: zod.z.number().optional()
|
|
3186
3418
|
}).passthrough();
|
|
@@ -3203,7 +3435,7 @@ function revokeOrganizationInvitationTool(proxy) {
|
|
|
3203
3435
|
}
|
|
3204
3436
|
//#endregion
|
|
3205
3437
|
//#region src/providers/clerk/tools/revoke-session.ts
|
|
3206
|
-
const revokeSessionInputSchema = zod.z.object({ session_id: zod.z.string() });
|
|
3438
|
+
const revokeSessionInputSchema = zod.z.object({ session_id: zod.z.string().min(1) });
|
|
3207
3439
|
const ResourceSchema$31 = zod.z.object({
|
|
3208
3440
|
id: zod.z.string(),
|
|
3209
3441
|
object: zod.z.string().optional(),
|
|
@@ -3217,7 +3449,7 @@ const ResourceSchema$31 = zod.z.object({
|
|
|
3217
3449
|
"removed",
|
|
3218
3450
|
"replaced",
|
|
3219
3451
|
"revoked"
|
|
3220
|
-
]).optional(),
|
|
3452
|
+
]).or(zod.z.string()).optional(),
|
|
3221
3453
|
last_active_at: zod.z.number().optional(),
|
|
3222
3454
|
expire_at: zod.z.number().optional(),
|
|
3223
3455
|
abandon_at: zod.z.number().optional(),
|
|
@@ -3244,7 +3476,7 @@ function revokeSessionTool(proxy) {
|
|
|
3244
3476
|
//#endregion
|
|
3245
3477
|
//#region src/providers/clerk/tools/update-email-address.ts
|
|
3246
3478
|
const updateEmailAddressInputSchema = zod.z.object({
|
|
3247
|
-
email_address_id: zod.z.string(),
|
|
3479
|
+
email_address_id: zod.z.string().min(1),
|
|
3248
3480
|
verified: zod.z.boolean().optional(),
|
|
3249
3481
|
primary: zod.z.boolean().optional(),
|
|
3250
3482
|
notify_primary_email_address_changed: zod.z.boolean().optional()
|
|
@@ -3287,16 +3519,22 @@ function updateEmailAddressTool(proxy) {
|
|
|
3287
3519
|
}
|
|
3288
3520
|
//#endregion
|
|
3289
3521
|
//#region src/providers/clerk/tools/update-organization-domain.ts
|
|
3290
|
-
const EnrollmentModeSchema = zod.z.enum([
|
|
3522
|
+
const EnrollmentModeSchema$1 = zod.z.enum([
|
|
3291
3523
|
"manual_invitation",
|
|
3292
3524
|
"automatic_invitation",
|
|
3293
3525
|
"automatic_suggestion",
|
|
3294
3526
|
"enterprise_sso"
|
|
3295
3527
|
]);
|
|
3528
|
+
const EnrollmentModeSchemaWidened = zod.z.enum([
|
|
3529
|
+
"manual_invitation",
|
|
3530
|
+
"automatic_invitation",
|
|
3531
|
+
"automatic_suggestion",
|
|
3532
|
+
"enterprise_sso"
|
|
3533
|
+
]).or(zod.z.string());
|
|
3296
3534
|
const updateOrganizationDomainInputSchema = zod.z.object({
|
|
3297
|
-
organization_id: zod.z.string(),
|
|
3298
|
-
domain_id: zod.z.string(),
|
|
3299
|
-
enrollment_mode: EnrollmentModeSchema.optional(),
|
|
3535
|
+
organization_id: zod.z.string().min(1),
|
|
3536
|
+
domain_id: zod.z.string().min(1),
|
|
3537
|
+
enrollment_mode: EnrollmentModeSchema$1.optional(),
|
|
3300
3538
|
verified: zod.z.boolean().optional()
|
|
3301
3539
|
});
|
|
3302
3540
|
const ResourceSchema$29 = zod.z.object({
|
|
@@ -3304,15 +3542,15 @@ const ResourceSchema$29 = zod.z.object({
|
|
|
3304
3542
|
object: zod.z.string().optional(),
|
|
3305
3543
|
organization_id: zod.z.string().optional(),
|
|
3306
3544
|
name: zod.z.string(),
|
|
3307
|
-
enrollment_mode:
|
|
3545
|
+
enrollment_mode: EnrollmentModeSchemaWidened.optional(),
|
|
3308
3546
|
affiliation_verification: zod.z.object({
|
|
3309
3547
|
attempts: zod.z.number().optional(),
|
|
3310
3548
|
status: zod.z.string().optional()
|
|
3311
|
-
}).passthrough().optional(),
|
|
3549
|
+
}).passthrough().nullable().optional(),
|
|
3312
3550
|
verification: zod.z.object({
|
|
3313
3551
|
attempts: zod.z.number().optional(),
|
|
3314
3552
|
status: zod.z.string().optional()
|
|
3315
|
-
}).passthrough().optional(),
|
|
3553
|
+
}).passthrough().nullable().optional(),
|
|
3316
3554
|
verified: zod.z.boolean().optional(),
|
|
3317
3555
|
created_at: zod.z.number().optional(),
|
|
3318
3556
|
updated_at: zod.z.number().optional()
|
|
@@ -3340,8 +3578,8 @@ function updateOrganizationDomainTool(proxy) {
|
|
|
3340
3578
|
//#endregion
|
|
3341
3579
|
//#region src/providers/clerk/tools/update-organization-membership-metadata.ts
|
|
3342
3580
|
const updateOrganizationMembershipMetadataInputSchema = zod.z.object({
|
|
3343
|
-
organization_id: zod.z.string(),
|
|
3344
|
-
user_id: zod.z.string(),
|
|
3581
|
+
organization_id: zod.z.string().min(1),
|
|
3582
|
+
user_id: zod.z.string().min(1),
|
|
3345
3583
|
public_metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
3346
3584
|
private_metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
3347
3585
|
});
|
|
@@ -3378,8 +3616,8 @@ function updateOrganizationMembershipMetadataTool(proxy) {
|
|
|
3378
3616
|
//#endregion
|
|
3379
3617
|
//#region src/providers/clerk/tools/update-organization-membership.ts
|
|
3380
3618
|
const updateOrganizationMembershipInputSchema$1 = zod.z.object({
|
|
3381
|
-
organization_id: zod.z.string(),
|
|
3382
|
-
user_id: zod.z.string(),
|
|
3619
|
+
organization_id: zod.z.string().min(1),
|
|
3620
|
+
user_id: zod.z.string().min(1),
|
|
3383
3621
|
role: zod.z.string()
|
|
3384
3622
|
});
|
|
3385
3623
|
const ResourceSchema$27 = zod.z.object({
|
|
@@ -3412,12 +3650,12 @@ function updateOrganizationMembershipTool$1(proxy) {
|
|
|
3412
3650
|
//#endregion
|
|
3413
3651
|
//#region src/providers/clerk/tools/update-organization-role.ts
|
|
3414
3652
|
const updateOrganizationRoleInputSchema = zod.z.object({
|
|
3415
|
-
organization_role_id: zod.z.string(),
|
|
3653
|
+
organization_role_id: zod.z.string().min(1),
|
|
3416
3654
|
name: zod.z.string().optional(),
|
|
3417
3655
|
key: zod.z.string().optional(),
|
|
3418
3656
|
description: zod.z.string().optional(),
|
|
3419
3657
|
permissions: zod.z.array(zod.z.string()).optional()
|
|
3420
|
-
});
|
|
3658
|
+
}).refine((value) => value.name !== void 0 || value.key !== void 0 || value.description !== void 0 || value.permissions !== void 0, { message: "Provide at least one of name, key, description, or permissions." });
|
|
3421
3659
|
const ResourceSchema$26 = zod.z.object({
|
|
3422
3660
|
id: zod.z.string(),
|
|
3423
3661
|
object: zod.z.string().optional(),
|
|
@@ -3461,7 +3699,8 @@ const updateOrganizationInputSchema$1 = zod.z.object({
|
|
|
3461
3699
|
name: zod.z.string().min(1).optional(),
|
|
3462
3700
|
slug: zod.z.string().optional(),
|
|
3463
3701
|
admin_delete_enabled: zod.z.boolean().optional(),
|
|
3464
|
-
max_allowed_memberships: zod.z.number().int().min(0).optional()
|
|
3702
|
+
max_allowed_memberships: zod.z.number().int().min(0).optional(),
|
|
3703
|
+
public_metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
3465
3704
|
});
|
|
3466
3705
|
const OrganizationSchema$1 = zod.z.object({
|
|
3467
3706
|
id: zod.z.string(),
|
|
@@ -3493,7 +3732,8 @@ function updateOrganizationTool$1(proxy) {
|
|
|
3493
3732
|
...input.name !== void 0 && { name: input.name },
|
|
3494
3733
|
...input.slug !== void 0 && { slug: input.slug },
|
|
3495
3734
|
...input.admin_delete_enabled !== void 0 && { admin_delete_enabled: input.admin_delete_enabled },
|
|
3496
|
-
...input.max_allowed_memberships !== void 0 && { max_allowed_memberships: input.max_allowed_memberships }
|
|
3735
|
+
...input.max_allowed_memberships !== void 0 && { max_allowed_memberships: input.max_allowed_memberships },
|
|
3736
|
+
...input.public_metadata !== void 0 && { public_metadata: input.public_metadata }
|
|
3497
3737
|
},
|
|
3498
3738
|
retries: 3
|
|
3499
3739
|
});
|
|
@@ -3504,7 +3744,7 @@ function updateOrganizationTool$1(proxy) {
|
|
|
3504
3744
|
//#endregion
|
|
3505
3745
|
//#region src/providers/clerk/tools/update-phone-number.ts
|
|
3506
3746
|
const updatePhoneNumberInputSchema = zod.z.object({
|
|
3507
|
-
phone_number_id: zod.z.string(),
|
|
3747
|
+
phone_number_id: zod.z.string().min(1),
|
|
3508
3748
|
verified: zod.z.boolean().optional(),
|
|
3509
3749
|
primary: zod.z.boolean().optional(),
|
|
3510
3750
|
reserved_for_second_factor: zod.z.boolean().optional()
|
|
@@ -3550,14 +3790,14 @@ function updatePhoneNumberTool(proxy) {
|
|
|
3550
3790
|
//#region src/providers/clerk/tools/update-user.ts
|
|
3551
3791
|
const updateUserInputSchema$1 = zod.z.object({
|
|
3552
3792
|
user_id: zod.z.string().min(1),
|
|
3553
|
-
first_name: zod.z.string().optional(),
|
|
3554
|
-
last_name: zod.z.string().optional(),
|
|
3555
|
-
username: zod.z.string().optional(),
|
|
3793
|
+
first_name: zod.z.string().nullable().optional().describe("Pass null to clear the first name."),
|
|
3794
|
+
last_name: zod.z.string().nullable().optional().describe("Pass null to clear the last name."),
|
|
3795
|
+
username: zod.z.string().nullable().optional().describe("Pass null to clear the username."),
|
|
3556
3796
|
password: zod.z.string().min(8).optional(),
|
|
3557
3797
|
skip_password_checks: zod.z.boolean().optional(),
|
|
3558
3798
|
sign_out_of_other_sessions: zod.z.boolean().optional(),
|
|
3559
|
-
external_id: zod.z.string().optional(),
|
|
3560
|
-
locale: zod.z.string().optional()
|
|
3799
|
+
external_id: zod.z.string().nullable().optional().describe("Pass null to clear the external ID."),
|
|
3800
|
+
locale: zod.z.string().nullable().optional().describe("Pass null to clear the locale.")
|
|
3561
3801
|
});
|
|
3562
3802
|
const UserSchema$24 = zod.z.object({
|
|
3563
3803
|
id: zod.z.string(),
|
|
@@ -3603,24 +3843,30 @@ function updateUserTool$1(proxy) {
|
|
|
3603
3843
|
}
|
|
3604
3844
|
//#endregion
|
|
3605
3845
|
//#region src/providers/clerk/tools/verify-organization-domain.ts
|
|
3846
|
+
const EnrollmentModeSchema = zod.z.enum([
|
|
3847
|
+
"manual_invitation",
|
|
3848
|
+
"automatic_invitation",
|
|
3849
|
+
"automatic_suggestion",
|
|
3850
|
+
"enterprise_sso"
|
|
3851
|
+
]).or(zod.z.string());
|
|
3606
3852
|
const verifyOrganizationDomainInputSchema$1 = zod.z.object({
|
|
3607
|
-
organization_id: zod.z.string(),
|
|
3608
|
-
domain_id: zod.z.string()
|
|
3853
|
+
organization_id: zod.z.string().min(1),
|
|
3854
|
+
domain_id: zod.z.string().min(1)
|
|
3609
3855
|
});
|
|
3610
3856
|
const ResourceSchema$24 = zod.z.object({
|
|
3611
3857
|
id: zod.z.string(),
|
|
3612
3858
|
object: zod.z.string().optional(),
|
|
3613
3859
|
organization_id: zod.z.string().optional(),
|
|
3614
3860
|
name: zod.z.string(),
|
|
3615
|
-
enrollment_mode:
|
|
3861
|
+
enrollment_mode: EnrollmentModeSchema.optional(),
|
|
3616
3862
|
affiliation_verification: zod.z.object({
|
|
3617
3863
|
attempts: zod.z.number().optional(),
|
|
3618
3864
|
status: zod.z.string().optional()
|
|
3619
|
-
}).passthrough().optional(),
|
|
3865
|
+
}).passthrough().nullable().optional(),
|
|
3620
3866
|
verification: zod.z.object({
|
|
3621
3867
|
attempts: zod.z.number().optional(),
|
|
3622
3868
|
status: zod.z.string().optional()
|
|
3623
|
-
}).passthrough().optional(),
|
|
3869
|
+
}).passthrough().nullable().optional(),
|
|
3624
3870
|
verified: zod.z.boolean().optional(),
|
|
3625
3871
|
created_at: zod.z.number().optional(),
|
|
3626
3872
|
updated_at: zod.z.number().optional()
|
|
@@ -5178,7 +5424,7 @@ const ChannelSchema$2 = zod.z.object({
|
|
|
5178
5424
|
recipients: zod.z.array(zod.z.unknown()).optional(),
|
|
5179
5425
|
icon: zod.z.string().nullable().optional(),
|
|
5180
5426
|
owner_id: zod.z.string().optional(),
|
|
5181
|
-
application_id: zod.z.string().optional(),
|
|
5427
|
+
application_id: zod.z.string().nullable().optional(),
|
|
5182
5428
|
managed: zod.z.boolean().optional(),
|
|
5183
5429
|
parent_id: zod.z.string().nullable().optional(),
|
|
5184
5430
|
last_pin_timestamp: zod.z.string().nullable().optional(),
|
|
@@ -34496,12 +34742,35 @@ const getCreateIssueMetadataInputSchema = zod.z.object({
|
|
|
34496
34742
|
issuetypeIds: zod.z.array(zod.z.string()).optional().describe("List of issue type IDs to filter by. Example: [\"10000\", \"10001\"]"),
|
|
34497
34743
|
expand: zod.z.string().optional().describe("Use expand to include additional information about issue metadata in the response. Supported values: projects, projects.issuetypes, projects.issuetypes.fields")
|
|
34498
34744
|
});
|
|
34745
|
+
const CreateIssueFieldSchema = zod.z.object({
|
|
34746
|
+
required: zod.z.boolean().optional(),
|
|
34747
|
+
schema: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
34748
|
+
name: zod.z.string().optional(),
|
|
34749
|
+
key: zod.z.string().optional(),
|
|
34750
|
+
hasDefaultValue: zod.z.boolean().optional(),
|
|
34751
|
+
operations: zod.z.array(zod.z.string()).optional(),
|
|
34752
|
+
allowedValues: zod.z.array(zod.z.unknown()).optional(),
|
|
34753
|
+
defaultValue: zod.z.unknown().optional(),
|
|
34754
|
+
autoCompleteUrl: zod.z.string().optional()
|
|
34755
|
+
});
|
|
34756
|
+
const IssueTypeSchema$1 = zod.z.object({
|
|
34757
|
+
id: zod.z.string(),
|
|
34758
|
+
name: zod.z.string(),
|
|
34759
|
+
self: zod.z.string().optional(),
|
|
34760
|
+
description: zod.z.string().optional(),
|
|
34761
|
+
iconUrl: zod.z.string().optional(),
|
|
34762
|
+
avatarId: zod.z.number().optional(),
|
|
34763
|
+
subtask: zod.z.boolean().optional(),
|
|
34764
|
+
hierarchyLevel: zod.z.number().optional(),
|
|
34765
|
+
fields: zod.z.record(zod.z.string(), CreateIssueFieldSchema).optional()
|
|
34766
|
+
});
|
|
34499
34767
|
const ProjectSchema$3 = zod.z.object({
|
|
34500
34768
|
id: zod.z.string(),
|
|
34501
34769
|
key: zod.z.string(),
|
|
34502
34770
|
name: zod.z.string(),
|
|
34503
34771
|
self: zod.z.string().optional(),
|
|
34504
|
-
avatarUrls: zod.z.record(zod.z.string(), zod.z.string()).optional()
|
|
34772
|
+
avatarUrls: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
34773
|
+
issuetypes: zod.z.array(IssueTypeSchema$1).optional()
|
|
34505
34774
|
});
|
|
34506
34775
|
const ProviderResponseSchema$149 = zod.z.object({ projects: zod.z.array(ProjectSchema$3).optional() });
|
|
34507
34776
|
const getCreateIssueMetadataOutputSchema = zod.z.object({ projects: zod.z.array(ProjectSchema$3).optional() });
|
|
@@ -35621,7 +35890,7 @@ zod.z.object({
|
|
|
35621
35890
|
cloudId: zod.z.string().optional(),
|
|
35622
35891
|
baseUrl: zod.z.string().optional()
|
|
35623
35892
|
});
|
|
35624
|
-
const listIssueTypesInputSchema = zod.z.object({});
|
|
35893
|
+
const listIssueTypesInputSchema = zod.z.object({ projectId: zod.z.string().optional().describe("Project ID used to list only issue types available in that project.") });
|
|
35625
35894
|
const IssueTypeSchema = zod.z.object({
|
|
35626
35895
|
id: zod.z.string(),
|
|
35627
35896
|
name: zod.z.string(),
|
|
@@ -35650,7 +35919,7 @@ const AccessibleResourceSchema$1 = zod.z.object({
|
|
|
35650
35919
|
function listIssueTypesTool(proxy) {
|
|
35651
35920
|
return (0, _mastra_core_tools.createTool)({
|
|
35652
35921
|
id: "jira_list_issue_types",
|
|
35653
|
-
description: "List Jira issue types available to the user",
|
|
35922
|
+
description: "List Jira issue types available to the user. Pass projectId to list only the issue types available in that project (recommended before creating an issue).",
|
|
35654
35923
|
inputSchema: listIssueTypesInputSchema,
|
|
35655
35924
|
outputSchema: listIssueTypesOutputSchema,
|
|
35656
35925
|
execute: async (input, { requestContext }) => {
|
|
@@ -35685,7 +35954,12 @@ function listIssueTypesTool(proxy) {
|
|
|
35685
35954
|
baseUrl
|
|
35686
35955
|
});
|
|
35687
35956
|
}
|
|
35688
|
-
const config = {
|
|
35957
|
+
const config = input.projectId ? {
|
|
35958
|
+
endpoint: `/ex/jira/${cloudId}/rest/api/3/issuetype/project`,
|
|
35959
|
+
params: { projectId: input.projectId },
|
|
35960
|
+
headers: { "X-Atlassian-Token": "no-check" },
|
|
35961
|
+
retries: 3
|
|
35962
|
+
} : {
|
|
35689
35963
|
endpoint: `/ex/jira/${cloudId}/rest/api/3/issuetype`,
|
|
35690
35964
|
headers: { "X-Atlassian-Token": "no-check" },
|
|
35691
35965
|
retries: 3
|
|
@@ -55243,7 +55517,7 @@ const cancelEmailInputSchema = zod.z.object({ email_id: zod.z.string() });
|
|
|
55243
55517
|
const ProviderResponseSchema$107 = zod.z.object({
|
|
55244
55518
|
object: zod.z.string().optional(),
|
|
55245
55519
|
id: zod.z.string().optional(),
|
|
55246
|
-
message_id: zod.z.string().optional(),
|
|
55520
|
+
message_id: zod.z.string().nullable().optional(),
|
|
55247
55521
|
to: zod.z.array(zod.z.string()).optional(),
|
|
55248
55522
|
from: zod.z.string().optional(),
|
|
55249
55523
|
created_at: zod.z.string().optional(),
|
|
@@ -56493,7 +56767,7 @@ const getEmailInputSchema = zod.z.object({ email_id: zod.z.string() });
|
|
|
56493
56767
|
const ProviderResponseSchema$76 = zod.z.object({
|
|
56494
56768
|
object: zod.z.string().optional(),
|
|
56495
56769
|
id: zod.z.string().optional(),
|
|
56496
|
-
message_id: zod.z.string().optional(),
|
|
56770
|
+
message_id: zod.z.string().nullable().optional(),
|
|
56497
56771
|
to: zod.z.array(zod.z.string()).optional(),
|
|
56498
56772
|
from: zod.z.string().optional(),
|
|
56499
56773
|
created_at: zod.z.string().optional(),
|
|
@@ -56580,7 +56854,7 @@ const ProviderResponseSchema$74 = zod.z.object({
|
|
|
56580
56854
|
to: zod.z.array(zod.z.string()).optional(),
|
|
56581
56855
|
from: zod.z.string().optional(),
|
|
56582
56856
|
subject: zod.z.string().optional(),
|
|
56583
|
-
message_id: zod.z.string().optional(),
|
|
56857
|
+
message_id: zod.z.string().nullable().optional(),
|
|
56584
56858
|
bcc: zod.z.array(zod.z.string()).nullable().optional(),
|
|
56585
56859
|
cc: zod.z.array(zod.z.string()).nullable().optional(),
|
|
56586
56860
|
reply_to: zod.z.array(zod.z.string()).nullable().optional(),
|
|
@@ -56654,7 +56928,7 @@ const ProviderResponseSchema$72 = zod.z.object({
|
|
|
56654
56928
|
current_version_id: zod.z.string().optional(),
|
|
56655
56929
|
name: zod.z.string().optional(),
|
|
56656
56930
|
alias: zod.z.string().optional(),
|
|
56657
|
-
from: zod.z.string().optional(),
|
|
56931
|
+
from: zod.z.string().nullable().optional(),
|
|
56658
56932
|
subject: zod.z.string().optional(),
|
|
56659
56933
|
reply_to: zod.z.array(zod.z.string()).nullable().optional(),
|
|
56660
56934
|
html: zod.z.string().optional(),
|
|
@@ -57377,7 +57651,7 @@ const ProviderResponseSchema$57 = zod.z.object({
|
|
|
57377
57651
|
data: zod.z.array(zod.z.object({
|
|
57378
57652
|
object: zod.z.string().optional(),
|
|
57379
57653
|
id: zod.z.string().optional(),
|
|
57380
|
-
message_id: zod.z.string().optional(),
|
|
57654
|
+
message_id: zod.z.string().nullable().optional(),
|
|
57381
57655
|
to: zod.z.array(zod.z.string()).optional(),
|
|
57382
57656
|
from: zod.z.string().optional(),
|
|
57383
57657
|
created_at: zod.z.string().optional(),
|
|
@@ -57496,7 +57770,7 @@ const ProviderResponseSchema$55 = zod.z.object({
|
|
|
57496
57770
|
to: zod.z.array(zod.z.string()).optional(),
|
|
57497
57771
|
from: zod.z.string().optional(),
|
|
57498
57772
|
subject: zod.z.string().nullable().optional(),
|
|
57499
|
-
message_id: zod.z.string().optional(),
|
|
57773
|
+
message_id: zod.z.string().nullable().optional(),
|
|
57500
57774
|
bcc: zod.z.array(zod.z.string()).nullable().optional(),
|
|
57501
57775
|
cc: zod.z.array(zod.z.string()).nullable().optional(),
|
|
57502
57776
|
reply_to: zod.z.array(zod.z.string()).nullable().optional(),
|
|
@@ -58184,7 +58458,7 @@ function updateContactTopicsTool(proxy) {
|
|
|
58184
58458
|
const config = {
|
|
58185
58459
|
endpoint: `/contacts/${encodeURIComponent(input["contact_id"])}/topics`,
|
|
58186
58460
|
retries: 3,
|
|
58187
|
-
data: input.body
|
|
58461
|
+
data: input.body.topics
|
|
58188
58462
|
};
|
|
58189
58463
|
const response = await platformProxy.patch(config);
|
|
58190
58464
|
return ProviderResponseSchema$39.parse(response.data);
|
|
@@ -73974,7 +74248,7 @@ function createWorkosTools(options) {
|
|
|
73974
74248
|
* Providers with checked-in HTTP toolsets. MCP-backed providers are discovered
|
|
73975
74249
|
* from the Platform integration catalog at runtime.
|
|
73976
74250
|
*/
|
|
73977
|
-
const
|
|
74251
|
+
const PROVIDERS = [
|
|
73978
74252
|
anthropicProvider,
|
|
73979
74253
|
clerkProvider,
|
|
73980
74254
|
discordProvider,
|
|
@@ -74007,27 +74281,16 @@ const TOOLS = [
|
|
|
74007
74281
|
}
|
|
74008
74282
|
];
|
|
74009
74283
|
/**
|
|
74010
|
-
* @deprecated Use `TOOLS`. This alias is retained for one release cycle so
|
|
74011
|
-
* downstream consumers keep working; it will be removed in the next minor.
|
|
74012
|
-
*/
|
|
74013
|
-
const PROVIDERS = TOOLS;
|
|
74014
|
-
function findRegistration(integrationId) {
|
|
74015
|
-
return TOOLS.find((p) => p.integrationId === integrationId);
|
|
74016
|
-
}
|
|
74017
|
-
/**
|
|
74018
74284
|
* Channel-capable providers with a hand-maintained `channels()` registration.
|
|
74019
74285
|
* The launch ships three (Slack, Telegram, Discord); the provider generator
|
|
74020
74286
|
* grows to cover new entries when a fourth lands.
|
|
74021
74287
|
*/
|
|
74022
74288
|
const CHANNELS = CHANNELS$1;
|
|
74023
|
-
function findChannelRegistration(integrationId) {
|
|
74024
|
-
return CHANNELS.find((c) => c.integrationId === integrationId);
|
|
74025
|
-
}
|
|
74026
74289
|
//#endregion
|
|
74027
74290
|
//#region src/resolution.ts
|
|
74028
74291
|
const INTEGRATION_ID_PATTERN = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
74029
|
-
function
|
|
74030
|
-
for (const integrationId of Object.keys(
|
|
74292
|
+
function validateProviderIds(providers) {
|
|
74293
|
+
for (const integrationId of Object.keys(providers ?? {})) if (!INTEGRATION_ID_PATTERN.test(integrationId)) throw new MastraConnectError("invalid_options", `Invalid provider '${integrationId}' in providers option: expected 1-128 letters, numbers, underscores, or hyphens.`);
|
|
74031
74294
|
}
|
|
74032
74295
|
function connectionIdEnvVar(integrationId) {
|
|
74033
74296
|
return `MASTRA_${integrationId.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_CONNECTION_ID`;
|
|
@@ -74042,42 +74305,8 @@ function groupByIntegrationId(connections) {
|
|
|
74042
74305
|
return byIntegrationId;
|
|
74043
74306
|
}
|
|
74044
74307
|
/**
|
|
74045
|
-
* Resolves the connection to use for one provider, per the contract:
|
|
74046
|
-
* option/env var wins; else a single active connection; anything else
|
|
74047
|
-
* (ambiguity, needs_reauth, no usable candidate) warns and skips so one bad
|
|
74048
|
-
* integration never takes down the whole resolution. A needs_reauth
|
|
74049
|
-
* connection is never silently mapped.
|
|
74050
|
-
*/
|
|
74051
|
-
function resolveConnection(request, candidates) {
|
|
74052
|
-
const integrationId = request.integrationId;
|
|
74053
|
-
const directed = request.connectionId?.trim() || process.env[request.envVar]?.trim() || void 0;
|
|
74054
|
-
if (directed) {
|
|
74055
|
-
const match = candidates.find((connection) => connection.id === directed);
|
|
74056
|
-
if (!match) {
|
|
74057
|
-
console.warn(`[@mastra/connect] Skipping ${integrationId}: pinned connection ${directed} is not attached to this project.`);
|
|
74058
|
-
return;
|
|
74059
|
-
}
|
|
74060
|
-
if (match.status === "needs_reauth") {
|
|
74061
|
-
console.warn(`[@mastra/connect] Skipping ${integrationId}: connection ${directed} needs re-auth.`);
|
|
74062
|
-
return;
|
|
74063
|
-
}
|
|
74064
|
-
if (match.status !== "active") {
|
|
74065
|
-
console.warn(`[@mastra/connect] Skipping ${integrationId}: connection ${directed} is not active (status '${match.status}').`);
|
|
74066
|
-
return;
|
|
74067
|
-
}
|
|
74068
|
-
return directed;
|
|
74069
|
-
}
|
|
74070
|
-
const active = candidates.filter((connection) => connection.status === "active");
|
|
74071
|
-
if (active.length === 1) return active[0].id;
|
|
74072
|
-
if (active.length === 0) {
|
|
74073
|
-
console.warn(`[@mastra/connect] Skipping ${integrationId}: no active connections (found ${candidates.length} in other states).`);
|
|
74074
|
-
return;
|
|
74075
|
-
}
|
|
74076
|
-
console.warn(`[@mastra/connect] Skipping ${integrationId}: ${active.length} active connections; pin one with connectionId or ${request.envVar}.`);
|
|
74077
|
-
}
|
|
74078
|
-
/**
|
|
74079
74308
|
* Resolves how to configure one provider given its candidate connections:
|
|
74080
|
-
* - An explicit pin (
|
|
74309
|
+
* - An explicit pin (`connectionId`) forces `single` at that id.
|
|
74081
74310
|
* - Exactly one active connection → `single`.
|
|
74082
74311
|
* - Two or more active connections → `multi`; the caller wraps tools with
|
|
74083
74312
|
* `connection_name` so the agent chooses per call at execute time.
|
|
@@ -74128,16 +74357,18 @@ const FAILURE_COOLDOWN_MS$1 = 3e4;
|
|
|
74128
74357
|
let nextResolverId = 0;
|
|
74129
74358
|
/**
|
|
74130
74359
|
* Returns a live toolset resolver over the project's Platform connections.
|
|
74131
|
-
* HTTP providers are loaded from the shipped `
|
|
74360
|
+
* HTTP providers are loaded from the shipped `PROVIDERS` registry. MCP providers
|
|
74132
74361
|
* are discovered from the Platform integration catalog. Tools from every supported
|
|
74133
74362
|
* provider with a matching project connection are merged into one flat record
|
|
74134
74363
|
* (matched by `integrationId`). The resolver serves a cached snapshot,
|
|
74135
|
-
* revalidating from the platform every `ttlMs`, so
|
|
74136
|
-
* to (or
|
|
74364
|
+
* revalidating from the platform every `ttlMs`, so providers connected
|
|
74365
|
+
* to (or disconnected from) the project are picked up (or dropped) without a
|
|
74137
74366
|
* restart.
|
|
74138
74367
|
*
|
|
74139
|
-
* Configuration errors (missing project id, bad ttlMs, malformed integration id
|
|
74140
|
-
* throw here — at call time — so they
|
|
74368
|
+
* Configuration errors (missing project id, bad ttlMs, malformed integration id,
|
|
74369
|
+
* the removed `autoApproveTools` key) throw here — at call time — so they
|
|
74370
|
+
* surface at startup. Configuration errors that need discovery to detect
|
|
74371
|
+
* (an unknown tool name in `requireApproval`) fail the resolution instead.
|
|
74141
74372
|
* Expected provider absence is silently skipped. Actionable per-integration
|
|
74142
74373
|
* problems during resolution (needs re-auth or ambiguity) are downgraded to
|
|
74143
74374
|
* warn-and-skip so one bad integration never takes down the whole toolset.
|
|
@@ -74150,9 +74381,14 @@ function tools(options = {}) {
|
|
|
74150
74381
|
const client = resolveClient(options.client);
|
|
74151
74382
|
const resolverId = ++nextResolverId;
|
|
74152
74383
|
const mcpClients = /* @__PURE__ */ new Map();
|
|
74153
|
-
const
|
|
74154
|
-
|
|
74155
|
-
|
|
74384
|
+
const normalizedProviders = normalizeProviderOverrides(options.providers);
|
|
74385
|
+
const providerOverrides = normalizedProviders.overrides;
|
|
74386
|
+
validateProviderIds(providerOverrides);
|
|
74387
|
+
validateProviderXor(providerOverrides);
|
|
74388
|
+
validateRequireApproval(providerOverrides);
|
|
74389
|
+
rejectRemovedAutoApproveTools(providerOverrides);
|
|
74390
|
+
if (options.allowTools !== void 0 && options.disallowTools !== void 0) throw new MastraConnectError("invalid_options", "Top-level allowTools and disallowTools are mutually exclusive; set at most one.");
|
|
74391
|
+
if (options.requireApproval !== void 0 && typeof options.requireApproval !== "boolean" && !(Array.isArray(options.requireApproval) && options.requireApproval.every((name) => typeof name === "string"))) throw new MastraConnectError("invalid_options", "Top-level requireApproval must be a boolean or an array of tool keys.");
|
|
74156
74392
|
let cache;
|
|
74157
74393
|
let inflight;
|
|
74158
74394
|
let closing;
|
|
@@ -74168,15 +74404,17 @@ function tools(options = {}) {
|
|
|
74168
74404
|
const connections = connectionsResult.value;
|
|
74169
74405
|
if (catalogResult.status === "fulfilled") return {
|
|
74170
74406
|
connections,
|
|
74171
|
-
catalog: catalogResult.value
|
|
74407
|
+
catalog: catalogResult.value,
|
|
74408
|
+
catalogAvailable: true
|
|
74172
74409
|
};
|
|
74173
|
-
const checkedIn = new Set(
|
|
74174
|
-
if (connections.some((connection) => connection.status === "active" && !checkedIn.has(connection.integrationId) && !
|
|
74410
|
+
const checkedIn = new Set(PROVIDERS.map((registration) => registration.integrationId));
|
|
74411
|
+
if (connections.some((connection) => connection.status === "active" && !checkedIn.has(connection.integrationId) && !providerOverrides[connection.integrationId]?.disabled && (normalizedProviders.only === void 0 || normalizedProviders.only.has(connection.integrationId)))) throw catalogResult.reason;
|
|
74175
74412
|
const reason = catalogResult.reason;
|
|
74176
74413
|
console.warn(`[@mastra/connect] Platform catalog unavailable (${reason instanceof Error ? reason.message : String(reason)}); resolving checked-in providers only.`);
|
|
74177
74414
|
return {
|
|
74178
74415
|
connections,
|
|
74179
|
-
catalog: []
|
|
74416
|
+
catalog: [],
|
|
74417
|
+
catalogAvailable: false
|
|
74180
74418
|
};
|
|
74181
74419
|
};
|
|
74182
74420
|
/**
|
|
@@ -74187,8 +74425,8 @@ function tools(options = {}) {
|
|
|
74187
74425
|
if (closing) return closing.then(refresh);
|
|
74188
74426
|
if (!inflight) inflight = (async () => {
|
|
74189
74427
|
try {
|
|
74190
|
-
const { connections, catalog } = await loadSnapshotInputs();
|
|
74191
|
-
const snapshot = await mapTools(connections, buildRequests(
|
|
74428
|
+
const { connections, catalog, catalogAvailable } = await loadSnapshotInputs();
|
|
74429
|
+
const snapshot = await mapTools(connections, buildRequests(normalizedProviders, catalog, catalogAvailable), options, client, mcpClients, resolverId);
|
|
74192
74430
|
cache = {
|
|
74193
74431
|
snapshot,
|
|
74194
74432
|
fetchedAt: Date.now()
|
|
@@ -74218,10 +74456,7 @@ function tools(options = {}) {
|
|
|
74218
74456
|
}
|
|
74219
74457
|
return refresh();
|
|
74220
74458
|
};
|
|
74221
|
-
|
|
74222
|
-
invalidate: () => {
|
|
74223
|
-
cache = void 0;
|
|
74224
|
-
},
|
|
74459
|
+
const resolver = Object.assign(resolve, {
|
|
74225
74460
|
refresh,
|
|
74226
74461
|
disconnect: () => {
|
|
74227
74462
|
closing ??= (async () => {
|
|
@@ -74236,28 +74471,75 @@ function tools(options = {}) {
|
|
|
74236
74471
|
}
|
|
74237
74472
|
})();
|
|
74238
74473
|
return closing;
|
|
74239
|
-
}
|
|
74474
|
+
},
|
|
74475
|
+
with: (extra) => withExtraTools(resolver, extra)
|
|
74240
74476
|
});
|
|
74477
|
+
return resolver;
|
|
74241
74478
|
}
|
|
74242
74479
|
/**
|
|
74243
|
-
*
|
|
74244
|
-
*
|
|
74245
|
-
*
|
|
74246
|
-
* Also rejects malformed inputs early (non-string array entries, duplicates)
|
|
74247
|
-
* so a bad option throws at tools() time rather than at first refresh.
|
|
74480
|
+
* Builds the resolver `.with()` returns: resolutions merge the base
|
|
74481
|
+
* resolver's tools with `extra` (extra wins on key collision), cache handles
|
|
74482
|
+
* delegate to the base, and further `.with()` calls chain.
|
|
74248
74483
|
*/
|
|
74249
|
-
function
|
|
74250
|
-
|
|
74251
|
-
|
|
74252
|
-
const
|
|
74253
|
-
|
|
74254
|
-
|
|
74255
|
-
|
|
74256
|
-
|
|
74257
|
-
|
|
74258
|
-
|
|
74484
|
+
function withExtraTools(base, extra) {
|
|
74485
|
+
const resolveExtra = typeof extra === "function" ? extra : () => extra;
|
|
74486
|
+
const resolve = async (ctx) => {
|
|
74487
|
+
const [baseTools, extraTools] = await Promise.all([base(ctx), resolveExtra(ctx)]);
|
|
74488
|
+
return {
|
|
74489
|
+
...baseTools,
|
|
74490
|
+
...extraTools
|
|
74491
|
+
};
|
|
74492
|
+
};
|
|
74493
|
+
const resolver = Object.assign(resolve, {
|
|
74494
|
+
refresh: async () => {
|
|
74495
|
+
const [baseTools, extraTools] = await Promise.all([base.refresh(), resolveExtra()]);
|
|
74496
|
+
return {
|
|
74497
|
+
...baseTools,
|
|
74498
|
+
...extraTools
|
|
74499
|
+
};
|
|
74500
|
+
},
|
|
74501
|
+
disconnect: () => base.disconnect(),
|
|
74502
|
+
with: (more) => withExtraTools(resolver, more)
|
|
74503
|
+
});
|
|
74504
|
+
return resolver;
|
|
74505
|
+
}
|
|
74506
|
+
/**
|
|
74507
|
+
* Turns the two accepted `providers` shapes into the internal form. The
|
|
74508
|
+
* array form (`["linear", "github"]`) becomes an allowlist with default
|
|
74509
|
+
* options; the record form expands boolean shorthands (`true` → `{}`,
|
|
74510
|
+
* `false` → an internal exclusion marker). Malformed inputs (non-string
|
|
74511
|
+
* array entries, duplicates, non-boolean/non-object record values) throw at
|
|
74512
|
+
* tools() time rather than at first refresh.
|
|
74513
|
+
*/
|
|
74514
|
+
function normalizeProviderOverrides(providers) {
|
|
74515
|
+
if (providers === void 0) return {
|
|
74516
|
+
overrides: {},
|
|
74517
|
+
only: void 0
|
|
74518
|
+
};
|
|
74519
|
+
if (Array.isArray(providers)) {
|
|
74520
|
+
const overrides = {};
|
|
74521
|
+
for (const entry of providers) {
|
|
74522
|
+
if (typeof entry !== "string") throw new MastraConnectError("invalid_options", `Invalid providers entry: expected a string provider id, got ${typeof entry}.`);
|
|
74523
|
+
if (overrides[entry] !== void 0) throw new MastraConnectError("invalid_options", `Duplicate provider '${entry}' in providers array.`);
|
|
74524
|
+
overrides[entry] = {};
|
|
74525
|
+
}
|
|
74526
|
+
return {
|
|
74527
|
+
overrides,
|
|
74528
|
+
only: new Set(Object.keys(overrides))
|
|
74529
|
+
};
|
|
74259
74530
|
}
|
|
74260
|
-
|
|
74531
|
+
const overrides = {};
|
|
74532
|
+
for (const [providerId, value] of Object.entries(providers)) {
|
|
74533
|
+
if (value === void 0) continue;
|
|
74534
|
+
if (value === true) overrides[providerId] = {};
|
|
74535
|
+
else if (value === false) overrides[providerId] = { disabled: true };
|
|
74536
|
+
else if (typeof value === "object" && value !== null && !Array.isArray(value)) overrides[providerId] = value;
|
|
74537
|
+
else throw new MastraConnectError("invalid_options", `Invalid providers entry for '${providerId}': expected true, false, or an options object, got ${value === null ? "null" : Array.isArray(value) ? "an array" : typeof value}.`);
|
|
74538
|
+
}
|
|
74539
|
+
return {
|
|
74540
|
+
overrides,
|
|
74541
|
+
only: void 0
|
|
74542
|
+
};
|
|
74261
74543
|
}
|
|
74262
74544
|
/**
|
|
74263
74545
|
* Rejects any provider that sets both `allowTools` and `disallowTools`.
|
|
@@ -74265,15 +74547,39 @@ function normalizeIntegrationOverrides(integrations) {
|
|
|
74265
74547
|
* runtime guard catches loosely typed inputs (e.g. built from JSON or a
|
|
74266
74548
|
* `Record<string, unknown>` upstream).
|
|
74267
74549
|
*/
|
|
74268
|
-
function
|
|
74269
|
-
for (const [integrationId, providerOptions] of Object.entries(
|
|
74550
|
+
function validateProviderXor(providers) {
|
|
74551
|
+
for (const [integrationId, providerOptions] of Object.entries(providers)) {
|
|
74270
74552
|
const filters = providerOptions;
|
|
74271
74553
|
if (filters.allowTools !== void 0 && filters.disallowTools !== void 0) throw new MastraConnectError("invalid_options", `Invalid options for '${integrationId}': allowTools and disallowTools are mutually exclusive; set at most one.`);
|
|
74272
74554
|
}
|
|
74273
74555
|
}
|
|
74274
|
-
|
|
74275
|
-
|
|
74276
|
-
|
|
74556
|
+
/**
|
|
74557
|
+
* Rejects a `requireApproval` value that is not a boolean or an array of
|
|
74558
|
+
* string tool keys. The approval branches check for literal `true` or an
|
|
74559
|
+
* array, so a loosely typed value like `'true'` would otherwise disable
|
|
74560
|
+
* approval on MCP providers silently (and crash the HTTP path into
|
|
74561
|
+
* warn-and-skip) instead of gating tools as the author intended.
|
|
74562
|
+
*/
|
|
74563
|
+
function validateRequireApproval(providers) {
|
|
74564
|
+
for (const [integrationId, providerOptions] of Object.entries(providers)) {
|
|
74565
|
+
const requireApproval = providerOptions.requireApproval;
|
|
74566
|
+
if (requireApproval === void 0 || typeof requireApproval === "boolean") continue;
|
|
74567
|
+
if (Array.isArray(requireApproval) && requireApproval.every((name) => typeof name === "string")) continue;
|
|
74568
|
+
throw new MastraConnectError("invalid_options", `Invalid options for '${integrationId}': requireApproval must be a boolean or an array of tool keys.`);
|
|
74569
|
+
}
|
|
74570
|
+
}
|
|
74571
|
+
/**
|
|
74572
|
+
* Rejects the removed `autoApproveTools` option by name. Discovered MCP tools
|
|
74573
|
+
* no longer require approval by default, so a loosely typed config still
|
|
74574
|
+
* carrying this key would otherwise be ignored silently and its tools would
|
|
74575
|
+
* run without the prompts the author expected.
|
|
74576
|
+
*/
|
|
74577
|
+
function rejectRemovedAutoApproveTools(providers) {
|
|
74578
|
+
for (const [integrationId, providerOptions] of Object.entries(providers)) if ("autoApproveTools" in providerOptions) throw new MastraConnectError("invalid_options", `Invalid options for '${integrationId}': autoApproveTools was removed. Tools no longer require approval by default; opt in with requireApproval: true or a list of tool keys to gate.`);
|
|
74579
|
+
}
|
|
74580
|
+
function buildRequests(providers, catalog, catalogAvailable) {
|
|
74581
|
+
const { overrides, only } = providers;
|
|
74582
|
+
const registrations = new Map(PROVIDERS.map((registration) => [registration.integrationId, registration]));
|
|
74277
74583
|
const catalogIds = new Set(catalog.map((integration) => integration.id));
|
|
74278
74584
|
for (const integration of catalog) {
|
|
74279
74585
|
if (!integration.capabilities.mcp) continue;
|
|
@@ -74283,9 +74589,14 @@ function buildRequests(integrations, catalog) {
|
|
|
74283
74589
|
transport: "mcp"
|
|
74284
74590
|
});
|
|
74285
74591
|
}
|
|
74286
|
-
|
|
74592
|
+
const unknown = Object.keys(overrides).filter((integrationId) => !registrations.has(integrationId) && !catalogIds.has(integrationId) && !overrides[integrationId]?.disabled);
|
|
74593
|
+
if (unknown.length > 0) {
|
|
74594
|
+
if (catalogAvailable) throw new MastraConnectConfigError(`Unknown provider${unknown.length > 1 ? "s" : ""} in the providers option: ${unknown.map((id) => `'${id}'`).join(", ")}. Expected a checked-in provider id or a platform catalog integration id.`);
|
|
74595
|
+
for (const integrationId of unknown) console.warn(`[@mastra/connect] Platform catalog unavailable; cannot verify provider '${integrationId}'. Skipping it this resolution.`);
|
|
74596
|
+
}
|
|
74287
74597
|
const requests = [];
|
|
74288
74598
|
for (const registration of registrations.values()) {
|
|
74599
|
+
if (only !== void 0 && !only.has(registration.integrationId)) continue;
|
|
74289
74600
|
const providerOptions = overrides[registration.integrationId] ?? {};
|
|
74290
74601
|
if (providerOptions.disabled) continue;
|
|
74291
74602
|
requests.push({
|
|
@@ -74301,6 +74612,7 @@ async function mapTools(connections, requests, options, client, mcpClients, reso
|
|
|
74301
74612
|
const activeMcpKeys = /* @__PURE__ */ new Set();
|
|
74302
74613
|
const result = {};
|
|
74303
74614
|
const toolOwners = /* @__PURE__ */ new Map();
|
|
74615
|
+
const matchedDefaultEntries = /* @__PURE__ */ new Set();
|
|
74304
74616
|
for (const request of requests) {
|
|
74305
74617
|
const integrationId = request.registration.integrationId;
|
|
74306
74618
|
let providerTools;
|
|
@@ -74320,16 +74632,19 @@ async function mapTools(connections, requests, options, client, mcpClients, reso
|
|
|
74320
74632
|
connectionId: resolution.connectionId,
|
|
74321
74633
|
allowTools: request.options.allowTools,
|
|
74322
74634
|
disallowTools: request.options.disallowTools,
|
|
74323
|
-
|
|
74635
|
+
requireApproval: request.options.requireApproval,
|
|
74324
74636
|
client,
|
|
74325
74637
|
mcpClients,
|
|
74326
74638
|
resolverId
|
|
74327
74639
|
});
|
|
74328
|
-
} else
|
|
74329
|
-
|
|
74330
|
-
|
|
74331
|
-
|
|
74332
|
-
|
|
74640
|
+
} else {
|
|
74641
|
+
providerTools = request.registration.createTools({
|
|
74642
|
+
connectionId: resolution.connectionId,
|
|
74643
|
+
client: options.client,
|
|
74644
|
+
...providerFilterOptions(request.options)
|
|
74645
|
+
});
|
|
74646
|
+
applyProxyRequireApproval(providerTools, integrationId, request.options.requireApproval);
|
|
74647
|
+
}
|
|
74333
74648
|
else if (request.registration.transport === "mcp") {
|
|
74334
74649
|
for (const connection of resolution.connections) activeMcpKeys.add(`${integrationId}::${connection.id}`);
|
|
74335
74650
|
providerTools = await buildMcpMultiConnectionTools({
|
|
@@ -74337,22 +74652,31 @@ async function mapTools(connections, requests, options, client, mcpClients, reso
|
|
|
74337
74652
|
connections: resolution.connections,
|
|
74338
74653
|
allowTools: request.options.allowTools,
|
|
74339
74654
|
disallowTools: request.options.disallowTools,
|
|
74340
|
-
|
|
74655
|
+
requireApproval: request.options.requireApproval,
|
|
74341
74656
|
client,
|
|
74342
74657
|
mcpClients,
|
|
74343
74658
|
resolverId
|
|
74344
74659
|
});
|
|
74345
|
-
} else
|
|
74346
|
-
|
|
74347
|
-
|
|
74348
|
-
|
|
74349
|
-
|
|
74350
|
-
|
|
74351
|
-
|
|
74660
|
+
} else {
|
|
74661
|
+
providerTools = buildProxyMultiConnectionTools({
|
|
74662
|
+
registration: request.registration,
|
|
74663
|
+
connections: resolution.connections,
|
|
74664
|
+
allowTools: request.options.allowTools,
|
|
74665
|
+
disallowTools: request.options.disallowTools,
|
|
74666
|
+
client: options.client
|
|
74667
|
+
});
|
|
74668
|
+
applyProxyRequireApproval(providerTools, integrationId, request.options.requireApproval, [listConnectionsToolKey(integrationId)]);
|
|
74669
|
+
}
|
|
74352
74670
|
} catch (error) {
|
|
74671
|
+
if (error instanceof MastraConnectConfigError) throw error;
|
|
74353
74672
|
console.warn(`[@mastra/connect] Skipping ${integrationId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
74354
74673
|
continue;
|
|
74355
74674
|
}
|
|
74675
|
+
if (!(request.options.allowTools !== void 0 || request.options.disallowTools !== void 0) && (options.allowTools !== void 0 || options.disallowTools !== void 0)) providerTools = applyDefaultFilter(providerTools, options, integrationId, matchedDefaultEntries);
|
|
74676
|
+
if (request.options.requireApproval === void 0 && options.requireApproval !== void 0) {
|
|
74677
|
+
const policy = options.requireApproval;
|
|
74678
|
+
if (policy !== false) applyDefaultRequireApproval(providerTools, policy, integrationId, matchedDefaultEntries);
|
|
74679
|
+
}
|
|
74356
74680
|
for (const toolKey of Object.keys(providerTools)) {
|
|
74357
74681
|
const existingOwner = toolOwners.get(toolKey);
|
|
74358
74682
|
if (existingOwner) throw new MastraConnectError("invalid_options", `Duplicate tool key '${toolKey}' from providers '${existingOwner}' and '${integrationId}'.`);
|
|
@@ -74360,22 +74684,114 @@ async function mapTools(connections, requests, options, client, mcpClients, reso
|
|
|
74360
74684
|
}
|
|
74361
74685
|
Object.assign(result, providerTools);
|
|
74362
74686
|
}
|
|
74687
|
+
if (Object.keys(result).length > 0) {
|
|
74688
|
+
const defaultEntries = [
|
|
74689
|
+
...options.allowTools ?? [],
|
|
74690
|
+
...options.disallowTools ?? [],
|
|
74691
|
+
...Array.isArray(options.requireApproval) ? options.requireApproval : []
|
|
74692
|
+
];
|
|
74693
|
+
for (const entry of defaultEntries) if (!matchedDefaultEntries.has(entry)) console.warn(`[@mastra/connect] Top-level entry '${entry}' matched no tools on any resolved provider.`);
|
|
74694
|
+
}
|
|
74363
74695
|
const staleClients = Array.from(mcpClients.entries()).filter(([key]) => !activeMcpKeys.has(key));
|
|
74364
74696
|
for (const [key] of staleClients) mcpClients.delete(key);
|
|
74365
74697
|
await Promise.allSettled(staleClients.map(([, entry]) => entry.client.disconnect()));
|
|
74366
74698
|
return result;
|
|
74367
74699
|
}
|
|
74368
74700
|
/**
|
|
74369
|
-
*
|
|
74701
|
+
* Applies the top-level default filter to a provider that set no filter of
|
|
74702
|
+
* its own. Lenient by design: the provider set is live, so a default entry
|
|
74703
|
+
* that matches nothing on this provider simply does not apply here. Entries
|
|
74704
|
+
* that match are recorded in `matchedEntries` so mapTools can warn about
|
|
74705
|
+
* defaults that matched nothing anywhere. The synthetic
|
|
74706
|
+
* `<provider>__list_connections` wrapper is never filtered by defaults,
|
|
74707
|
+
* matching the per-provider multi-connection behavior.
|
|
74708
|
+
*/
|
|
74709
|
+
function applyDefaultFilter(providerTools, defaults, integrationId, matchedEntries) {
|
|
74710
|
+
const listToolKey = listConnectionsToolKey(integrationId);
|
|
74711
|
+
const matchers = (defaults.allowTools ?? defaults.disallowTools ?? []).map((entry) => ({
|
|
74712
|
+
entry,
|
|
74713
|
+
matches: compileToolMatcher([entry])
|
|
74714
|
+
}));
|
|
74715
|
+
const filtered = {};
|
|
74716
|
+
for (const [key, tool] of Object.entries(providerTools)) {
|
|
74717
|
+
if (key === listToolKey) {
|
|
74718
|
+
filtered[key] = tool;
|
|
74719
|
+
continue;
|
|
74720
|
+
}
|
|
74721
|
+
let matchedAny = false;
|
|
74722
|
+
for (const { entry, matches } of matchers) if (matches(key)) {
|
|
74723
|
+
matchedEntries.add(entry);
|
|
74724
|
+
matchedAny = true;
|
|
74725
|
+
}
|
|
74726
|
+
if (defaults.allowTools !== void 0 ? matchedAny : !matchedAny) filtered[key] = tool;
|
|
74727
|
+
}
|
|
74728
|
+
return filtered;
|
|
74729
|
+
}
|
|
74730
|
+
/**
|
|
74731
|
+
* Applies the top-level default `requireApproval` policy to a provider that
|
|
74732
|
+
* set no policy of its own. `true` gates every tool except the synthetic
|
|
74733
|
+
* `<provider>__list_connections` wrapper; an array gates matching keys with
|
|
74734
|
+
* the same lenient semantics as {@link applyDefaultFilter}.
|
|
74735
|
+
*/
|
|
74736
|
+
function applyDefaultRequireApproval(providerTools, policy, integrationId, matchedEntries) {
|
|
74737
|
+
const listToolKey = listConnectionsToolKey(integrationId);
|
|
74738
|
+
if (policy === true) {
|
|
74739
|
+
for (const [key, tool] of Object.entries(providerTools)) {
|
|
74740
|
+
if (key === listToolKey) continue;
|
|
74741
|
+
tool.requireApproval = true;
|
|
74742
|
+
}
|
|
74743
|
+
return;
|
|
74744
|
+
}
|
|
74745
|
+
const matchers = policy.map((entry) => ({
|
|
74746
|
+
entry,
|
|
74747
|
+
matches: compileToolMatcher([entry])
|
|
74748
|
+
}));
|
|
74749
|
+
for (const [key, tool] of Object.entries(providerTools)) {
|
|
74750
|
+
if (key === listToolKey) continue;
|
|
74751
|
+
for (const { entry, matches } of matchers) if (matches(key)) {
|
|
74752
|
+
matchedEntries.add(entry);
|
|
74753
|
+
tool.requireApproval = true;
|
|
74754
|
+
}
|
|
74755
|
+
}
|
|
74756
|
+
}
|
|
74757
|
+
/**
|
|
74758
|
+
* Extracts whichever provider tool filter is set. Since `ToolsProviderOptions`
|
|
74370
74759
|
* is an XOR union and tools() validates co-occurrence up front, at most one
|
|
74371
74760
|
* of the two will ever be defined here.
|
|
74372
74761
|
*/
|
|
74373
74762
|
function providerFilterOptions(options) {
|
|
74374
74763
|
return options.allowTools !== void 0 ? { allowTools: options.allowTools } : options.disallowTools !== void 0 ? { disallowTools: options.disallowTools } : {};
|
|
74375
74764
|
}
|
|
74765
|
+
/**
|
|
74766
|
+
* Applies a per-provider `requireApproval` policy to a checked-in HTTP
|
|
74767
|
+
* toolset by marking the selected tools. `true` gates every provider tool
|
|
74768
|
+
* (but never the synthetic `<provider>__list_connections` wrapper tool,
|
|
74769
|
+
* matching the MCP paths, where only server-discovered tools are gated);
|
|
74770
|
+
* an array gates the listed keys — entries containing `*` are globs,
|
|
74771
|
+
* expanded against the provider tools minus the synthetic wrapper so a
|
|
74772
|
+
* broad glob behaves like `true` — and rejects unknown names and dead
|
|
74773
|
+
* globs with the same `invalid_options` error MCP discovery raises, so a
|
|
74774
|
+
* typo never silently widens access.
|
|
74775
|
+
*/
|
|
74776
|
+
function applyProxyRequireApproval(providerTools, integrationId, requireApproval, excludeKeys = []) {
|
|
74777
|
+
if (!requireApproval) return;
|
|
74778
|
+
const excluded = new Set(excludeKeys);
|
|
74779
|
+
if (requireApproval === true) {
|
|
74780
|
+
for (const [toolKey, tool] of Object.entries(providerTools)) {
|
|
74781
|
+
if (excluded.has(toolKey)) continue;
|
|
74782
|
+
tool.requireApproval = true;
|
|
74783
|
+
}
|
|
74784
|
+
return;
|
|
74785
|
+
}
|
|
74786
|
+
const known = Object.keys(providerTools);
|
|
74787
|
+
const expanded = expandToolPatterns(requireApproval, known.filter((key) => !excluded.has(key)), `requireApproval for '${integrationId}'`);
|
|
74788
|
+
const unknown = expanded.filter((name) => !known.includes(name));
|
|
74789
|
+
if (unknown.length > 0) throw new MastraConnectConfigError(`Unknown tool name(s) in requireApproval for '${integrationId}': ${unknown.join(", ")}. Known tools: ${known.join(", ")}.`);
|
|
74790
|
+
for (const name of expanded) providerTools[name].requireApproval = true;
|
|
74791
|
+
}
|
|
74376
74792
|
async function discoverMcpTools(input) {
|
|
74377
|
-
const { registration, connectionId, allowTools, disallowTools,
|
|
74378
|
-
const
|
|
74793
|
+
const { registration, connectionId, allowTools, disallowTools, requireApproval, client, mcpClients, resolverId } = input;
|
|
74794
|
+
const requireApprovalFor = Array.isArray(requireApproval) ? compileToolMatcher(requireApproval) : void 0;
|
|
74379
74795
|
const cacheKey = `${registration.integrationId}::${connectionId}`;
|
|
74380
74796
|
let entry = mcpClients.get(cacheKey);
|
|
74381
74797
|
if (!entry) {
|
|
@@ -74387,7 +74803,7 @@ async function discoverMcpTools(input) {
|
|
|
74387
74803
|
id: `mastra-connect-${resolverId}-${registration.integrationId}-${connectionId}`,
|
|
74388
74804
|
servers: { [registration.integrationId]: {
|
|
74389
74805
|
...transport,
|
|
74390
|
-
requireToolApproval: ({ toolName }) =>
|
|
74806
|
+
...requireApproval === true ? { requireToolApproval: true } : requireApprovalFor ? { requireToolApproval: ({ toolName }) => requireApprovalFor(`${registration.integrationId}_${String(toolName)}`) } : {}
|
|
74391
74807
|
} }
|
|
74392
74808
|
})
|
|
74393
74809
|
};
|
|
@@ -74396,31 +74812,16 @@ async function discoverMcpTools(input) {
|
|
|
74396
74812
|
const discovery = await entry.client.listToolsWithErrors();
|
|
74397
74813
|
const error = discovery.errors[registration.integrationId];
|
|
74398
74814
|
if (error) throw new Error(`MCP tool discovery failed: ${error}`);
|
|
74399
|
-
|
|
74400
|
-
|
|
74815
|
+
if (Array.isArray(requireApproval)) {
|
|
74816
|
+
const unknown = expandToolPatterns(requireApproval, Object.keys(discovery.tools), `requireApproval for '${registration.integrationId}'`).filter((name) => !(name in discovery.tools));
|
|
74817
|
+
if (unknown.length > 0) throw new MastraConnectConfigError(`Unknown tool name(s) in requireApproval for '${registration.integrationId}': ${unknown.join(", ")}. Known tools: ${Object.keys(discovery.tools).join(", ")}.`);
|
|
74818
|
+
}
|
|
74401
74819
|
return applyToolFilter(discovery.tools, {
|
|
74402
74820
|
allowTools,
|
|
74403
74821
|
disallowTools
|
|
74404
74822
|
});
|
|
74405
74823
|
}
|
|
74406
74824
|
//#endregion
|
|
74407
|
-
//#region src/connect.ts
|
|
74408
|
-
/**
|
|
74409
|
-
* @deprecated Use `tools` from `@mastra/connect` instead. This module is a
|
|
74410
|
-
* thin re-export retained for one release cycle so downstream consumers keep
|
|
74411
|
-
* working; it will be removed in the next minor.
|
|
74412
|
-
*/
|
|
74413
|
-
/**
|
|
74414
|
-
* @deprecated Renamed to {@link tools}.
|
|
74415
|
-
*
|
|
74416
|
-
* `connect(options)` is a drop-in alias for `tools(options)`. Prefer `tools`
|
|
74417
|
-
* from `@mastra/connect` in new code; this export will be removed in the next
|
|
74418
|
-
* minor version.
|
|
74419
|
-
*/
|
|
74420
|
-
function connect(options = {}) {
|
|
74421
|
-
return tools(options);
|
|
74422
|
-
}
|
|
74423
|
-
//#endregion
|
|
74424
74825
|
//#region src/channels.ts
|
|
74425
74826
|
const DEFAULT_TTL_MS = 3e4;
|
|
74426
74827
|
/** Minimum wait after a failed platform fetch before another background revalidation. */
|
|
@@ -74433,7 +74834,7 @@ const FAILURE_COOLDOWN_MS = 3e4;
|
|
|
74433
74834
|
* Discord) are constructed once, up front and credential-less, so their
|
|
74434
74835
|
* webhook/OAuth routes can mount at Mastra construction. Each resolution
|
|
74435
74836
|
* fetches the project's connections and late-binds credentials into the live
|
|
74436
|
-
* instances:
|
|
74837
|
+
* instances: providers with an active connection appear in the resolved
|
|
74437
74838
|
* map, others don't — so connecting a new channel on the platform takes
|
|
74438
74839
|
* effect without redeploying the app.
|
|
74439
74840
|
*
|
|
@@ -74458,12 +74859,17 @@ async function channels(options = {}) {
|
|
|
74458
74859
|
const projectId = options.projectId?.trim() || process.env.MASTRA_PROJECT_ID?.trim();
|
|
74459
74860
|
if (!projectId) throw new MastraConnectError("missing_project_id", "Missing project id: set MASTRA_PROJECT_ID or pass projectId.");
|
|
74460
74861
|
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.`);
|
|
74461
|
-
|
|
74862
|
+
const { overrides: providerOverrides, only } = normalizeChannelProviders(options.providers);
|
|
74863
|
+
validateProviderIds(providerOverrides);
|
|
74864
|
+
const knownChannelIds = new Set(CHANNELS.map((registration) => registration.integrationId));
|
|
74865
|
+
const unknownChannelIds = Object.keys(providerOverrides).filter((integrationId) => !knownChannelIds.has(integrationId) && !providerOverrides[integrationId]?.disabled);
|
|
74866
|
+
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(", ")}.`);
|
|
74462
74867
|
const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
|
|
74463
74868
|
const client = resolveClient(options.client);
|
|
74464
74869
|
const states = [];
|
|
74465
74870
|
for (const registration of CHANNELS) {
|
|
74466
|
-
|
|
74871
|
+
if (only !== void 0 && !only.has(registration.integrationId)) continue;
|
|
74872
|
+
const overrides = providerOverrides[registration.integrationId] ?? {};
|
|
74467
74873
|
if (overrides.disabled) continue;
|
|
74468
74874
|
const state = {
|
|
74469
74875
|
registration,
|
|
@@ -74499,6 +74905,7 @@ async function channels(options = {}) {
|
|
|
74499
74905
|
let cache;
|
|
74500
74906
|
let inflight;
|
|
74501
74907
|
let lastFailureAt;
|
|
74908
|
+
let warnedStaleSlackConnection = false;
|
|
74502
74909
|
const buildSnapshot = async () => {
|
|
74503
74910
|
let connections;
|
|
74504
74911
|
try {
|
|
@@ -74509,9 +74916,13 @@ async function channels(options = {}) {
|
|
|
74509
74916
|
}
|
|
74510
74917
|
const byIntegrationId = groupByIntegrationId(connections);
|
|
74511
74918
|
const providers = {};
|
|
74919
|
+
if (!warnedStaleSlackConnection && states.some((state) => state.registration.integrationId === "slack-channels") && (byIntegrationId.get("slack")?.length ?? 0) > 0 && (byIntegrationId.get("slack-channels")?.length ?? 0) === 0) {
|
|
74920
|
+
warnedStaleSlackConnection = true;
|
|
74921
|
+
console.warn(`[@mastra/connect] Project ${projectId} has an active 'slack' connection but no 'slack-channels' connection: the Slack channel is now keyed off 'slack-channels'. Connect Slack again as 'slack-channels' to restore it; the existing 'slack' connection still powers the generated Slack tools.`);
|
|
74922
|
+
}
|
|
74512
74923
|
for (const state of states) {
|
|
74513
74924
|
const integrationId = state.registration.integrationId;
|
|
74514
|
-
const overrides =
|
|
74925
|
+
const overrides = providerOverrides[integrationId] ?? {};
|
|
74515
74926
|
const candidates = byIntegrationId.get(integrationId) ?? [];
|
|
74516
74927
|
const connectionId = candidates.length === 0 ? void 0 : selectChannelConnection(integrationId, overrides.connectionId, candidates);
|
|
74517
74928
|
state.connectionId = connectionId;
|
|
@@ -74558,9 +74969,6 @@ async function channels(options = {}) {
|
|
|
74558
74969
|
};
|
|
74559
74970
|
const invocable = ((_context) => resolve());
|
|
74560
74971
|
invocable.getRoutes = () => states.flatMap((state) => state.instance.provider.getRoutes());
|
|
74561
|
-
invocable.invalidate = () => {
|
|
74562
|
-
cache = void 0;
|
|
74563
|
-
};
|
|
74564
74972
|
invocable.refresh = refresh;
|
|
74565
74973
|
invocable.disconnect = async () => {
|
|
74566
74974
|
cache = void 0;
|
|
@@ -74568,15 +74976,73 @@ async function channels(options = {}) {
|
|
|
74568
74976
|
return invocable;
|
|
74569
74977
|
}
|
|
74570
74978
|
/**
|
|
74979
|
+
* Friendly channel-key aliases. The Slack channel is keyed `slack-channels`
|
|
74980
|
+
* on the platform (plain `slack` names the Slack tools provider), but inside
|
|
74981
|
+
* a channels() config `slack` is unambiguous — accept it and canonicalize to
|
|
74982
|
+
* the platform key for registration and connection lookup.
|
|
74983
|
+
*/
|
|
74984
|
+
const CHANNEL_KEY_ALIASES = { slack: "slack-channels" };
|
|
74985
|
+
const canonicalChannelId = (id) => CHANNEL_KEY_ALIASES[id] ?? id;
|
|
74986
|
+
/** Throws when two option keys (e.g. `slack` and `slack-channels`) name the same channel. */
|
|
74987
|
+
function rejectAliasCollision(sourceKeys, canonical, key) {
|
|
74988
|
+
const existing = sourceKeys[canonical];
|
|
74989
|
+
if (existing === void 0) return;
|
|
74990
|
+
throw new MastraConnectError("invalid_options", existing === key ? `Duplicate provider '${key}' in providers array.` : `Both '${existing}' and '${key}' name the '${canonical}' channel in the providers option; use one key.`);
|
|
74991
|
+
}
|
|
74992
|
+
/**
|
|
74993
|
+
* Turns the two accepted `providers` shapes into the internal form, mirroring
|
|
74994
|
+
* `tools()`. The array form becomes an allowlist with default options; the
|
|
74995
|
+
* record form expands boolean shorthands (`true` → `{}`, `false` → an
|
|
74996
|
+
* internal exclusion marker). Alias keys canonicalize first, so `slack` and
|
|
74997
|
+
* `slack-channels` configure the same channel (and collide loudly). Malformed
|
|
74998
|
+
* inputs throw at channels() time.
|
|
74999
|
+
*/
|
|
75000
|
+
function normalizeChannelProviders(providers) {
|
|
75001
|
+
if (providers === void 0) return {
|
|
75002
|
+
overrides: {},
|
|
75003
|
+
only: void 0
|
|
75004
|
+
};
|
|
75005
|
+
const sourceKeys = {};
|
|
75006
|
+
if (Array.isArray(providers)) {
|
|
75007
|
+
const overrides = {};
|
|
75008
|
+
for (const entry of providers) {
|
|
75009
|
+
if (typeof entry !== "string") throw new MastraConnectError("invalid_options", `Invalid providers entry: expected a string channel id, got ${typeof entry}.`);
|
|
75010
|
+
const canonical = canonicalChannelId(entry);
|
|
75011
|
+
rejectAliasCollision(sourceKeys, canonical, entry);
|
|
75012
|
+
sourceKeys[canonical] = entry;
|
|
75013
|
+
overrides[canonical] = {};
|
|
75014
|
+
}
|
|
75015
|
+
return {
|
|
75016
|
+
overrides,
|
|
75017
|
+
only: new Set(Object.keys(overrides))
|
|
75018
|
+
};
|
|
75019
|
+
}
|
|
75020
|
+
const overrides = {};
|
|
75021
|
+
for (const [providerId, value] of Object.entries(providers)) {
|
|
75022
|
+
if (value === void 0) continue;
|
|
75023
|
+
const canonical = canonicalChannelId(providerId);
|
|
75024
|
+
rejectAliasCollision(sourceKeys, canonical, providerId);
|
|
75025
|
+
sourceKeys[canonical] = providerId;
|
|
75026
|
+
if (value === true) overrides[canonical] = {};
|
|
75027
|
+
else if (value === false) overrides[canonical] = { disabled: true };
|
|
75028
|
+
else if (typeof value === "object" && value !== null && !Array.isArray(value)) overrides[canonical] = value;
|
|
75029
|
+
else throw new MastraConnectError("invalid_options", `Invalid providers entry for '${providerId}': expected true, false, or an options object, got ${value === null ? "null" : Array.isArray(value) ? "an array" : typeof value}.`);
|
|
75030
|
+
}
|
|
75031
|
+
return {
|
|
75032
|
+
overrides,
|
|
75033
|
+
only: void 0
|
|
75034
|
+
};
|
|
75035
|
+
}
|
|
75036
|
+
/**
|
|
74571
75037
|
* Selects the connection `channels()` should use for one provider.
|
|
74572
75038
|
*
|
|
74573
|
-
* - Pinned `connectionId` (from `
|
|
75039
|
+
* - Pinned `connectionId` (from `providers.<id>.connectionId`) wins, but is
|
|
74574
75040
|
* skipped if the pinned id isn't attached to the project or the connection
|
|
74575
75041
|
* isn't `active`.
|
|
74576
75042
|
* - Otherwise, the single active connection is used.
|
|
74577
75043
|
* - When more than one active connection exists, this warns naming the chosen
|
|
74578
75044
|
* id and picks the first active connection. There is no env-var fallback;
|
|
74579
|
-
* pin explicitly with `
|
|
75045
|
+
* pin explicitly with `providers.<id>.connectionId` when the deterministic
|
|
74580
75046
|
* choice matters.
|
|
74581
75047
|
*/
|
|
74582
75048
|
function selectChannelConnection(integrationId, pinnedId, candidates) {
|
|
@@ -74605,7 +75071,7 @@ function selectChannelConnection(integrationId, pinnedId, candidates) {
|
|
|
74605
75071
|
if (active.length === 1) return active[0].id;
|
|
74606
75072
|
const chosen = active[0].id;
|
|
74607
75073
|
const others = active.slice(1).map((connection) => connection.id).join(", ");
|
|
74608
|
-
console.warn(`[@mastra/connect] ${integrationId} channel: found ${active.length} active connections; using ${chosen}. Ignoring ${others}. Pin one with
|
|
75074
|
+
console.warn(`[@mastra/connect] ${integrationId} channel: found ${active.length} active connections; using ${chosen}. Ignoring ${others}. Pin one with providers.${integrationId}.connectionId to silence this warning.`);
|
|
74609
75075
|
return chosen;
|
|
74610
75076
|
}
|
|
74611
75077
|
//#endregion
|
|
@@ -74618,121 +75084,11 @@ async function credential(connectionId, options) {
|
|
|
74618
75084
|
return getCredential(resolveClient(options?.client), connectionId);
|
|
74619
75085
|
}
|
|
74620
75086
|
//#endregion
|
|
74621
|
-
//#region src/environment.ts
|
|
74622
|
-
function credentialToken(credential) {
|
|
74623
|
-
return credential.type === "oauth2" ? credential.accessToken : credential.apiKey;
|
|
74624
|
-
}
|
|
74625
|
-
/**
|
|
74626
|
-
* Wires git's credential helper to read the token from the environment at use
|
|
74627
|
-
* time, so the secret lives in the process env rather than in git config or
|
|
74628
|
-
* remote URLs. `gh` needs no setup: it honors GH_TOKEN directly.
|
|
74629
|
-
*/
|
|
74630
|
-
const GITHUB_GIT_CREDENTIAL_HELPER = "!f() { echo username=x-access-token; echo \"password=$GH_TOKEN\"; }; f";
|
|
74631
|
-
/** Providers that know how to materialize sandbox credentials. */
|
|
74632
|
-
const ENVIRONMENT_CONTRIBUTORS = [{
|
|
74633
|
-
integrationId: "github",
|
|
74634
|
-
envVar: "MASTRA_GITHUB_CONNECTION_ID",
|
|
74635
|
-
build(credential) {
|
|
74636
|
-
const token = credentialToken(credential);
|
|
74637
|
-
return {
|
|
74638
|
-
env: {
|
|
74639
|
-
GH_TOKEN: token,
|
|
74640
|
-
GITHUB_TOKEN: token
|
|
74641
|
-
},
|
|
74642
|
-
onStart: async ({ sandbox }) => {
|
|
74643
|
-
if (!sandbox.executeCommand) {
|
|
74644
|
-
console.warn("[@mastra/connect] github environment: sandbox does not support executeCommand; skipping git credential setup (gh still works via GH_TOKEN).");
|
|
74645
|
-
return;
|
|
74646
|
-
}
|
|
74647
|
-
await sandbox.executeCommand("git", [
|
|
74648
|
-
"config",
|
|
74649
|
-
"--global",
|
|
74650
|
-
"credential.https://github.com.helper",
|
|
74651
|
-
GITHUB_GIT_CREDENTIAL_HELPER
|
|
74652
|
-
]);
|
|
74653
|
-
}
|
|
74654
|
-
};
|
|
74655
|
-
}
|
|
74656
|
-
}];
|
|
74657
|
-
/**
|
|
74658
|
-
* Resolves the project's Platform connections into sandbox credentials:
|
|
74659
|
-
* environment variables plus a start hook that finishes in-sandbox setup.
|
|
74660
|
-
* Currently GitHub-aware (`GH_TOKEN`/`GITHUB_TOKEN` + git credential helper);
|
|
74661
|
-
* more providers plug in over time.
|
|
74662
|
-
*
|
|
74663
|
-
* Connection resolution matches `connect()`: a per-integration `connectionId`
|
|
74664
|
-
* or the provider's `MASTRA_*_CONNECTION_ID` env var wins, else a single
|
|
74665
|
-
* active connection; ambiguity, needs_reauth, and credential-fetch failures
|
|
74666
|
-
* warn and skip that provider. Configuration errors (missing project id,
|
|
74667
|
-
* malformed integration id) throw here so they surface at startup.
|
|
74668
|
-
*
|
|
74669
|
-
* The returned `env` is a snapshot: call `environment()` again for a fresh
|
|
74670
|
-
* token when starting new sandboxes.
|
|
74671
|
-
*
|
|
74672
|
-
* @example
|
|
74673
|
-
* const { env, onStart } = await environment({ projectId });
|
|
74674
|
-
* const sandbox = new E2BSandbox({ env, onStart });
|
|
74675
|
-
* // in the sandbox: `gh pr list`, `git clone https://github.com/org/repo` just work
|
|
74676
|
-
*/
|
|
74677
|
-
async function environment(options = {}) {
|
|
74678
|
-
const projectId = options.projectId?.trim() || process.env.MASTRA_PROJECT_ID?.trim();
|
|
74679
|
-
if (!projectId) throw new MastraConnectError("missing_project_id", "Missing project id: set MASTRA_PROJECT_ID or pass projectId.");
|
|
74680
|
-
validateIntegrationOverrides(options.integrations);
|
|
74681
|
-
const client = resolveClient(options.client);
|
|
74682
|
-
const byIntegrationId = groupByIntegrationId(await listProjectConnections(client, projectId));
|
|
74683
|
-
const env = {};
|
|
74684
|
-
const hooks = [];
|
|
74685
|
-
for (const contributor of ENVIRONMENT_CONTRIBUTORS) {
|
|
74686
|
-
const integrationId = contributor.integrationId;
|
|
74687
|
-
const overrides = options.integrations?.[integrationId] ?? {};
|
|
74688
|
-
if (overrides.disabled) continue;
|
|
74689
|
-
const candidates = byIntegrationId.get(integrationId) ?? [];
|
|
74690
|
-
if (candidates.length === 0) continue;
|
|
74691
|
-
const connectionId = resolveConnection({
|
|
74692
|
-
integrationId,
|
|
74693
|
-
envVar: contributor.envVar,
|
|
74694
|
-
connectionId: overrides.connectionId
|
|
74695
|
-
}, candidates);
|
|
74696
|
-
if (!connectionId) continue;
|
|
74697
|
-
let credential;
|
|
74698
|
-
try {
|
|
74699
|
-
credential = await getCredential(client, connectionId);
|
|
74700
|
-
} catch (error) {
|
|
74701
|
-
console.warn(`[@mastra/connect] Skipping ${integrationId} environment: ${error instanceof Error ? error.message : String(error)}`);
|
|
74702
|
-
continue;
|
|
74703
|
-
}
|
|
74704
|
-
const contribution = contributor.build(credential);
|
|
74705
|
-
for (const [key, value] of Object.entries(contribution.env)) {
|
|
74706
|
-
if (key in env) console.warn(`[@mastra/connect] ${integrationId} environment overwrites env var '${key}' set by an earlier provider.`);
|
|
74707
|
-
env[key] = value;
|
|
74708
|
-
}
|
|
74709
|
-
if (contribution.onStart) hooks.push({
|
|
74710
|
-
integrationId,
|
|
74711
|
-
hook: contribution.onStart
|
|
74712
|
-
});
|
|
74713
|
-
}
|
|
74714
|
-
const onStart = async (args) => {
|
|
74715
|
-
for (const { hook } of hooks) await hook(args);
|
|
74716
|
-
};
|
|
74717
|
-
return {
|
|
74718
|
-
env,
|
|
74719
|
-
onStart
|
|
74720
|
-
};
|
|
74721
|
-
}
|
|
74722
|
-
//#endregion
|
|
74723
75087
|
exports.CHANNELS = CHANNELS;
|
|
74724
75088
|
exports.MastraConnectError = MastraConnectError;
|
|
74725
75089
|
exports.PROVIDERS = PROVIDERS;
|
|
74726
|
-
exports.TOOLS = TOOLS;
|
|
74727
|
-
exports.applyAllowTools = applyAllowTools;
|
|
74728
75090
|
exports.channels = channels;
|
|
74729
|
-
exports.connect = connect;
|
|
74730
75091
|
exports.credential = credential;
|
|
74731
|
-
exports.defineProxyTool = defineProxyTool;
|
|
74732
|
-
exports.environment = environment;
|
|
74733
|
-
exports.findChannelRegistration = findChannelRegistration;
|
|
74734
|
-
exports.findRegistration = findRegistration;
|
|
74735
|
-
exports.resolveConnectionId = resolveConnectionId;
|
|
74736
75092
|
exports.tools = tools;
|
|
74737
75093
|
|
|
74738
75094
|
//# sourceMappingURL=index.cjs.map
|