@opensumi/ide-ai-native 3.8.3-next-1745568063.0 → 3.8.3-next-1745835516.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/ai-core.contribution.d.ts +2 -0
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +58 -12
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/components/ChatInput.js +1 -1
- package/lib/browser/components/ChatInput.js.map +1 -1
- package/lib/browser/components/ChatMentionInput.js +1 -1
- package/lib/browser/components/ChatMentionInput.js.map +1 -1
- package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
- package/lib/browser/components/ChatToolRender.js +2 -1
- package/lib/browser/components/ChatToolRender.js.map +1 -1
- package/lib/browser/components/ChatToolResult.d.ts +8 -0
- package/lib/browser/components/ChatToolResult.d.ts.map +1 -0
- package/lib/browser/components/ChatToolResult.js +38 -0
- package/lib/browser/components/ChatToolResult.js.map +1 -0
- package/lib/browser/components/ChatToolResult.module.less +24 -0
- package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -1
- package/lib/browser/components/mention-input/mention-input.js +9 -7
- package/lib/browser/components/mention-input/mention-input.js.map +1 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +15 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/mcp/config/components/mcp-config.module.less +4 -1
- package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -1
- package/lib/browser/mcp/config/components/mcp-config.view.js +27 -119
- package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -1
- package/lib/browser/mcp/config/components/mcp-server-form.d.ts +1 -1
- package/lib/browser/mcp/config/components/mcp-server-form.d.ts.map +1 -1
- package/lib/browser/mcp/config/components/mcp-server-form.js +8 -8
- package/lib/browser/mcp/config/components/mcp-server-form.js.map +1 -1
- package/lib/browser/mcp/config/mcp-config.commands.d.ts +11 -4
- package/lib/browser/mcp/config/mcp-config.commands.d.ts.map +1 -1
- package/lib/browser/mcp/config/mcp-config.commands.js +23 -6
- package/lib/browser/mcp/config/mcp-config.commands.js.map +1 -1
- package/lib/browser/mcp/config/mcp-config.contribution.d.ts +4 -1
- package/lib/browser/mcp/config/mcp-config.contribution.d.ts.map +1 -1
- package/lib/browser/mcp/config/mcp-config.contribution.js +20 -1
- package/lib/browser/mcp/config/mcp-config.contribution.js.map +1 -1
- package/lib/browser/mcp/config/mcp-config.service.d.ts +30 -0
- package/lib/browser/mcp/config/mcp-config.service.d.ts.map +1 -0
- package/lib/browser/mcp/config/mcp-config.service.js +236 -0
- package/lib/browser/mcp/config/mcp-config.service.js.map +1 -0
- package/lib/browser/mcp/mcp-folder-preference-provider.d.ts +6 -0
- package/lib/browser/mcp/mcp-folder-preference-provider.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-folder-preference-provider.js +29 -0
- package/lib/browser/mcp/mcp-folder-preference-provider.js.map +1 -0
- package/lib/browser/mcp/mcp-preferences-contribution.d.ts +15 -0
- package/lib/browser/mcp/mcp-preferences-contribution.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-preferences-contribution.js +49 -0
- package/lib/browser/mcp/mcp-preferences-contribution.js.map +1 -0
- package/lib/browser/mcp/mcp-preferences.d.ts +6 -0
- package/lib/browser/mcp/mcp-preferences.d.ts.map +1 -0
- package/lib/browser/mcp/mcp-preferences.js +47 -0
- package/lib/browser/mcp/mcp-preferences.js.map +1 -0
- package/lib/browser/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +3 -0
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/common/mcp-server-manager.d.ts +2 -1
- package/lib/common/mcp-server-manager.d.ts.map +1 -1
- package/lib/common/mcp-server-manager.js +2 -1
- package/lib/common/mcp-server-manager.js.map +1 -1
- package/lib/common/types.d.ts +1 -1
- package/lib/common/types.d.ts.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.d.ts +3 -3
- package/lib/node/mcp/sumi-mcp-server.js +1 -1
- package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
- package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
- package/lib/node/mcp-server-manager-impl.js +9 -4
- package/lib/node/mcp-server-manager-impl.js.map +1 -1
- package/lib/node/mcp-server.sse.d.ts +10 -37
- package/lib/node/mcp-server.sse.d.ts.map +1 -1
- package/lib/node/mcp-server.sse.js +43 -15
- package/lib/node/mcp-server.sse.js.map +1 -1
- package/lib/node/mcp-server.stdio.d.ts +7 -34
- package/lib/node/mcp-server.stdio.d.ts.map +1 -1
- package/lib/node/mcp-server.stdio.js +27 -2
- package/lib/node/mcp-server.stdio.js.map +1 -1
- package/package.json +24 -24
- package/src/browser/ai-core.contribution.ts +71 -16
- package/src/browser/components/ChatInput.tsx +2 -2
- package/src/browser/components/ChatMentionInput.tsx +2 -2
- package/src/browser/components/ChatToolRender.tsx +3 -1
- package/src/browser/components/ChatToolResult.module.less +24 -0
- package/src/browser/components/ChatToolResult.tsx +64 -0
- package/src/browser/components/mention-input/mention-input.tsx +27 -23
- package/src/browser/index.ts +16 -0
- package/src/browser/mcp/config/components/mcp-config.module.less +4 -1
- package/src/browser/mcp/config/components/mcp-config.view.tsx +37 -125
- package/src/browser/mcp/config/components/mcp-server-form.tsx +10 -10
- package/src/browser/mcp/config/mcp-config.commands.ts +22 -6
- package/src/browser/mcp/config/mcp-config.contribution.ts +24 -2
- package/src/browser/mcp/config/mcp-config.service.ts +285 -0
- package/src/browser/mcp/mcp-folder-preference-provider.ts +23 -0
- package/src/browser/mcp/mcp-preferences-contribution.ts +62 -0
- package/src/browser/mcp/mcp-preferences.ts +48 -0
- package/src/browser/preferences/schema.ts +3 -0
- package/src/common/mcp-server-manager.ts +3 -1
- package/src/common/types.ts +1 -1
- package/src/node/mcp/sumi-mcp-server.ts +1 -1
- package/src/node/mcp-server-manager-impl.ts +8 -4
- package/src/node/mcp-server.sse.ts +41 -14
- package/src/node/mcp-server.stdio.ts +26 -2
|
@@ -1,190 +1,99 @@
|
|
|
1
1
|
import cls from 'classnames';
|
|
2
2
|
import React, { useCallback } from 'react';
|
|
3
3
|
|
|
4
|
-
import { Badge, Button, Popover, PopoverTriggerType } from '@opensumi/ide-components';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { PreferenceScope, localize } from '@opensumi/ide-core-common';
|
|
8
|
-
import { IMessageService } from '@opensumi/ide-overlay';
|
|
4
|
+
import { Badge, Button, Icon, Popover, PopoverTriggerType } from '@opensumi/ide-components';
|
|
5
|
+
import { useInjectable } from '@opensumi/ide-core-browser';
|
|
6
|
+
import { MCPConfigServiceToken, localize } from '@opensumi/ide-core-common';
|
|
9
7
|
|
|
10
|
-
import { BUILTIN_MCP_SERVER_NAME
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { MCPServerProxyService } from '../../mcp-server-proxy.service';
|
|
8
|
+
import { BUILTIN_MCP_SERVER_NAME } from '../../../../common';
|
|
9
|
+
import { MCPServer } from '../../../../common/types';
|
|
10
|
+
import { MCPConfigService } from '../mcp-config.service';
|
|
14
11
|
|
|
15
12
|
import styles from './mcp-config.module.less';
|
|
16
13
|
import { MCPServerForm, MCPServerFormData } from './mcp-server-form';
|
|
17
14
|
|
|
18
15
|
export const MCPConfigView: React.FC = () => {
|
|
19
|
-
const
|
|
20
|
-
const preferenceService = useInjectable<PreferenceService>(PreferenceService);
|
|
21
|
-
const messageService = useInjectable<IMessageService>(IMessageService);
|
|
22
|
-
const sumiMCPServerBackendProxy = useInjectable<ISumiMCPServerBackend>(SumiMCPServerProxyServicePath);
|
|
23
|
-
const logger = useInjectable<ILogger>(ILogger);
|
|
16
|
+
const mcpConfigService = useInjectable<MCPConfigService>(MCPConfigServiceToken);
|
|
24
17
|
const [servers, setServers] = React.useState<MCPServer[]>([]);
|
|
25
18
|
const [formVisible, setFormVisible] = React.useState(false);
|
|
26
19
|
const [editingServer, setEditingServer] = React.useState<MCPServerFormData | undefined>();
|
|
27
20
|
const [loadingServer, setLoadingServer] = React.useState<string | undefined>();
|
|
21
|
+
const [isReady, setIsReady] = React.useState(false);
|
|
22
|
+
|
|
28
23
|
const loadServers = useCallback(async () => {
|
|
29
|
-
const
|
|
30
|
-
const runningServers = await mcpServerProxyService.$getServers();
|
|
31
|
-
const builtinServer = runningServers.find((server) => server.name === BUILTIN_MCP_SERVER_NAME);
|
|
32
|
-
const allServers = userServers
|
|
33
|
-
.filter((server) => server.type === MCP_SERVER_TYPE.STDIO || server.type === MCP_SERVER_TYPE.SSE)
|
|
34
|
-
.map((server) => {
|
|
35
|
-
const runningServer = runningServers.find((s) => s.name === server.name);
|
|
36
|
-
return {
|
|
37
|
-
...server,
|
|
38
|
-
name: server.name,
|
|
39
|
-
isStarted: runningServer?.isStarted,
|
|
40
|
-
tools: runningServer?.tools,
|
|
41
|
-
};
|
|
42
|
-
}) as MCPServer[];
|
|
43
|
-
if (builtinServer) {
|
|
44
|
-
allServers.unshift(builtinServer);
|
|
45
|
-
}
|
|
24
|
+
const allServers = await mcpConfigService.getServers();
|
|
46
25
|
setServers(allServers);
|
|
47
|
-
}, [
|
|
26
|
+
}, [mcpConfigService]);
|
|
48
27
|
|
|
49
28
|
React.useEffect(() => {
|
|
50
29
|
loadServers();
|
|
51
|
-
const disposer =
|
|
30
|
+
const disposer = mcpConfigService.onMCPServersChange((isReady) => {
|
|
31
|
+
if (isReady) {
|
|
32
|
+
setIsReady(true);
|
|
33
|
+
}
|
|
52
34
|
loadServers();
|
|
53
35
|
});
|
|
54
36
|
|
|
55
37
|
return () => {
|
|
56
38
|
disposer.dispose();
|
|
57
39
|
};
|
|
58
|
-
}, []);
|
|
40
|
+
}, [loadServers]);
|
|
59
41
|
|
|
60
42
|
const handleServerControl = useCallback(
|
|
61
43
|
async (serverName: string, start: boolean) => {
|
|
62
44
|
try {
|
|
63
45
|
setLoadingServer(serverName);
|
|
64
|
-
|
|
65
|
-
await mcpServerProxyService.$startServer(serverName);
|
|
66
|
-
} else {
|
|
67
|
-
await mcpServerProxyService.$stopServer(serverName);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Update enabled state in preferences
|
|
71
|
-
const servers = preferenceService.get<MCPServerDescription[]>(AINativeSettingSectionsId.MCPServers, []);
|
|
72
|
-
let updatedServers = servers;
|
|
73
|
-
// 处理内置服务器的特殊情况
|
|
74
|
-
if (serverName === BUILTIN_MCP_SERVER_NAME) {
|
|
75
|
-
const builtinServerExists = servers.some((server) => server.name === BUILTIN_MCP_SERVER_NAME);
|
|
76
|
-
if (!builtinServerExists && !start) {
|
|
77
|
-
// 如果是停止内置服务器且之前没有配置,添加一个新的配置项
|
|
78
|
-
// 内置服务器不需要 command,因为它是直接集成在 IDE 中的
|
|
79
|
-
updatedServers = [
|
|
80
|
-
...servers,
|
|
81
|
-
{
|
|
82
|
-
name: BUILTIN_MCP_SERVER_NAME,
|
|
83
|
-
enabled: false,
|
|
84
|
-
type: MCP_SERVER_TYPE.BUILTIN,
|
|
85
|
-
},
|
|
86
|
-
];
|
|
87
|
-
} else {
|
|
88
|
-
// 如果已经存在配置,更新 enabled 状态
|
|
89
|
-
updatedServers = servers.map((server) => {
|
|
90
|
-
if (server.name === BUILTIN_MCP_SERVER_NAME) {
|
|
91
|
-
return { ...server, enabled: start };
|
|
92
|
-
}
|
|
93
|
-
return server;
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
} else {
|
|
97
|
-
// 处理其他外部服务器
|
|
98
|
-
updatedServers = servers.map((server) => {
|
|
99
|
-
if (server.name === serverName) {
|
|
100
|
-
return { ...server, enabled: start };
|
|
101
|
-
}
|
|
102
|
-
return server;
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
await preferenceService.set(AINativeSettingSectionsId.MCPServers, updatedServers, PreferenceScope.User);
|
|
46
|
+
await mcpConfigService.controlServer(serverName, start);
|
|
107
47
|
await loadServers();
|
|
108
48
|
setLoadingServer(undefined);
|
|
109
49
|
} catch (error) {
|
|
110
|
-
const msg = error.message || error;
|
|
111
|
-
logger.error(`Failed to ${start ? 'start' : 'stop'} server ${serverName}:`, msg);
|
|
112
|
-
messageService.error(msg);
|
|
113
50
|
setLoadingServer(undefined);
|
|
114
51
|
}
|
|
115
52
|
},
|
|
116
|
-
[
|
|
53
|
+
[mcpConfigService, loadServers],
|
|
117
54
|
);
|
|
118
55
|
|
|
119
56
|
const handleAddServer = useCallback(() => {
|
|
120
57
|
setEditingServer(undefined);
|
|
121
58
|
setFormVisible(true);
|
|
122
|
-
}, [
|
|
59
|
+
}, []);
|
|
123
60
|
|
|
124
61
|
const handleEditServer = useCallback(
|
|
125
|
-
(server: MCPServer) => {
|
|
126
|
-
const
|
|
127
|
-
const serverConfig = servers.find((s) => s.name === server.name);
|
|
128
|
-
|
|
62
|
+
async (server: MCPServer) => {
|
|
63
|
+
const serverConfig = await mcpConfigService.getServerConfigByName(server.name);
|
|
129
64
|
if (serverConfig) {
|
|
130
65
|
setEditingServer(serverConfig);
|
|
131
66
|
setFormVisible(true);
|
|
132
67
|
}
|
|
133
68
|
},
|
|
134
|
-
[
|
|
69
|
+
[mcpConfigService],
|
|
135
70
|
);
|
|
136
71
|
|
|
137
72
|
const handleDeleteServer = useCallback(
|
|
138
73
|
async (serverName: string) => {
|
|
139
|
-
|
|
140
|
-
const updatedServers = servers.filter((s) => s.name !== serverName);
|
|
141
|
-
sumiMCPServerBackendProxy.$removeServer(serverName);
|
|
142
|
-
await preferenceService.set(AINativeSettingSectionsId.MCPServers, updatedServers, PreferenceScope.User);
|
|
74
|
+
await mcpConfigService.deleteServer(serverName);
|
|
143
75
|
await loadServers();
|
|
144
76
|
},
|
|
145
|
-
[
|
|
77
|
+
[mcpConfigService, loadServers],
|
|
146
78
|
);
|
|
147
79
|
|
|
148
80
|
const handleSaveServer = useCallback(
|
|
149
81
|
async (data: MCPServerFormData) => {
|
|
150
|
-
|
|
151
|
-
const existingIndex = servers.findIndex((s) => s.name === data.name);
|
|
152
|
-
|
|
153
|
-
if (existingIndex >= 0) {
|
|
154
|
-
servers[existingIndex] = data;
|
|
155
|
-
} else {
|
|
156
|
-
servers.push(data);
|
|
157
|
-
}
|
|
158
|
-
setServers(servers as MCPServer[]);
|
|
82
|
+
await mcpConfigService.saveServer(data);
|
|
159
83
|
setFormVisible(false);
|
|
160
|
-
await sumiMCPServerBackendProxy.$addOrUpdateServer(data as MCPServerDescription);
|
|
161
|
-
await preferenceService.set(AINativeSettingSectionsId.MCPServers, servers, PreferenceScope.User);
|
|
162
84
|
await loadServers();
|
|
163
85
|
},
|
|
164
|
-
[
|
|
86
|
+
[mcpConfigService, loadServers],
|
|
165
87
|
);
|
|
166
88
|
|
|
167
|
-
const getReadableServerType = useCallback((type: string) => {
|
|
168
|
-
switch (type) {
|
|
169
|
-
case MCP_SERVER_TYPE.STDIO:
|
|
170
|
-
return localize('ai.native.mcp.type.stdio');
|
|
171
|
-
case MCP_SERVER_TYPE.SSE:
|
|
172
|
-
return localize('ai.native.mcp.type.sse');
|
|
173
|
-
case MCP_SERVER_TYPE.BUILTIN:
|
|
174
|
-
return localize('ai.native.mcp.type.builtin');
|
|
175
|
-
default:
|
|
176
|
-
return type;
|
|
177
|
-
}
|
|
178
|
-
}, []);
|
|
179
|
-
|
|
180
89
|
const handleSyncServer = useCallback(
|
|
181
90
|
async (server: MCPServer) => {
|
|
182
91
|
setLoadingServer(server.name);
|
|
183
|
-
await
|
|
92
|
+
await mcpConfigService.syncServer(server.name);
|
|
184
93
|
await loadServers();
|
|
185
94
|
setLoadingServer(undefined);
|
|
186
95
|
},
|
|
187
|
-
[
|
|
96
|
+
[mcpConfigService, loadServers],
|
|
188
97
|
);
|
|
189
98
|
|
|
190
99
|
return (
|
|
@@ -194,8 +103,9 @@ export const MCPConfigView: React.FC = () => {
|
|
|
194
103
|
<h2 className={styles.title}>MCP Servers</h2>
|
|
195
104
|
<p className={styles.description}>{localize('ai.native.mcp.manage.connections')}</p>
|
|
196
105
|
</div>
|
|
197
|
-
<button className={styles.
|
|
198
|
-
|
|
106
|
+
<button className={styles.actionButton} onClick={handleAddServer}>
|
|
107
|
+
<Icon icon='plus' className={styles.actionButtonIcon} />
|
|
108
|
+
{localize('ai.native.mcp.addMCPServer.title')}
|
|
199
109
|
</button>
|
|
200
110
|
</div>
|
|
201
111
|
<div className={styles.serversList}>
|
|
@@ -225,7 +135,7 @@ export const MCPConfigView: React.FC = () => {
|
|
|
225
135
|
>
|
|
226
136
|
<i
|
|
227
137
|
className={`codicon ${
|
|
228
|
-
loadingServer === server.name
|
|
138
|
+
loadingServer === server.name || (!isReady && server.name !== BUILTIN_MCP_SERVER_NAME)
|
|
229
139
|
? 'codicon-loading kt-icon-loading'
|
|
230
140
|
: server.isStarted
|
|
231
141
|
? 'codicon-check'
|
|
@@ -268,7 +178,9 @@ export const MCPConfigView: React.FC = () => {
|
|
|
268
178
|
{server.type && (
|
|
269
179
|
<div className={styles.detailRow}>
|
|
270
180
|
<span className={styles.detailLabel}>Type:</span>
|
|
271
|
-
<Badge className={cls(styles.serverType, styles.typeTag)}>
|
|
181
|
+
<Badge className={cls(styles.serverType, styles.typeTag)}>
|
|
182
|
+
{mcpConfigService.getReadableServerType(server.type)}
|
|
183
|
+
</Badge>
|
|
272
184
|
</div>
|
|
273
185
|
)}
|
|
274
186
|
</div>
|
|
@@ -294,11 +206,11 @@ export const MCPConfigView: React.FC = () => {
|
|
|
294
206
|
</div>
|
|
295
207
|
</div>
|
|
296
208
|
)}
|
|
297
|
-
{server.
|
|
209
|
+
{server.url && (
|
|
298
210
|
<div className={styles.serverDetail}>
|
|
299
211
|
<div className={styles.detailRow}>
|
|
300
212
|
<span className={styles.detailLabel}>Server Link:</span>
|
|
301
|
-
<span className={cls(styles.detailContent, styles.link)}>{server.
|
|
213
|
+
<span className={cls(styles.detailContent, styles.link)}>{server.url}</span>
|
|
302
214
|
</div>
|
|
303
215
|
</div>
|
|
304
216
|
)}
|
|
@@ -17,7 +17,7 @@ export interface MCPServerFormData {
|
|
|
17
17
|
args?: string[];
|
|
18
18
|
env?: Record<string, string>;
|
|
19
19
|
type: MCP_SERVER_TYPE;
|
|
20
|
-
|
|
20
|
+
url?: string;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
interface Props {
|
|
@@ -81,9 +81,9 @@ export const MCPServerForm: FC<Props> = ({ visible, initialData, onSave, onCance
|
|
|
81
81
|
return false;
|
|
82
82
|
}
|
|
83
83
|
if (formData.type === MCP_SERVER_TYPE.SSE) {
|
|
84
|
-
const isServerHostValid = formData.
|
|
84
|
+
const isServerHostValid = formData.url?.trim() !== '';
|
|
85
85
|
if (!isServerHostValid) {
|
|
86
|
-
messageService.error(localize('ai.native.mcp.
|
|
86
|
+
messageService.error(localize('ai.native.mcp.url.isRequired'));
|
|
87
87
|
}
|
|
88
88
|
return isServerHostValid;
|
|
89
89
|
}
|
|
@@ -107,7 +107,7 @@ export const MCPServerForm: FC<Props> = ({ visible, initialData, onSave, onCance
|
|
|
107
107
|
...formData,
|
|
108
108
|
};
|
|
109
109
|
if (formData.type === MCP_SERVER_TYPE.SSE) {
|
|
110
|
-
form.
|
|
110
|
+
form.url = form.url?.trim();
|
|
111
111
|
} else {
|
|
112
112
|
const args = argsText.split(' ').filter(Boolean);
|
|
113
113
|
const env = envText
|
|
@@ -127,7 +127,7 @@ export const MCPServerForm: FC<Props> = ({ visible, initialData, onSave, onCance
|
|
|
127
127
|
setFormData({
|
|
128
128
|
...formData,
|
|
129
129
|
command: '',
|
|
130
|
-
|
|
130
|
+
url: '',
|
|
131
131
|
args: [],
|
|
132
132
|
env: {},
|
|
133
133
|
});
|
|
@@ -160,7 +160,7 @@ export const MCPServerForm: FC<Props> = ({ visible, initialData, onSave, onCance
|
|
|
160
160
|
|
|
161
161
|
const handleServerHostChange = useCallback(
|
|
162
162
|
(e: ChangeEvent<HTMLTextAreaElement>) => {
|
|
163
|
-
setFormData({ ...formData,
|
|
163
|
+
setFormData({ ...formData, url: e.target.value });
|
|
164
164
|
},
|
|
165
165
|
[formData],
|
|
166
166
|
);
|
|
@@ -173,7 +173,7 @@ export const MCPServerForm: FC<Props> = ({ visible, initialData, onSave, onCance
|
|
|
173
173
|
command: '',
|
|
174
174
|
args: [],
|
|
175
175
|
env: {},
|
|
176
|
-
|
|
176
|
+
url: '',
|
|
177
177
|
});
|
|
178
178
|
},
|
|
179
179
|
[formData],
|
|
@@ -217,11 +217,11 @@ export const MCPServerForm: FC<Props> = ({ visible, initialData, onSave, onCance
|
|
|
217
217
|
return (
|
|
218
218
|
<>
|
|
219
219
|
<div className={styles.formItem}>
|
|
220
|
-
<label>{localize('ai.native.mcp.
|
|
220
|
+
<label>{localize('ai.native.mcp.url')}</label>
|
|
221
221
|
<textarea
|
|
222
|
-
value={formData.
|
|
222
|
+
value={formData.url}
|
|
223
223
|
onChange={handleServerHostChange}
|
|
224
|
-
placeholder={localize('ai.native.mcp.
|
|
224
|
+
placeholder={localize('ai.native.mcp.url.placeHolder')}
|
|
225
225
|
rows={3}
|
|
226
226
|
/>
|
|
227
227
|
</div>
|
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
import { Autowired } from '@opensumi/di';
|
|
2
2
|
import { CommandContribution, CommandRegistry, URI } from '@opensumi/ide-core-browser';
|
|
3
|
-
import { Domain } from '@opensumi/ide-core-common';
|
|
3
|
+
import { Domain, MCPConfigServiceToken } from '@opensumi/ide-core-common';
|
|
4
4
|
import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
5
5
|
|
|
6
6
|
import { MCP_CONFIG_COMPONENTS_SCHEME_ID } from './mcp-config.contribution';
|
|
7
|
+
import { MCPConfigService } from './mcp-config.service';
|
|
7
8
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
export namespace MCPConfigCommands {
|
|
10
|
+
export const OPEN_MCP_CONFIG = {
|
|
11
|
+
id: 'mcp.openConfig',
|
|
12
|
+
label: 'Open MCP Configuration',
|
|
13
|
+
};
|
|
12
14
|
|
|
15
|
+
export const OPEN_MCP_CONFIG_FILE = {
|
|
16
|
+
id: 'mcp.openConfigFile',
|
|
17
|
+
label: 'Open MCP Configuration (JSON)',
|
|
18
|
+
};
|
|
19
|
+
}
|
|
13
20
|
@Domain(CommandContribution)
|
|
14
21
|
export class MCPConfigCommandContribution implements CommandContribution {
|
|
15
22
|
@Autowired(WorkbenchEditorService)
|
|
16
23
|
private readonly editorService: WorkbenchEditorService;
|
|
17
24
|
|
|
25
|
+
@Autowired(MCPConfigServiceToken)
|
|
26
|
+
private readonly mcpConfigService: MCPConfigService;
|
|
27
|
+
|
|
18
28
|
registerCommands(registry: CommandRegistry) {
|
|
19
|
-
registry.registerCommand(
|
|
29
|
+
registry.registerCommand(MCPConfigCommands.OPEN_MCP_CONFIG, {
|
|
20
30
|
execute: () => {
|
|
21
31
|
const uri = new URI().withScheme(MCP_CONFIG_COMPONENTS_SCHEME_ID);
|
|
22
32
|
this.editorService.open(uri, {
|
|
@@ -25,5 +35,11 @@ export class MCPConfigCommandContribution implements CommandContribution {
|
|
|
25
35
|
});
|
|
26
36
|
},
|
|
27
37
|
});
|
|
38
|
+
|
|
39
|
+
registry.registerCommand(MCPConfigCommands.OPEN_MCP_CONFIG_FILE, {
|
|
40
|
+
execute: () => {
|
|
41
|
+
this.mcpConfigService.openConfigFile();
|
|
42
|
+
},
|
|
43
|
+
});
|
|
28
44
|
}
|
|
29
45
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Autowired } from '@opensumi/di';
|
|
2
2
|
import { getIcon } from '@opensumi/ide-components';
|
|
3
|
+
import { MenuContribution } from '@opensumi/ide-core-browser/lib/menu/next';
|
|
4
|
+
import { IMenuRegistry } from '@opensumi/ide-core-browser/lib/menu/next/base';
|
|
5
|
+
import { MenuId } from '@opensumi/ide-core-browser/lib/menu/next/menu-id';
|
|
3
6
|
import { LabelService } from '@opensumi/ide-core-browser/lib/services';
|
|
4
7
|
import { Domain, URI, localize } from '@opensumi/ide-core-common';
|
|
5
8
|
import {
|
|
@@ -13,14 +16,15 @@ import { IconService } from '@opensumi/ide-theme/lib/browser';
|
|
|
13
16
|
import { IWorkspaceService } from '@opensumi/ide-workspace/lib/common';
|
|
14
17
|
|
|
15
18
|
import { MCPConfigView } from './components/mcp-config.view';
|
|
19
|
+
import { MCPConfigCommands } from './mcp-config.commands';
|
|
16
20
|
|
|
17
21
|
const COMPONENTS_ID = 'opensumi-mcp-config-viewer';
|
|
18
22
|
export const MCP_CONFIG_COMPONENTS_SCHEME_ID = 'mcp-config';
|
|
19
23
|
|
|
20
24
|
export type IMCPConfigResource = IResource<{ configType: string }>;
|
|
21
25
|
|
|
22
|
-
@Domain(BrowserEditorContribution)
|
|
23
|
-
export class MCPConfigContribution implements BrowserEditorContribution {
|
|
26
|
+
@Domain(BrowserEditorContribution, MenuContribution)
|
|
27
|
+
export class MCPConfigContribution implements BrowserEditorContribution, MenuContribution {
|
|
24
28
|
@Autowired(IWorkspaceService)
|
|
25
29
|
protected readonly workspaceService: IWorkspaceService;
|
|
26
30
|
|
|
@@ -63,4 +67,22 @@ export class MCPConfigContribution implements BrowserEditorContribution {
|
|
|
63
67
|
},
|
|
64
68
|
});
|
|
65
69
|
}
|
|
70
|
+
|
|
71
|
+
registerMenus(menus: IMenuRegistry) {
|
|
72
|
+
menus.registerMenuItem(MenuId.EditorTitle, {
|
|
73
|
+
command: MCPConfigCommands.OPEN_MCP_CONFIG_FILE.id,
|
|
74
|
+
iconClass: getIcon('open'),
|
|
75
|
+
group: 'navigation',
|
|
76
|
+
order: 4,
|
|
77
|
+
when: `resourceScheme == ${MCP_CONFIG_COMPONENTS_SCHEME_ID}`,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
menus.registerMenuItem(MenuId.EditorTitle, {
|
|
81
|
+
command: MCPConfigCommands.OPEN_MCP_CONFIG.id,
|
|
82
|
+
iconClass: getIcon('open'),
|
|
83
|
+
group: 'navigation',
|
|
84
|
+
order: 4,
|
|
85
|
+
when: 'resourceFilename =~ /mcp.json/',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
66
88
|
}
|