@@ -4,7 +4,7 @@ import { ApiOutlined, SaveOutlined, DisconnectOutlined } from '@ant-design/icons
44import { useDispatch , useSelector } from 'react-redux' ;
55import { connectToServer , disconnectFromServer } from '../store/mcpSlice' ;
66import { RootState } from '../store' ;
7- import { MCPServerConfig } from '../types/mcp' ;
7+ import { MCPServerConfig , MCPTransportMode } from '../types/mcp' ;
88import { storage } from '../utils/storage' ;
99import AuthConfigComponent from './AuthConfig' ;
1010import { useI18n } from '../hooks/useI18n' ;
@@ -29,6 +29,7 @@ const ConfigPanel: React.FC<ConfigPanelProps> = ({ onConfigLoad, selectedConfig,
2929 form . setFieldsValue ( {
3030 name : selectedConfig . name ,
3131 host : selectedConfig . host ,
32+ transport : selectedConfig . transport ,
3233 ssePath : selectedConfig . ssePath ,
3334 sessionId : selectedConfig . sessionId
3435 } ) ;
@@ -42,9 +43,9 @@ const ConfigPanel: React.FC<ConfigPanelProps> = ({ onConfigLoad, selectedConfig,
4243 const serverConfig : MCPServerConfig = {
4344 name : values . name || 'MCP Server' , // 如果没有填写名称,使用默认值
4445 host : values . host ,
45- ssePath : values . ssePath ,
46+ ssePath : values . ssePath , // 两种模式都需要路径
4647 messagePath : '' , // 现在从SSE自动获取,不需要配置
47- transport : 'sse' , // 固定为SSE传输方式
48+ transport : values . transport as MCPTransportMode , // 使用选择的传输方式
4849 sessionId : values . sessionId || undefined ,
4950 headers : values . headers ? JSON . parse ( values . headers || '{}' ) : undefined ,
5051 auth : authConfig // 添加认证配置
@@ -106,9 +107,9 @@ const ConfigPanel: React.FC<ConfigPanelProps> = ({ onConfigLoad, selectedConfig,
106107 const serverConfig : MCPServerConfig = {
107108 name : values . name || 'MCP Server' ,
108109 host : values . host ,
109- ssePath : values . ssePath ,
110+ ssePath : values . ssePath , // 两种模式都需要路径
110111 messagePath : '' ,
111- transport : 'sse' ,
112+ transport : values . transport as MCPTransportMode ,
112113 sessionId : values . sessionId || undefined ,
113114 headers : values . headers ? JSON . parse ( values . headers || '{}' ) : undefined ,
114115 auth : authConfig
@@ -152,6 +153,18 @@ const ConfigPanel: React.FC<ConfigPanelProps> = ({ onConfigLoad, selectedConfig,
152153 < Input placeholder = { t . config . serverNamePlaceholder } />
153154 </ Form . Item >
154155
156+ < Form . Item
157+ name = "transport"
158+ label = { t . config . transportMode }
159+ rules = { [ { required : true , message : t . config . messages . transportModeRequired } ] }
160+ tooltip = { t . config . transportModeTooltip }
161+ >
162+ < Select placeholder = { t . config . transportModePlaceholder } >
163+ < Select . Option value = "sse" > { t . config . transportModes . sse } </ Select . Option >
164+ < Select . Option value = "streamable" > { t . config . transportModes . streamable } </ Select . Option >
165+ </ Select >
166+ </ Form . Item >
167+
155168 < Form . Item
156169 name = "host"
157170 label = { t . config . serverHost }
@@ -168,12 +181,37 @@ const ConfigPanel: React.FC<ConfigPanelProps> = ({ onConfigLoad, selectedConfig,
168181 </ Form . Item >
169182
170183 < Form . Item
171- name = "ssePath"
172- label = { t . config . ssePath }
173- rules = { [ { required : true , message : t . config . messages . ssePathRequired } ] }
174- tooltip = { t . config . ssePathPlaceholder }
184+ noStyle
185+ shouldUpdate = { ( prevValues , currentValues ) => prevValues . transport !== currentValues . transport }
175186 >
176- < Input placeholder = { t . config . ssePathPlaceholder } />
187+ { ( { getFieldValue, setFieldsValue } ) => {
188+ const transport = getFieldValue ( 'transport' ) ;
189+
190+ // 当传输模式改变时,自动更新路径默认值(移除useEffect,直接在渲染时检查)
191+ const currentPath = getFieldValue ( 'ssePath' ) ;
192+ if ( ! currentPath || currentPath === '/sse' || currentPath === '/mcp' ) {
193+ const newPath = transport === 'sse' ? '/sse' : '/mcp' ;
194+ if ( currentPath !== newPath ) {
195+ // 使用 setTimeout 避免在渲染过程中更新状态
196+ setTimeout ( ( ) => {
197+ setFieldsValue ( {
198+ ssePath : newPath
199+ } ) ;
200+ } , 0 ) ;
201+ }
202+ }
203+
204+ return (
205+ < Form . Item
206+ name = "ssePath"
207+ label = { transport === 'sse' ? t . config . ssePath : t . config . mcpPath }
208+ rules = { [ { required : true , message : transport === 'sse' ? t . config . messages . ssePathRequired : t . config . messages . mcpPathRequired } ] }
209+ tooltip = { transport === 'sse' ? t . config . ssePathPlaceholder : t . config . mcpPathPlaceholder }
210+ >
211+ < Input placeholder = { transport === 'sse' ? t . config . ssePathPlaceholder : t . config . mcpPathPlaceholder } />
212+ </ Form . Item >
213+ ) ;
214+ } }
177215 </ Form . Item >
178216
179217 < Form . Item label = { t . config . authentication } >
@@ -223,6 +261,11 @@ const ConfigPanel: React.FC<ConfigPanelProps> = ({ onConfigLoad, selectedConfig,
223261 < div style = { { marginBottom : 16 , padding : 12 , backgroundColor : '#f6ffed' , border : '1px solid #b7eb8f' , borderRadius : 4 } } >
224262 < p > < strong > { t . config . connectionStatus . connected } :</ strong > { serverConfig ?. name } </ p >
225263 < p > < strong > { t . config . serverHost } :</ strong > { serverConfig ?. host } </ p >
264+ < p > < strong > { t . config . transportMode } :</ strong > {
265+ serverConfig ?. transport === 'streamable'
266+ ? t . config . transportModes . streamable
267+ : t . config . transportModes . sse
268+ } </ p >
226269 < p > < strong > { t . config . authType } :</ strong > {
227270 ( ( ) => {
228271 const authType = serverConfig ?. auth ?. type ;
0 commit comments