1
- "use server" ;
1
+ if ( ! EXPORT_MODE ) {
2
+ ( "use server" ) ;
3
+ }
2
4
import {
3
5
createClient ,
4
6
executeRequest ,
@@ -14,14 +16,22 @@ import {
14
16
ServerConfig ,
15
17
ServerStatusResponse ,
16
18
} from "./types" ;
17
- import fs from "fs/promises" ;
18
- import path from "path" ;
19
- import { getServerSideConfig } from "../config/server" ;
19
+
20
+ const JSON_INDENT = 2 ;
20
21
21
22
const logger = new MCPClientLogger ( "MCP Actions" ) ;
22
- const CONFIG_PATH = path . join ( process . cwd ( ) , "app/mcp/mcp_config.json" ) ;
23
+
24
+ const getConfigPath = async ( ) => {
25
+ if ( EXPORT_MODE ) {
26
+ return "/mcp/config.json" ;
27
+ } else {
28
+ const path = await import ( "path" ) ;
29
+ return path . join ( process . cwd ( ) , "app/mcp/mcp_config.json" ) ;
30
+ }
31
+ } ;
23
32
24
33
const clientsMap = new Map < string , McpClientData > ( ) ;
34
+ const toolToClientMap = new Map < string , string > ( ) ;
25
35
26
36
// 获取客户端状态
27
37
export async function getClientsStatus ( ) : Promise <
@@ -126,6 +136,13 @@ async function initializeSingleClient(
126
136
`Supported tools for [${ clientId } ]: ${ JSON . stringify ( tools , null , 2 ) } ` ,
127
137
) ;
128
138
clientsMap . set ( clientId , { client, tools, errorMsg : null } ) ;
139
+ if ( tools ?. tools ) {
140
+ for ( const tool of tools . tools ) {
141
+ if ( tool . name ) {
142
+ toolToClientMap . set ( tool . name , clientId ) ;
143
+ }
144
+ }
145
+ }
129
146
logger . success ( `Client [${ clientId } ] initialized successfully` ) ;
130
147
} )
131
148
. catch ( ( error ) => {
@@ -243,6 +260,13 @@ export async function resumeMcpServer(clientId: string): Promise<void> {
243
260
const client = await createClient ( clientId , serverConfig ) ;
244
261
const tools = await listTools ( client ) ;
245
262
clientsMap . set ( clientId , { client, tools, errorMsg : null } ) ;
263
+ if ( tools ?. tools ) {
264
+ for ( const tool of tools . tools ) {
265
+ if ( tool . name ) {
266
+ toolToClientMap . set ( tool . name , clientId ) ;
267
+ }
268
+ }
269
+ }
246
270
logger . success ( `Client [${ clientId } ] initialized successfully` ) ;
247
271
248
272
// 初始化成功后更新配置
@@ -339,7 +363,19 @@ export async function executeMcpAction(
339
363
request : McpRequestMessage ,
340
364
) {
341
365
try {
342
- const client = clientsMap . get ( clientId ) ;
366
+ let client = clientsMap . get ( clientId ) ;
367
+ if (
368
+ ! client &&
369
+ request . params ?. name &&
370
+ typeof request . params . name === "string"
371
+ ) {
372
+ // Use a tool-to-client mapping that's maintained when tools are initialized
373
+ const toolName = request . params . name ;
374
+ const toolClientId = toolToClientMap . get ( toolName ) ;
375
+ if ( toolClientId ) {
376
+ client = clientsMap . get ( toolClientId ) ;
377
+ }
378
+ }
343
379
if ( ! client ?. client ) {
344
380
throw new Error ( `Client ${ clientId } not found` ) ;
345
381
}
@@ -354,8 +390,30 @@ export async function executeMcpAction(
354
390
// 获取 MCP 配置文件
355
391
export async function getMcpConfigFromFile ( ) : Promise < McpConfigData > {
356
392
try {
357
- const configStr = await fs . readFile ( CONFIG_PATH , "utf-8" ) ;
358
- return JSON . parse ( configStr ) ;
393
+ if ( EXPORT_MODE ) {
394
+ const res = await fetch ( await getConfigPath ( ) ) ;
395
+ const config : McpConfigData = await res . json ( ) ;
396
+ const storage = localStorage ;
397
+ const storedConfig_str = storage . getItem ( "McpConfig" ) ;
398
+ if ( storedConfig_str ) {
399
+ const storedConfig : McpConfigData = JSON . parse ( storedConfig_str ) ;
400
+ // Create a merged configuration that combines both sources
401
+ const merged = { ...config . mcpServers } ;
402
+ if ( storedConfig . mcpServers ) {
403
+ // Ensure we process all servers from stored config
404
+ for ( const id in storedConfig . mcpServers ) {
405
+ merged [ id ] = { ...merged [ id ] , ...storedConfig . mcpServers [ id ] } ;
406
+ }
407
+ }
408
+
409
+ config . mcpServers = merged ;
410
+ }
411
+ return config ;
412
+ } else {
413
+ const fs = await import ( "fs/promises" ) ;
414
+ const configStr = await fs . readFile ( await getConfigPath ( ) , "utf-8" ) ;
415
+ return JSON . parse ( configStr ) ;
416
+ }
359
417
} catch ( error ) {
360
418
logger . error ( `Failed to load MCP config, using default config: ${ error } ` ) ;
361
419
return DEFAULT_MCP_CONFIG ;
@@ -364,20 +422,42 @@ export async function getMcpConfigFromFile(): Promise<McpConfigData> {
364
422
365
423
// 更新 MCP 配置文件
366
424
async function updateMcpConfig ( config : McpConfigData ) : Promise < void > {
367
- try {
425
+ if ( EXPORT_MODE ) {
426
+ try {
427
+ const storage = localStorage ;
428
+ storage . setItem ( "McpConfig" , JSON . stringify ( config ) ) ;
429
+ } catch ( storageError ) {
430
+ logger . warn ( `Failed to save MCP config to localStorage: ${ storageError } ` ) ;
431
+ // Continue execution without storage
432
+ }
433
+ } else {
434
+ const fs = await import ( "fs/promises" ) ;
435
+ const path = await import ( "path" ) ;
368
436
// 确保目录存在
369
- await fs . mkdir ( path . dirname ( CONFIG_PATH ) , { recursive : true } ) ;
370
- await fs . writeFile ( CONFIG_PATH , JSON . stringify ( config , null , 2 ) ) ;
371
- } catch ( error ) {
372
- throw error ;
437
+ await fs . mkdir ( path . dirname ( await getConfigPath ( ) ) , { recursive : true } ) ;
438
+ await fs . writeFile (
439
+ await getConfigPath ( ) ,
440
+ JSON . stringify ( config , null , JSON_INDENT ) ,
441
+ ) ;
373
442
}
374
443
}
375
444
376
445
// 检查 MCP 是否启用
377
446
export async function isMcpEnabled ( ) {
378
447
try {
379
- const serverConfig = getServerSideConfig ( ) ;
380
- return serverConfig . enableMcp ;
448
+ const config = await getMcpConfigFromFile ( ) ;
449
+ if ( typeof config . enableMcp === "boolean" ) {
450
+ return config . enableMcp ;
451
+ }
452
+ if ( EXPORT_MODE ) {
453
+ const { getClientConfig } = await import ( "../config/client" ) ;
454
+ const clientConfig = getClientConfig ( ) ;
455
+ return clientConfig ?. enableMcp === true ;
456
+ } else {
457
+ const { getServerSideConfig } = await import ( "../config/server" ) ;
458
+ const serverConfig = getServerSideConfig ( ) ;
459
+ return serverConfig . enableMcp ;
460
+ }
381
461
} catch ( error ) {
382
462
logger . error ( `Failed to check MCP status: ${ error } ` ) ;
383
463
return false ;
0 commit comments