"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var McpClientTool_node_exports = {};
__export(McpClientTool_node_exports, {
  McpClientTool: () => McpClientTool
});
module.exports = __toCommonJS(McpClientTool_node_exports);
var import_types = require("@modelcontextprotocol/sdk/types.js");
var import_n8n_workflow = require("n8n-workflow");
var import_logWrapper = require("../../../utils/logWrapper");
var import_sharedFields = require("../../../utils/sharedFields");
var import_loadOptions = require("./loadOptions");
var import_utils = require("./utils");
var import_descriptions = require("../shared/descriptions");
var import_utils2 = require("../shared/utils");
var import_pick = __toESM(require("lodash/pick"));
function getNodeConfig(ctx, itemIndex) {
  const node = ctx.getNode();
  const authentication = ctx.getNodeParameter(
    "authentication",
    itemIndex
  );
  const timeout = ctx.getNodeParameter("options.timeout", itemIndex, 6e4);
  let serverTransport;
  let endpointUrl;
  if (node.typeVersion === 1) {
    serverTransport = "sse";
    endpointUrl = ctx.getNodeParameter("sseEndpoint", itemIndex);
  } else {
    serverTransport = ctx.getNodeParameter("serverTransport", itemIndex);
    endpointUrl = ctx.getNodeParameter("endpointUrl", itemIndex);
  }
  const mode = ctx.getNodeParameter("include", itemIndex);
  const includeTools = ctx.getNodeParameter("includeTools", itemIndex, []);
  const excludeTools = ctx.getNodeParameter("excludeTools", itemIndex, []);
  return {
    authentication,
    timeout,
    serverTransport,
    endpointUrl,
    mode,
    includeTools,
    excludeTools
  };
}
async function connectAndGetTools(ctx, config) {
  const node = ctx.getNode();
  const { headers } = await (0, import_utils2.getAuthHeaders)(ctx, config.authentication);
  const client = await (0, import_utils2.connectMcpClient)({
    serverTransport: config.serverTransport,
    endpointUrl: config.endpointUrl,
    headers,
    name: node.type,
    version: node.typeVersion,
    onUnauthorized: async (headers2) => await (0, import_utils2.tryRefreshOAuth2Token)(ctx, config.authentication, headers2)
  });
  if (!client.ok) {
    return { client, mcpTools: null, error: client.error };
  }
  const allTools = await (0, import_utils2.getAllTools)(client.result);
  const mcpTools = (0, import_utils.getSelectedTools)({
    tools: allTools,
    mode: config.mode,
    includeTools: config.includeTools,
    excludeTools: config.excludeTools
  });
  return { client: client.result, mcpTools, error: null };
}
class McpClientTool {
  constructor() {
    this.description = {
      displayName: "MCP Client Tool",
      name: "mcpClientTool",
      icon: {
        light: "file:../mcp.svg",
        dark: "file:../mcp.dark.svg"
      },
      group: ["output"],
      version: [1, 1.1, 1.2],
      description: "Connect tools from an MCP Server",
      defaults: {
        name: "MCP Client"
      },
      codex: {
        categories: ["AI"],
        subcategories: {
          AI: ["Model Context Protocol", "Tools"]
        },
        alias: ["Model Context Protocol", "MCP Client"],
        resources: {
          primaryDocumentation: [
            {
              url: "https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolmcp/"
            }
          ]
        }
      },
      inputs: [],
      outputs: [{ type: import_n8n_workflow.NodeConnectionTypes.AiTool, displayName: "Tools" }],
      credentials: import_descriptions.credentials,
      properties: [
        (0, import_sharedFields.getConnectionHintNoticeField)([import_n8n_workflow.NodeConnectionTypes.AiAgent]),
        {
          displayName: "SSE Endpoint",
          name: "sseEndpoint",
          type: "string",
          description: "SSE Endpoint of your MCP server",
          placeholder: "e.g. https://my-mcp-server.ai/sse",
          default: "",
          required: true,
          displayOptions: {
            show: {
              "@version": [1]
            }
          }
        },
        {
          displayName: "Endpoint",
          name: "endpointUrl",
          type: "string",
          description: "Endpoint of your MCP server",
          placeholder: "e.g. https://my-mcp-server.ai/mcp",
          default: "",
          required: true,
          displayOptions: {
            show: {
              "@version": [{ _cnd: { gte: 1.1 } }]
            }
          }
        },
        (0, import_descriptions.transportSelect)({
          defaultOption: "sse",
          displayOptions: {
            show: {
              "@version": [1.1]
            }
          }
        }),
        (0, import_descriptions.transportSelect)({
          defaultOption: "httpStreamable",
          displayOptions: {
            show: {
              "@version": [{ _cnd: { gte: 1.2 } }]
            }
          }
        }),
        {
          displayName: "Authentication",
          name: "authentication",
          type: "options",
          options: [
            {
              name: "Bearer Auth",
              value: "bearerAuth"
            },
            {
              name: "Header Auth",
              value: "headerAuth"
            },
            {
              name: "None",
              value: "none"
            }
          ],
          default: "none",
          description: "The way to authenticate with your endpoint",
          displayOptions: {
            show: {
              "@version": [{ _cnd: { lt: 1.2 } }]
            }
          }
        },
        {
          displayName: "Authentication",
          name: "authentication",
          type: "options",
          options: [
            {
              name: "Bearer Auth",
              value: "bearerAuth"
            },
            {
              name: "Header Auth",
              value: "headerAuth"
            },
            {
              name: "MCP OAuth2",
              value: "mcpOAuth2Api"
            },
            {
              name: "Multiple Headers Auth",
              value: "multipleHeadersAuth"
            },
            {
              name: "None",
              value: "none"
            }
          ],
          default: "none",
          description: "The way to authenticate with your endpoint",
          displayOptions: {
            show: {
              "@version": [{ _cnd: { gte: 1.2 } }]
            }
          }
        },
        {
          displayName: "Credentials",
          name: "credentials",
          type: "credentials",
          default: "",
          displayOptions: {
            show: {
              authentication: ["headerAuth", "bearerAuth", "mcpOAuth2Api", "multipleHeadersAuth"]
            }
          }
        },
        {
          displayName: "Tools to Include",
          name: "include",
          type: "options",
          description: "How to select the tools you want to be exposed to the AI Agent",
          default: "all",
          options: [
            {
              name: "All",
              value: "all",
              description: "Also include all unchanged fields from the input"
            },
            {
              name: "Selected",
              value: "selected",
              description: 'Also include the tools listed in the parameter "Tools to Include"'
            },
            {
              name: "All Except",
              value: "except",
              description: 'Exclude the tools listed in the parameter "Tools to Exclude"'
            }
          ]
        },
        {
          displayName: "Tools to Include",
          name: "includeTools",
          type: "multiOptions",
          default: [],
          description: 'Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
          typeOptions: {
            loadOptionsMethod: "getTools",
            loadOptionsDependsOn: ["sseEndpoint"]
          },
          displayOptions: {
            show: {
              include: ["selected"]
            }
          }
        },
        {
          displayName: "Tools to Exclude",
          name: "excludeTools",
          type: "multiOptions",
          default: [],
          description: 'Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
          typeOptions: {
            loadOptionsMethod: "getTools"
          },
          displayOptions: {
            show: {
              include: ["except"]
            }
          }
        },
        {
          displayName: "Options",
          name: "options",
          placeholder: "Add Option",
          description: "Additional options to add",
          type: "collection",
          default: {},
          options: [
            {
              displayName: "Timeout",
              name: "timeout",
              type: "number",
              typeOptions: {
                minValue: 1
              },
              default: 6e4,
              description: "Time in ms to wait for tool calls to finish"
            }
          ]
        }
      ]
    };
    this.methods = {
      loadOptions: {
        getTools: import_loadOptions.getTools
      }
    };
  }
  async supplyData(itemIndex) {
    const node = this.getNode();
    const config = getNodeConfig(this, itemIndex);
    const setError = (error2) => {
      this.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, itemIndex, error2);
      throw error2;
    };
    const { client, mcpTools, error } = await connectAndGetTools(this, config);
    if (error) {
      this.logger.error("McpClientTool: Failed to connect to MCP Server", { error });
      return setError((0, import_utils2.mapToNodeOperationError)(node, error));
    }
    this.logger.debug("McpClientTool: Successfully connected to MCP Server");
    if (!mcpTools?.length) {
      return setError(
        new import_n8n_workflow.NodeOperationError(node, "MCP Server returned no tools", {
          itemIndex,
          description: "Connected successfully to your MCP server but it returned an empty list of tools."
        })
      );
    }
    const tools = mcpTools.map(
      (tool) => (0, import_logWrapper.logWrapper)(
        (0, import_utils.mcpToolToDynamicTool)(
          tool,
          (0, import_utils.createCallTool)(tool.name, client, config.timeout, (errorMessage) => {
            const error2 = new import_n8n_workflow.NodeOperationError(node, errorMessage, { itemIndex });
            void this.addOutputData(import_n8n_workflow.NodeConnectionTypes.AiTool, itemIndex, error2);
            this.logger.error(`McpClientTool: Tool "${tool.name}" failed to execute`, { error: error2 });
          })
        ),
        this
      )
    );
    this.logger.debug(`McpClientTool: Connected to MCP Server with ${tools.length} tools`);
    const toolkit = new import_utils.McpToolkit(tools);
    return { response: toolkit, closeFunction: async () => await client.close() };
  }
  async execute() {
    const node = this.getNode();
    const items = this.getInputData();
    const returnData = [];
    for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
      const item = items[itemIndex];
      const config = getNodeConfig(this, itemIndex);
      const { client, mcpTools, error } = await connectAndGetTools(this, config);
      if (error) {
        throw new import_n8n_workflow.NodeOperationError(node, error.error, { itemIndex });
      }
      if (!mcpTools?.length) {
        throw new import_n8n_workflow.NodeOperationError(node, "MCP Server returned no tools", { itemIndex });
      }
      for (const tool of mcpTools) {
        if (!item.json.tool || typeof item.json.tool !== "string") {
          throw new import_n8n_workflow.NodeOperationError(node, "Tool name not found in item.json.tool or item.tool", {
            itemIndex
          });
        }
        const toolName = item.json.tool;
        if (toolName === tool.name) {
          const { tool: _, ...toolArguments } = item.json;
          const schema = tool.inputSchema;
          const sanitizedToolArguments = schema.additionalProperties !== true ? (0, import_pick.default)(toolArguments, Object.keys(schema.properties ?? {})) : toolArguments;
          const params = {
            name: tool.name,
            arguments: sanitizedToolArguments
          };
          const result = await client.callTool(params, import_types.CallToolResultSchema, {
            timeout: config.timeout
          });
          returnData.push({
            json: {
              response: result.content
            },
            pairedItem: {
              item: itemIndex
            }
          });
        }
      }
    }
    return [returnData];
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  McpClientTool
});
//# sourceMappingURL=McpClientTool.node.js.map