Add Sequential Thinking MCP tool for structured problem-solving (#4143)

This commit is contained in:
Asharib Ali
2025-03-10 15:15:10 +05:00
committed by GitHub
parent a369f0c1cc
commit 69a272201a
4 changed files with 316 additions and 151 deletions
@@ -0,0 +1,98 @@
import { Tool } from '@langchain/core/tools'
import { ICommonObject, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../../src/Interface'
import { getNodeModulesPackagePath } from '../../../../src/utils'
import { MCPToolkit } from '../core'
class SequentialThinking_MCP implements INode {
label: string
name: string
version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
documentation: string
inputs: INodeParams[]
constructor() {
this.label = 'Sequential Thinking MCP'
this.name = 'sequentialThinkingMCP'
this.version = 1.0
this.type = 'Sequential Thinking MCP Tool'
this.icon = 'sequentialthinking.svg'
this.category = 'Tools (MCP)'
this.description =
'MCP server that provides a tool for dynamic and reflective problem-solving through a structured thinking process'
this.documentation = 'https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking'
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 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 packagePath = getNodeModulesPackagePath('@modelcontextprotocol/server-sequential-thinking/dist/index.js')
const serverParams = {
command: 'node',
args: [packagePath]
}
const toolkit = new MCPToolkit(serverParams, 'stdio')
await toolkit.initialize()
const tools = toolkit.tools ?? []
return tools as Tool[]
}
}
module.exports = { nodeClass: SequentialThinking_MCP }
@@ -0,0 +1,36 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Brain outline -->
<path d="M16 4C12.5 4 9.5 6.5 9.5 9.5C9.5 10.5 9.8 11.4 10.3 12.2C8.9 13.2 8 14.8 8 16.5C8 17.8 8.5 19 9.3 20C8.5 20.8 8 21.9 8 23C8 25.2 9.8 27 12 27H20C22.2 27 24 25.2 24 23C24 21.9 23.5 20.8 22.7 20C23.5 19 24 17.8 24 16.5C24 14.8 23.1 13.2 21.7 12.2C22.2 11.4 22.5 10.5 22.5 9.5C22.5 6.5 19.5 4 16 4Z" stroke="#6366F1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<!-- Sequential steps/thoughts -->
<circle cx="12" cy="10" r="1.5" fill="#6366F1"/>
<circle cx="16" cy="10" r="1.5" fill="#6366F1"/>
<circle cx="20" cy="10" r="1.5" fill="#6366F1"/>
<circle cx="12" cy="16" r="1.5" fill="#6366F1"/>
<circle cx="16" cy="16" r="1.5" fill="#6366F1"/>
<circle cx="20" cy="16" r="1.5" fill="#6366F1"/>
<circle cx="12" cy="22" r="1.5" fill="#6366F1"/>
<circle cx="16" cy="22" r="1.5" fill="#6366F1"/>
<circle cx="20" cy="22" r="1.5" fill="#6366F1"/>
<!-- Connecting lines representing sequential thinking -->
<path d="M12 11.5L12 14.5" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M16 11.5L16 14.5" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M20 11.5L20 14.5" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M12 17.5L12 20.5" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M16 17.5L16 20.5" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M20 17.5L20 20.5" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<!-- Branching thought line -->
<path d="M13.5 10L14.5 10" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M17.5 10L18.5 10" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M13.5 16L14.5 16" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M17.5 16L18.5 16" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M13.5 22L14.5 22" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
<path d="M17.5 22L18.5 22" stroke="#6366F1" stroke-width="1.5" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

+1
View File
@@ -63,6 +63,7 @@
"@modelcontextprotocol/server-brave-search": "^0.6.2",
"@modelcontextprotocol/server-github": "^2025.1.23",
"@modelcontextprotocol/server-postgres": "^0.6.2",
"@modelcontextprotocol/server-sequential-thinking": "^0.6.2",
"@modelcontextprotocol/server-slack": "^2025.1.17",
"@notionhq/client": "^2.2.8",
"@opensearch-project/opensearch": "^1.2.0",
+181 -151
View File
File diff suppressed because one or more lines are too long