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