@mastra/mcp 1.17.3 → 1.18.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/configuration.d.ts +13 -21
- package/dist/client/configuration.d.ts.map +1 -1
- package/dist/docs/SKILL.md +2 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-auth-fga.md +1 -1
- package/dist/docs/references/docs-connections-connect-mcp-client.md +211 -0
- package/dist/docs/references/reference-tools-mcp-server.md +29 -1
- package/dist/index.cjs +1187 -178
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1189 -181
- package/dist/index.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/mastra-api-mcp-server.d.ts +32 -0
- package/dist/server/mastra-api-mcp-server.d.ts.map +1 -0
- package/dist/server/mastra-api-operations.generated.d.ts +364 -0
- package/dist/server/mastra-api-operations.generated.d.ts.map +1 -0
- package/dist/server/server.d.ts +15 -17
- package/dist/server/server.d.ts.map +1 -1
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -10,9 +10,9 @@ import { createHash, randomUUID, timingSafeEqual } from "crypto";
|
|
|
10
10
|
import equal from "fast-deep-equal";
|
|
11
11
|
import { createServer } from "http";
|
|
12
12
|
import { MCPServerBase } from "@mastra/core/mcp";
|
|
13
|
-
import { isStandardSchemaWithJSON, standardSchemaToJSONSchema } from "@mastra/core/schema";
|
|
13
|
+
import { isStandardSchemaWithJSON, standardSchemaToJSONSchema, toStandardSchema } from "@mastra/core/schema";
|
|
14
14
|
import { readFileSync } from "fs";
|
|
15
|
-
import { RequestContext } from "@mastra/core/request-context";
|
|
15
|
+
import { MASTRA_AUTH_TOKEN_KEY, RequestContext } from "@mastra/core/request-context";
|
|
16
16
|
import { makeCoreTool } from "@mastra/core/utils";
|
|
17
17
|
import { PromptSchema } from "@modelcontextprotocol/core";
|
|
18
18
|
import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "@modelcontextprotocol/ext-apps";
|
|
@@ -9809,11 +9809,11 @@ var AiSdkSchemaWrapper = class {
|
|
|
9809
9809
|
* const jsonSchema = standardSchema['~standard'].jsonSchema.output({ target: 'draft-07' });
|
|
9810
9810
|
* ```
|
|
9811
9811
|
*/
|
|
9812
|
-
function toStandardSchema$
|
|
9812
|
+
function toStandardSchema$5(schema) {
|
|
9813
9813
|
return new AiSdkSchemaWrapper(schema);
|
|
9814
9814
|
}
|
|
9815
9815
|
//#endregion
|
|
9816
|
-
//#region ../schema-compat/dist/json-schema-
|
|
9816
|
+
//#region ../schema-compat/dist/json-schema-BKit3LVN.js
|
|
9817
9817
|
var require_code$1 = /* @__PURE__ */ __commonJSMin$1(((exports) => {
|
|
9818
9818
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9819
9819
|
exports.regexpCode = exports.getEsmExportName = exports.getProperty = exports.safeStringify = exports.stringify = exports.strConcat = exports.addCodeArg = exports.str = exports._ = exports.nil = exports._Code = exports.Name = exports.IDENTIFIER = exports._CodeOrName = void 0;
|
|
@@ -12419,11 +12419,27 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12419
12419
|
/** @type {(value: string) => boolean} */
|
|
12420
12420
|
const isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
12421
12421
|
/** @type {(value: string) => boolean} */
|
|
12422
|
+
const isPort = RegExp.prototype.test.bind(/^\d*$/u);
|
|
12423
|
+
/** @type {(value: string) => boolean} */
|
|
12422
12424
|
const isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
12423
12425
|
/** @type {(value: string) => boolean} */
|
|
12424
12426
|
const isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
12425
12427
|
/** @type {(value: string) => boolean} */
|
|
12426
|
-
const isPathCharacter = RegExp.prototype.test.bind(/^[
|
|
12428
|
+
const isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
|
|
12429
|
+
/** @type {(value: string) => boolean} */
|
|
12430
|
+
const isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
|
|
12431
|
+
/** @type {(value: string) => boolean} */
|
|
12432
|
+
const isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
|
|
12433
|
+
const BYTE_HEX = new Array(256);
|
|
12434
|
+
{
|
|
12435
|
+
const HEX_DIGITS = "0123456789ABCDEF";
|
|
12436
|
+
for (let i = 0; i < 256; i++) BYTE_HEX[i] = "%" + HEX_DIGITS[i >> 4] + HEX_DIGITS[i & 15];
|
|
12437
|
+
}
|
|
12438
|
+
function percentEncodeNonAscii(cp) {
|
|
12439
|
+
if (cp < 2048) return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
|
|
12440
|
+
if (cp < 65536) return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
12441
|
+
return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
12442
|
+
}
|
|
12427
12443
|
/**
|
|
12428
12444
|
* @param {Array<string>} input
|
|
12429
12445
|
* @returns {string}
|
|
@@ -12446,119 +12462,162 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12446
12462
|
}
|
|
12447
12463
|
return acc;
|
|
12448
12464
|
}
|
|
12449
|
-
/**
|
|
12450
|
-
|
|
12451
|
-
|
|
12452
|
-
|
|
12453
|
-
|
|
12454
|
-
|
|
12465
|
+
/** @type {(value: string) => boolean} */
|
|
12466
|
+
const isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
|
|
12467
|
+
/** @type {(value: string) => boolean} */
|
|
12468
|
+
const isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
|
|
12469
|
+
/** @type {(value: string) => boolean} */
|
|
12470
|
+
const isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
|
|
12455
12471
|
/**
|
|
12456
12472
|
* @param {string} value
|
|
12457
12473
|
* @returns {boolean}
|
|
12458
12474
|
*/
|
|
12459
12475
|
const nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
|
|
12460
12476
|
/**
|
|
12461
|
-
* @param {
|
|
12477
|
+
* @param {string} zone
|
|
12462
12478
|
* @returns {boolean}
|
|
12463
12479
|
*/
|
|
12464
|
-
function
|
|
12465
|
-
|
|
12480
|
+
function isZoneIdentifier(zone) {
|
|
12481
|
+
if (zone.length === 0) return false;
|
|
12482
|
+
for (let i = 0; i < zone.length; i++) {
|
|
12483
|
+
if (isZoneCharacter(zone[i])) continue;
|
|
12484
|
+
if (zone[i] === "%" && i + 2 < zone.length && isHexPair(zone.slice(i + 1, i + 3))) {
|
|
12485
|
+
i += 2;
|
|
12486
|
+
continue;
|
|
12487
|
+
}
|
|
12488
|
+
return false;
|
|
12489
|
+
}
|
|
12466
12490
|
return true;
|
|
12467
12491
|
}
|
|
12468
12492
|
/**
|
|
12469
|
-
*
|
|
12470
|
-
*
|
|
12471
|
-
*
|
|
12472
|
-
* @
|
|
12493
|
+
* Compresses the longest run of zero hextets to "::" per RFC 5952. A run of a
|
|
12494
|
+
* single zero hextet is left uncompressed. On ties the leftmost run wins.
|
|
12495
|
+
*
|
|
12496
|
+
* @param {string[]} hextets
|
|
12497
|
+
* @returns {string}
|
|
12473
12498
|
*/
|
|
12474
|
-
function
|
|
12475
|
-
|
|
12476
|
-
|
|
12477
|
-
|
|
12478
|
-
|
|
12479
|
-
|
|
12480
|
-
|
|
12499
|
+
function compressIPv6ZeroRun(hextets) {
|
|
12500
|
+
let bestStart = -1;
|
|
12501
|
+
let bestLength = 0;
|
|
12502
|
+
let runStart = -1;
|
|
12503
|
+
let runLength = 0;
|
|
12504
|
+
for (let i = 0; i < hextets.length; i++) if (hextets[i] === "0") {
|
|
12505
|
+
if (runStart === -1) runStart = i;
|
|
12506
|
+
runLength++;
|
|
12507
|
+
if (runLength > bestLength) {
|
|
12508
|
+
bestLength = runLength;
|
|
12509
|
+
bestStart = runStart;
|
|
12481
12510
|
}
|
|
12482
|
-
|
|
12511
|
+
} else {
|
|
12512
|
+
runStart = -1;
|
|
12513
|
+
runLength = 0;
|
|
12483
12514
|
}
|
|
12484
|
-
return
|
|
12515
|
+
if (bestLength < 2) return hextets.join(":");
|
|
12516
|
+
const head = hextets.slice(0, bestStart).join(":");
|
|
12517
|
+
const tail = hextets.slice(bestStart + bestLength).join(":");
|
|
12518
|
+
return head + "::" + tail;
|
|
12485
12519
|
}
|
|
12486
12520
|
/**
|
|
12521
|
+
* Validates an IPv6 address against the alternatives in RFC 3986 section
|
|
12522
|
+
* 3.2.2 and returns the same address with leading hextet zeroes removed.
|
|
12523
|
+
* An embedded IPv4 address counts as two hextets and is only valid at the end.
|
|
12524
|
+
*
|
|
12487
12525
|
* @param {string} input
|
|
12488
|
-
* @returns {
|
|
12526
|
+
* @returns {string|undefined}
|
|
12489
12527
|
*/
|
|
12490
|
-
function
|
|
12491
|
-
|
|
12492
|
-
|
|
12493
|
-
|
|
12494
|
-
|
|
12495
|
-
|
|
12496
|
-
|
|
12497
|
-
|
|
12498
|
-
|
|
12499
|
-
|
|
12500
|
-
|
|
12501
|
-
let
|
|
12502
|
-
|
|
12503
|
-
|
|
12504
|
-
|
|
12505
|
-
|
|
12506
|
-
|
|
12507
|
-
if (cursor === ":") {
|
|
12508
|
-
if (endipv6Encountered === true) endIpv6 = true;
|
|
12509
|
-
if (!consume(buffer, address, output)) break;
|
|
12510
|
-
if (++tokenCount > 7) {
|
|
12511
|
-
output.error = true;
|
|
12512
|
-
break;
|
|
12513
|
-
}
|
|
12514
|
-
if (i > 0 && input[i - 1] === ":") endipv6Encountered = true;
|
|
12515
|
-
address.push(":");
|
|
12516
|
-
continue;
|
|
12517
|
-
} else if (cursor === "%") {
|
|
12518
|
-
if (!consume(buffer, address, output)) break;
|
|
12519
|
-
consume = consumeIsZone;
|
|
12520
|
-
} else {
|
|
12521
|
-
buffer.push(cursor);
|
|
12528
|
+
function normalizeIPv6Address(input) {
|
|
12529
|
+
const compression = input.indexOf("::");
|
|
12530
|
+
if (compression !== -1 && input.indexOf("::", compression + 1) !== -1) return void 0;
|
|
12531
|
+
const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
|
|
12532
|
+
const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
|
|
12533
|
+
if (compression !== -1) {
|
|
12534
|
+
if (left.length === 1 && left[0] === "") left.length = 0;
|
|
12535
|
+
if (right.length === 1 && right[0] === "") right.length = 0;
|
|
12536
|
+
}
|
|
12537
|
+
const parts = left.concat(right);
|
|
12538
|
+
let hextetCount = 0;
|
|
12539
|
+
for (let i = 0; i < parts.length; i++) {
|
|
12540
|
+
const part = parts[i];
|
|
12541
|
+
if (part === "") return void 0;
|
|
12542
|
+
if (part.indexOf(".") !== -1) {
|
|
12543
|
+
if (i !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part)) return void 0;
|
|
12544
|
+
hextetCount += 2;
|
|
12522
12545
|
continue;
|
|
12523
12546
|
}
|
|
12547
|
+
if (!isHextet(part)) return void 0;
|
|
12548
|
+
parts[i] = parseInt(part, 16).toString(16);
|
|
12549
|
+
hextetCount++;
|
|
12524
12550
|
}
|
|
12525
|
-
if (
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
|
|
12529
|
-
return
|
|
12551
|
+
if (compression === -1) {
|
|
12552
|
+
if (hextetCount !== 8) return void 0;
|
|
12553
|
+
return compressIPv6ZeroRun(parts);
|
|
12554
|
+
}
|
|
12555
|
+
if (hextetCount >= 8) return void 0;
|
|
12556
|
+
const expanded = parts.slice(0, left.length);
|
|
12557
|
+
for (let i = hextetCount; i < 8; i++) expanded.push("0");
|
|
12558
|
+
for (let i = left.length; i < parts.length; i++) expanded.push(parts[i]);
|
|
12559
|
+
return compressIPv6ZeroRun(expanded);
|
|
12530
12560
|
}
|
|
12531
12561
|
/**
|
|
12532
12562
|
* @typedef {Object} NormalizeIPv6Result
|
|
12533
12563
|
* @property {string} host - The normalized host.
|
|
12534
12564
|
* @property {string} [escapedHost] - The escaped host.
|
|
12535
12565
|
* @property {boolean} isIPV6 - Indicates if the host is an IPv6 address.
|
|
12566
|
+
* @property {boolean} [isIPVFuture] - Indicates if the host is an IPvFuture literal.
|
|
12567
|
+
* @property {boolean} [error] - Indicates if a bracketed IP literal is malformed.
|
|
12536
12568
|
*/
|
|
12537
12569
|
/**
|
|
12570
|
+
* Validates and normalizes a bracketed IP literal. Raw zone separators remain
|
|
12571
|
+
* accepted for backwards compatibility, while encoded separators and zone
|
|
12572
|
+
* contents follow RFC 6874.
|
|
12573
|
+
*
|
|
12538
12574
|
* @param {string} host
|
|
12539
12575
|
* @returns {NormalizeIPv6Result}
|
|
12540
12576
|
*/
|
|
12541
12577
|
function normalizeIPv6(host) {
|
|
12542
|
-
|
|
12578
|
+
const bracketed = host[0] === "[" && host[host.length - 1] === "]";
|
|
12579
|
+
if ((host[0] === "[" || host[host.length - 1] === "]") && !bracketed) return {
|
|
12543
12580
|
host,
|
|
12544
|
-
isIPV6: false
|
|
12581
|
+
isIPV6: false,
|
|
12582
|
+
error: true
|
|
12545
12583
|
};
|
|
12546
|
-
|
|
12547
|
-
if (
|
|
12548
|
-
|
|
12549
|
-
let escapedHost = ipv6.address;
|
|
12550
|
-
if (ipv6.zone) {
|
|
12551
|
-
newHost += "%" + ipv6.zone;
|
|
12552
|
-
escapedHost += "%25" + ipv6.zone;
|
|
12553
|
-
}
|
|
12584
|
+
let input = bracketed ? host.slice(1, -1) : host;
|
|
12585
|
+
if (bracketed && isIPvFuture(input)) {
|
|
12586
|
+
input = input.toLowerCase();
|
|
12554
12587
|
return {
|
|
12555
|
-
host:
|
|
12556
|
-
|
|
12557
|
-
|
|
12588
|
+
host: `[${input}]`,
|
|
12589
|
+
escapedHost: input,
|
|
12590
|
+
isIPV6: false,
|
|
12591
|
+
isIPVFuture: true
|
|
12592
|
+
};
|
|
12593
|
+
}
|
|
12594
|
+
if (findToken(input, ":") < 2) return {
|
|
12595
|
+
host,
|
|
12596
|
+
isIPV6: false,
|
|
12597
|
+
error: bracketed
|
|
12598
|
+
};
|
|
12599
|
+
let zoneIdentifier = "";
|
|
12600
|
+
const zoneSeparator = input.indexOf("%");
|
|
12601
|
+
if (zoneSeparator !== -1) {
|
|
12602
|
+
const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
|
|
12603
|
+
zoneIdentifier = input.slice(zoneSeparator + separatorLength);
|
|
12604
|
+
if (!isZoneIdentifier(zoneIdentifier)) return {
|
|
12605
|
+
host,
|
|
12606
|
+
isIPV6: false,
|
|
12607
|
+
error: true
|
|
12558
12608
|
};
|
|
12559
|
-
|
|
12609
|
+
input = input.slice(0, zoneSeparator);
|
|
12610
|
+
}
|
|
12611
|
+
const address = normalizeIPv6Address(input);
|
|
12612
|
+
if (address === void 0) return {
|
|
12560
12613
|
host,
|
|
12561
|
-
isIPV6: false
|
|
12614
|
+
isIPV6: false,
|
|
12615
|
+
error: true
|
|
12616
|
+
};
|
|
12617
|
+
return {
|
|
12618
|
+
host: address + (zoneIdentifier ? "%" + zoneIdentifier : ""),
|
|
12619
|
+
escapedHost: address + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
|
|
12620
|
+
isIPV6: true
|
|
12562
12621
|
};
|
|
12563
12622
|
}
|
|
12564
12623
|
/**
|
|
@@ -12671,7 +12730,7 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12671
12730
|
}
|
|
12672
12731
|
/**
|
|
12673
12732
|
* Normalizes percent escapes and optionally decodes only unreserved ASCII bytes.
|
|
12674
|
-
* Reserved delimiters such as `%2F`
|
|
12733
|
+
* Reserved delimiters such as `%2F` stay escaped; `%2E` is unreserved.
|
|
12675
12734
|
*
|
|
12676
12735
|
* @param {string} input
|
|
12677
12736
|
* @param {boolean} [decodeUnreserved=false]
|
|
@@ -12707,7 +12766,8 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12707
12766
|
function normalizePathEncoding(input) {
|
|
12708
12767
|
let output = "";
|
|
12709
12768
|
for (let i = 0; i < input.length; i++) {
|
|
12710
|
-
|
|
12769
|
+
const ch = input[i];
|
|
12770
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
12711
12771
|
const hex = input.slice(i + 1, i + 3);
|
|
12712
12772
|
if (isHexPair(hex)) {
|
|
12713
12773
|
const normalizedHex = hex.toUpperCase();
|
|
@@ -12718,8 +12778,168 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12718
12778
|
continue;
|
|
12719
12779
|
}
|
|
12720
12780
|
}
|
|
12721
|
-
if (isPathCharacter(
|
|
12722
|
-
else
|
|
12781
|
+
if (isPathCharacter(ch)) output += ch;
|
|
12782
|
+
else {
|
|
12783
|
+
const code = input.charCodeAt(i);
|
|
12784
|
+
if (code < 128) output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
12785
|
+
else if (code < 55296 || code > 57343) output += percentEncodeNonAscii(code);
|
|
12786
|
+
else if (code <= 56319 && i + 1 < input.length) {
|
|
12787
|
+
const low = input.charCodeAt(i + 1);
|
|
12788
|
+
if (low >= 56320 && low <= 57343) {
|
|
12789
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
12790
|
+
i++;
|
|
12791
|
+
} else output += percentEncodeNonAscii(65533);
|
|
12792
|
+
} else output += percentEncodeNonAscii(65533);
|
|
12793
|
+
}
|
|
12794
|
+
}
|
|
12795
|
+
return output;
|
|
12796
|
+
}
|
|
12797
|
+
/**
|
|
12798
|
+
* Serializes a path without rewriting reserved data. Raw RFC 3986 path
|
|
12799
|
+
* characters remain literal, valid escapes are preserved and uppercased, and
|
|
12800
|
+
* everything else is UTF-8 percent-encoded. In a path-noscheme, a colon in the
|
|
12801
|
+
* first segment must be escaped so the result cannot be parsed as a scheme.
|
|
12802
|
+
*
|
|
12803
|
+
* @param {string} input
|
|
12804
|
+
* @param {boolean} [pathNoScheme=false]
|
|
12805
|
+
* @returns {string}
|
|
12806
|
+
*/
|
|
12807
|
+
function serializePathEncoding(input, pathNoScheme = false) {
|
|
12808
|
+
let output = "";
|
|
12809
|
+
let firstSegment = pathNoScheme && input[0] !== "/";
|
|
12810
|
+
for (let i = 0; i < input.length; i++) {
|
|
12811
|
+
const ch = input[i];
|
|
12812
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
12813
|
+
const hex = input.slice(i + 1, i + 3);
|
|
12814
|
+
if (isHexPair(hex)) {
|
|
12815
|
+
output += "%" + hex.toUpperCase();
|
|
12816
|
+
i += 2;
|
|
12817
|
+
continue;
|
|
12818
|
+
}
|
|
12819
|
+
}
|
|
12820
|
+
if (ch === "/") firstSegment = false;
|
|
12821
|
+
if (isPathCharacter(ch) && (ch !== ":" || !firstSegment)) output += ch;
|
|
12822
|
+
else {
|
|
12823
|
+
const code = input.charCodeAt(i);
|
|
12824
|
+
if (code < 128) output += BYTE_HEX[code];
|
|
12825
|
+
else if (code < 55296 || code > 57343) output += percentEncodeNonAscii(code);
|
|
12826
|
+
else if (code <= 56319 && i + 1 < input.length) {
|
|
12827
|
+
const low = input.charCodeAt(i + 1);
|
|
12828
|
+
if (low >= 56320 && low <= 57343) {
|
|
12829
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
12830
|
+
i++;
|
|
12831
|
+
} else output += percentEncodeNonAscii(65533);
|
|
12832
|
+
} else output += percentEncodeNonAscii(65533);
|
|
12833
|
+
}
|
|
12834
|
+
}
|
|
12835
|
+
return output;
|
|
12836
|
+
}
|
|
12837
|
+
/**
|
|
12838
|
+
* Percent-encodes a URI component using its RFC 3986 literal character set.
|
|
12839
|
+
* Existing valid escapes are preserved and normalized to uppercase hex.
|
|
12840
|
+
*
|
|
12841
|
+
* @param {string} input
|
|
12842
|
+
* @param {(value: string) => boolean} isAllowed
|
|
12843
|
+
* @returns {string}
|
|
12844
|
+
*/
|
|
12845
|
+
function encodeComponent(input, isAllowed) {
|
|
12846
|
+
let output = "";
|
|
12847
|
+
for (let i = 0; i < input.length; i++) {
|
|
12848
|
+
const ch = input[i];
|
|
12849
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
12850
|
+
const hex = input.slice(i + 1, i + 3);
|
|
12851
|
+
if (isHexPair(hex)) {
|
|
12852
|
+
output += "%" + hex.toUpperCase();
|
|
12853
|
+
i += 2;
|
|
12854
|
+
continue;
|
|
12855
|
+
}
|
|
12856
|
+
}
|
|
12857
|
+
if (isAllowed(ch)) output += ch;
|
|
12858
|
+
else {
|
|
12859
|
+
const code = input.charCodeAt(i);
|
|
12860
|
+
if (code < 128) output += BYTE_HEX[code];
|
|
12861
|
+
else if (code < 55296 || code > 57343) output += percentEncodeNonAscii(code);
|
|
12862
|
+
else if (code <= 56319 && i + 1 < input.length) {
|
|
12863
|
+
const low = input.charCodeAt(i + 1);
|
|
12864
|
+
if (low >= 56320 && low <= 57343) {
|
|
12865
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
12866
|
+
i++;
|
|
12867
|
+
} else output += percentEncodeNonAscii(65533);
|
|
12868
|
+
} else output += percentEncodeNonAscii(65533);
|
|
12869
|
+
}
|
|
12870
|
+
}
|
|
12871
|
+
return output;
|
|
12872
|
+
}
|
|
12873
|
+
/**
|
|
12874
|
+
* Encodes userinfo while preserving its RFC 3986 §3.2.1 literal characters.
|
|
12875
|
+
* In particular, authority delimiters such as `@`, `/`, `?`, and `#` are data.
|
|
12876
|
+
*
|
|
12877
|
+
* @param {string} input
|
|
12878
|
+
* @returns {string}
|
|
12879
|
+
*/
|
|
12880
|
+
function encodeUserinfo(input) {
|
|
12881
|
+
return encodeComponent(input, isUserinfoCharacter);
|
|
12882
|
+
}
|
|
12883
|
+
/**
|
|
12884
|
+
* Encodes query data using the RFC 3986 §3.4 grammar. A literal `#` must be
|
|
12885
|
+
* escaped because it would otherwise begin the fragment component.
|
|
12886
|
+
*
|
|
12887
|
+
* @param {string} input
|
|
12888
|
+
* @returns {string}
|
|
12889
|
+
*/
|
|
12890
|
+
function encodeQuery(input) {
|
|
12891
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
12892
|
+
}
|
|
12893
|
+
/**
|
|
12894
|
+
* Encodes fragment data using the RFC 3986 §3.5 grammar.
|
|
12895
|
+
*
|
|
12896
|
+
* @param {string} input
|
|
12897
|
+
* @returns {string}
|
|
12898
|
+
*/
|
|
12899
|
+
function encodeFragment(input) {
|
|
12900
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
12901
|
+
}
|
|
12902
|
+
function isEscapeSafe(cp) {
|
|
12903
|
+
return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
|
|
12904
|
+
}
|
|
12905
|
+
/**
|
|
12906
|
+
* Normalizes the percent-encoding of a query or fragment component.
|
|
12907
|
+
*
|
|
12908
|
+
* Like `normalizePathEncoding`, but uses the query/fragment character set
|
|
12909
|
+
* (which additionally allows `?`) and decodes `.` since it has no dot-segment
|
|
12910
|
+
* meaning outside of a path.
|
|
12911
|
+
*
|
|
12912
|
+
* @param {string} input
|
|
12913
|
+
* @returns {string}
|
|
12914
|
+
*/
|
|
12915
|
+
function normalizeQueryFragmentEncoding(input) {
|
|
12916
|
+
let output = "";
|
|
12917
|
+
for (let i = 0; i < input.length; i++) {
|
|
12918
|
+
const ch = input[i];
|
|
12919
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
12920
|
+
const hex = input.slice(i + 1, i + 3);
|
|
12921
|
+
if (isHexPair(hex)) {
|
|
12922
|
+
const normalizedHex = hex.toUpperCase();
|
|
12923
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
12924
|
+
if (isUnreserved(decoded)) output += decoded;
|
|
12925
|
+
else output += "%" + normalizedHex;
|
|
12926
|
+
i += 2;
|
|
12927
|
+
continue;
|
|
12928
|
+
}
|
|
12929
|
+
}
|
|
12930
|
+
if (isQueryFragmentCharacter(ch)) output += ch;
|
|
12931
|
+
else {
|
|
12932
|
+
const code = input.charCodeAt(i);
|
|
12933
|
+
if (code < 128) output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
12934
|
+
else if (code < 55296 || code > 57343) output += percentEncodeNonAscii(code);
|
|
12935
|
+
else if (code <= 56319 && i + 1 < input.length) {
|
|
12936
|
+
const low = input.charCodeAt(i + 1);
|
|
12937
|
+
if (low >= 56320 && low <= 57343) {
|
|
12938
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
12939
|
+
i++;
|
|
12940
|
+
} else output += percentEncodeNonAscii(65533);
|
|
12941
|
+
} else output += percentEncodeNonAscii(65533);
|
|
12942
|
+
}
|
|
12723
12943
|
}
|
|
12724
12944
|
return output;
|
|
12725
12945
|
}
|
|
@@ -12751,21 +12971,27 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12751
12971
|
function recomposeAuthority(component) {
|
|
12752
12972
|
const uriTokens = [];
|
|
12753
12973
|
if (component.userinfo !== void 0) {
|
|
12754
|
-
uriTokens.push(component.userinfo);
|
|
12974
|
+
uriTokens.push(encodeUserinfo(component.userinfo));
|
|
12755
12975
|
uriTokens.push("@");
|
|
12756
12976
|
}
|
|
12757
12977
|
if (component.host !== void 0) {
|
|
12758
|
-
let host =
|
|
12978
|
+
let host = component.host;
|
|
12759
12979
|
if (!isIPv4(host)) {
|
|
12760
|
-
|
|
12761
|
-
if (ipV6res.isIPV6
|
|
12980
|
+
let ipV6res = normalizeIPv6(host);
|
|
12981
|
+
if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
|
|
12982
|
+
host = normalizePercentEncoding(host, true);
|
|
12983
|
+
ipV6res = normalizeIPv6(host);
|
|
12984
|
+
}
|
|
12985
|
+
if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) host = `[${ipV6res.escapedHost}]`;
|
|
12762
12986
|
else host = reescapeHostDelimiters(host, false);
|
|
12763
12987
|
}
|
|
12764
12988
|
uriTokens.push(host);
|
|
12765
12989
|
}
|
|
12766
12990
|
if (typeof component.port === "number" || typeof component.port === "string") {
|
|
12991
|
+
const port = String(component.port);
|
|
12992
|
+
if (!isPort(port)) throw new TypeError("URI port is malformed.");
|
|
12767
12993
|
uriTokens.push(":");
|
|
12768
|
-
uriTokens.push(
|
|
12994
|
+
uriTokens.push(port);
|
|
12769
12995
|
}
|
|
12770
12996
|
return uriTokens.length ? uriTokens.join("") : void 0;
|
|
12771
12997
|
}
|
|
@@ -12775,6 +13001,11 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12775
13001
|
reescapeHostDelimiters,
|
|
12776
13002
|
normalizePercentEncoding,
|
|
12777
13003
|
normalizePathEncoding,
|
|
13004
|
+
serializePathEncoding,
|
|
13005
|
+
normalizeQueryFragmentEncoding,
|
|
13006
|
+
encodeUserinfo,
|
|
13007
|
+
encodeQuery,
|
|
13008
|
+
encodeFragment,
|
|
12778
13009
|
escapePreservingEscapes,
|
|
12779
13010
|
removeDotSegments,
|
|
12780
13011
|
isIPv4,
|
|
@@ -12785,7 +13016,7 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12785
13016
|
}));
|
|
12786
13017
|
var require_schemes = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
12787
13018
|
const { isUUID } = require_utils();
|
|
12788
|
-
const URN_REG =
|
|
13019
|
+
const URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
|
|
12789
13020
|
const supportedSchemeNames = [
|
|
12790
13021
|
"http",
|
|
12791
13022
|
"https",
|
|
@@ -12856,9 +13087,10 @@ var require_schemes = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12856
13087
|
wsComponent.secure = void 0;
|
|
12857
13088
|
}
|
|
12858
13089
|
if (wsComponent.resourceName) {
|
|
12859
|
-
const
|
|
13090
|
+
const queryIndex = wsComponent.resourceName.indexOf("?");
|
|
13091
|
+
const path = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
|
|
12860
13092
|
wsComponent.path = path && path !== "/" ? path : void 0;
|
|
12861
|
-
wsComponent.query =
|
|
13093
|
+
wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
|
|
12862
13094
|
wsComponent.resourceName = void 0;
|
|
12863
13095
|
}
|
|
12864
13096
|
wsComponent.fragment = void 0;
|
|
@@ -12871,7 +13103,7 @@ var require_schemes = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12871
13103
|
return urnComponent;
|
|
12872
13104
|
}
|
|
12873
13105
|
const matches = urnComponent.path.match(URN_REG);
|
|
12874
|
-
if (matches) {
|
|
13106
|
+
if (matches && matches[0] === urnComponent.path) {
|
|
12875
13107
|
const scheme = options.scheme || urnComponent.scheme || "urn";
|
|
12876
13108
|
urnComponent.nid = matches[1].toLowerCase();
|
|
12877
13109
|
urnComponent.nss = matches[2];
|
|
@@ -12965,8 +13197,19 @@ var require_schemes = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12965
13197
|
};
|
|
12966
13198
|
}));
|
|
12967
13199
|
var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
12968
|
-
const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding,
|
|
13200
|
+
const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
12969
13201
|
const { SCHEMES, getSchemeHandler } = require_schemes();
|
|
13202
|
+
const VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
|
|
13203
|
+
const MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
|
|
13204
|
+
/**
|
|
13205
|
+
* @param {string} scheme
|
|
13206
|
+
* @returns {string}
|
|
13207
|
+
*/
|
|
13208
|
+
function decodeValidScheme(scheme) {
|
|
13209
|
+
const decodedScheme = unescape(String(scheme));
|
|
13210
|
+
if (!VALID_SCHEME.test(decodedScheme)) throw new TypeError(MALFORMED_SCHEME_ERROR);
|
|
13211
|
+
return decodedScheme;
|
|
13212
|
+
}
|
|
12970
13213
|
/**
|
|
12971
13214
|
* @template {import('./types/index').URIComponent|string} T
|
|
12972
13215
|
* @param {T} uri
|
|
@@ -12986,10 +13229,16 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
12986
13229
|
*/
|
|
12987
13230
|
function resolve(baseURI, relativeURI, options) {
|
|
12988
13231
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
12989
|
-
const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
|
|
12990
|
-
const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
|
|
12991
|
-
if (baseMalformed || relativeMalformed) throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
13232
|
+
const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed, malformedPercentEncoding: baseMalformedPercentEncoding, malformedSchemeSpecific: baseMalformedSchemeSpecific, malformedHost: baseMalformedHost, malformedScheme: baseMalformedScheme } = parseWithStatus(baseURI, schemelessOptions);
|
|
13233
|
+
const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed, malformedPercentEncoding: relativeMalformedPercentEncoding, malformedSchemeSpecific: relativeMalformedSchemeSpecific, malformedHost: relativeMalformedHost, malformedScheme: relativeMalformedScheme } = parseWithStatus(relativeURI, schemelessOptions);
|
|
13234
|
+
if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
12992
13235
|
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
13236
|
+
const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
|
|
13237
|
+
const resolvedHost = resolved.host;
|
|
13238
|
+
const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
|
|
13239
|
+
canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
|
|
13240
|
+
const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !/\P{ASCII}/u.test(resolvedHost);
|
|
13241
|
+
if (resolved.error && !encodedASCIIHost) throw new Error(resolved.error);
|
|
12993
13242
|
schemelessOptions.skipEscape = true;
|
|
12994
13243
|
return serialize(resolved, schemelessOptions);
|
|
12995
13244
|
}
|
|
@@ -13055,7 +13304,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13055
13304
|
function equal(uriA, uriB, options) {
|
|
13056
13305
|
const normalizedA = normalizeComparableURI(uriA, options);
|
|
13057
13306
|
const normalizedB = normalizeComparableURI(uriB, options);
|
|
13058
|
-
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA
|
|
13307
|
+
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
|
|
13059
13308
|
}
|
|
13060
13309
|
/**
|
|
13061
13310
|
* @param {Readonly<import('./types/index').URIComponent>} cmpts
|
|
@@ -13081,13 +13330,17 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13081
13330
|
};
|
|
13082
13331
|
const options = Object.assign({}, opts);
|
|
13083
13332
|
const uriTokens = [];
|
|
13333
|
+
if (component.scheme) component.scheme = decodeValidScheme(component.scheme);
|
|
13084
13334
|
const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
|
|
13085
13335
|
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
13086
|
-
|
|
13087
|
-
|
|
13088
|
-
|
|
13089
|
-
|
|
13090
|
-
if (options.reference !== "suffix" && component.scheme)
|
|
13336
|
+
const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
|
|
13337
|
+
const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
|
|
13338
|
+
if (component.path !== void 0) if (!options.skipEscape) component.path = serializePathEncoding(component.path, pathNoScheme);
|
|
13339
|
+
else component.path = normalizePercentEncoding(component.path);
|
|
13340
|
+
if (options.reference !== "suffix" && component.scheme) {
|
|
13341
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
13342
|
+
uriTokens.push(component.scheme, ":");
|
|
13343
|
+
}
|
|
13091
13344
|
const authority = recomposeAuthority(component);
|
|
13092
13345
|
if (authority !== void 0) {
|
|
13093
13346
|
if (options.reference !== "suffix") uriTokens.push("//");
|
|
@@ -13097,11 +13350,12 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13097
13350
|
if (component.path !== void 0) {
|
|
13098
13351
|
let s = component.path;
|
|
13099
13352
|
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) s = removeDotSegments(s);
|
|
13353
|
+
if (pathNoScheme) s = serializePathEncoding(s, true);
|
|
13100
13354
|
if (authority === void 0 && s[0] === "/" && s[1] === "/") s = "/%2F" + s.slice(2);
|
|
13101
13355
|
uriTokens.push(s);
|
|
13102
13356
|
}
|
|
13103
|
-
if (component.query !== void 0) uriTokens.push("?", component.query);
|
|
13104
|
-
if (component.fragment !== void 0) uriTokens.push("#", component.fragment);
|
|
13357
|
+
if (component.query !== void 0) uriTokens.push("?", encodeQuery(component.query));
|
|
13358
|
+
if (component.fragment !== void 0) uriTokens.push("#", encodeFragment(component.fragment));
|
|
13105
13359
|
return uriTokens.join("");
|
|
13106
13360
|
}
|
|
13107
13361
|
const URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
@@ -13117,9 +13371,61 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13117
13371
|
if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) return "URI port is malformed.";
|
|
13118
13372
|
}
|
|
13119
13373
|
/**
|
|
13374
|
+
* Checks percent syntax without decoding the represented octets. RFC 3986
|
|
13375
|
+
* percent-encoding is byte-oriented, so sequences such as `%FF` are valid even
|
|
13376
|
+
* though they are not independently valid UTF-8.
|
|
13377
|
+
*
|
|
13378
|
+
* @param {string|undefined} component
|
|
13379
|
+
* @returns {boolean}
|
|
13380
|
+
*/
|
|
13381
|
+
function hasMalformedPercentEncoding(component) {
|
|
13382
|
+
if (component === void 0) return false;
|
|
13383
|
+
let percent = component.indexOf("%");
|
|
13384
|
+
while (percent !== -1) {
|
|
13385
|
+
if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) return true;
|
|
13386
|
+
percent = component.indexOf("%", percent + 3);
|
|
13387
|
+
}
|
|
13388
|
+
return false;
|
|
13389
|
+
}
|
|
13390
|
+
/**
|
|
13391
|
+
* Whether the host is a bracketed IP literal (RFC 3986 `IP-literal`).
|
|
13392
|
+
* An unterminated `[` is not a literal, so it must still be validated as a
|
|
13393
|
+
* reg-name instead of being waved through as an IP.
|
|
13394
|
+
*
|
|
13395
|
+
* @param {string} host
|
|
13396
|
+
* @returns {boolean}
|
|
13397
|
+
*/
|
|
13398
|
+
function isIPLiteral(host) {
|
|
13399
|
+
return host[0] === "[" && host[host.length - 1] === "]";
|
|
13400
|
+
}
|
|
13401
|
+
/**
|
|
13402
|
+
* @param {RegExpMatchArray} matches
|
|
13403
|
+
* @returns {boolean}
|
|
13404
|
+
*/
|
|
13405
|
+
function hasMalformedComponentPercentEncoding(matches) {
|
|
13406
|
+
const host = matches[4];
|
|
13407
|
+
return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
|
|
13408
|
+
}
|
|
13409
|
+
/**
|
|
13410
|
+
* @param {import('./types/index').URIComponent} parsed
|
|
13411
|
+
* @param {import('./types/index').Options} options
|
|
13412
|
+
* @param {{ domainHost?: boolean, unicodeSupport?: boolean }|undefined} schemeHandler
|
|
13413
|
+
* @param {boolean} isIP
|
|
13414
|
+
* @returns {boolean} whether host conversion failed
|
|
13415
|
+
*/
|
|
13416
|
+
function canonicalizeHost(parsed, options, schemeHandler, isIP) {
|
|
13417
|
+
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) try {
|
|
13418
|
+
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
13419
|
+
} catch (e) {
|
|
13420
|
+
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
13421
|
+
return true;
|
|
13422
|
+
}
|
|
13423
|
+
return false;
|
|
13424
|
+
}
|
|
13425
|
+
/**
|
|
13120
13426
|
* @param {string} uri
|
|
13121
13427
|
* @param {import('./types/index').Options} [opts]
|
|
13122
|
-
* @returns {{ parsed: import('./types/index').URIComponent, malformedAuthorityOrPort: boolean }}
|
|
13428
|
+
* @returns {{ parsed: import('./types/index').URIComponent, malformedAuthorityOrPort: boolean, malformedPercentEncoding: boolean, malformedSchemeSpecific: boolean, malformedHost: boolean, malformedScheme: boolean }}
|
|
13123
13429
|
*/
|
|
13124
13430
|
function parseWithStatus(uri, opts) {
|
|
13125
13431
|
const options = Object.assign({}, opts);
|
|
@@ -13134,6 +13440,11 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13134
13440
|
fragment: void 0
|
|
13135
13441
|
};
|
|
13136
13442
|
let malformedAuthorityOrPort = false;
|
|
13443
|
+
let malformedPercentEncoding = false;
|
|
13444
|
+
let malformedSchemeSpecific = false;
|
|
13445
|
+
let malformedHost = false;
|
|
13446
|
+
let malformedIPLiteral = false;
|
|
13447
|
+
let malformedScheme = false;
|
|
13137
13448
|
let isIP = false;
|
|
13138
13449
|
if (options.reference === "suffix") if (options.scheme) uri = options.scheme + ":" + uri;
|
|
13139
13450
|
else uri = "//" + uri;
|
|
@@ -13165,6 +13476,16 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13165
13476
|
parsed.path = matches[6] || "";
|
|
13166
13477
|
parsed.query = matches[7];
|
|
13167
13478
|
parsed.fragment = matches[8];
|
|
13479
|
+
if (parsed.scheme !== void 0) {
|
|
13480
|
+
const decodedScheme = unescape(parsed.scheme);
|
|
13481
|
+
if (VALID_SCHEME.test(decodedScheme)) parsed.scheme = decodedScheme.toLowerCase();
|
|
13482
|
+
else {
|
|
13483
|
+
parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
|
|
13484
|
+
malformedScheme = true;
|
|
13485
|
+
}
|
|
13486
|
+
}
|
|
13487
|
+
malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
|
|
13488
|
+
if (malformedPercentEncoding) parsed.error = parsed.error || "URI contains malformed percent-encoding.";
|
|
13168
13489
|
if (isNaN(parsed.port)) parsed.port = matches[5];
|
|
13169
13490
|
const parseError = getParseError(parsed, matches);
|
|
13170
13491
|
if (parseError !== void 0) {
|
|
@@ -13172,9 +13493,16 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13172
13493
|
malformedAuthorityOrPort = true;
|
|
13173
13494
|
}
|
|
13174
13495
|
if (parsed.host) if (isIPv4(parsed.host) === false) {
|
|
13496
|
+
const bracketedIPLiteral = isIPLiteral(parsed.host);
|
|
13497
|
+
const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
|
|
13175
13498
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
13176
|
-
|
|
13177
|
-
|
|
13499
|
+
isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
|
|
13500
|
+
malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
|
|
13501
|
+
parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
|
|
13502
|
+
if (malformedIPLiteral) {
|
|
13503
|
+
parsed.error = parsed.error || "URI host is malformed.";
|
|
13504
|
+
malformedAuthorityOrPort = true;
|
|
13505
|
+
}
|
|
13178
13506
|
} else isIP = true;
|
|
13179
13507
|
if (parsed.scheme === void 0 && parsed.userinfo === void 0 && parsed.host === void 0 && parsed.port === void 0 && parsed.query === void 0 && !parsed.path) parsed.reference = "same-document";
|
|
13180
13508
|
else if (parsed.scheme === void 0) parsed.reference = "relative";
|
|
@@ -13182,30 +13510,30 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13182
13510
|
else parsed.reference = "uri";
|
|
13183
13511
|
if (options.reference && options.reference !== "suffix" && options.reference !== parsed.reference) parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
|
|
13184
13512
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
13185
|
-
if (!
|
|
13186
|
-
if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) try {
|
|
13187
|
-
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
13188
|
-
} catch (e) {
|
|
13189
|
-
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
13190
|
-
}
|
|
13191
|
-
}
|
|
13513
|
+
if (!malformedIPLiteral) malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
13192
13514
|
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
13193
13515
|
if (uri.indexOf("%") !== -1) {
|
|
13194
|
-
if (parsed.
|
|
13195
|
-
|
|
13516
|
+
if (parsed.host !== void 0 && !malformedIPLiteral) {
|
|
13517
|
+
const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
13518
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
13519
|
+
}
|
|
13196
13520
|
}
|
|
13197
13521
|
if (parsed.path) parsed.path = normalizePathEncoding(parsed.path);
|
|
13198
|
-
if (parsed.
|
|
13199
|
-
|
|
13200
|
-
|
|
13201
|
-
|
|
13202
|
-
|
|
13522
|
+
if (parsed.query) parsed.query = normalizeQueryFragmentEncoding(parsed.query);
|
|
13523
|
+
if (parsed.fragment) parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
|
|
13524
|
+
}
|
|
13525
|
+
if (schemeHandler && schemeHandler.parse) {
|
|
13526
|
+
schemeHandler.parse(parsed, options);
|
|
13527
|
+
if (schemeHandler === SCHEMES.urn && parsed.nid === void 0) malformedSchemeSpecific = true;
|
|
13203
13528
|
}
|
|
13204
|
-
if (schemeHandler && schemeHandler.parse) schemeHandler.parse(parsed, options);
|
|
13205
13529
|
} else parsed.error = parsed.error || "URI can not be parsed.";
|
|
13206
13530
|
return {
|
|
13207
13531
|
parsed,
|
|
13208
|
-
malformedAuthorityOrPort
|
|
13532
|
+
malformedAuthorityOrPort,
|
|
13533
|
+
malformedPercentEncoding,
|
|
13534
|
+
malformedSchemeSpecific,
|
|
13535
|
+
malformedHost,
|
|
13536
|
+
malformedScheme
|
|
13209
13537
|
};
|
|
13210
13538
|
}
|
|
13211
13539
|
/**
|
|
@@ -13227,13 +13555,17 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13227
13555
|
/**
|
|
13228
13556
|
* @param {string} uri
|
|
13229
13557
|
* @param {import('./types/index').Options} [opts]
|
|
13230
|
-
* @returns {{ normalized: string, malformedAuthorityOrPort: boolean }}
|
|
13558
|
+
* @returns {{ normalized: string, malformedAuthorityOrPort: boolean, malformedPercentEncoding: boolean, malformedSchemeSpecific: boolean, malformedHost: boolean, malformedScheme: boolean }}
|
|
13231
13559
|
*/
|
|
13232
13560
|
function normalizeStringWithStatus(uri, opts) {
|
|
13233
|
-
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
13561
|
+
const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
|
|
13234
13562
|
return {
|
|
13235
|
-
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
13236
|
-
malformedAuthorityOrPort
|
|
13563
|
+
normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
|
|
13564
|
+
malformedAuthorityOrPort,
|
|
13565
|
+
malformedPercentEncoding,
|
|
13566
|
+
malformedSchemeSpecific,
|
|
13567
|
+
malformedHost,
|
|
13568
|
+
malformedScheme
|
|
13237
13569
|
};
|
|
13238
13570
|
}
|
|
13239
13571
|
/**
|
|
@@ -13242,11 +13574,15 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
13242
13574
|
* @returns {string|undefined}
|
|
13243
13575
|
*/
|
|
13244
13576
|
function normalizeComparableURI(uri, opts) {
|
|
13245
|
-
if (typeof uri
|
|
13246
|
-
|
|
13247
|
-
|
|
13577
|
+
if (typeof uri !== "string" && typeof uri !== "object") return;
|
|
13578
|
+
let value;
|
|
13579
|
+
try {
|
|
13580
|
+
value = typeof uri === "string" ? uri : serialize(uri, opts);
|
|
13581
|
+
} catch {
|
|
13582
|
+
return;
|
|
13248
13583
|
}
|
|
13249
|
-
|
|
13584
|
+
const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
|
|
13585
|
+
return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
|
|
13250
13586
|
}
|
|
13251
13587
|
const fastUri = {
|
|
13252
13588
|
SCHEMES,
|
|
@@ -16422,7 +16758,7 @@ var JsonSchemaWrapper = class {
|
|
|
16422
16758
|
* const jsonSchema = standardSchema['~standard'].jsonSchema.output({ target: 'draft-07' });
|
|
16423
16759
|
* ```
|
|
16424
16760
|
*/
|
|
16425
|
-
function toStandardSchema$
|
|
16761
|
+
function toStandardSchema$4(schema, options) {
|
|
16426
16762
|
return new JsonSchemaWrapper(schema, options);
|
|
16427
16763
|
}
|
|
16428
16764
|
//#endregion
|
|
@@ -16498,7 +16834,7 @@ function convertToJsonSchema$1(zodSchema, options) {
|
|
|
16498
16834
|
* const jsonSchema = standardSchema['~standard'].jsonSchema.output({ target: 'draft-07' });
|
|
16499
16835
|
* ```
|
|
16500
16836
|
*/
|
|
16501
|
-
function toStandardSchema$
|
|
16837
|
+
function toStandardSchema$3(zodSchema) {
|
|
16502
16838
|
const wrapper = Object.create(zodSchema);
|
|
16503
16839
|
const existingStandard = zodSchema["~standard"];
|
|
16504
16840
|
const jsonSchemaConverter = {
|
|
@@ -16521,7 +16857,7 @@ function toStandardSchema$2(zodSchema) {
|
|
|
16521
16857
|
return wrapper;
|
|
16522
16858
|
}
|
|
16523
16859
|
//#endregion
|
|
16524
|
-
//#region ../schema-compat/dist/schema-
|
|
16860
|
+
//#region ../schema-compat/dist/schema-D_ikovK6.js
|
|
16525
16861
|
/**
|
|
16526
16862
|
* Supported JSON Schema targets for z.toJSONSchema().
|
|
16527
16863
|
* Works with both real Zod v4 and Zod 3.25's v4 compat layer.
|
|
@@ -16650,18 +16986,18 @@ function isZodV3(schema) {
|
|
|
16650
16986
|
}
|
|
16651
16987
|
return schema instanceof v3_default.ZodType;
|
|
16652
16988
|
}
|
|
16653
|
-
function toStandardSchema(schema) {
|
|
16989
|
+
function toStandardSchema$2(schema) {
|
|
16654
16990
|
if (isZodV4(schema)) patchRecordSchemas(schema);
|
|
16655
16991
|
if (isStandardSchemaWithJSON$1(schema)) return schema;
|
|
16656
16992
|
if (isZodV4(schema)) return toStandardSchema$1(schema, {
|
|
16657
16993
|
unrepresentable: JSON_SCHEMA_LIBRARY_OPTIONS.unrepresentable,
|
|
16658
16994
|
override: JSON_SCHEMA_LIBRARY_OPTIONS.override
|
|
16659
16995
|
});
|
|
16660
|
-
if (isZodV3(schema)) return toStandardSchema$
|
|
16661
|
-
if (isVercelSchema(schema)) return toStandardSchema$
|
|
16996
|
+
if (isZodV3(schema)) return toStandardSchema$3(schema);
|
|
16997
|
+
if (isVercelSchema(schema)) return toStandardSchema$5(schema);
|
|
16662
16998
|
if (schema === null || typeof schema !== "object" && typeof schema !== "function") throw new Error(`Unsupported schema type: ${typeof schema}`);
|
|
16663
16999
|
if (typeof schema === "function") throw new Error(`Unsupported schema type: function (schema libraries should implement StandardSchemaWithJSON)`);
|
|
16664
|
-
return toStandardSchema$
|
|
17000
|
+
return toStandardSchema$4(schema);
|
|
16665
17001
|
}
|
|
16666
17002
|
/**
|
|
16667
17003
|
* Type guard to check if a value implements the StandardSchemaV1 interface.
|
|
@@ -22059,7 +22395,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
22059
22395
|
convertOutputSchema(outputSchema) {
|
|
22060
22396
|
if (!outputSchema) return outputSchema;
|
|
22061
22397
|
return { "~standard": {
|
|
22062
|
-
...toStandardSchema("jsonSchema" in outputSchema ? outputSchema.jsonSchema : outputSchema)["~standard"],
|
|
22398
|
+
...toStandardSchema$2("jsonSchema" in outputSchema ? outputSchema.jsonSchema : outputSchema)["~standard"],
|
|
22063
22399
|
validate: (value) => ({ value })
|
|
22064
22400
|
} };
|
|
22065
22401
|
}
|
|
@@ -22180,7 +22516,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
22180
22516
|
...annotations ? { annotations } : {}
|
|
22181
22517
|
} } : {};
|
|
22182
22518
|
const rawOutputSchema = tool.outputSchema ? "jsonSchema" in tool.outputSchema ? tool.outputSchema.jsonSchema : tool.outputSchema : void 0;
|
|
22183
|
-
const outputValidator = rawOutputSchema ? toStandardSchema(rawOutputSchema) : void 0;
|
|
22519
|
+
const outputValidator = rawOutputSchema ? toStandardSchema$2(rawOutputSchema) : void 0;
|
|
22184
22520
|
const mastraTool = createTool({
|
|
22185
22521
|
id: `${this.name}_${tool.name}`,
|
|
22186
22522
|
description: tool.description || "",
|
|
@@ -22927,38 +23263,30 @@ function isLoopbackHostname(hostname) {
|
|
|
22927
23263
|
return hostname === "localhost" || hostname === "[::1]" || hostname === "::1" || LOOPBACK_IPV4.test(hostname);
|
|
22928
23264
|
}
|
|
22929
23265
|
/**
|
|
22930
|
-
*
|
|
23266
|
+
* Manages Model Context Protocol (MCP) server connections and tool namespacing,
|
|
23267
|
+
* with access to tools, resources, prompts, and elicitation.
|
|
22931
23268
|
*
|
|
22932
|
-
*
|
|
22933
|
-
* resources, prompts, and elicitation across all configured servers.
|
|
23269
|
+
* Configure authentication when required by your servers.
|
|
22934
23270
|
*
|
|
22935
23271
|
* @example
|
|
23272
|
+
* `yourServerUrl` is a URL for a running MCP server's HTTP endpoint.
|
|
22936
23273
|
* ```typescript
|
|
22937
23274
|
* import { MCPClient } from '@mastra/mcp';
|
|
22938
|
-
* import { Agent } from '@mastra/core/agent';
|
|
22939
23275
|
*
|
|
22940
23276
|
* const mcp = new MCPClient({
|
|
22941
23277
|
* servers: {
|
|
22942
|
-
*
|
|
22943
|
-
* url: new URL('http://localhost:8080/sse'),
|
|
22944
|
-
* },
|
|
22945
|
-
* stockPrice: {
|
|
22946
|
-
* command: 'npx',
|
|
22947
|
-
* args: ['tsx', 'stock-price.ts'],
|
|
22948
|
-
* env: { API_KEY: 'your-api-key' },
|
|
22949
|
-
* },
|
|
23278
|
+
* remote: { url: yourServerUrl },
|
|
22950
23279
|
* },
|
|
22951
|
-
* timeout: 30000,
|
|
22952
|
-
* });
|
|
22953
|
-
*
|
|
22954
|
-
* const agent = new Agent({
|
|
22955
|
-
* id: 'multi-tool-agent',
|
|
22956
|
-
* name: 'Multi-tool Agent',
|
|
22957
|
-
* instructions: 'You have access to multiple tools.',
|
|
22958
|
-
* model: 'openai/gpt-4o',
|
|
22959
|
-
* tools: await mcp.listTools(),
|
|
22960
23280
|
* });
|
|
22961
23281
|
* ```
|
|
23282
|
+
*
|
|
23283
|
+
* @see For documentation bundled with your installed package, locate
|
|
23284
|
+
* `@mastra/mcp/package.json` with your project's resolver or package-manager
|
|
23285
|
+
* tooling, then read `dist/docs/SKILL.md` from that package root and follow its
|
|
23286
|
+
* reference links. Use package-manager tools for virtual or archived packages.
|
|
23287
|
+
*
|
|
23288
|
+
* @see [MCP client documentation](https://mastra.ai/reference/tools/mcp-client)
|
|
23289
|
+
* if packaged docs are unavailable.
|
|
22962
23290
|
*/
|
|
22963
23291
|
var MCPClient = class extends MastraBase {
|
|
22964
23292
|
serverConfigs = {};
|
|
@@ -24365,7 +24693,7 @@ var streamSSE = (c, cb, onError) => {
|
|
|
24365
24693
|
return c.newResponse(stream.responseReadable);
|
|
24366
24694
|
};
|
|
24367
24695
|
//#endregion
|
|
24368
|
-
//#region ../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/hono-mcp-server-sse-transport/0.0.7/
|
|
24696
|
+
//#region ../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/hono-mcp-server-sse-transport/0.0.7/64266f0b1652040acd07ff3bd56a63a27af87510caf8cd4ce871013cbd451c67/node_modules/hono-mcp-server-sse-transport/build/sse.js
|
|
24369
24697
|
const MAXIMUM_MESSAGE_SIZE = 4 * 1024 * 1024;
|
|
24370
24698
|
var SSETransport = class {
|
|
24371
24699
|
messageUrl;
|
|
@@ -24878,32 +25206,30 @@ const ACCEPTED_MODERN_ERA_HTTP_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
|
24878
25206
|
"sessionIdGenerator"
|
|
24879
25207
|
]);
|
|
24880
25208
|
/**
|
|
24881
|
-
*
|
|
24882
|
-
*
|
|
24883
|
-
*
|
|
24884
|
-
* Mastra capabilities. It supports both stdio (subprocess) and SSE (HTTP) MCP transports.
|
|
25209
|
+
* Exposes Mastra tools, agents, and workflows to Model Context Protocol (MCP) clients.
|
|
25210
|
+
* Supports stdio, SSE, and Streamable HTTP transports; start or mount a transport
|
|
25211
|
+
* to accept client connections.
|
|
24885
25212
|
*
|
|
24886
25213
|
* @example
|
|
25214
|
+
* `yourTool` is a tool you have already configured.
|
|
24887
25215
|
* ```typescript
|
|
24888
25216
|
* import { MCPServer } from '@mastra/mcp';
|
|
24889
|
-
* import { createTool } from '@mastra/core/tools';
|
|
24890
|
-
* import { z } from 'zod';
|
|
24891
|
-
*
|
|
24892
|
-
* const weatherTool = createTool({
|
|
24893
|
-
* id: 'getWeather',
|
|
24894
|
-
* description: 'Gets the current weather for a location.',
|
|
24895
|
-
* inputSchema: z.object({ location: z.string() }),
|
|
24896
|
-
* execute: async (inputData) => `Weather in ${inputData.location} is sunny.`,
|
|
24897
|
-
* });
|
|
24898
25217
|
*
|
|
24899
25218
|
* const server = new MCPServer({
|
|
24900
|
-
*
|
|
25219
|
+
* id: 'my-server',
|
|
25220
|
+
* name: 'My Server',
|
|
24901
25221
|
* version: '1.0.0',
|
|
24902
|
-
* tools: {
|
|
25222
|
+
* tools: { yourTool },
|
|
24903
25223
|
* });
|
|
24904
|
-
*
|
|
24905
|
-
* await server.startStdio();
|
|
24906
25224
|
* ```
|
|
25225
|
+
*
|
|
25226
|
+
* @see For documentation bundled with your installed package, locate
|
|
25227
|
+
* `@mastra/mcp/package.json` with your project's resolver or package-manager
|
|
25228
|
+
* tooling, then read `dist/docs/SKILL.md` from that package root and follow its
|
|
25229
|
+
* reference links. Use package-manager tools for virtual or archived packages.
|
|
25230
|
+
*
|
|
25231
|
+
* @see [MCP server documentation](https://mastra.ai/reference/tools/mcp-server)
|
|
25232
|
+
* if packaged docs are unavailable.
|
|
24907
25233
|
*/
|
|
24908
25234
|
var MCPServer = class extends MCPServerBase {
|
|
24909
25235
|
server;
|
|
@@ -27052,6 +27378,688 @@ var MCPServer = class extends MCPServerBase {
|
|
|
27052
27378
|
}
|
|
27053
27379
|
};
|
|
27054
27380
|
//#endregion
|
|
27381
|
+
//#region src/server/mastra-api-operations.generated.ts
|
|
27382
|
+
const MASTRA_API_OPERATIONS = [
|
|
27383
|
+
{
|
|
27384
|
+
name: "agent_list",
|
|
27385
|
+
description: "List available agents",
|
|
27386
|
+
method: "GET",
|
|
27387
|
+
path: "/agents",
|
|
27388
|
+
destructive: false
|
|
27389
|
+
},
|
|
27390
|
+
{
|
|
27391
|
+
name: "agent_get",
|
|
27392
|
+
description: "Get agent details",
|
|
27393
|
+
method: "GET",
|
|
27394
|
+
path: "/agents/:agentId",
|
|
27395
|
+
destructive: false
|
|
27396
|
+
},
|
|
27397
|
+
{
|
|
27398
|
+
name: "agent_run",
|
|
27399
|
+
description: "Run an agent with JSON input",
|
|
27400
|
+
method: "POST",
|
|
27401
|
+
path: "/agents/:agentId/generate",
|
|
27402
|
+
destructive: true
|
|
27403
|
+
},
|
|
27404
|
+
{
|
|
27405
|
+
name: "workflow_list",
|
|
27406
|
+
description: "List available workflows",
|
|
27407
|
+
method: "GET",
|
|
27408
|
+
path: "/workflows",
|
|
27409
|
+
destructive: false
|
|
27410
|
+
},
|
|
27411
|
+
{
|
|
27412
|
+
name: "workflow_get",
|
|
27413
|
+
description: "Get workflow details",
|
|
27414
|
+
method: "GET",
|
|
27415
|
+
path: "/workflows/:workflowId",
|
|
27416
|
+
destructive: false
|
|
27417
|
+
},
|
|
27418
|
+
{
|
|
27419
|
+
name: "workflow_run_start",
|
|
27420
|
+
description: "Start a workflow run",
|
|
27421
|
+
method: "POST",
|
|
27422
|
+
path: "/workflows/:workflowId/start-async",
|
|
27423
|
+
destructive: true
|
|
27424
|
+
},
|
|
27425
|
+
{
|
|
27426
|
+
name: "workflow_run_list",
|
|
27427
|
+
description: "List workflow runs",
|
|
27428
|
+
method: "GET",
|
|
27429
|
+
path: "/workflows/:workflowId/runs",
|
|
27430
|
+
destructive: false
|
|
27431
|
+
},
|
|
27432
|
+
{
|
|
27433
|
+
name: "workflow_run_get",
|
|
27434
|
+
description: "Get workflow run details",
|
|
27435
|
+
method: "GET",
|
|
27436
|
+
path: "/workflows/:workflowId/runs/:runId",
|
|
27437
|
+
destructive: false
|
|
27438
|
+
},
|
|
27439
|
+
{
|
|
27440
|
+
name: "workflow_run_resume",
|
|
27441
|
+
description: "Resume a suspended workflow run",
|
|
27442
|
+
method: "POST",
|
|
27443
|
+
path: "/workflows/:workflowId/resume-async",
|
|
27444
|
+
destructive: true
|
|
27445
|
+
},
|
|
27446
|
+
{
|
|
27447
|
+
name: "workflow_run_cancel",
|
|
27448
|
+
description: "Cancel a workflow run",
|
|
27449
|
+
method: "POST",
|
|
27450
|
+
path: "/workflows/:workflowId/runs/:runId/cancel",
|
|
27451
|
+
destructive: true
|
|
27452
|
+
},
|
|
27453
|
+
{
|
|
27454
|
+
name: "tool_list",
|
|
27455
|
+
description: "List available tools",
|
|
27456
|
+
method: "GET",
|
|
27457
|
+
path: "/tools",
|
|
27458
|
+
destructive: false
|
|
27459
|
+
},
|
|
27460
|
+
{
|
|
27461
|
+
name: "tool_get",
|
|
27462
|
+
description: "Get tool details and input schema",
|
|
27463
|
+
method: "GET",
|
|
27464
|
+
path: "/tools/:toolId",
|
|
27465
|
+
destructive: false
|
|
27466
|
+
},
|
|
27467
|
+
{
|
|
27468
|
+
name: "tool_execute",
|
|
27469
|
+
description: "Execute a tool with JSON input",
|
|
27470
|
+
method: "POST",
|
|
27471
|
+
path: "/tools/:toolId/execute",
|
|
27472
|
+
destructive: true
|
|
27473
|
+
},
|
|
27474
|
+
{
|
|
27475
|
+
name: "mcp_list",
|
|
27476
|
+
description: "List MCP servers",
|
|
27477
|
+
method: "GET",
|
|
27478
|
+
path: "/mcp/v0/servers",
|
|
27479
|
+
destructive: false
|
|
27480
|
+
},
|
|
27481
|
+
{
|
|
27482
|
+
name: "mcp_get",
|
|
27483
|
+
description: "Get MCP server details",
|
|
27484
|
+
method: "GET",
|
|
27485
|
+
path: "/mcp/v0/servers/:id",
|
|
27486
|
+
destructive: false
|
|
27487
|
+
},
|
|
27488
|
+
{
|
|
27489
|
+
name: "mcp_tool_list",
|
|
27490
|
+
description: "List tools for an MCP server",
|
|
27491
|
+
method: "GET",
|
|
27492
|
+
path: "/mcp/:serverId/tools",
|
|
27493
|
+
destructive: false
|
|
27494
|
+
},
|
|
27495
|
+
{
|
|
27496
|
+
name: "mcp_tool_get",
|
|
27497
|
+
description: "Get MCP tool details",
|
|
27498
|
+
method: "GET",
|
|
27499
|
+
path: "/mcp/:serverId/tools/:toolId",
|
|
27500
|
+
destructive: false
|
|
27501
|
+
},
|
|
27502
|
+
{
|
|
27503
|
+
name: "mcp_tool_execute",
|
|
27504
|
+
description: "Execute an MCP tool with JSON input",
|
|
27505
|
+
method: "POST",
|
|
27506
|
+
path: "/mcp/:serverId/tools/:toolId/execute",
|
|
27507
|
+
destructive: true
|
|
27508
|
+
},
|
|
27509
|
+
{
|
|
27510
|
+
name: "thread_list",
|
|
27511
|
+
description: "List memory threads",
|
|
27512
|
+
method: "GET",
|
|
27513
|
+
path: "/memory/threads",
|
|
27514
|
+
destructive: false
|
|
27515
|
+
},
|
|
27516
|
+
{
|
|
27517
|
+
name: "thread_get",
|
|
27518
|
+
description: "Get thread details",
|
|
27519
|
+
method: "GET",
|
|
27520
|
+
path: "/memory/threads/:threadId",
|
|
27521
|
+
destructive: false
|
|
27522
|
+
},
|
|
27523
|
+
{
|
|
27524
|
+
name: "thread_create",
|
|
27525
|
+
description: "Create a memory thread",
|
|
27526
|
+
method: "POST",
|
|
27527
|
+
path: "/memory/threads",
|
|
27528
|
+
destructive: true
|
|
27529
|
+
},
|
|
27530
|
+
{
|
|
27531
|
+
name: "thread_update",
|
|
27532
|
+
description: "Update a memory thread",
|
|
27533
|
+
method: "PATCH",
|
|
27534
|
+
path: "/memory/threads/:threadId",
|
|
27535
|
+
destructive: true
|
|
27536
|
+
},
|
|
27537
|
+
{
|
|
27538
|
+
name: "thread_delete",
|
|
27539
|
+
description: "Delete a memory thread",
|
|
27540
|
+
method: "DELETE",
|
|
27541
|
+
path: "/memory/threads/:threadId",
|
|
27542
|
+
destructive: true
|
|
27543
|
+
},
|
|
27544
|
+
{
|
|
27545
|
+
name: "thread_messages",
|
|
27546
|
+
description: "List messages in a memory thread",
|
|
27547
|
+
method: "GET",
|
|
27548
|
+
path: "/memory/threads/:threadId/messages",
|
|
27549
|
+
destructive: false
|
|
27550
|
+
},
|
|
27551
|
+
{
|
|
27552
|
+
name: "memory_search",
|
|
27553
|
+
description: "Search long-term memory",
|
|
27554
|
+
method: "GET",
|
|
27555
|
+
path: "/memory/search",
|
|
27556
|
+
destructive: false
|
|
27557
|
+
},
|
|
27558
|
+
{
|
|
27559
|
+
name: "memory_current_get",
|
|
27560
|
+
description: "Get current working memory",
|
|
27561
|
+
method: "GET",
|
|
27562
|
+
path: "/memory/threads/:threadId/working-memory",
|
|
27563
|
+
destructive: false
|
|
27564
|
+
},
|
|
27565
|
+
{
|
|
27566
|
+
name: "memory_current_update",
|
|
27567
|
+
description: "Update current working memory",
|
|
27568
|
+
method: "POST",
|
|
27569
|
+
path: "/memory/threads/:threadId/working-memory",
|
|
27570
|
+
destructive: true
|
|
27571
|
+
},
|
|
27572
|
+
{
|
|
27573
|
+
name: "memory_status",
|
|
27574
|
+
description: "Get memory system status",
|
|
27575
|
+
method: "GET",
|
|
27576
|
+
path: "/memory/status",
|
|
27577
|
+
destructive: false
|
|
27578
|
+
},
|
|
27579
|
+
{
|
|
27580
|
+
name: "trace_list",
|
|
27581
|
+
description: "List observability traces",
|
|
27582
|
+
method: "GET",
|
|
27583
|
+
path: "/observability/traces/light",
|
|
27584
|
+
verbosePath: "/observability/traces",
|
|
27585
|
+
destructive: false
|
|
27586
|
+
},
|
|
27587
|
+
{
|
|
27588
|
+
name: "trace_get",
|
|
27589
|
+
description: "Get trace details",
|
|
27590
|
+
method: "GET",
|
|
27591
|
+
path: "/observability/traces/:traceId/light",
|
|
27592
|
+
verbosePath: "/observability/traces/:traceId",
|
|
27593
|
+
destructive: false
|
|
27594
|
+
},
|
|
27595
|
+
{
|
|
27596
|
+
name: "trace_span",
|
|
27597
|
+
description: "Get a trace span",
|
|
27598
|
+
method: "GET",
|
|
27599
|
+
path: "/observability/traces/:traceId/spans/:spanId",
|
|
27600
|
+
destructive: false
|
|
27601
|
+
},
|
|
27602
|
+
{
|
|
27603
|
+
name: "log_list",
|
|
27604
|
+
description: "List runtime logs",
|
|
27605
|
+
method: "GET",
|
|
27606
|
+
path: "/observability/logs",
|
|
27607
|
+
destructive: false
|
|
27608
|
+
},
|
|
27609
|
+
{
|
|
27610
|
+
name: "metric_aggregate",
|
|
27611
|
+
description: "Get an aggregate metric value",
|
|
27612
|
+
method: "POST",
|
|
27613
|
+
path: "/observability/metrics/aggregate",
|
|
27614
|
+
destructive: true
|
|
27615
|
+
},
|
|
27616
|
+
{
|
|
27617
|
+
name: "metric_breakdown",
|
|
27618
|
+
description: "Get metric values grouped by a label or field",
|
|
27619
|
+
method: "POST",
|
|
27620
|
+
path: "/observability/metrics/breakdown",
|
|
27621
|
+
destructive: true
|
|
27622
|
+
},
|
|
27623
|
+
{
|
|
27624
|
+
name: "metric_timeseries",
|
|
27625
|
+
description: "Get metric values over time",
|
|
27626
|
+
method: "POST",
|
|
27627
|
+
path: "/observability/metrics/timeseries",
|
|
27628
|
+
destructive: true
|
|
27629
|
+
},
|
|
27630
|
+
{
|
|
27631
|
+
name: "metric_percentiles",
|
|
27632
|
+
description: "Get metric percentile values over time",
|
|
27633
|
+
method: "POST",
|
|
27634
|
+
path: "/observability/metrics/percentiles",
|
|
27635
|
+
destructive: true
|
|
27636
|
+
},
|
|
27637
|
+
{
|
|
27638
|
+
name: "metric_names",
|
|
27639
|
+
description: "List discovered metric names",
|
|
27640
|
+
method: "GET",
|
|
27641
|
+
path: "/observability/discovery/metric-names",
|
|
27642
|
+
destructive: false
|
|
27643
|
+
},
|
|
27644
|
+
{
|
|
27645
|
+
name: "metric_label_keys",
|
|
27646
|
+
description: "List label keys for a metric",
|
|
27647
|
+
method: "GET",
|
|
27648
|
+
path: "/observability/discovery/metric-label-keys",
|
|
27649
|
+
destructive: false
|
|
27650
|
+
},
|
|
27651
|
+
{
|
|
27652
|
+
name: "metric_label_values",
|
|
27653
|
+
description: "List label values for a metric label key",
|
|
27654
|
+
method: "GET",
|
|
27655
|
+
path: "/observability/discovery/metric-label-values",
|
|
27656
|
+
destructive: false
|
|
27657
|
+
},
|
|
27658
|
+
{
|
|
27659
|
+
name: "score_create",
|
|
27660
|
+
description: "Create a score",
|
|
27661
|
+
method: "POST",
|
|
27662
|
+
path: "/observability/scores",
|
|
27663
|
+
destructive: true
|
|
27664
|
+
},
|
|
27665
|
+
{
|
|
27666
|
+
name: "score_list",
|
|
27667
|
+
description: "List scores",
|
|
27668
|
+
method: "GET",
|
|
27669
|
+
path: "/observability/scores",
|
|
27670
|
+
destructive: false
|
|
27671
|
+
},
|
|
27672
|
+
{
|
|
27673
|
+
name: "score_get",
|
|
27674
|
+
description: "Get score details",
|
|
27675
|
+
method: "GET",
|
|
27676
|
+
path: "/observability/scores/:scoreId",
|
|
27677
|
+
destructive: false
|
|
27678
|
+
},
|
|
27679
|
+
{
|
|
27680
|
+
name: "dataset_list",
|
|
27681
|
+
description: "List datasets",
|
|
27682
|
+
method: "GET",
|
|
27683
|
+
path: "/datasets",
|
|
27684
|
+
destructive: false
|
|
27685
|
+
},
|
|
27686
|
+
{
|
|
27687
|
+
name: "dataset_get",
|
|
27688
|
+
description: "Get dataset details",
|
|
27689
|
+
method: "GET",
|
|
27690
|
+
path: "/datasets/:datasetId",
|
|
27691
|
+
destructive: false
|
|
27692
|
+
},
|
|
27693
|
+
{
|
|
27694
|
+
name: "dataset_create",
|
|
27695
|
+
description: "Create a dataset",
|
|
27696
|
+
method: "POST",
|
|
27697
|
+
path: "/datasets",
|
|
27698
|
+
destructive: true
|
|
27699
|
+
},
|
|
27700
|
+
{
|
|
27701
|
+
name: "dataset_items",
|
|
27702
|
+
description: "List dataset items",
|
|
27703
|
+
method: "GET",
|
|
27704
|
+
path: "/datasets/:datasetId/items",
|
|
27705
|
+
destructive: false
|
|
27706
|
+
},
|
|
27707
|
+
{
|
|
27708
|
+
name: "experiment_list",
|
|
27709
|
+
description: "List dataset experiments",
|
|
27710
|
+
method: "GET",
|
|
27711
|
+
path: "/datasets/:datasetId/experiments",
|
|
27712
|
+
destructive: false
|
|
27713
|
+
},
|
|
27714
|
+
{
|
|
27715
|
+
name: "experiment_get",
|
|
27716
|
+
description: "Get experiment details",
|
|
27717
|
+
method: "GET",
|
|
27718
|
+
path: "/datasets/:datasetId/experiments/:experimentId",
|
|
27719
|
+
destructive: false
|
|
27720
|
+
},
|
|
27721
|
+
{
|
|
27722
|
+
name: "experiment_run",
|
|
27723
|
+
description: "Run a dataset experiment",
|
|
27724
|
+
method: "POST",
|
|
27725
|
+
path: "/datasets/:datasetId/experiments",
|
|
27726
|
+
destructive: true
|
|
27727
|
+
},
|
|
27728
|
+
{
|
|
27729
|
+
name: "experiment_results",
|
|
27730
|
+
description: "List experiment results",
|
|
27731
|
+
method: "GET",
|
|
27732
|
+
path: "/datasets/:datasetId/experiments/:experimentId/results",
|
|
27733
|
+
destructive: false
|
|
27734
|
+
},
|
|
27735
|
+
{
|
|
27736
|
+
name: "learning_entities",
|
|
27737
|
+
description: "List entities with Trace Intelligence output",
|
|
27738
|
+
method: "GET",
|
|
27739
|
+
path: "/learning/entities",
|
|
27740
|
+
destructive: false
|
|
27741
|
+
},
|
|
27742
|
+
{
|
|
27743
|
+
name: "learning_snapshots",
|
|
27744
|
+
description: "List analysis snapshots for an entity and ordered trace signals",
|
|
27745
|
+
method: "GET",
|
|
27746
|
+
path: "/learning/entities/:entityId/theme-snapshots",
|
|
27747
|
+
destructive: false
|
|
27748
|
+
},
|
|
27749
|
+
{
|
|
27750
|
+
name: "learning_flow",
|
|
27751
|
+
description: "Get the cross-signal theme flow for one snapshot",
|
|
27752
|
+
method: "GET",
|
|
27753
|
+
path: "/learning/entities/:entityId/theme-flow",
|
|
27754
|
+
destructive: false
|
|
27755
|
+
},
|
|
27756
|
+
{
|
|
27757
|
+
name: "learning_paths",
|
|
27758
|
+
description: "Get per-trace theme assignments for one snapshot",
|
|
27759
|
+
method: "GET",
|
|
27760
|
+
path: "/learning/entities/:entityId/theme-paths",
|
|
27761
|
+
destructive: false
|
|
27762
|
+
},
|
|
27763
|
+
{
|
|
27764
|
+
name: "learning_theme_list",
|
|
27765
|
+
description: "List themes for one trace signal in one snapshot",
|
|
27766
|
+
method: "GET",
|
|
27767
|
+
path: "/learning/entities/:entityId/themes",
|
|
27768
|
+
destructive: false
|
|
27769
|
+
},
|
|
27770
|
+
{
|
|
27771
|
+
name: "learning_theme_get",
|
|
27772
|
+
description: "Get one theme in one snapshot",
|
|
27773
|
+
method: "GET",
|
|
27774
|
+
path: "/learning/entities/:entityId/themes/:themeId",
|
|
27775
|
+
destructive: false
|
|
27776
|
+
},
|
|
27777
|
+
{
|
|
27778
|
+
name: "learning_theme_examples",
|
|
27779
|
+
description: "List trace examples for one theme in one snapshot",
|
|
27780
|
+
method: "GET",
|
|
27781
|
+
path: "/learning/entities/:entityId/themes/:themeId/examples",
|
|
27782
|
+
destructive: false
|
|
27783
|
+
},
|
|
27784
|
+
{
|
|
27785
|
+
name: "learning_theme_history",
|
|
27786
|
+
description: "Get lifecycle history for one durable theme",
|
|
27787
|
+
method: "GET",
|
|
27788
|
+
path: "/learning/entities/:entityId/themes/:themeId/history",
|
|
27789
|
+
destructive: false
|
|
27790
|
+
},
|
|
27791
|
+
{
|
|
27792
|
+
name: "learning_noise_get",
|
|
27793
|
+
description: "Get the noise bucket for one trace signal in one snapshot",
|
|
27794
|
+
method: "GET",
|
|
27795
|
+
path: "/learning/entities/:entityId/noise",
|
|
27796
|
+
destructive: false
|
|
27797
|
+
},
|
|
27798
|
+
{
|
|
27799
|
+
name: "learning_noise_examples",
|
|
27800
|
+
description: "List trace examples for the noise bucket in one snapshot",
|
|
27801
|
+
method: "GET",
|
|
27802
|
+
path: "/learning/entities/:entityId/noise/examples",
|
|
27803
|
+
destructive: false
|
|
27804
|
+
}
|
|
27805
|
+
];
|
|
27806
|
+
//#endregion
|
|
27807
|
+
//#region src/server/mastra-api-mcp-server.ts
|
|
27808
|
+
var MastraApiRequester = class {
|
|
27809
|
+
options;
|
|
27810
|
+
constructor(options) {
|
|
27811
|
+
this.options = options;
|
|
27812
|
+
}
|
|
27813
|
+
async getSchemaManifest() {
|
|
27814
|
+
const value = await this.request({
|
|
27815
|
+
method: "GET",
|
|
27816
|
+
path: "/system/api-schema",
|
|
27817
|
+
pathParamSchema: void 0,
|
|
27818
|
+
queryParamSchema: void 0,
|
|
27819
|
+
bodySchema: void 0
|
|
27820
|
+
}, {});
|
|
27821
|
+
if (!isRecord(value) || value.version !== 1 || !Array.isArray(value.routes)) throw new Error("The Mastra server returned an invalid API schema manifest. Confirm that the target server supports GET /api/system/api-schema.");
|
|
27822
|
+
const routes = value.routes.filter(isApiSchemaRoute);
|
|
27823
|
+
if (routes.length !== value.routes.length) throw new Error("The Mastra server API schema manifest contains an invalid route definition.");
|
|
27824
|
+
return routes;
|
|
27825
|
+
}
|
|
27826
|
+
async request(route, input, authInfo, requestSignal) {
|
|
27827
|
+
const pathParams = schemaPropertyNames(route.pathParamSchema);
|
|
27828
|
+
const queryParams = new Set(schemaPropertyNames(route.queryParamSchema));
|
|
27829
|
+
const bodyParams = new Set(schemaPropertyNames(route.bodySchema));
|
|
27830
|
+
const remainingInput = { ...input };
|
|
27831
|
+
let path = route.path;
|
|
27832
|
+
for (const name of pathParams) {
|
|
27833
|
+
path = path.replace(`:${name}`, encodeURIComponent(remainingInput[name]));
|
|
27834
|
+
delete remainingInput[name];
|
|
27835
|
+
}
|
|
27836
|
+
const url = new URL(joinUrl(this.options.baseUrl, this.options.apiPrefix, path));
|
|
27837
|
+
const body = {};
|
|
27838
|
+
for (const [name, value] of Object.entries(remainingInput)) {
|
|
27839
|
+
if (value === void 0) continue;
|
|
27840
|
+
if (route.method === "GET" || queryParams.has(name) && !bodyParams.has(name)) {
|
|
27841
|
+
if (value === null) continue;
|
|
27842
|
+
url.searchParams.set(name, typeof value === "object" ? JSON.stringify(value) : String(value));
|
|
27843
|
+
} else body[name] = value;
|
|
27844
|
+
}
|
|
27845
|
+
const headers = new Headers(this.options.headers);
|
|
27846
|
+
headers.set("accept", "application/json");
|
|
27847
|
+
const callerToken = getAuthToken(authInfo);
|
|
27848
|
+
if (callerToken) headers.set("authorization", `Bearer ${callerToken}`);
|
|
27849
|
+
const controller = new AbortController();
|
|
27850
|
+
const timeout = setTimeout(() => controller.abort(/* @__PURE__ */ new Error("request timed out")), this.options.timeoutMs);
|
|
27851
|
+
const abortRequest = () => controller.abort(requestSignal?.reason);
|
|
27852
|
+
if (requestSignal?.aborted) abortRequest();
|
|
27853
|
+
else requestSignal?.addEventListener("abort", abortRequest, { once: true });
|
|
27854
|
+
try {
|
|
27855
|
+
const hasBody = route.method !== "GET" && route.bodySchema !== void 0;
|
|
27856
|
+
if (hasBody) headers.set("content-type", "application/json");
|
|
27857
|
+
const response = await this.options.fetch(url, {
|
|
27858
|
+
method: route.method,
|
|
27859
|
+
headers,
|
|
27860
|
+
signal: controller.signal,
|
|
27861
|
+
...hasBody ? { body: JSON.stringify(body) } : {}
|
|
27862
|
+
});
|
|
27863
|
+
const responseBody = await readResponseBody(response);
|
|
27864
|
+
if (!response.ok) {
|
|
27865
|
+
const detail = getErrorDetail(responseBody);
|
|
27866
|
+
throw new Error(`Mastra API request ${route.method} ${route.path} failed with status ${response.status}${detail ? `: ${detail}` : "."}`);
|
|
27867
|
+
}
|
|
27868
|
+
return responseBody;
|
|
27869
|
+
} catch (error) {
|
|
27870
|
+
if (controller.signal.aborted) {
|
|
27871
|
+
if (requestSignal?.aborted) throw new Error(`Mastra API request ${route.method} ${route.path} was canceled.`, { cause: error });
|
|
27872
|
+
throw new Error(`Mastra API request ${route.method} ${route.path} timed out after ${this.options.timeoutMs}ms.`, { cause: error });
|
|
27873
|
+
}
|
|
27874
|
+
if (error instanceof Error && error.message.startsWith("Mastra API request ")) throw error;
|
|
27875
|
+
throw new Error(`Could not reach the Mastra server at ${this.options.baseUrl}. Check the server URL and network access.`, { cause: error });
|
|
27876
|
+
} finally {
|
|
27877
|
+
clearTimeout(timeout);
|
|
27878
|
+
requestSignal?.removeEventListener("abort", abortRequest);
|
|
27879
|
+
}
|
|
27880
|
+
}
|
|
27881
|
+
};
|
|
27882
|
+
/**
|
|
27883
|
+
* An MCP server that exposes the Mastra API CLI operations from a remote Mastra server.
|
|
27884
|
+
*
|
|
27885
|
+
* The factory reads the target server's schema manifest, registers the CLI operations
|
|
27886
|
+
* supported by that server, and uses the route schemas as MCP tool input schemas.
|
|
27887
|
+
*/
|
|
27888
|
+
var MastraApiMCPServer = class MastraApiMCPServer extends MCPServer {
|
|
27889
|
+
constructor(options, tools) {
|
|
27890
|
+
super({
|
|
27891
|
+
id: options.id ?? "mastra-api",
|
|
27892
|
+
name: options.name ?? "Mastra Server",
|
|
27893
|
+
version: options.version ?? "1.0.0",
|
|
27894
|
+
description: "Inspect and operate a Mastra server.",
|
|
27895
|
+
instructions: "Inspect resources before using them. Pass tool input inside the data field for tool_execute and mcp_tool_execute. Ask for confirmation before calling a tool marked as destructive.",
|
|
27896
|
+
protocolVersion: "2026-07-28",
|
|
27897
|
+
tools
|
|
27898
|
+
});
|
|
27899
|
+
}
|
|
27900
|
+
/** Creates a stateless MCP server for the target Mastra server. */
|
|
27901
|
+
static async create(options) {
|
|
27902
|
+
const requester = new MastraApiRequester(normalizeOptions(options));
|
|
27903
|
+
const tools = createApiTools(await requester.getSchemaManifest(), requester);
|
|
27904
|
+
if (Object.keys(tools).length === 0) throw new Error("The target Mastra server does not support any of the MCP server operations.");
|
|
27905
|
+
return new MastraApiMCPServer(options, tools);
|
|
27906
|
+
}
|
|
27907
|
+
};
|
|
27908
|
+
function createApiTools(routes, requester) {
|
|
27909
|
+
const tools = {};
|
|
27910
|
+
for (const operation of MASTRA_API_OPERATIONS) {
|
|
27911
|
+
const primaryRoute = routes.find((candidate) => candidate.method === operation.method && candidate.path === operation.path);
|
|
27912
|
+
const verboseRoute = "verbosePath" in operation ? routes.find((candidate) => candidate.method === operation.method && candidate.path === operation.verbosePath) : void 0;
|
|
27913
|
+
const route = primaryRoute ?? verboseRoute;
|
|
27914
|
+
if (!route) continue;
|
|
27915
|
+
const readOnly = operation.method === "GET";
|
|
27916
|
+
tools[operation.name] = createTool({
|
|
27917
|
+
id: operation.name,
|
|
27918
|
+
description: operation.description,
|
|
27919
|
+
inputSchema: toStandardSchema(mergeInputSchemas(route, primaryRoute !== void 0 && verboseRoute !== void 0)),
|
|
27920
|
+
mcp: { annotations: {
|
|
27921
|
+
title: operation.description,
|
|
27922
|
+
readOnlyHint: readOnly,
|
|
27923
|
+
destructiveHint: operation.destructive,
|
|
27924
|
+
idempotentHint: readOnly || operation.method === "DELETE",
|
|
27925
|
+
openWorldHint: true
|
|
27926
|
+
} },
|
|
27927
|
+
execute: async (input, context) => {
|
|
27928
|
+
let requestInput = input;
|
|
27929
|
+
let selectedRoute = route;
|
|
27930
|
+
if (primaryRoute && verboseRoute) {
|
|
27931
|
+
const { verbose, ...inputWithoutVerbose } = input;
|
|
27932
|
+
requestInput = inputWithoutVerbose;
|
|
27933
|
+
if (verbose === true) selectedRoute = verboseRoute;
|
|
27934
|
+
}
|
|
27935
|
+
return requester.request(selectedRoute, requestInput, context.mcp?.extra.authInfo ?? getRequestAuthInfo(context.requestContext), context.abortSignal ?? context.mcp?.extra.signal);
|
|
27936
|
+
}
|
|
27937
|
+
});
|
|
27938
|
+
}
|
|
27939
|
+
return tools;
|
|
27940
|
+
}
|
|
27941
|
+
function normalizeOptions(options) {
|
|
27942
|
+
let url;
|
|
27943
|
+
try {
|
|
27944
|
+
url = new URL(options.url);
|
|
27945
|
+
} catch (error) {
|
|
27946
|
+
throw new Error("The Mastra server URL must be a valid absolute URL.", { cause: error });
|
|
27947
|
+
}
|
|
27948
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error("The Mastra server URL must use HTTP or HTTPS.");
|
|
27949
|
+
if (url.username || url.password) throw new Error("The Mastra server URL cannot contain credentials. Use the headers option for authentication.");
|
|
27950
|
+
if (url.search || url.hash) throw new Error("The Mastra server URL cannot contain a query string or fragment.");
|
|
27951
|
+
const apiPrefix = normalizeApiPrefix(options.apiPrefix ?? "/api");
|
|
27952
|
+
const timeoutMs = options.timeoutMs ?? 12e4;
|
|
27953
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) throw new Error("The request timeout must be a positive integer in milliseconds.");
|
|
27954
|
+
return {
|
|
27955
|
+
baseUrl: url.toString().replace(/\/$/, ""),
|
|
27956
|
+
apiPrefix,
|
|
27957
|
+
headers: { ...options.headers },
|
|
27958
|
+
timeoutMs,
|
|
27959
|
+
fetch: options.fetch ?? globalThis.fetch
|
|
27960
|
+
};
|
|
27961
|
+
}
|
|
27962
|
+
function normalizeApiPrefix(value) {
|
|
27963
|
+
if (value.includes("..") || value.includes("?") || value.includes("#")) throw new Error("The Mastra API prefix cannot contain \"..\", a query string, or a fragment.");
|
|
27964
|
+
let start = 0;
|
|
27965
|
+
let end = value.length;
|
|
27966
|
+
while (start < end && value[start] === "/") start++;
|
|
27967
|
+
while (end > start && value[end - 1] === "/") end--;
|
|
27968
|
+
return start === end ? "" : `/${value.slice(start, end)}`;
|
|
27969
|
+
}
|
|
27970
|
+
function joinUrl(baseUrl, apiPrefix, path) {
|
|
27971
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
27972
|
+
if (!apiPrefix || baseUrl.endsWith(apiPrefix)) return `${baseUrl}${normalizedPath}`;
|
|
27973
|
+
return `${baseUrl}${apiPrefix}${normalizedPath}`;
|
|
27974
|
+
}
|
|
27975
|
+
function mergeInputSchemas(route, supportsVerbose = false) {
|
|
27976
|
+
const definitions = {};
|
|
27977
|
+
const schemas = [
|
|
27978
|
+
"pathParamSchema",
|
|
27979
|
+
"queryParamSchema",
|
|
27980
|
+
"bodySchema"
|
|
27981
|
+
].flatMap((key) => {
|
|
27982
|
+
const source = route[key];
|
|
27983
|
+
if (!isRecord(source)) return [];
|
|
27984
|
+
const schema = relocateSchemaReferences(source, `#/definitions/${key}`);
|
|
27985
|
+
definitions[key] = schema;
|
|
27986
|
+
return [schema];
|
|
27987
|
+
});
|
|
27988
|
+
const properties = {};
|
|
27989
|
+
const pathParams = new Set(schemaPropertyNames(route.pathParamSchema));
|
|
27990
|
+
const required = new Set(pathParams);
|
|
27991
|
+
let allowsAdditionalProperties = false;
|
|
27992
|
+
for (const schema of schemas) {
|
|
27993
|
+
if (isRecord(schema.properties)) for (const [name, property] of Object.entries(schema.properties)) properties[name] = pathParams.has(name) && Object.hasOwn(properties, name) ? { allOf: [properties[name], property] } : property;
|
|
27994
|
+
if (Array.isArray(schema.required)) {
|
|
27995
|
+
for (const name of schema.required) if (typeof name === "string") required.add(name);
|
|
27996
|
+
}
|
|
27997
|
+
if (schema.additionalProperties === true || isRecord(schema.additionalProperties)) allowsAdditionalProperties = true;
|
|
27998
|
+
}
|
|
27999
|
+
if (supportsVerbose) properties.verbose = {
|
|
28000
|
+
type: "boolean",
|
|
28001
|
+
description: "Return the full response instead of the lightweight response.",
|
|
28002
|
+
default: false
|
|
28003
|
+
};
|
|
28004
|
+
for (const name of pathParams) properties[name] = {
|
|
28005
|
+
type: "string",
|
|
28006
|
+
minLength: 1,
|
|
28007
|
+
allOf: [properties[name]]
|
|
28008
|
+
};
|
|
28009
|
+
return {
|
|
28010
|
+
type: "object",
|
|
28011
|
+
properties,
|
|
28012
|
+
required: [...required],
|
|
28013
|
+
additionalProperties: allowsAdditionalProperties,
|
|
28014
|
+
definitions
|
|
28015
|
+
};
|
|
28016
|
+
}
|
|
28017
|
+
function relocateSchemaReferences(value, root) {
|
|
28018
|
+
if (Array.isArray(value)) return value.map((item) => relocateSchemaReferences(item, root));
|
|
28019
|
+
if (!isRecord(value)) return value;
|
|
28020
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, key === "$ref" && typeof child === "string" && (child === "#" || child.startsWith("#/")) ? `${root}${child.slice(1)}` : relocateSchemaReferences(child, root)]));
|
|
28021
|
+
}
|
|
28022
|
+
function schemaPropertyNames(schema) {
|
|
28023
|
+
return isRecord(schema?.properties) ? Object.keys(schema.properties) : [];
|
|
28024
|
+
}
|
|
28025
|
+
function isApiSchemaRoute(value) {
|
|
28026
|
+
if (!isRecord(value) || typeof value.method !== "string" || typeof value.path !== "string") return false;
|
|
28027
|
+
return [
|
|
28028
|
+
"pathParamSchema",
|
|
28029
|
+
"queryParamSchema",
|
|
28030
|
+
"bodySchema"
|
|
28031
|
+
].every((key) => value[key] === void 0 || isRecord(value[key]));
|
|
28032
|
+
}
|
|
28033
|
+
function isRecord(value) {
|
|
28034
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28035
|
+
}
|
|
28036
|
+
function getAuthToken(authInfo) {
|
|
28037
|
+
if (!isRecord(authInfo)) return void 0;
|
|
28038
|
+
return typeof authInfo.token === "string" && authInfo.token.length > 0 ? authInfo.token : void 0;
|
|
28039
|
+
}
|
|
28040
|
+
function getRequestAuthInfo(requestContext) {
|
|
28041
|
+
const authInfo = requestContext?.get("authInfo");
|
|
28042
|
+
if (authInfo !== void 0) return authInfo;
|
|
28043
|
+
const token = requestContext?.get(MASTRA_AUTH_TOKEN_KEY);
|
|
28044
|
+
return typeof token === "string" && token.length > 0 ? { token } : void 0;
|
|
28045
|
+
}
|
|
28046
|
+
async function readResponseBody(response) {
|
|
28047
|
+
const text = await response.text();
|
|
28048
|
+
if (!text) return null;
|
|
28049
|
+
try {
|
|
28050
|
+
return JSON.parse(text);
|
|
28051
|
+
} catch {
|
|
28052
|
+
return text;
|
|
28053
|
+
}
|
|
28054
|
+
}
|
|
28055
|
+
function getErrorDetail(body) {
|
|
28056
|
+
if (typeof body === "string") return body.slice(0, 500);
|
|
28057
|
+
if (!isRecord(body)) return void 0;
|
|
28058
|
+
const error = isRecord(body.error) ? body.error : body;
|
|
28059
|
+
if (typeof error.message === "string") return error.message.slice(0, 500);
|
|
28060
|
+
return JSON.stringify(body).slice(0, 500);
|
|
28061
|
+
}
|
|
28062
|
+
//#endregion
|
|
27055
28063
|
//#region src/server/oauth-middleware.ts
|
|
27056
28064
|
/**
|
|
27057
28065
|
* Creates an OAuth middleware function for protecting MCP server endpoints.
|
|
@@ -27298,6 +28306,6 @@ function createIntrospectionValidator(introspectionEndpoint, clientCredentials)
|
|
|
27298
28306
|
};
|
|
27299
28307
|
}
|
|
27300
28308
|
//#endregion
|
|
27301
|
-
export { InMemoryOAuthStorage, InternalMastraMCPClient, MCPClient, MCPClientServerProxy, MCPOAuthClientProvider, MCPServer, MCP_CALL_TOOL_CONTENT, MCP_CALL_TOOL_META, UnauthorizedError, auth, buildDiscoveryUrls, createIntrospectionValidator, createOAuthCallbackServer, createOAuthMiddleware, createSimpleTokenProvider, createStaticTokenValidator, discoverAuthorizationServerMetadata, discoverOAuthMetadata, discoverOAuthProtectedResourceMetadata, exchangeAuthorization, extractBearerToken, extractResourceMetadataUrl, generateProtectedResourceMetadata, generateWWWAuthenticateHeader, getCallbackUrlCandidates, getMcpCallToolContent, getMcpCallToolMeta, parseErrorResponse, refreshAuthorization, registerClient, selectResourceURL, startAuthorization };
|
|
28309
|
+
export { InMemoryOAuthStorage, InternalMastraMCPClient, MCPClient, MCPClientServerProxy, MCPOAuthClientProvider, MCPServer, MCP_CALL_TOOL_CONTENT, MCP_CALL_TOOL_META, MastraApiMCPServer, UnauthorizedError, auth, buildDiscoveryUrls, createIntrospectionValidator, createOAuthCallbackServer, createOAuthMiddleware, createSimpleTokenProvider, createStaticTokenValidator, discoverAuthorizationServerMetadata, discoverOAuthMetadata, discoverOAuthProtectedResourceMetadata, exchangeAuthorization, extractBearerToken, extractResourceMetadataUrl, generateProtectedResourceMetadata, generateWWWAuthenticateHeader, getCallbackUrlCandidates, getMcpCallToolContent, getMcpCallToolMeta, parseErrorResponse, refreshAuthorization, registerClient, selectResourceURL, startAuthorization };
|
|
27302
28310
|
|
|
27303
28311
|
//# sourceMappingURL=index.js.map
|