> = (props) => {
})()
const resetEditor = useStore(s => s.setControlPromptEditorRerenderKey)
-
+ console.log(canChooseMCPTool)
return
> = (props) => {
agent_strategy_label: inputs.agent_strategy_label!,
agent_output_schema: inputs.output_schema,
plugin_unique_identifier: inputs.plugin_unique_identifier!,
+ meta: inputs.meta,
} : undefined}
onStrategyChange={(strategy) => {
setInputs({
@@ -102,6 +104,7 @@ const AgentPanel: FC> = (props) => {
agent_strategy_label: strategy?.agent_strategy_label,
output_schema: strategy!.agent_output_schema,
plugin_unique_identifier: strategy!.plugin_unique_identifier,
+ meta: strategy?.meta,
})
resetEditor(Date.now())
}}
diff --git a/web/app/components/workflow/nodes/agent/types.ts b/web/app/components/workflow/nodes/agent/types.ts
index ca8bb5e71d..e50586bd27 100644
--- a/web/app/components/workflow/nodes/agent/types.ts
+++ b/web/app/components/workflow/nodes/agent/types.ts
@@ -1,11 +1,13 @@
import type { CommonNodeType, Memory } from '@/app/components/workflow/types'
import type { ToolVarInputs } from '../tool/types'
+import type { PluginMeta } from '@/app/components/plugins/types'
export type AgentNodeType = CommonNodeType & {
agent_strategy_provider_name?: string
agent_strategy_name?: string
agent_strategy_label?: string
agent_parameters?: ToolVarInputs
+ meta?: PluginMeta
output_schema: Record
plugin_unique_identifier?: string
memory?: Memory
diff --git a/web/app/components/workflow/nodes/agent/use-config.ts b/web/app/components/workflow/nodes/agent/use-config.ts
index 8196caa3f5..1dc20fcbcd 100644
--- a/web/app/components/workflow/nodes/agent/use-config.ts
+++ b/web/app/components/workflow/nodes/agent/use-config.ts
@@ -14,6 +14,7 @@ import type { Memory, Var } from '../../types'
import { VarType as VarKindType } from '../../types'
import useAvailableVarList from '../_base/hooks/use-available-var-list'
import produce from 'immer'
+import { isSupportMCP } from '@/utils/plugin-version-feature'
export type StrategyStatus = {
plugin: {
@@ -214,6 +215,7 @@ const useConfig = (id: string, payload: AgentNodeType) => {
outputSchema,
handleMemoryChange,
isChatMode,
+ canChooseMCPTool: isSupportMCP(inputs.meta?.version),
}
}
diff --git a/web/app/components/workflow/types.ts b/web/app/components/workflow/types.ts
index 884bdfbd10..56cd9ffdf9 100644
--- a/web/app/components/workflow/types.ts
+++ b/web/app/components/workflow/types.ts
@@ -15,6 +15,7 @@ import type {
} from '@/app/components/workflow/nodes/_base/components/error-handle/types'
import type { WorkflowRetryConfig } from '@/app/components/workflow/nodes/_base/components/retry/types'
import type { StructuredOutput } from '@/app/components/workflow/nodes/llm/types'
+import type { PluginMeta } from '../plugins/types'
export enum BlockEnum {
Start = 'start',
@@ -400,6 +401,7 @@ export type MoreInfo = {
export type ToolWithProvider = Collection & {
tools: Tool[]
+ meta: PluginMeta
}
export enum SupportUploadFileTypes {
diff --git a/web/utils/plugin-version-feature.spec.ts b/web/utils/plugin-version-feature.spec.ts
new file mode 100644
index 0000000000..12ca239aa9
--- /dev/null
+++ b/web/utils/plugin-version-feature.spec.ts
@@ -0,0 +1,26 @@
+import { isSupportMCP } from './plugin-version-feature'
+
+describe('plugin-version-feature', () => {
+ beforeEach(() => {
+ jest.clearAllMocks()
+ })
+
+ describe('isSupportMCP', () => {
+ it('should call isEqualOrLaterThanVersion with the correct parameters', () => {
+ expect(isSupportMCP('0.0.3')).toBe(true)
+ expect(isSupportMCP('1.0.0')).toBe(true)
+ })
+
+ it('should return true when version is equal to the supported MCP version', () => {
+ const mockVersion = '0.0.2'
+ const result = isSupportMCP(mockVersion)
+ expect(result).toBe(true)
+ })
+
+ it('should return false when version is less than the supported MCP version', () => {
+ const mockVersion = '0.0.1'
+ const result = isSupportMCP(mockVersion)
+ expect(result).toBe(false)
+ })
+ })
+})
diff --git a/web/utils/plugin-version-feature.ts b/web/utils/plugin-version-feature.ts
new file mode 100644
index 0000000000..51d366bf9c
--- /dev/null
+++ b/web/utils/plugin-version-feature.ts
@@ -0,0 +1,10 @@
+import { isEqualOrLaterThanVersion } from './semver'
+
+const SUPPORT_MCP_VERSION = '0.0.2'
+
+export const isSupportMCP = (version?: string): boolean => {
+ if (!version)
+ return false
+
+ return isEqualOrLaterThanVersion(version, SUPPORT_MCP_VERSION)
+}
diff --git a/web/utils/semver.spec.ts b/web/utils/semver.spec.ts
new file mode 100644
index 0000000000..c2188a976c
--- /dev/null
+++ b/web/utils/semver.spec.ts
@@ -0,0 +1,75 @@
+import { compareVersion, getLatestVersion, isEqualOrLaterThanVersion } from './semver'
+
+describe('semver utilities', () => {
+ describe('getLatestVersion', () => {
+ it('should return the latest version from a list of versions', () => {
+ expect(getLatestVersion(['1.0.0', '1.1.0', '1.0.1'])).toBe('1.1.0')
+ expect(getLatestVersion(['2.0.0', '1.9.9', '1.10.0'])).toBe('2.0.0')
+ expect(getLatestVersion(['1.0.0-alpha', '1.0.0-beta', '1.0.0'])).toBe('1.0.0')
+ })
+
+ it('should handle patch versions correctly', () => {
+ expect(getLatestVersion(['1.0.1', '1.0.2', '1.0.0'])).toBe('1.0.2')
+ expect(getLatestVersion(['1.0.10', '1.0.9', '1.0.11'])).toBe('1.0.11')
+ })
+
+ it('should handle mixed version formats', () => {
+ expect(getLatestVersion(['v1.0.0', '1.1.0', 'v1.2.0'])).toBe('v1.2.0')
+ expect(getLatestVersion(['1.0.0-rc.1', '1.0.0', '1.0.0-beta'])).toBe('1.0.0')
+ })
+
+ it('should return the only version if only one version is provided', () => {
+ expect(getLatestVersion(['1.0.0'])).toBe('1.0.0')
+ })
+ })
+
+ describe('compareVersion', () => {
+ it('should return 1 when first version is greater', () => {
+ expect(compareVersion('1.1.0', '1.0.0')).toBe(1)
+ expect(compareVersion('2.0.0', '1.9.9')).toBe(1)
+ expect(compareVersion('1.0.1', '1.0.0')).toBe(1)
+ })
+
+ it('should return -1 when first version is less', () => {
+ expect(compareVersion('1.0.0', '1.1.0')).toBe(-1)
+ expect(compareVersion('1.9.9', '2.0.0')).toBe(-1)
+ expect(compareVersion('1.0.0', '1.0.1')).toBe(-1)
+ })
+
+ it('should return 0 when versions are equal', () => {
+ expect(compareVersion('1.0.0', '1.0.0')).toBe(0)
+ expect(compareVersion('2.1.3', '2.1.3')).toBe(0)
+ })
+
+ it('should handle pre-release versions correctly', () => {
+ expect(compareVersion('1.0.0-beta', '1.0.0-alpha')).toBe(1)
+ expect(compareVersion('1.0.0', '1.0.0-beta')).toBe(1)
+ expect(compareVersion('1.0.0-alpha', '1.0.0-beta')).toBe(-1)
+ })
+ })
+
+ describe('isEqualOrLaterThanVersion', () => {
+ it('should return true when baseVersion is greater than targetVersion', () => {
+ expect(isEqualOrLaterThanVersion('1.1.0', '1.0.0')).toBe(true)
+ expect(isEqualOrLaterThanVersion('2.0.0', '1.9.9')).toBe(true)
+ expect(isEqualOrLaterThanVersion('1.0.1', '1.0.0')).toBe(true)
+ })
+
+ it('should return true when baseVersion is equal to targetVersion', () => {
+ expect(isEqualOrLaterThanVersion('1.0.0', '1.0.0')).toBe(true)
+ expect(isEqualOrLaterThanVersion('2.1.3', '2.1.3')).toBe(true)
+ })
+
+ it('should return false when baseVersion is less than targetVersion', () => {
+ expect(isEqualOrLaterThanVersion('1.0.0', '1.1.0')).toBe(false)
+ expect(isEqualOrLaterThanVersion('1.9.9', '2.0.0')).toBe(false)
+ expect(isEqualOrLaterThanVersion('1.0.0', '1.0.1')).toBe(false)
+ })
+
+ it('should handle pre-release versions correctly', () => {
+ expect(isEqualOrLaterThanVersion('1.0.0', '1.0.0-beta')).toBe(true)
+ expect(isEqualOrLaterThanVersion('1.0.0-beta', '1.0.0-alpha')).toBe(true)
+ expect(isEqualOrLaterThanVersion('1.0.0-alpha', '1.0.0')).toBe(false)
+ })
+ })
+})
diff --git a/web/utils/semver.ts b/web/utils/semver.ts
index f1b9eb8d7e..aea84153ec 100644
--- a/web/utils/semver.ts
+++ b/web/utils/semver.ts
@@ -7,3 +7,7 @@ export const getLatestVersion = (versionList: string[]) => {
export const compareVersion = (v1: string, v2: string) => {
return semver.compare(v1, v2)
}
+
+export const isEqualOrLaterThanVersion = (baseVersion: string, targetVersion: string) => {
+ return semver.gte(baseVersion, targetVersion)
+}