Skip to content

Commit 50a8641

Browse files
committed
feat(ui): adapt GitHub MCP server for the new version
1 parent 099cf48 commit 50a8641

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { Tool } from '@langchain/core/tools'
2+
import { ICommonObject, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../../src/Interface'
3+
import { getCredentialData, getCredentialParam } from '../../../../src/utils'
4+
import { MCPToolkit } from '../core'
5+
6+
class GithubV2_MCP implements INode {
7+
label: string
8+
name: string
9+
version: number
10+
description: string
11+
type: string
12+
icon: string
13+
category: string
14+
baseClasses: string[]
15+
documentation: string
16+
credential: INodeParams
17+
inputs: INodeParams[]
18+
19+
constructor() {
20+
this.label = 'Github V2 MCP (Remote)'
21+
this.name = 'githubV2MCP'
22+
this.version = 1.0
23+
this.type = 'Github V2 MCP Tool'
24+
this.icon = 'github.svg'
25+
this.category = 'Tools (MCP)'
26+
this.description = 'Official GitHub MCP Server (Remote/Cloud Version) with enhanced capabilities'
27+
this.documentation = 'https://github.com/github/github-mcp-server'
28+
this.credential = {
29+
label: 'Connect Credential',
30+
name: 'credential',
31+
type: 'credential',
32+
credentialNames: ['githubApi']
33+
}
34+
this.inputs = [
35+
{
36+
label: 'Available Actions',
37+
name: 'mcpActions',
38+
type: 'asyncMultiOptions',
39+
loadMethod: 'listActions',
40+
refresh: true,
41+
description: 'Select from 15+ toolsets including Actions, Issues, PRs, Discussions, and more'
42+
}
43+
]
44+
this.baseClasses = ['Tool']
45+
}
46+
47+
//@ts-ignore
48+
loadMethods = {
49+
listActions: async (nodeData: INodeData, options: ICommonObject): Promise<INodeOptionsValue[]> => {
50+
try {
51+
const toolset = await this.getTools(nodeData, options)
52+
toolset.sort((a: any, b: any) => a.name.localeCompare(b.name))
53+
54+
return toolset.map(({ name, ...rest }) => ({
55+
label: name.toUpperCase(),
56+
name: name,
57+
description: rest.description || name
58+
}))
59+
} catch (error) {
60+
console.error('Error listing actions:', error)
61+
return [
62+
{
63+
label: 'No Available Actions',
64+
name: 'error',
65+
description: 'No available actions, please check your Github Access Token and refresh'
66+
}
67+
]
68+
}
69+
}
70+
}
71+
72+
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
73+
const tools = await this.getTools(nodeData, options)
74+
75+
const _mcpActions = nodeData.inputs?.mcpActions
76+
let mcpActions = []
77+
if (_mcpActions) {
78+
try {
79+
mcpActions = typeof _mcpActions === 'string' ? JSON.parse(_mcpActions) : _mcpActions
80+
} catch (error) {
81+
console.error('Error parsing mcp actions:', error)
82+
}
83+
}
84+
85+
return tools.filter((tool: any) => mcpActions.includes(tool.name))
86+
}
87+
88+
async getTools(nodeData: INodeData, options: ICommonObject): Promise<Tool[]> {
89+
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
90+
const accessToken = getCredentialParam('accessToken', credentialData, nodeData)
91+
92+
if (!accessToken) {
93+
throw new Error('Missing Github Access Token')
94+
}
95+
96+
// Remote GitHub MCP Server configuration
97+
const serverParams = {
98+
url: 'https://api.githubcopilot.com/mcp/',
99+
headers: {
100+
'Authorization': `Bearer ${accessToken}`
101+
}
102+
}
103+
104+
const toolkit = new MCPToolkit(serverParams, 'sse')
105+
await toolkit.initialize()
106+
107+
const tools = toolkit.tools ?? []
108+
109+
return tools as Tool[]
110+
}
111+
}
112+
113+
module.exports = { nodeClass: GithubV2_MCP }
Lines changed: 13 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)