@anvia/core 0.26.0 → 1.0.0-rc.2
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 +303 -94
- package/dist/agent/index.d.ts +36 -70
- package/dist/agent/index.js +25 -18
- package/dist/agent-yBG8e9Jj.d.ts +153 -0
- package/dist/chunk-4WI3VGZK.js +127 -0
- package/dist/chunk-4WI3VGZK.js.map +1 -0
- package/dist/chunk-77AIYARB.js +654 -0
- package/dist/chunk-77AIYARB.js.map +1 -0
- package/dist/chunk-AI5JMUW7.js +45 -0
- package/dist/chunk-AI5JMUW7.js.map +1 -0
- package/dist/chunk-BEYBU7VJ.js +53 -0
- package/dist/chunk-BEYBU7VJ.js.map +1 -0
- package/dist/chunk-CWM7B2OO.js +315 -0
- package/dist/chunk-CWM7B2OO.js.map +1 -0
- package/dist/chunk-D37WMSP6.js +131 -0
- package/dist/chunk-D37WMSP6.js.map +1 -0
- package/dist/chunk-DBSCKTUL.js +3793 -0
- package/dist/chunk-DBSCKTUL.js.map +1 -0
- package/dist/chunk-EINTGEGY.js +629 -0
- package/dist/chunk-EINTGEGY.js.map +1 -0
- package/dist/chunk-FMHLROPQ.js +351 -0
- package/dist/chunk-FMHLROPQ.js.map +1 -0
- package/dist/chunk-FN7HLLAZ.js +211 -0
- package/dist/chunk-FN7HLLAZ.js.map +1 -0
- package/dist/chunk-GKDERULJ.js +50 -0
- package/dist/chunk-GKDERULJ.js.map +1 -0
- package/dist/{chunk-CWUJUSOS.js → chunk-KIDGIJM7.js} +26 -5
- package/dist/chunk-KIDGIJM7.js.map +1 -0
- package/dist/chunk-KR3RCCHJ.js +500 -0
- package/dist/chunk-KR3RCCHJ.js.map +1 -0
- package/dist/chunk-MGNTXGTX.js +37 -0
- package/dist/chunk-MGNTXGTX.js.map +1 -0
- package/dist/{chunk-MRQLEK2B.js → chunk-OJH6HWHX.js} +63 -51
- package/dist/chunk-OJH6HWHX.js.map +1 -0
- package/dist/chunk-QOUPWOGW.js +29 -0
- package/dist/chunk-QOUPWOGW.js.map +1 -0
- package/dist/chunk-TIZYTPJO.js +208 -0
- package/dist/chunk-TIZYTPJO.js.map +1 -0
- package/dist/{chunk-NCPN4SJR.js → chunk-XKYYBABH.js} +13 -13
- package/dist/chunk-XKYYBABH.js.map +1 -0
- package/dist/client-B8DT1vUG.d.ts +83 -0
- package/dist/completion/index.d.ts +6 -36
- package/dist/completion/index.js +25 -29
- package/dist/dynamic-tools-KwEGRbHp.d.ts +45 -0
- package/dist/embeddings/index.d.ts +11 -9
- package/dist/embeddings/index.js +2 -4
- package/dist/evals/index.d.ts +47 -20
- package/dist/evals/index.js +104 -65
- package/dist/evals/index.js.map +1 -1
- package/dist/extractor/index.d.ts +27 -42
- package/dist/extractor/index.js +7 -22
- package/dist/guardrails/index.d.ts +3 -2
- package/dist/guardrails/index.js +1 -1
- package/dist/image-generation/index.d.ts +23 -23
- package/dist/image-generation/index.js +5 -39
- package/dist/image-generation/index.js.map +1 -1
- package/dist/index.d.ts +25 -20
- package/dist/index.js +60 -63
- package/dist/internal/agent.d.ts +163 -9
- package/dist/internal/agent.js +25 -18
- package/dist/loaders/index.d.ts +6 -10
- package/dist/loaders/index.js.map +1 -1
- package/dist/mcp/index.d.ts +19 -13
- package/dist/mcp/index.js +13 -348
- package/dist/mcp/index.js.map +1 -1
- package/dist/memory/index.d.ts +20 -6
- package/dist/memory/index.js +9 -10
- package/dist/message-schema-Cn7ezRfJ.d.ts +52 -0
- package/dist/middleware-C7PdmKF7.d.ts +56 -0
- package/dist/model-call-options-CZkSw_xN.d.ts +6 -0
- package/dist/model-listing/index.d.ts +3 -1
- package/dist/observability/index.d.ts +20 -3
- package/dist/observability/index.js +8 -5
- package/dist/observability/index.js.map +1 -1
- package/dist/pipeline/index.d.ts +114 -72
- package/dist/pipeline/index.js +478 -286
- package/dist/pipeline/index.js.map +1 -1
- package/dist/retry-CjvSlKGW.d.ts +16 -0
- package/dist/skills/index.d.ts +5 -4
- package/dist/skills/index.js +7 -8
- package/dist/speech-generation/index.d.ts +37 -0
- package/dist/speech-generation/index.js +8 -0
- package/dist/streaming/index.js +37 -3
- package/dist/streaming/index.js.map +1 -1
- package/dist/{think-tool-DfCMuO8e.d.ts → think-tool-6H2QNQzQ.d.ts} +5 -5
- package/dist/tool/index.d.ts +10 -6
- package/dist/tool/index.js +15 -21
- package/dist/tool--Mz4v1eL.d.ts +57 -0
- package/dist/transcription/index.d.ts +29 -22
- package/dist/transcription/index.js +5 -57
- package/dist/transcription/index.js.map +1 -1
- package/dist/type-utils-CtHVDRn_.d.ts +6 -0
- package/dist/types-3x3mOLHU.d.ts +379 -0
- package/dist/types-BVzM4RsC.d.ts +155 -0
- package/dist/types-CQ_ioXWK.d.ts +319 -0
- package/dist/types-Cr4uiYo5.d.ts +99 -0
- package/dist/{types-04LqWrmy.d.ts → types-DiJqJejp.d.ts} +1 -1
- package/dist/types-Dld1TpWj.d.ts +130 -0
- package/dist/vector-store/index.d.ts +33 -34
- package/dist/vector-store/index.js +6 -6
- package/package.json +6 -18
- package/dist/agent-x3YTyv5i.d.ts +0 -222
- package/dist/audio-generation/index.d.ts +0 -33
- package/dist/audio-generation/index.js +0 -42
- package/dist/audio-generation/index.js.map +0 -1
- package/dist/chunk-2ODTMRHP.js +0 -54
- package/dist/chunk-2ODTMRHP.js.map +0 -1
- package/dist/chunk-ADH7NNCS.js +0 -512
- package/dist/chunk-ADH7NNCS.js.map +0 -1
- package/dist/chunk-BALBBVI3.js +0 -2732
- package/dist/chunk-BALBBVI3.js.map +0 -1
- package/dist/chunk-CWUJUSOS.js.map +0 -1
- package/dist/chunk-DALYP4PX.js +0 -225
- package/dist/chunk-DALYP4PX.js.map +0 -1
- package/dist/chunk-HYUYZEAJ.js +0 -223
- package/dist/chunk-HYUYZEAJ.js.map +0 -1
- package/dist/chunk-I6XOQ4LK.js +0 -466
- package/dist/chunk-I6XOQ4LK.js.map +0 -1
- package/dist/chunk-JI5YZWNT.js +0 -220
- package/dist/chunk-JI5YZWNT.js.map +0 -1
- package/dist/chunk-MC3CCKEB.js +0 -221
- package/dist/chunk-MC3CCKEB.js.map +0 -1
- package/dist/chunk-MELYDKWQ.js +0 -337
- package/dist/chunk-MELYDKWQ.js.map +0 -1
- package/dist/chunk-MNWK2USR.js +0 -243
- package/dist/chunk-MNWK2USR.js.map +0 -1
- package/dist/chunk-MRQLEK2B.js.map +0 -1
- package/dist/chunk-NCPN4SJR.js.map +0 -1
- package/dist/chunk-OIMLU4SF.js +0 -20
- package/dist/chunk-OIMLU4SF.js.map +0 -1
- package/dist/chunk-Q25IWLBT.js +0 -138
- package/dist/chunk-Q25IWLBT.js.map +0 -1
- package/dist/chunk-UQX6EXWG.js +0 -33
- package/dist/chunk-UQX6EXWG.js.map +0 -1
- package/dist/chunk-WQKHFADH.js +0 -12
- package/dist/chunk-WQKHFADH.js.map +0 -1
- package/dist/chunk-XUUY2L2D.js +0 -42
- package/dist/chunk-XUUY2L2D.js.map +0 -1
- package/dist/chunk-XWUC7CIT.js +0 -1
- package/dist/chunk-XWUC7CIT.js.map +0 -1
- package/dist/chunk-YLMDBQO4.js +0 -141
- package/dist/chunk-YLMDBQO4.js.map +0 -1
- package/dist/errors-2moLDuuN.d.ts +0 -17
- package/dist/hooks/index.d.ts +0 -12
- package/dist/hooks/index.js +0 -17
- package/dist/index-BxSbmOMr.d.ts +0 -257
- package/dist/json-BVPssigK.d.ts +0 -39
- package/dist/middleware-Dp3d_pxi.d.ts +0 -90
- package/dist/request/index.d.ts +0 -28
- package/dist/request/index.js +0 -25
- package/dist/request/index.js.map +0 -1
- package/dist/tool-Cohdv5GC.d.ts +0 -65
- package/dist/types-BCTRUGex.d.ts +0 -47
- package/dist/types-BrLbKnEz.d.ts +0 -119
- package/dist/types-D9JpeAPF.d.ts +0 -114
- package/dist/types-G12i56s2.d.ts +0 -354
- package/dist/types-JJCxRnaZ.d.ts +0 -70
- package/dist/types-O-abTIin.d.ts +0 -79
- package/dist/ui/index.d.ts +0 -107
- package/dist/ui/index.js +0 -10
- package/dist/ui/index.js.map +0 -1
- /package/dist/{hooks → speech-generation}/index.js.map +0 -0
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isRecord
|
|
3
|
+
} from "./chunk-CQNNSZPG.js";
|
|
4
|
+
import {
|
|
5
|
+
ToolOutput
|
|
6
|
+
} from "./chunk-77AIYARB.js";
|
|
7
|
+
import {
|
|
8
|
+
abortError,
|
|
9
|
+
throwIfAborted
|
|
10
|
+
} from "./chunk-FN7HLLAZ.js";
|
|
11
|
+
|
|
12
|
+
// src/mcp/client.ts
|
|
13
|
+
import { readFileSync } from "fs";
|
|
14
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
15
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
16
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
17
|
+
|
|
18
|
+
// src/mcp/abort.ts
|
|
19
|
+
function linkAbortSignal(source, target) {
|
|
20
|
+
if (source === void 0) {
|
|
21
|
+
return () => void 0;
|
|
22
|
+
}
|
|
23
|
+
if (source.aborted) {
|
|
24
|
+
target.abort(source.reason);
|
|
25
|
+
return () => void 0;
|
|
26
|
+
}
|
|
27
|
+
const onAbort = () => target.abort(source.reason);
|
|
28
|
+
source.addEventListener("abort", onAbort, { once: true });
|
|
29
|
+
return () => source.removeEventListener("abort", onAbort);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/mcp/result.ts
|
|
33
|
+
function createCallToolParams(name, args) {
|
|
34
|
+
if (args === null || args === void 0) {
|
|
35
|
+
return { name };
|
|
36
|
+
}
|
|
37
|
+
if (!isRecord(args)) {
|
|
38
|
+
throw new Error("MCP tool arguments must be a JSON object");
|
|
39
|
+
}
|
|
40
|
+
return { name, arguments: args };
|
|
41
|
+
}
|
|
42
|
+
function mapMcpToolResult(result) {
|
|
43
|
+
if ("toolResult" in result) {
|
|
44
|
+
return [{ type: "text", text: serializeMcpValue(result.toolResult) }];
|
|
45
|
+
}
|
|
46
|
+
if (result.isError === true) {
|
|
47
|
+
throw new Error(mcpErrorMessage(result.content));
|
|
48
|
+
}
|
|
49
|
+
const content = result.content.map(mapMcpContent);
|
|
50
|
+
if (content.length === 0 && result.structuredContent !== void 0) {
|
|
51
|
+
content.push({ type: "text", text: serializeMcpValue(result.structuredContent) });
|
|
52
|
+
}
|
|
53
|
+
return content;
|
|
54
|
+
}
|
|
55
|
+
function mcpErrorMessage(content) {
|
|
56
|
+
const text = content.map((item) => item.type === "text" ? item.text : void 0).filter((item) => item !== void 0).join("\n");
|
|
57
|
+
return text === "" ? "MCP tool returned an error" : text;
|
|
58
|
+
}
|
|
59
|
+
function mapMcpContent(content) {
|
|
60
|
+
if (content.type === "text") {
|
|
61
|
+
return { type: "text", text: content.text };
|
|
62
|
+
}
|
|
63
|
+
if (content.type === "image") {
|
|
64
|
+
return {
|
|
65
|
+
type: "file",
|
|
66
|
+
data: { type: "data", data: content.data },
|
|
67
|
+
mediaType: content.mimeType
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (content.type === "resource") {
|
|
71
|
+
return { type: "text", text: serializeResource(content.resource) };
|
|
72
|
+
}
|
|
73
|
+
if (content.type === "audio") {
|
|
74
|
+
throw new Error(`Unsupported MCP tool result content type: audio (${content.mimeType})`);
|
|
75
|
+
}
|
|
76
|
+
throw new Error(`Unsupported MCP tool result content type: resource_link (${content.uri})`);
|
|
77
|
+
}
|
|
78
|
+
function serializeResource(resource) {
|
|
79
|
+
const mediaType = resource.mimeType ?? ("text" in resource ? "text/plain" : "application/octet-stream");
|
|
80
|
+
const encoding = "text" in resource ? "text" : "base64";
|
|
81
|
+
const data = "text" in resource ? resource.text : resource.blob;
|
|
82
|
+
return `MCP resource (${resource.uri}; ${mediaType}; ${encoding})
|
|
83
|
+
${data}`;
|
|
84
|
+
}
|
|
85
|
+
function serializeMcpValue(value) {
|
|
86
|
+
if (typeof value === "string") {
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
let serialized;
|
|
90
|
+
try {
|
|
91
|
+
serialized = JSON.stringify(value);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
throw new TypeError("MCP tool results must be JSON-serializable.", { cause: error });
|
|
94
|
+
}
|
|
95
|
+
if (serialized === void 0) {
|
|
96
|
+
throw new TypeError("MCP tool results must be JSON-serializable.");
|
|
97
|
+
}
|
|
98
|
+
return serialized;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/mcp/tool.ts
|
|
102
|
+
function createMcpTool(options) {
|
|
103
|
+
const { definition, client, serverName, prefix = "" } = options;
|
|
104
|
+
const exposedName = `${prefix}${definition.name}`;
|
|
105
|
+
const provenance = Object.freeze({
|
|
106
|
+
serverName,
|
|
107
|
+
remoteName: definition.name
|
|
108
|
+
});
|
|
109
|
+
const toolDefinition = Object.freeze({
|
|
110
|
+
name: exposedName,
|
|
111
|
+
description: definition.description ?? "",
|
|
112
|
+
parameters: deepFreeze(structuredClone(definition.inputSchema))
|
|
113
|
+
});
|
|
114
|
+
const tool = {
|
|
115
|
+
name: exposedName,
|
|
116
|
+
mcp: provenance,
|
|
117
|
+
definition() {
|
|
118
|
+
return toolDefinition;
|
|
119
|
+
},
|
|
120
|
+
async call(args, context) {
|
|
121
|
+
const result = await client.callTool(
|
|
122
|
+
createCallToolParams(definition.name, args),
|
|
123
|
+
void 0,
|
|
124
|
+
context?.abortSignal === void 0 ? {} : { signal: context.abortSignal }
|
|
125
|
+
);
|
|
126
|
+
return ToolOutput.content(mapMcpToolResult(result));
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
return Object.freeze(tool);
|
|
130
|
+
}
|
|
131
|
+
function isMcpTool(tool) {
|
|
132
|
+
if (typeof tool !== "object" || tool === null || !("mcp" in tool)) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
const mcp = tool.mcp;
|
|
136
|
+
return typeof mcp === "object" && mcp !== null && "serverName" in mcp && typeof mcp.serverName === "string" && mcp.serverName.length > 0 && "remoteName" in mcp && typeof mcp.remoteName === "string" && mcp.remoteName.length > 0;
|
|
137
|
+
}
|
|
138
|
+
function deepFreeze(value) {
|
|
139
|
+
if (typeof value !== "object" || value === null || Object.isFrozen(value)) {
|
|
140
|
+
return value;
|
|
141
|
+
}
|
|
142
|
+
for (const child of Object.values(value)) {
|
|
143
|
+
deepFreeze(child);
|
|
144
|
+
}
|
|
145
|
+
return Object.freeze(value);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// src/mcp/url-safety.ts
|
|
149
|
+
import { lookup } from "dns/promises";
|
|
150
|
+
import { BlockList, isIP } from "net";
|
|
151
|
+
import { Agent, Pool, fetch as undiciFetch } from "undici";
|
|
152
|
+
var blockedIpv4Addresses = new BlockList();
|
|
153
|
+
var blockedIpv6Addresses = new BlockList();
|
|
154
|
+
for (const [network, prefix] of [
|
|
155
|
+
["0.0.0.0", 8],
|
|
156
|
+
["10.0.0.0", 8],
|
|
157
|
+
["100.64.0.0", 10],
|
|
158
|
+
["127.0.0.0", 8],
|
|
159
|
+
["169.254.0.0", 16],
|
|
160
|
+
["172.16.0.0", 12],
|
|
161
|
+
["192.0.0.0", 24],
|
|
162
|
+
["192.0.2.0", 24],
|
|
163
|
+
["192.88.99.0", 24],
|
|
164
|
+
["192.168.0.0", 16],
|
|
165
|
+
["198.18.0.0", 15],
|
|
166
|
+
["198.51.100.0", 24],
|
|
167
|
+
["203.0.113.0", 24],
|
|
168
|
+
["224.0.0.0", 4],
|
|
169
|
+
["240.0.0.0", 4]
|
|
170
|
+
]) {
|
|
171
|
+
blockedIpv4Addresses.addSubnet(network, prefix, "ipv4");
|
|
172
|
+
}
|
|
173
|
+
for (const [network, prefix] of [
|
|
174
|
+
["::", 96],
|
|
175
|
+
["::ffff:0:0", 96],
|
|
176
|
+
["64:ff9b::", 96],
|
|
177
|
+
["64:ff9b:1::", 48],
|
|
178
|
+
["100::", 64],
|
|
179
|
+
["2001::", 32],
|
|
180
|
+
["2001:2::", 48],
|
|
181
|
+
["2001:10::", 28],
|
|
182
|
+
["2001:20::", 28],
|
|
183
|
+
["2001:db8::", 32],
|
|
184
|
+
["2002::", 16],
|
|
185
|
+
["fc00::", 7],
|
|
186
|
+
["fe80::", 10],
|
|
187
|
+
["fec0::", 10],
|
|
188
|
+
["ff00::", 8]
|
|
189
|
+
]) {
|
|
190
|
+
blockedIpv6Addresses.addSubnet(network, prefix, "ipv6");
|
|
191
|
+
}
|
|
192
|
+
var defaultAddressResolver = (hostname) => lookup(hostname, { all: true, verbatim: true });
|
|
193
|
+
function parseAndValidateMcpUrl(url) {
|
|
194
|
+
let parsed;
|
|
195
|
+
try {
|
|
196
|
+
parsed = new URL(url);
|
|
197
|
+
} catch {
|
|
198
|
+
throw new Error(`Invalid MCP URL: ${url}`);
|
|
199
|
+
}
|
|
200
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
201
|
+
throw new Error(`MCP URL blocked: only HTTP(S) URLs are allowed (${parsed.protocol})`);
|
|
202
|
+
}
|
|
203
|
+
validateMcpHostname(parsed.hostname);
|
|
204
|
+
return parsed;
|
|
205
|
+
}
|
|
206
|
+
async function resolveAndValidateMcpHostname(hostname, resolveAddresses = defaultAddressResolver) {
|
|
207
|
+
const normalizedHostname = normalizeHostname(hostname);
|
|
208
|
+
validateMcpHostname(normalizedHostname);
|
|
209
|
+
const family = isIP(normalizedHostname);
|
|
210
|
+
if (family !== 0) {
|
|
211
|
+
return [{ address: normalizedHostname, family }];
|
|
212
|
+
}
|
|
213
|
+
let addresses;
|
|
214
|
+
try {
|
|
215
|
+
addresses = await resolveAddresses(normalizedHostname);
|
|
216
|
+
} catch (cause) {
|
|
217
|
+
throw new Error(`Unable to resolve MCP URL hostname (${normalizedHostname})`, { cause });
|
|
218
|
+
}
|
|
219
|
+
if (addresses.length === 0) {
|
|
220
|
+
throw new Error(`Unable to resolve MCP URL hostname (${normalizedHostname})`);
|
|
221
|
+
}
|
|
222
|
+
for (const { address } of addresses) {
|
|
223
|
+
validateMcpHostname(address);
|
|
224
|
+
}
|
|
225
|
+
return addresses;
|
|
226
|
+
}
|
|
227
|
+
function createSafeMcpLookup(resolveAddresses = defaultAddressResolver) {
|
|
228
|
+
return (hostname, options, callback) => {
|
|
229
|
+
void resolveAndValidateMcpHostname(hostname, resolveAddresses).then(
|
|
230
|
+
(addresses) => {
|
|
231
|
+
const requestedFamily = normalizeRequestedFamily(options.family);
|
|
232
|
+
const matchingAddresses = requestedFamily === 0 ? addresses : addresses.filter(({ family }) => family === requestedFamily);
|
|
233
|
+
if (matchingAddresses.length === 0) {
|
|
234
|
+
const error = new Error(`No matching address family for MCP URL (${hostname})`);
|
|
235
|
+
Object.assign(error, { code: "EAI_ADDRFAMILY" });
|
|
236
|
+
callback(error, []);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (options.all) {
|
|
240
|
+
callback(null, matchingAddresses);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const address = matchingAddresses[0];
|
|
244
|
+
if (!address) {
|
|
245
|
+
callback(new Error(`Unable to resolve MCP URL hostname (${hostname})`), []);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
callback(null, address.address, address.family);
|
|
249
|
+
},
|
|
250
|
+
(cause) => {
|
|
251
|
+
callback(asError(cause), []);
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function createSafeMcpFetch() {
|
|
257
|
+
return (url, init) => {
|
|
258
|
+
parseAndValidateMcpUrl(url);
|
|
259
|
+
return undiciFetch(url, {
|
|
260
|
+
...init,
|
|
261
|
+
dispatcher: safeMcpDispatcher
|
|
262
|
+
});
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
function validateMcpHostname(hostname) {
|
|
266
|
+
const normalizedHostname = normalizeHostname(hostname);
|
|
267
|
+
if (normalizedHostname === "localhost" || normalizedHostname.endsWith(".localhost")) {
|
|
268
|
+
throw new Error(`MCP URL blocked: localhost not allowed (${normalizedHostname})`);
|
|
269
|
+
}
|
|
270
|
+
const family = isIP(normalizedHostname);
|
|
271
|
+
if (family === 0) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
if (family === 4 && normalizedHostname.startsWith("127.") || family === 6 && normalizedHostname === "::1") {
|
|
275
|
+
throw new Error(`MCP URL blocked: localhost not allowed (${normalizedHostname})`);
|
|
276
|
+
}
|
|
277
|
+
if (normalizedHostname === "169.254.169.254" || normalizedHostname === "fd00:ec2::254") {
|
|
278
|
+
throw new Error(`MCP URL blocked: cloud metadata endpoint not allowed (${normalizedHostname})`);
|
|
279
|
+
}
|
|
280
|
+
if (family === 4 && blockedIpv4Addresses.check(normalizedHostname, "ipv4") || family === 6 && blockedIpv6Addresses.check(normalizedHostname, "ipv6")) {
|
|
281
|
+
const range = family === 4 ? "IP" : "IPv6";
|
|
282
|
+
throw new Error(`MCP URL blocked: private ${range} range not allowed (${normalizedHostname})`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function normalizeHostname(hostname) {
|
|
286
|
+
const withoutBrackets = hostname.startsWith("[") && hostname.endsWith("]") ? hostname.slice(1, -1) : hostname;
|
|
287
|
+
return withoutBrackets.toLowerCase().replace(/\.+$/, "");
|
|
288
|
+
}
|
|
289
|
+
function normalizeRequestedFamily(family) {
|
|
290
|
+
if (family === 4 || family === "IPv4") {
|
|
291
|
+
return 4;
|
|
292
|
+
}
|
|
293
|
+
if (family === 6 || family === "IPv6") {
|
|
294
|
+
return 6;
|
|
295
|
+
}
|
|
296
|
+
return 0;
|
|
297
|
+
}
|
|
298
|
+
function asError(cause) {
|
|
299
|
+
return cause instanceof Error ? cause : new Error(String(cause));
|
|
300
|
+
}
|
|
301
|
+
var safeMcpDispatcher = new Agent({
|
|
302
|
+
autoSelectFamily: true,
|
|
303
|
+
connect: {
|
|
304
|
+
lookup: createSafeMcpLookup()
|
|
305
|
+
},
|
|
306
|
+
factory(origin, options) {
|
|
307
|
+
parseAndValidateMcpUrl(origin);
|
|
308
|
+
return new Pool(origin, options);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// src/mcp/client.ts
|
|
313
|
+
var coreClientVersion;
|
|
314
|
+
var McpClient = class {
|
|
315
|
+
name;
|
|
316
|
+
#options;
|
|
317
|
+
#closed = false;
|
|
318
|
+
#connectAbortController;
|
|
319
|
+
#connecting;
|
|
320
|
+
#resource;
|
|
321
|
+
#server;
|
|
322
|
+
constructor(options) {
|
|
323
|
+
if (options.name.trim() === "") {
|
|
324
|
+
throw new TypeError("MCP client name must not be empty");
|
|
325
|
+
}
|
|
326
|
+
this.name = options.name;
|
|
327
|
+
this.#options = options;
|
|
328
|
+
}
|
|
329
|
+
connect(options = {}) {
|
|
330
|
+
if (this.#closed) {
|
|
331
|
+
return Promise.reject(new Error(`MCP client "${this.name}" is closed`));
|
|
332
|
+
}
|
|
333
|
+
if (this.#server !== void 0) {
|
|
334
|
+
return Promise.resolve(this.#server);
|
|
335
|
+
}
|
|
336
|
+
if (this.#connecting !== void 0) {
|
|
337
|
+
return this.#connecting;
|
|
338
|
+
}
|
|
339
|
+
if (options.abortSignal?.aborted === true) {
|
|
340
|
+
return Promise.reject(abortError(options.abortSignal.reason));
|
|
341
|
+
}
|
|
342
|
+
const abortController = new AbortController();
|
|
343
|
+
const unlinkAbortSignal = linkAbortSignal(options.abortSignal, abortController);
|
|
344
|
+
this.#connectAbortController = abortController;
|
|
345
|
+
const connecting = this.#initialize(abortController.signal);
|
|
346
|
+
this.#connecting = connecting;
|
|
347
|
+
const clearConnecting = () => {
|
|
348
|
+
unlinkAbortSignal();
|
|
349
|
+
if (this.#connecting === connecting) {
|
|
350
|
+
this.#connecting = void 0;
|
|
351
|
+
}
|
|
352
|
+
if (this.#connectAbortController === abortController) {
|
|
353
|
+
this.#connectAbortController = void 0;
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
void connecting.then(clearConnecting, clearConnecting);
|
|
357
|
+
return connecting;
|
|
358
|
+
}
|
|
359
|
+
async close() {
|
|
360
|
+
this.#closed = true;
|
|
361
|
+
this.#connectAbortController?.abort(
|
|
362
|
+
abortError(new Error(`MCP client "${this.name}" was closed during connection`))
|
|
363
|
+
);
|
|
364
|
+
const resource = this.#resource;
|
|
365
|
+
if (resource !== void 0) {
|
|
366
|
+
await closeResource(resource);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
async #initialize(abortSignal) {
|
|
370
|
+
const client = createSdkClient();
|
|
371
|
+
const resource = { client };
|
|
372
|
+
this.#resource = resource;
|
|
373
|
+
try {
|
|
374
|
+
throwIfAborted(abortSignal);
|
|
375
|
+
const transport = await createTransport(this.#options, { abortSignal });
|
|
376
|
+
throwIfAborted(abortSignal);
|
|
377
|
+
await client.connect(transport, requestOptions(abortSignal));
|
|
378
|
+
throwIfAborted(abortSignal);
|
|
379
|
+
const definitions = await listAllTools(client, abortSignal);
|
|
380
|
+
throwIfAborted(abortSignal);
|
|
381
|
+
const tools = definitions.map(
|
|
382
|
+
(definition) => createMcpTool({
|
|
383
|
+
definition,
|
|
384
|
+
client,
|
|
385
|
+
serverName: this.name,
|
|
386
|
+
prefix: this.#options.tools?.prefix
|
|
387
|
+
})
|
|
388
|
+
);
|
|
389
|
+
assertUniqueToolNames(tools, this.name);
|
|
390
|
+
if (this.#closed) {
|
|
391
|
+
throw new Error(`MCP client "${this.name}" was closed during connection`);
|
|
392
|
+
}
|
|
393
|
+
const serverInfo = copyServerInfo(client.getServerVersion());
|
|
394
|
+
const capabilities = copyJsonObject(client.getServerCapabilities());
|
|
395
|
+
const instructions = client.getInstructions();
|
|
396
|
+
const server = freezeServer({
|
|
397
|
+
name: this.name,
|
|
398
|
+
tools,
|
|
399
|
+
...serverInfo === void 0 ? {} : { serverInfo },
|
|
400
|
+
...capabilities === void 0 ? {} : { capabilities },
|
|
401
|
+
...instructions === void 0 ? {} : { instructions }
|
|
402
|
+
});
|
|
403
|
+
this.#server = server;
|
|
404
|
+
return server;
|
|
405
|
+
} catch (error) {
|
|
406
|
+
try {
|
|
407
|
+
await closeResource(resource);
|
|
408
|
+
} catch {
|
|
409
|
+
}
|
|
410
|
+
if (this.#resource === resource) {
|
|
411
|
+
this.#resource = void 0;
|
|
412
|
+
}
|
|
413
|
+
this.#server = void 0;
|
|
414
|
+
throw error;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
async function createTransport(options, connectOptions) {
|
|
419
|
+
const transport = options.transport;
|
|
420
|
+
if (transport.type === "custom") {
|
|
421
|
+
return transport.create({ abortSignal: connectOptions.abortSignal });
|
|
422
|
+
}
|
|
423
|
+
if (transport.type === "stdio") {
|
|
424
|
+
return new StdioClientTransport({
|
|
425
|
+
command: transport.command,
|
|
426
|
+
...transport.args === void 0 ? {} : { args: transport.args },
|
|
427
|
+
...transport.env === void 0 ? {} : { env: transport.env },
|
|
428
|
+
...transport.cwd === void 0 ? {} : { cwd: transport.cwd },
|
|
429
|
+
...transport.stderr === void 0 ? {} : { stderr: transport.stderr },
|
|
430
|
+
...transport.maxBufferSize === void 0 ? {} : { maxBufferSize: transport.maxBufferSize }
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
return asSdkTransport(
|
|
434
|
+
new StreamableHTTPClientTransport(parseAndValidateMcpUrl(transport.url), {
|
|
435
|
+
...transport.requestInit === void 0 ? {} : { requestInit: transport.requestInit },
|
|
436
|
+
...transport.authProvider === void 0 ? {} : { authProvider: transport.authProvider },
|
|
437
|
+
...transport.reconnectionOptions === void 0 ? {} : { reconnectionOptions: transport.reconnectionOptions },
|
|
438
|
+
...transport.sessionId === void 0 ? {} : { sessionId: transport.sessionId },
|
|
439
|
+
fetch: createSafeMcpFetch()
|
|
440
|
+
})
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
async function listAllTools(client, abortSignal) {
|
|
444
|
+
const tools = [];
|
|
445
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
446
|
+
let cursor;
|
|
447
|
+
do {
|
|
448
|
+
const page = await client.listTools(
|
|
449
|
+
cursor === void 0 ? void 0 : { cursor },
|
|
450
|
+
requestOptions(abortSignal)
|
|
451
|
+
);
|
|
452
|
+
tools.push(...page.tools);
|
|
453
|
+
cursor = page.nextCursor;
|
|
454
|
+
if (cursor !== void 0 && seenCursors.has(cursor)) {
|
|
455
|
+
throw new Error(`MCP server returned a repeated tools cursor: ${cursor}`);
|
|
456
|
+
}
|
|
457
|
+
if (cursor !== void 0) {
|
|
458
|
+
seenCursors.add(cursor);
|
|
459
|
+
}
|
|
460
|
+
} while (cursor !== void 0);
|
|
461
|
+
return tools;
|
|
462
|
+
}
|
|
463
|
+
function assertUniqueToolNames(tools, serverName) {
|
|
464
|
+
const names = /* @__PURE__ */ new Set();
|
|
465
|
+
for (const tool of tools) {
|
|
466
|
+
if (names.has(tool.name)) {
|
|
467
|
+
throw new Error(`Duplicate MCP tool name "${tool.name}" from server "${serverName}"`);
|
|
468
|
+
}
|
|
469
|
+
names.add(tool.name);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function createSdkClient() {
|
|
473
|
+
return new Client({
|
|
474
|
+
name: "@anvia/core",
|
|
475
|
+
version: getCoreClientVersion()
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
function getCoreClientVersion() {
|
|
479
|
+
if (coreClientVersion === void 0) {
|
|
480
|
+
coreClientVersion = readCorePackageVersion();
|
|
481
|
+
}
|
|
482
|
+
return coreClientVersion;
|
|
483
|
+
}
|
|
484
|
+
function requestOptions(signal) {
|
|
485
|
+
return signal === void 0 ? {} : { signal };
|
|
486
|
+
}
|
|
487
|
+
function asSdkTransport(transport) {
|
|
488
|
+
return transport;
|
|
489
|
+
}
|
|
490
|
+
function closeResource(resource) {
|
|
491
|
+
resource.closePromise ??= resource.client.close();
|
|
492
|
+
return resource.closePromise;
|
|
493
|
+
}
|
|
494
|
+
function readCorePackageVersion() {
|
|
495
|
+
try {
|
|
496
|
+
const packageJson = JSON.parse(
|
|
497
|
+
readFileSync(new URL("../../package.json", import.meta.url), "utf8")
|
|
498
|
+
);
|
|
499
|
+
return typeof packageJson.version === "string" ? packageJson.version : "0.0.0";
|
|
500
|
+
} catch {
|
|
501
|
+
return "0.0.0";
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function copyServerInfo(value) {
|
|
505
|
+
if (value === void 0) {
|
|
506
|
+
return void 0;
|
|
507
|
+
}
|
|
508
|
+
return deepFreeze2(structuredClone(value));
|
|
509
|
+
}
|
|
510
|
+
function copyJsonObject(value) {
|
|
511
|
+
if (value === void 0) {
|
|
512
|
+
return void 0;
|
|
513
|
+
}
|
|
514
|
+
return deepFreeze2(structuredClone(value));
|
|
515
|
+
}
|
|
516
|
+
function freezeServer(server) {
|
|
517
|
+
Object.freeze(server.tools);
|
|
518
|
+
return Object.freeze(server);
|
|
519
|
+
}
|
|
520
|
+
function deepFreeze2(value) {
|
|
521
|
+
if (typeof value !== "object" || value === null || Object.isFrozen(value)) {
|
|
522
|
+
return value;
|
|
523
|
+
}
|
|
524
|
+
for (const child of Object.values(value)) {
|
|
525
|
+
deepFreeze2(child);
|
|
526
|
+
}
|
|
527
|
+
return Object.freeze(value);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// src/mcp/client-group.ts
|
|
531
|
+
var McpClientGroup = class _McpClientGroup {
|
|
532
|
+
clients;
|
|
533
|
+
servers;
|
|
534
|
+
#closePromise;
|
|
535
|
+
constructor(clients, servers) {
|
|
536
|
+
this.clients = Object.freeze([...clients]);
|
|
537
|
+
this.servers = Object.freeze([...servers]);
|
|
538
|
+
}
|
|
539
|
+
static async connect(options) {
|
|
540
|
+
const clients = [...options.clients];
|
|
541
|
+
assertUniqueClientNames(clients);
|
|
542
|
+
const abortController = new AbortController();
|
|
543
|
+
const unlinkAbortSignal = linkAbortSignal(options.abortSignal, abortController);
|
|
544
|
+
let firstConnectionFailure;
|
|
545
|
+
let connectionFailed = false;
|
|
546
|
+
const connections = clients.map(
|
|
547
|
+
(client) => client.connect({ abortSignal: abortController.signal }).catch((error) => {
|
|
548
|
+
if (!connectionFailed) {
|
|
549
|
+
connectionFailed = true;
|
|
550
|
+
firstConnectionFailure = error;
|
|
551
|
+
abortController.abort(error);
|
|
552
|
+
}
|
|
553
|
+
throw error;
|
|
554
|
+
})
|
|
555
|
+
);
|
|
556
|
+
const settled = await Promise.allSettled(connections).finally(unlinkAbortSignal);
|
|
557
|
+
const firstFailure = settled.find(
|
|
558
|
+
(result) => result.status === "rejected"
|
|
559
|
+
);
|
|
560
|
+
if (firstFailure !== void 0) {
|
|
561
|
+
await rollbackSuccessfulClients(clients, settled);
|
|
562
|
+
throw connectionFailed ? firstConnectionFailure : firstFailure.reason;
|
|
563
|
+
}
|
|
564
|
+
const servers = settled.map((result) => result.value);
|
|
565
|
+
try {
|
|
566
|
+
assertUniqueServerAndToolNames(servers);
|
|
567
|
+
} catch (error) {
|
|
568
|
+
try {
|
|
569
|
+
await closeAll(clients);
|
|
570
|
+
} catch {
|
|
571
|
+
}
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
574
|
+
return new _McpClientGroup(clients, servers);
|
|
575
|
+
}
|
|
576
|
+
close() {
|
|
577
|
+
this.#closePromise ??= closeAll(this.clients);
|
|
578
|
+
return this.#closePromise;
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
function assertUniqueClientNames(clients) {
|
|
582
|
+
const names = /* @__PURE__ */ new Set();
|
|
583
|
+
for (const client of clients) {
|
|
584
|
+
if (names.has(client.name)) {
|
|
585
|
+
throw new Error(`Duplicate MCP client name "${client.name}"`);
|
|
586
|
+
}
|
|
587
|
+
names.add(client.name);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
function assertUniqueServerAndToolNames(servers) {
|
|
591
|
+
const serverNames = /* @__PURE__ */ new Set();
|
|
592
|
+
const toolNames = /* @__PURE__ */ new Map();
|
|
593
|
+
for (const server of servers) {
|
|
594
|
+
if (serverNames.has(server.name)) {
|
|
595
|
+
throw new Error(`Duplicate MCP server name "${server.name}"`);
|
|
596
|
+
}
|
|
597
|
+
serverNames.add(server.name);
|
|
598
|
+
for (const tool of server.tools) {
|
|
599
|
+
const existing = toolNames.get(tool.name);
|
|
600
|
+
if (existing !== void 0) {
|
|
601
|
+
throw new Error(
|
|
602
|
+
`Duplicate MCP tool name "${tool.name}" from servers "${existing}" and "${server.name}"`
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
toolNames.set(tool.name, server.name);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
async function rollbackSuccessfulClients(clients, settled) {
|
|
610
|
+
const successful = clients.filter((_, index) => settled[index]?.status === "fulfilled");
|
|
611
|
+
try {
|
|
612
|
+
await closeAll(successful);
|
|
613
|
+
} catch {
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
async function closeAll(clients) {
|
|
617
|
+
const settled = await Promise.allSettled(clients.map((client) => client.close()));
|
|
618
|
+
const errors = settled.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
619
|
+
if (errors.length > 0) {
|
|
620
|
+
throw new AggregateError(errors, "Failed to close one or more MCP clients");
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export {
|
|
625
|
+
isMcpTool,
|
|
626
|
+
McpClient,
|
|
627
|
+
McpClientGroup
|
|
628
|
+
};
|
|
629
|
+
//# sourceMappingURL=chunk-EINTGEGY.js.map
|