mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 11:22:15 +00:00
feat(MCP Client Tool Node): Add support for HTTP Streamable Transport (#15454)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { DynamicStructuredTool, type DynamicStructuredToolInput } from '@langchain/core/tools';
|
||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
||||
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
||||
import { CompatibilityCallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { Toolkit } from 'langchain/agents';
|
||||
import {
|
||||
@@ -14,7 +15,12 @@ import { z } from 'zod';
|
||||
|
||||
import { convertJsonSchemaToZod } from '@utils/schemaParsing';
|
||||
|
||||
import type { McpAuthenticationOption, McpTool, McpToolIncludeMode } from './types';
|
||||
import type {
|
||||
McpAuthenticationOption,
|
||||
McpTool,
|
||||
McpServerTransport,
|
||||
McpToolIncludeMode,
|
||||
} from './types';
|
||||
|
||||
export async function getAllTools(client: Client, cursor?: string): Promise<McpTool[]> {
|
||||
const { tools, nextCursor } = await client.listTools({ cursor });
|
||||
@@ -145,23 +151,39 @@ type ConnectMcpClientError =
|
||||
| { type: 'connection'; error: Error };
|
||||
export async function connectMcpClient({
|
||||
headers,
|
||||
sseEndpoint,
|
||||
serverTransport,
|
||||
endpointUrl,
|
||||
name,
|
||||
version,
|
||||
}: {
|
||||
sseEndpoint: string;
|
||||
serverTransport: McpServerTransport;
|
||||
endpointUrl: string;
|
||||
headers?: Record<string, string>;
|
||||
name: string;
|
||||
version: number;
|
||||
}): Promise<Result<Client, ConnectMcpClientError>> {
|
||||
try {
|
||||
const endpoint = normalizeAndValidateUrl(sseEndpoint);
|
||||
const endpoint = normalizeAndValidateUrl(endpointUrl);
|
||||
|
||||
if (!endpoint.ok) {
|
||||
return createResultError({ type: 'invalid_url', error: endpoint.error });
|
||||
if (!endpoint.ok) {
|
||||
return createResultError({ type: 'invalid_url', error: endpoint.error });
|
||||
}
|
||||
|
||||
const client = new Client({ name, version: version.toString() }, { capabilities: { tools: {} } });
|
||||
|
||||
if (serverTransport === 'httpStreamable') {
|
||||
try {
|
||||
const transport = new StreamableHTTPClientTransport(endpoint.result, {
|
||||
requestInit: { headers },
|
||||
});
|
||||
await client.connect(transport);
|
||||
return createResultOk(client);
|
||||
} catch (error) {
|
||||
return createResultError({ type: 'connection', error });
|
||||
}
|
||||
}
|
||||
|
||||
const transport = new SSEClientTransport(endpoint.result, {
|
||||
try {
|
||||
const sseTransport = new SSEClientTransport(endpoint.result, {
|
||||
eventSourceInit: {
|
||||
fetch: async (url, init) =>
|
||||
await fetch(url, {
|
||||
@@ -174,13 +196,7 @@ export async function connectMcpClient({
|
||||
},
|
||||
requestInit: { headers },
|
||||
});
|
||||
|
||||
const client = new Client(
|
||||
{ name, version: version.toString() },
|
||||
{ capabilities: { tools: {} } },
|
||||
);
|
||||
|
||||
await client.connect(transport);
|
||||
await client.connect(sseTransport);
|
||||
return createResultOk(client);
|
||||
} catch (error) {
|
||||
return createResultError({ type: 'connection', error });
|
||||
|
||||
Reference in New Issue
Block a user