Flowise/packages/components/nodes/tools/MCP/PostgreSQL/PostgreSQLMCP.ts

112 lines
3.7 KiB
TypeScript

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 PostgreSQL_MCP implements INode {
label: string
name: string
version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
credential: INodeParams
documentation: string
inputs: INodeParams[]
constructor() {
this.label = 'PostgreSQL MCP'
this.name = 'postgreSQLMCP'
this.version = 1.0
this.type = 'PostgreSQL MCP Tool'
this.icon = 'postgres.svg'
this.category = 'Tools (MCP)'
this.description = 'MCP server that provides read-only access to PostgreSQL databases'
this.documentation = 'https://github.com/modelcontextprotocol/servers/tree/main/src/postgres'
this.credential = {
label: 'Connect Credential',
name: 'credential',
type: 'credential',
credentialNames: ['PostgresUrl']
}
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 postgres url 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 postgresUrl = getCredentialParam('postgresUrl', credentialData, nodeData)
if (!postgresUrl) {
throw new Error('No postgres url provided')
}
const packagePath = getNodeModulesPackagePath('@modelcontextprotocol/server-postgres/dist/index.js')
const serverParams = {
command: 'node',
args: [packagePath, postgresUrl]
}
const toolkit = new MCPToolkit(serverParams, 'stdio')
await toolkit.initialize()
const tools = toolkit.tools ?? []
return tools as Tool[]
}
}
module.exports = { nodeClass: PostgreSQL_MCP }