feat: the frontend part of mcp (#22131)

Co-authored-by: jZonG <jzongcode@gmail.com>
Co-authored-by: Novice <novice12185727@gmail.com>
Co-authored-by: nite-knite <nkCoding@gmail.com>
Co-authored-by: Hanqing Zhao <sherry9277@gmail.com>
This commit is contained in:
Joel
2025-07-10 14:14:02 +08:00
committed by GitHub
parent 535fff62f3
commit 5375d9bb27
152 changed files with 6340 additions and 695 deletions

View File

@@ -337,8 +337,8 @@ export const verifyWebAppForgotPasswordToken: Fetcher<CommonResponse & { is_vali
export const changeWebAppPasswordWithToken: Fetcher<CommonResponse, { url: string; body: { token: string; new_password: string; password_confirm: string } }> = ({ url, body }) =>
post<CommonResponse>(url, { body }, { isPublicAPI: true })
export const uploadRemoteFileInfo = (url: string, isPublic?: boolean) => {
return post<{ id: string; name: string; size: number; mime_type: string; url: string }>('/remote-files/upload', { body: { url } }, { isPublicAPI: isPublic })
export const uploadRemoteFileInfo = (url: string, isPublic?: boolean, silent?: boolean) => {
return post<{ id: string; name: string; size: number; mime_type: string; url: string }>('/remote-files/upload', { body: { url } }, { isPublicAPI: isPublic, silent })
}
export const sendEMailLoginCode = (email: string, language = 'en-US') =>

View File

@@ -124,6 +124,10 @@ export const fetchAllWorkflowTools = () => {
return get<ToolWithProvider[]>('/workspaces/current/tools/workflow')
}
export const fetchAllMCPTools = () => {
return get<ToolWithProvider[]>('/workspaces/current/tools/mcp')
}
export const fetchLabelList = () => {
return get<Label[]>('/workspaces/current/tool-labels')
}

View File

@@ -1,9 +1,11 @@
import { get, post } from './base'
import { del, get, post, put } from './base'
import type {
Collection,
MCPServerDetail,
Tool,
} from '@/app/components/tools/types'
import type { ToolWithProvider } from '@/app/components/workflow/types'
import type { AppIconType } from '@/types/app'
import { useInvalid } from './use-base'
import {
useMutation,
@@ -61,6 +63,191 @@ export const useInvalidateAllWorkflowTools = () => {
return useInvalid(useAllWorkflowToolsKey)
}
const useAllMCPToolsKey = [NAME_SPACE, 'MCPTools']
export const useAllMCPTools = () => {
return useQuery<ToolWithProvider[]>({
queryKey: useAllMCPToolsKey,
queryFn: () => get<ToolWithProvider[]>('/workspaces/current/tools/mcp'),
})
}
export const useInvalidateAllMCPTools = () => {
return useInvalid(useAllMCPToolsKey)
}
export const useCreateMCP = () => {
return useMutation({
mutationKey: [NAME_SPACE, 'create-mcp'],
mutationFn: (payload: {
name: string
server_url: string
icon_type: AppIconType
icon: string
icon_background?: string | null
}) => {
return post<ToolWithProvider>('workspaces/current/tool-provider/mcp', {
body: {
...payload,
},
})
},
})
}
export const useUpdateMCP = ({
onSuccess,
}: {
onSuccess?: () => void
}) => {
return useMutation({
mutationKey: [NAME_SPACE, 'update-mcp'],
mutationFn: (payload: {
name: string
server_url: string
icon_type: AppIconType
icon: string
icon_background?: string | null
provider_id: string
}) => {
return put('workspaces/current/tool-provider/mcp', {
body: {
...payload,
},
})
},
onSuccess,
})
}
export const useDeleteMCP = ({
onSuccess,
}: {
onSuccess?: () => void
}) => {
return useMutation({
mutationKey: [NAME_SPACE, 'delete-mcp'],
mutationFn: (id: string) => {
return del('/workspaces/current/tool-provider/mcp', {
body: {
provider_id: id,
},
})
},
onSuccess,
})
}
export const useAuthorizeMCP = () => {
return useMutation({
mutationKey: [NAME_SPACE, 'authorize-mcp'],
mutationFn: (payload: { provider_id: string; }) => {
return post<{ result?: string; authorization_url?: string }>('/workspaces/current/tool-provider/mcp/auth', {
body: payload,
})
},
})
}
export const useUpdateMCPAuthorizationToken = () => {
return useMutation({
mutationKey: [NAME_SPACE, 'refresh-mcp-server-code'],
mutationFn: (payload: { provider_id: string; authorization_code: string }) => {
return get<MCPServerDetail>('/workspaces/current/tool-provider/mcp/token', {
params: {
...payload,
},
})
},
})
}
export const useMCPTools = (providerID: string) => {
return useQuery({
enabled: !!providerID,
queryKey: [NAME_SPACE, 'get-MCP-provider-tool', providerID],
queryFn: () => get<{ tools: Tool[] }>(`/workspaces/current/tool-provider/mcp/tools/${providerID}`),
})
}
export const useInvalidateMCPTools = () => {
const queryClient = useQueryClient()
return (providerID: string) => {
queryClient.invalidateQueries(
{
queryKey: [NAME_SPACE, 'get-MCP-provider-tool', providerID],
})
}
}
export const useUpdateMCPTools = () => {
return useMutation({
mutationFn: (providerID: string) => get<{ tools: Tool[] }>(`/workspaces/current/tool-provider/mcp/update/${providerID}`),
})
}
export const useMCPServerDetail = (appID: string) => {
return useQuery<MCPServerDetail>({
queryKey: [NAME_SPACE, 'MCPServerDetail', appID],
queryFn: () => get<MCPServerDetail>(`/apps/${appID}/server`),
})
}
export const useInvalidateMCPServerDetail = () => {
const queryClient = useQueryClient()
return (appID: string) => {
queryClient.invalidateQueries(
{
queryKey: [NAME_SPACE, 'MCPServerDetail', appID],
})
}
}
export const useCreateMCPServer = () => {
return useMutation({
mutationKey: [NAME_SPACE, 'create-mcp-server'],
mutationFn: (payload: {
appID: string
description: string
parameters?: Record<string, string>
}) => {
const { appID, ...rest } = payload
return post(`apps/${appID}/server`, {
body: {
...rest,
},
})
},
})
}
export const useUpdateMCPServer = () => {
return useMutation({
mutationKey: [NAME_SPACE, 'update-mcp-server'],
mutationFn: (payload: {
appID: string
id: string
description?: string
status?: string
parameters?: Record<string, string>
}) => {
const { appID, ...rest } = payload
return put(`apps/${appID}/server`, {
body: {
...rest,
},
})
},
})
}
export const useRefreshMCPServerCode = () => {
return useMutation({
mutationKey: [NAME_SPACE, 'refresh-mcp-server-code'],
mutationFn: (appID: string) => {
return get<MCPServerDetail>(`apps/${appID}/server/refresh`)
},
})
}
export const useBuiltinProviderInfo = (providerName: string) => {
return useQuery({
queryKey: [NAME_SPACE, 'builtin-provider-info', providerName],

View File

@@ -1,5 +1,5 @@
import { del, get, patch, post, put } from './base'
import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query'
import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import type {
FetchWorkflowDraftPageParams,
FetchWorkflowDraftPageResponse,
@@ -23,6 +23,16 @@ export const useAppWorkflow = (appID: string) => {
})
}
export const useInvalidateAppWorkflow = () => {
const queryClient = useQueryClient()
return (appID: string) => {
queryClient.invalidateQueries(
{
queryKey: [NAME_SPACE, 'publish', appID],
})
}
}
export const useWorkflowConfig = (appId: string, onSuccess: (v: WorkflowConfigResponse) => void) => {
return useQuery({
queryKey: [NAME_SPACE, 'config', appId],