Feature/MCP (Model Context Protocol) (#4134)

add mcp tools
This commit is contained in:
Henry Heng
2025-03-06 13:57:18 +00:00
committed by GitHub
parent 9c22bee991
commit 713ed26971
21 changed files with 1321 additions and 105 deletions
@@ -0,0 +1,114 @@
import { Tool } from '@langchain/core/tools'
import { ICommonObject, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../../src/Interface'
import { getCredentialData, getCredentialParam, getNodeModulesPackagePath } from '../../../../src/utils'
import { MCPToolkit } from '../core'
class Github_MCP implements INode {
label: string
name: string
version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
documentation: string
credential: INodeParams
inputs: INodeParams[]
constructor() {
this.label = 'Github MCP'
this.name = 'githubMCP'
this.version = 1.0
this.type = 'Github MCP Tool'
this.icon = 'github.svg'
this.category = 'Tools (MCP)'
this.description = 'MCP Server for the GitHub API'
this.documentation = 'https://github.com/modelcontextprotocol/servers/tree/main/src/github'
this.credential = {
label: 'Connect Credential',
name: 'credential',
type: 'credential',
credentialNames: ['githubApi']
}
this.inputs = [
{
label: 'Available Actions',
name: 'mcpActions',
type: 'asyncMultiOptions',
loadMethod: 'listActions',
refresh: true
}
]
this.baseClasses = ['Tool']
}
//@ts-ignore
loadMethods = {
listActions: async (nodeData: INodeData, options: ICommonObject): Promise<INodeOptionsValue[]> => {
try {
const toolset = await this.getTools(nodeData, options)
toolset.sort((a: any, b: any) => a.name.localeCompare(b.name))
return toolset.map(({ name, ...rest }) => ({
label: name.toUpperCase(),
name: name,
description: rest.description || name
}))
} catch (error) {
console.error('Error listing actions:', error)
return [
{
label: 'No Available Actions',
name: 'error',
description: 'No available actions, please check your Github Access Token and refresh'
}
]
}
}
}
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
const tools = await this.getTools(nodeData, options)
const _mcpActions = nodeData.inputs?.mcpActions
let mcpActions = []
if (_mcpActions) {
try {
mcpActions = typeof _mcpActions === 'string' ? JSON.parse(_mcpActions) : _mcpActions
} catch (error) {
console.error('Error parsing mcp actions:', error)
}
}
return tools.filter((tool: any) => mcpActions.includes(tool.name))
}
async getTools(nodeData: INodeData, options: ICommonObject): Promise<Tool[]> {
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
const accessToken = getCredentialParam('accessToken', credentialData, nodeData)
if (!accessToken) {
throw new Error('Missing Github Access Token')
}
const packagePath = getNodeModulesPackagePath('@modelcontextprotocol/server-github/dist/index.js')
const serverParams = {
command: 'node',
args: [packagePath],
env: {
GITHUB_PERSONAL_ACCESS_TOKEN: accessToken
}
}
const toolkit = new MCPToolkit(serverParams, 'stdio')
await toolkit.initialize()
const tools = toolkit.tools ?? []
return tools as Tool[]
}
}
module.exports = { nodeClass: Github_MCP }
@@ -0,0 +1,13 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_115_14646)">
<path d="M13.9788 7C13.3909 6.0801 12.5809 5.32307 11.6234 4.79876C10.6658 4.27445 9.59167 3.99974 8.5 4C8.0144 4.83956 7.72314 5.77729 7.64765 6.74423C7.57215 7.71117 7.71434 8.68274 8.06375 9.5875C7.37968 10.5949 7.00951 11.7824 7 13V14C7 15.5913 7.63214 17.1174 8.75736 18.2426C9.88258 19.3679 11.4087 20 13 20H19C20.5913 20 22.1174 19.3679 23.2426 18.2426C24.3679 17.1174 25 15.5913 25 14V13C24.9905 11.7824 24.6203 10.5949 23.9363 9.5875C24.2857 8.68274 24.4278 7.71117 24.3524 6.74423C24.2769 5.77729 23.9856 4.83956 23.5 4C22.4083 3.99974 21.3342 4.27445 20.3766 4.79876C19.4191 5.32307 18.6091 6.0801 18.0212 7H13.9788Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 29V24C12 21.7909 13.7909 20 16 20V20C18.2091 20 20 21.7909 20 24V29" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 26H10C8.93913 26 7.92172 25.5786 7.17157 24.8284C6.42143 24.0783 6 23.0609 6 22C6 20.9391 5.57857 19.9217 4.82843 19.1716C4.07828 18.4214 3.06087 18 2 18" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 26H10C7.79086 26 6 24.2091 6 22V22C6 19.7909 4.20914 18 2 18V18" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_115_14646">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB