@n8n/n8n-nodes-langchain
Version:

231 lines • 7.7 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var utils_exports = {};
__export(utils_exports, {
connectMcpClient: () => connectMcpClient,
getAllTools: () => getAllTools,
getAuthHeaders: () => getAuthHeaders,
mapToNodeOperationError: () => mapToNodeOperationError,
tryRefreshOAuth2Token: () => tryRefreshOAuth2Token
});
module.exports = __toCommonJS(utils_exports);
var import_client = require("@modelcontextprotocol/sdk/client/index.js");
var import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
var import_n8n_workflow = require("n8n-workflow");
var import_httpProxyAgent = require("../../../utils/httpProxyAgent");
async function getAllTools(client, cursor) {
const { tools, nextCursor } = await client.listTools({ cursor });
if (nextCursor) {
return tools.concat(await getAllTools(client, nextCursor));
}
return tools;
}
function safeCreateUrl(url, baseUrl) {
try {
return (0, import_n8n_workflow.createResultOk)(new URL(url, baseUrl));
} catch (error) {
return (0, import_n8n_workflow.createResultError)(error);
}
}
function normalizeAndValidateUrl(input) {
const withProtocol = !/^https?:\/\//i.test(input) ? `https://${input}` : input;
const parsedUrl = safeCreateUrl(withProtocol);
if (!parsedUrl.ok) {
return (0, import_n8n_workflow.createResultError)(parsedUrl.error);
}
return parsedUrl;
}
function errorHasCode(error, code) {
return !!error && typeof error === "object" && ("code" in error && Number(error.code) === code || "message" in error && typeof error.message === "string" && error.message.includes(code.toString()));
}
function isUnauthorizedError(error) {
return errorHasCode(error, 401);
}
function isForbiddenError(error) {
return errorHasCode(error, 403);
}
function mapToNodeOperationError(node, error) {
switch (error.type) {
case "invalid_url":
return new import_n8n_workflow.NodeOperationError(node, error.error, {
message: "Could not connect to your MCP server. The provided URL is invalid."
});
case "auth":
return new import_n8n_workflow.NodeOperationError(node, error.error, {
message: "Could not connect to your MCP server. Authentication failed."
});
case "connection":
default:
return new import_n8n_workflow.NodeOperationError(node, error.error, {
message: "Could not connect to your MCP server"
});
}
}
async function connectMcpClient({
headers,
serverTransport,
endpointUrl,
name,
version,
onUnauthorized
}) {
const endpoint = normalizeAndValidateUrl(endpointUrl);
if (!endpoint.ok) {
return (0, import_n8n_workflow.createResultError)({ type: "invalid_url", error: endpoint.error });
}
const client = new import_client.Client({ name, version: version.toString() }, { capabilities: {} });
if (serverTransport === "httpStreamable") {
try {
const transport = new import_streamableHttp.StreamableHTTPClientTransport(endpoint.result, {
requestInit: { headers },
fetch: import_httpProxyAgent.proxyFetch
});
await client.connect(transport);
return (0, import_n8n_workflow.createResultOk)(client);
} catch (error) {
if (onUnauthorized && isUnauthorizedError(error)) {
const newHeaders = await onUnauthorized(headers);
if (newHeaders) {
return await connectMcpClient({
headers: newHeaders,
serverTransport,
endpointUrl,
name,
version
});
}
}
if (isUnauthorizedError(error) || isForbiddenError(error)) {
return (0, import_n8n_workflow.createResultError)({ type: "auth", error });
} else {
return (0, import_n8n_workflow.createResultError)({ type: "connection", error });
}
}
}
try {
const sseTransport = new import_sse.SSEClientTransport(endpoint.result, {
eventSourceInit: {
fetch: async (url, init) => await (0, import_httpProxyAgent.proxyFetch)(url, {
...init,
headers: {
...headers,
Accept: "text/event-stream"
}
})
},
fetch: import_httpProxyAgent.proxyFetch,
requestInit: { headers }
});
await client.connect(sseTransport);
return (0, import_n8n_workflow.createResultOk)(client);
} catch (error) {
if (onUnauthorized && isUnauthorizedError(error)) {
const newHeaders = await onUnauthorized(headers);
if (newHeaders) {
return await connectMcpClient({
headers: newHeaders,
serverTransport,
endpointUrl,
name,
version
});
}
}
if (isUnauthorizedError(error) || isForbiddenError(error)) {
return (0, import_n8n_workflow.createResultError)({ type: "auth", error });
} else {
return (0, import_n8n_workflow.createResultError)({ type: "connection", error });
}
}
}
async function getAuthHeaders(ctx, authentication) {
switch (authentication) {
case "headerAuth": {
const header = await ctx.getCredentials("httpHeaderAuth").catch(() => null);
if (!header) return {};
return { headers: { [header.name]: header.value } };
}
case "bearerAuth": {
const result = await ctx.getCredentials("httpBearerAuth").catch(() => null);
if (!result) return {};
return { headers: { Authorization: `Bearer ${result.token}` } };
}
case "mcpOAuth2Api": {
const result = await ctx.getCredentials("mcpOAuth2Api").catch(() => null);
if (!result) return {};
return { headers: { Authorization: `Bearer ${result.oauthTokenData.access_token}` } };
}
case "multipleHeadersAuth": {
const result = await ctx.getCredentials(
"httpMultipleHeadersAuth"
).catch(() => null);
if (!result) return {};
return {
headers: result.headers.values.reduce(
(acc, cur) => {
acc[cur.name] = cur.value;
return acc;
},
{}
)
};
}
case "none":
default: {
return {};
}
}
}
async function tryRefreshOAuth2Token(ctx, authentication, headers) {
if (authentication !== "mcpOAuth2Api") {
return null;
}
let access_token = null;
try {
const result = await ctx.helpers.refreshOAuth2Token.call(
ctx,
"mcpOAuth2Api"
);
access_token = result?.access_token;
} catch (error) {
return null;
}
if (!access_token) {
return null;
}
if (!headers) {
return {
Authorization: `Bearer ${access_token}`
};
}
return {
...headers,
Authorization: `Bearer ${access_token}`
};
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
connectMcpClient,
getAllTools,
getAuthHeaders,
mapToNodeOperationError,
tryRefreshOAuth2Token
});
//# sourceMappingURL=utils.js.map