feat: streamable http mcp (#4695)

* feat: streamable http mcp

* mcp api path

* fix: ts
This commit is contained in:
Archer
2025-04-28 12:45:51 +08:00
committed by GitHub
parent d91b2ae303
commit ca8adbbf95
15 changed files with 562 additions and 457 deletions

View File

@@ -184,16 +184,12 @@ const DashboardContainer = ({
: [])
]
},
...(feConfigs?.mcpServerProxyEndpoint
? [
{
groupId: TabEnum.mcp_server,
groupAvatar: 'key',
groupName: t('common:mcp_server'),
children: []
}
]
: [])
{
groupId: TabEnum.mcp_server,
groupAvatar: 'key',
groupName: t('common:mcp_server'),
children: []
}
];
}, [currentType, feConfigs.appTemplateCourse, pluginGroups, t, templateList, templateTags]);

View File

@@ -1,59 +1,113 @@
import { McpKeyType } from '@fastgpt/global/support/mcp/type';
import MyModal from '@fastgpt/web/components/common/MyModal';
import React from 'react';
import React, { useState } from 'react';
import { useTranslation } from 'next-i18next';
import { Box, Flex, HStack, ModalBody } from '@chakra-ui/react';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
import CopyBox from '@fastgpt/web/components/common/String/CopyBox';
import MyIconButton from '@fastgpt/web/components/common/Icon/button';
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
type LinkWay = 'sse' | 'http';
const UsageWay = ({ mcp, onClose }: { mcp: McpKeyType; onClose: () => void }) => {
const { t } = useTranslation();
const { feConfigs } = useSystemStore();
const [linkWay, setLinkWay] = useState<LinkWay>('http');
const sseUrl = `${feConfigs?.mcpServerProxyEndpoint}/${mcp.key}/sse`;
const jsonConfig = `{
const { url, jsonConfig } = (() => {
if (linkWay === 'http') {
const baseUrl = feConfigs?.customApiDomain || `${location.origin}/api`;
const url = `${baseUrl}/mcp/app/${mcp.key}/mcp`;
const jsonConfig = `{
"mcpServers": {
"${feConfigs?.systemTitle}-mcp-${mcp._id}": {
"url": "${sseUrl}"
"url": "${url}"
}
}
}`;
return {
url,
jsonConfig
};
}
const url = feConfigs?.mcpServerProxyEndpoint
? `${feConfigs?.mcpServerProxyEndpoint}/${mcp.key}/sse`
: '';
const jsonConfig = `{
"mcpServers": {
"${feConfigs?.systemTitle}-mcp-${mcp._id}": {
"url": "${url}"
}
}
}`;
return {
url,
jsonConfig
};
})();
return (
<MyModal isOpen title={t('dashboard_mcp:usage_way')} onClose={onClose}>
<MyModal iconSrc="key" isOpen title={t('dashboard_mcp:usage_way')} onClose={onClose}>
<ModalBody>
<Box>
<FormLabel>{t('dashboard_mcp:mcp_endpoints')}</FormLabel>
<HStack mt={0.5} bg={'myGray.50'} px={2} py={1} borderRadius={'md'} fontSize={'sm'}>
<Box userSelect={'all'} flex={'1 0 0'} whiteSpace={'pre-wrap'} wordBreak={'break-all'}>
{sseUrl}
<Flex>
<LightRowTabs<LinkWay>
m={'auto'}
w={'100%'}
list={[
{ label: 'Streamable HTTP', value: 'http' },
{ label: 'SSE', value: 'sse' }
]}
value={linkWay}
onChange={setLinkWay}
/>
</Flex>
{url ? (
<>
<Box mt={4}>
<FormLabel>{t('dashboard_mcp:mcp_endpoints')}</FormLabel>
<HStack mt={0.5} bg={'myGray.50'} px={2} py={1} borderRadius={'md'} fontSize={'sm'}>
<Box
userSelect={'all'}
flex={'1 0 0'}
whiteSpace={'pre-wrap'}
wordBreak={'break-all'}
>
{url}
</Box>
<CopyBox value={url}>
<MyIconButton icon="copy" />
</CopyBox>
</HStack>
</Box>
<CopyBox value={sseUrl}>
<MyIconButton icon="copy" />
</CopyBox>
</HStack>
</Box>
<Box mt={4}>
<Box borderRadius={'md'} bg={'myGray.100'} overflow={'hidden'} fontSize={'sm'}>
<Flex
p={3}
bg={'myWhite.500'}
border={'base'}
borderTopLeftRadius={'md'}
borderTopRightRadius={'md'}
>
<Box flex={1}>{t('dashboard_mcp:mcp_json_config')}</Box>
<CopyBox value={jsonConfig}>
<MyIconButton icon="copy" />
</CopyBox>
</Flex>
<Box whiteSpace={'pre-wrap'} wordBreak={'break-all'} p={3} overflowX={'auto'}>
{jsonConfig}
<Box mt={4}>
<Box borderRadius={'md'} bg={'myGray.100'} overflow={'hidden'} fontSize={'sm'}>
<Flex
p={3}
bg={'myWhite.500'}
border={'base'}
borderTopLeftRadius={'md'}
borderTopRightRadius={'md'}
>
<Box flex={1}>{t('dashboard_mcp:mcp_json_config')}</Box>
<CopyBox value={jsonConfig}>
<MyIconButton icon="copy" />
</CopyBox>
</Flex>
<Box whiteSpace={'pre-wrap'} wordBreak={'break-all'} p={3} overflowX={'auto'}>
{jsonConfig}
</Box>
</Box>
</Box>
</Box>
</Box>
</>
) : (
<Flex h={'200px'} justifyContent={'center'} alignItems={'center'}>
{t('dashboard_mcp:not_sse_server')}
</Flex>
)}
</ModalBody>
</MyModal>
);