Skip to content

Commit ad39bf4

Browse files
HenryHengZJJJK801
authored andcommitted
Feature/Custom MCP (FlowiseAI#4136)
* add mcp tools * add custom MCP
1 parent 26d6164 commit ad39bf4

File tree

3 files changed

+131
-2
lines changed

3 files changed

+131
-2
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import { Tool } from '@langchain/core/tools'
2+
import { INode, INodeData, INodeOptionsValue, INodeParams } from '../../../../src/Interface'
3+
import { MCPToolkit } from '../core'
4+
5+
const mcpServerConfig = `{
6+
"command": "npx",
7+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/files"]
8+
}`
9+
10+
class Custom_MCP implements INode {
11+
label: string
12+
name: string
13+
version: number
14+
description: string
15+
type: string
16+
icon: string
17+
category: string
18+
baseClasses: string[]
19+
documentation: string
20+
credential: INodeParams
21+
inputs: INodeParams[]
22+
23+
constructor() {
24+
this.label = 'Custom MCP'
25+
this.name = 'customMCP'
26+
this.version = 1.0
27+
this.type = 'Custom MCP Tool'
28+
this.icon = 'customMCP.png'
29+
this.category = 'Tools (MCP)'
30+
this.description = 'Custom MCP Config'
31+
this.documentation = 'https://github.com/modelcontextprotocol/servers/tree/main/src/brave-search'
32+
this.inputs = [
33+
{
34+
label: 'MCP Server Config',
35+
name: 'mcpServerConfig',
36+
type: 'code',
37+
hideCodeExecute: true,
38+
placeholder: mcpServerConfig
39+
},
40+
{
41+
label: 'Available Actions',
42+
name: 'mcpActions',
43+
type: 'asyncMultiOptions',
44+
loadMethod: 'listActions',
45+
refresh: true
46+
}
47+
]
48+
this.baseClasses = ['Tool']
49+
}
50+
51+
//@ts-ignore
52+
loadMethods = {
53+
listActions: async (nodeData: INodeData): Promise<INodeOptionsValue[]> => {
54+
try {
55+
const toolset = await this.getTools(nodeData)
56+
toolset.sort((a: any, b: any) => a.name.localeCompare(b.name))
57+
58+
return toolset.map(({ name, ...rest }) => ({
59+
label: name.toUpperCase(),
60+
name: name,
61+
description: rest.description || name
62+
}))
63+
} catch (error) {
64+
return [
65+
{
66+
label: 'No Available Actions',
67+
name: 'error',
68+
description: 'No available actions, please check your API key and refresh'
69+
}
70+
]
71+
}
72+
}
73+
}
74+
75+
async init(nodeData: INodeData): Promise<any> {
76+
const tools = await this.getTools(nodeData)
77+
78+
const _mcpActions = nodeData.inputs?.mcpActions
79+
let mcpActions = []
80+
if (_mcpActions) {
81+
try {
82+
mcpActions = typeof _mcpActions === 'string' ? JSON.parse(_mcpActions) : _mcpActions
83+
} catch (error) {
84+
console.error('Error parsing mcp actions:', error)
85+
}
86+
}
87+
88+
return tools.filter((tool: any) => mcpActions.includes(tool.name))
89+
}
90+
91+
async getTools(nodeData: INodeData): Promise<Tool[]> {
92+
const mcpServerConfig = nodeData.inputs?.mcpServerConfig as string
93+
94+
if (!mcpServerConfig) {
95+
throw new Error('MCP Server Config is required')
96+
}
97+
98+
try {
99+
let serverParams
100+
if (typeof mcpServerConfig === 'object') {
101+
serverParams = mcpServerConfig
102+
} else if (typeof mcpServerConfig === 'string') {
103+
const serverParamsString = convertToValidJSONString(mcpServerConfig)
104+
serverParams = JSON.parse(serverParamsString)
105+
}
106+
107+
const toolkit = new MCPToolkit(serverParams, 'stdio')
108+
await toolkit.initialize()
109+
110+
const tools = toolkit.tools ?? []
111+
112+
return tools as Tool[]
113+
} catch (error) {
114+
throw new Error(`Invalid MCP Server Config: ${error}`)
115+
}
116+
}
117+
}
118+
119+
function convertToValidJSONString(inputString: string) {
120+
try {
121+
const jsObject = Function('return ' + inputString)()
122+
return JSON.stringify(jsObject, null, 2)
123+
} catch (error) {
124+
console.error('Error converting to JSON:', error)
125+
return ''
126+
}
127+
}
128+
129+
module.exports = { nodeClass: Custom_MCP }
Loading

packages/components/nodes/tools/MCP/core.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ export class MCPToolkit extends BaseToolkit {
1515
if (transport === 'stdio') {
1616
this.transport = new StdioClientTransport(serverParams as StdioServerParameters)
1717
} else {
18-
//this.transport = new SSEClientTransport(serverParams.url);
18+
// TODO: this.transport = new SSEClientTransport(serverParams.url);
1919
}
2020
}
2121
async initialize() {
2222
if (this._tools === null) {
2323
this.client = new Client(
2424
{
25-
name: 'langchain-js-client',
25+
name: 'flowise-client',
2626
version: '1.0.0'
2727
},
2828
{

0 commit comments

Comments
 (0)