feat: add mcp tab and merge tool with server ts define

This commit is contained in:
Joel 2025-05-08 14:55:22 +08:00
parent b3faaa3754
commit 347cb2685e
10 changed files with 43 additions and 28 deletions

View File

@ -9,6 +9,10 @@ export const listData = [
is_team_authorization: true, is_team_authorization: true,
tools: ['aaa', 'bbb'], tools: ['aaa', 'bbb'],
update_elapsed_time: 1744793369, update_elapsed_time: 1744793369,
label: {
en_US: 'GOGOGO',
zh_Hans: 'GOGOGO',
},
}, },
{ {
id: 'fdjklajfkljadslf222', id: 'fdjklajfkljadslf222',
@ -20,6 +24,10 @@ export const listData = [
is_team_authorization: false, is_team_authorization: false,
tools: [], tools: [],
update_elapsed_time: 1744793369, update_elapsed_time: 1744793369,
label: {
en_US: 'GOGOGO2',
zh_Hans: 'GOGOGO2',
},
}, },
{ {
id: 'fdjklajfkljadslf333', id: 'fdjklajfkljadslf333',
@ -31,5 +39,9 @@ export const listData = [
is_team_authorization: true, is_team_authorization: true,
tools: ['aaa', 'bbb'], tools: ['aaa', 'bbb'],
update_elapsed_time: 1744793369, update_elapsed_time: 1744793369,
label: {
en_US: 'GOGOGO3',
zh_Hans: 'GOGOGO3',
},
}, },
] ]

View File

@ -9,13 +9,13 @@ import { RiHammerFill } from '@remixicon/react'
import Indicator from '@/app/components/header/indicator' import Indicator from '@/app/components/header/indicator'
import Icon from '@/app/components/plugins/card/base/card-icon' import Icon from '@/app/components/plugins/card/base/card-icon'
import { useFormatTimeFromNow } from './hooks' import { useFormatTimeFromNow } from './hooks'
import type { MCPProvider } from '@/app/components/tools/types' import type { ToolWithProvider } from '../../workflow/types'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
type Props = { type Props = {
currentProvider?: MCPProvider currentProvider?: ToolWithProvider
data: MCPProvider data: ToolWithProvider
handleSelect: (provider: MCPProvider) => void handleSelect: (provider: ToolWithProvider) => void
} }
const MCPCard = ({ const MCPCard = ({
@ -27,7 +27,7 @@ const MCPCard = ({
const { formatTimeFromNow } = useFormatTimeFromNow() const { formatTimeFromNow } = useFormatTimeFromNow()
// const { locale } = useContext(I18n) // const { locale } = useContext(I18n)
// const language = getLanguage(locale) // const language = getLanguage(locale)
// const { isCurrentWorkspaceManager } = useAppContext() // const { isCurrentWorkspaceManager } = useAppContext()
return ( return (
<div <div
@ -52,7 +52,7 @@ const MCPCard = ({
)} )}
</div> </div>
<div className='system-xs-regular text-divider-deep'>/</div> <div className='system-xs-regular text-divider-deep'>/</div>
<div className='system-xs-regular truncate text-text-tertiary'>{`${t('tools.mcp.updateTime')} ${formatTimeFromNow(data.update_elapsed_time * 1000)}`}</div> <div className='system-xs-regular truncate text-text-tertiary'>{`${t('tools.mcp.updateTime')} ${formatTimeFromNow(data.update_elapsed_time! * 1000)}`}</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -2,11 +2,11 @@
import React from 'react' import React from 'react'
import type { FC } from 'react' import type { FC } from 'react'
import Drawer from '@/app/components/base/drawer' import Drawer from '@/app/components/base/drawer'
import type { MCPProvider } from '@/app/components/tools/types'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import type { ToolWithProvider } from '../../workflow/types'
type Props = { type Props = {
detail?: MCPProvider detail?: ToolWithProvider
onUpdate: () => void onUpdate: () => void
onHide: () => void onHide: () => void
} }

View File

@ -51,6 +51,9 @@ export type Collection = {
labels: string[] labels: string[]
plugin_id?: string plugin_id?: string
letter?: string letter?: string
// MCP Server
server_url?: string
update_elapsed_time?: number
} }
export type ToolParameter = { export type ToolParameter = {
@ -169,15 +172,3 @@ export type WorkflowToolProviderResponse = {
} }
privacy_policy: string privacy_policy: string
} }
export type MCPProvider = {
id: string
author: string
name: string
icon: string | Emoji
server_url: string
type: CollectionType
is_team_authorization: boolean
tools: string[]
update_elapsed_time: number
}

View File

@ -31,6 +31,7 @@ type AllToolsProps = {
buildInTools: ToolWithProvider[] buildInTools: ToolWithProvider[]
customTools: ToolWithProvider[] customTools: ToolWithProvider[]
workflowTools: ToolWithProvider[] workflowTools: ToolWithProvider[]
mcpTools: ToolWithProvider[]
onSelect: OnSelectBlock onSelect: OnSelectBlock
supportAddCustomTool?: boolean supportAddCustomTool?: boolean
onAddedCustomTool?: () => void onAddedCustomTool?: () => void
@ -49,6 +50,7 @@ const AllTools = ({
buildInTools, buildInTools,
workflowTools, workflowTools,
customTools, customTools,
mcpTools = [],
supportAddCustomTool, supportAddCustomTool,
onShowAddCustomCollectionModal, onShowAddCustomCollectionModal,
selectedTools, selectedTools,
@ -64,13 +66,15 @@ const AllTools = ({
const tools = useMemo(() => { const tools = useMemo(() => {
let mergedTools: ToolWithProvider[] = [] let mergedTools: ToolWithProvider[] = []
if (activeTab === ToolTypeEnum.All) if (activeTab === ToolTypeEnum.All)
mergedTools = [...buildInTools, ...customTools, ...workflowTools] mergedTools = [...buildInTools, ...customTools, ...workflowTools, ...mcpTools]
if (activeTab === ToolTypeEnum.BuiltIn) if (activeTab === ToolTypeEnum.BuiltIn)
mergedTools = buildInTools mergedTools = buildInTools
if (activeTab === ToolTypeEnum.Custom) if (activeTab === ToolTypeEnum.Custom)
mergedTools = customTools mergedTools = customTools
if (activeTab === ToolTypeEnum.Workflow) if (activeTab === ToolTypeEnum.Workflow)
mergedTools = workflowTools mergedTools = workflowTools
if (activeTab === ToolTypeEnum.MCP)
mergedTools = mcpTools
if (!hasFilter) if (!hasFilter)
return mergedTools.filter(toolWithProvider => toolWithProvider.tools.length > 0) return mergedTools.filter(toolWithProvider => toolWithProvider.tools.length > 0)
@ -80,7 +84,7 @@ const AllTools = ({
return tool.label[language].toLowerCase().includes(searchText.toLowerCase()) || tool.name.toLowerCase().includes(searchText.toLowerCase()) return tool.label[language].toLowerCase().includes(searchText.toLowerCase()) || tool.name.toLowerCase().includes(searchText.toLowerCase())
}) })
}) })
}, [activeTab, buildInTools, customTools, workflowTools, searchText, language, hasFilter]) }, [activeTab, buildInTools, customTools, workflowTools, mcpTools, searchText, language, hasFilter])
const { const {
queryPluginsWithDebounced: fetchPlugins, queryPluginsWithDebounced: fetchPlugins,

View File

@ -51,5 +51,9 @@ export const useToolTabs = () => {
key: ToolTypeEnum.Workflow, key: ToolTypeEnum.Workflow,
name: t('workflow.tabs.workflowTool'), name: t('workflow.tabs.workflowTool'),
}, },
{
key: ToolTypeEnum.MCP,
name: 'MCP',
},
] ]
} }

View File

@ -1,6 +1,6 @@
import type { FC } from 'react' import type { FC } from 'react'
import { memo } from 'react' import { memo } from 'react'
import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools } from '@/service/use-tools' import { useAllBuiltInTools, useAllCustomTools, useAllMCPTools, useAllWorkflowTools } from '@/service/use-tools'
import type { BlockEnum } from '../types' import type { BlockEnum } from '../types'
import { useTabs } from './hooks' import { useTabs } from './hooks'
import type { ToolDefaultValue } from './types' import type { ToolDefaultValue } from './types'
@ -31,6 +31,7 @@ const Tabs: FC<TabsProps> = ({
const { data: buildInTools } = useAllBuiltInTools() const { data: buildInTools } = useAllBuiltInTools()
const { data: customTools } = useAllCustomTools() const { data: customTools } = useAllCustomTools()
const { data: workflowTools } = useAllWorkflowTools() const { data: workflowTools } = useAllWorkflowTools()
const { data: mcpTools } = useAllMCPTools()
return ( return (
<div onClick={e => e.stopPropagation()}> <div onClick={e => e.stopPropagation()}>
@ -75,6 +76,7 @@ const Tabs: FC<TabsProps> = ({
buildInTools={buildInTools || []} buildInTools={buildInTools || []}
customTools={customTools || []} customTools={customTools || []}
workflowTools={workflowTools || []} workflowTools={workflowTools || []}
mcpTools={mcpTools || []}
/> />
) )
} }

View File

@ -23,7 +23,7 @@ import {
} from '@/service/tools' } from '@/service/tools'
import type { CustomCollectionBackend } from '@/app/components/tools/types' import type { CustomCollectionBackend } from '@/app/components/tools/types'
import Toast from '@/app/components/base/toast' import Toast from '@/app/components/base/toast'
import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools, useInvalidateAllCustomTools } from '@/service/use-tools' import { useAllBuiltInTools, useAllCustomTools, useAllMCPTools, useAllWorkflowTools, useInvalidateAllCustomTools } from '@/service/use-tools'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
type Props = { type Props = {
@ -61,6 +61,7 @@ const ToolPicker: FC<Props> = ({
const { data: customTools } = useAllCustomTools() const { data: customTools } = useAllCustomTools()
const invalidateCustomTools = useInvalidateAllCustomTools() const invalidateCustomTools = useInvalidateAllCustomTools()
const { data: workflowTools } = useAllWorkflowTools() const { data: workflowTools } = useAllWorkflowTools()
const { data: mcpTools } = useAllMCPTools()
const { builtinToolList, customToolList, workflowToolList } = useMemo(() => { const { builtinToolList, customToolList, workflowToolList } = useMemo(() => {
if (scope === 'plugins') { if (scope === 'plugins') {
@ -162,6 +163,7 @@ const ToolPicker: FC<Props> = ({
buildInTools={builtinToolList || []} buildInTools={builtinToolList || []}
customTools={customToolList || []} customTools={customToolList || []}
workflowTools={workflowToolList || []} workflowTools={workflowToolList || []}
mcpTools={mcpTools || []}
supportAddCustomTool={supportAddCustomTool} supportAddCustomTool={supportAddCustomTool}
onAddedCustomTool={handleAddedCustomTool} onAddedCustomTool={handleAddedCustomTool}
onShowAddCustomCollectionModal={showEditCustomCollectionModal} onShowAddCustomCollectionModal={showEditCustomCollectionModal}

View File

@ -8,6 +8,7 @@ export enum ToolTypeEnum {
BuiltIn = 'built-in', BuiltIn = 'built-in',
Custom = 'custom', Custom = 'custom',
Workflow = 'workflow', Workflow = 'workflow',
MCP = 'mcp',
} }
export enum BlockClassificationEnum { export enum BlockClassificationEnum {

View File

@ -4,7 +4,6 @@ import type {
Tool, Tool,
} from '@/app/components/tools/types' } from '@/app/components/tools/types'
import type { ToolWithProvider } from '@/app/components/workflow/types' import type { ToolWithProvider } from '@/app/components/workflow/types'
import type { MCPProvider } from '@/app/components/tools/types'
import { useInvalid } from './use-base' import { useInvalid } from './use-base'
import { import {
useMutation, useMutation,
@ -66,11 +65,11 @@ export const useInvalidateAllWorkflowTools = () => {
const useAllMCPToolsKey = [NAME_SPACE, 'MCPTools'] const useAllMCPToolsKey = [NAME_SPACE, 'MCPTools']
export const useAllMCPTools = () => { export const useAllMCPTools = () => {
return useQuery<MCPProvider[]>({ return useQuery<ToolWithProvider[]>({
queryKey: useAllMCPToolsKey, queryKey: useAllMCPToolsKey,
// queryFn: () => get<MCPProvider[]>('/workspaces/current/tools/mcp'), // queryFn: () => get<ToolWithProvider[]>('/workspaces/current/tools/mcp'),
queryFn: () => { queryFn: () => {
return listData as unknown as MCPProvider[] return listData as unknown as ToolWithProvider[]
}, },
}) })
} }