aiexecode 1.0.90 → 1.0.92
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.
Potentially problematic release.
This version of aiexecode might be problematic. Click here for more details.
- package/README.md +1 -0
- package/index.js +13 -11
- package/mcp-agent-lib/init.sh +3 -0
- package/mcp-agent-lib/package-lock.json +14 -1
- package/mcp-agent-lib/package.json +4 -6
- package/mcp-agent-lib/sampleFastMCPClient/client.py +25 -0
- package/mcp-agent-lib/sampleFastMCPClient/run.sh +3 -0
- package/mcp-agent-lib/sampleFastMCPServer/run.sh +3 -0
- package/mcp-agent-lib/sampleFastMCPServer/server.py +12 -0
- package/mcp-agent-lib/sampleFastMCPServerElicitationRequest/run.sh +3 -0
- package/mcp-agent-lib/sampleFastMCPServerElicitationRequest/server.py +43 -0
- package/mcp-agent-lib/sampleFastMCPServerRootsRequest/server.py +63 -0
- package/mcp-agent-lib/sampleMCPHost/index.js +182 -63
- package/mcp-agent-lib/sampleMCPHost/mcp_config.json +7 -1
- package/mcp-agent-lib/sampleMCPHostFeatures/elicitation.js +151 -0
- package/mcp-agent-lib/sampleMCPHostFeatures/index.js +166 -0
- package/mcp-agent-lib/sampleMCPHostFeatures/roots.js +197 -0
- package/mcp-agent-lib/src/mcp_client.js +129 -67
- package/mcp-agent-lib/src/mcp_message_logger.js +516 -0
- package/package.json +3 -1
- package/payload_viewer/out/404/index.html +1 -1
- package/payload_viewer/out/404.html +1 -1
- package/payload_viewer/out/index.html +1 -1
- package/payload_viewer/out/index.txt +1 -1
- package/src/LLMClient/client.js +992 -0
- package/src/LLMClient/converters/input-normalizer.js +238 -0
- package/src/LLMClient/converters/responses-to-claude.js +454 -0
- package/src/LLMClient/converters/responses-to-gemini.js +648 -0
- package/src/LLMClient/converters/responses-to-ollama.js +348 -0
- package/src/LLMClient/errors.js +372 -0
- package/src/LLMClient/index.js +31 -0
- package/src/commands/apikey.js +10 -22
- package/src/commands/model.js +28 -28
- package/src/commands/reasoning_effort.js +9 -23
- package/src/config/ai_models.js +212 -0
- package/src/config/feature_flags.js +1 -1
- package/src/frontend/App.js +5 -10
- package/src/frontend/components/CurrentModelView.js +0 -33
- package/src/frontend/components/Footer.js +3 -3
- package/src/frontend/components/ModelListView.js +30 -87
- package/src/frontend/components/ModelUpdatedView.js +7 -142
- package/src/frontend/components/SetupWizard.js +37 -32
- package/src/system/ai_request.js +57 -42
- package/src/util/config.js +26 -4
- package/src/util/setup_wizard.js +1 -6
- package/mcp-agent-lib/.claude/settings.local.json +0 -9
- package/src/config/openai_models.js +0 -152
- /package/payload_viewer/out/_next/static/{w4dMVYalgk7djrLxRxWiE → d0-fu2rgYnshgGFPxr1CR}/_buildManifest.js +0 -0
- /package/payload_viewer/out/_next/static/{w4dMVYalgk7djrLxRxWiE → d0-fu2rgYnshgGFPxr1CR}/_clientMiddlewareManifest.json +0 -0
- /package/payload_viewer/out/_next/static/{w4dMVYalgk7djrLxRxWiE → d0-fu2rgYnshgGFPxr1CR}/_ssgManifest.js +0 -0
|
@@ -19,6 +19,8 @@ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
|
|
|
19
19
|
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
20
20
|
// HTTP 전송: 일반 HTTP/HTTPS 요청-응답 기반 통신
|
|
21
21
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
22
|
+
// RAW 메시지 로거
|
|
23
|
+
import { MCPMessageLogger, attachLoggerToTransport } from './mcp_message_logger.js';
|
|
22
24
|
|
|
23
25
|
// 내부 디버그용 로그 함수 - 실제로는 아무 작업도 하지 않음 (성능 최적화)
|
|
24
26
|
function consolelog() { }
|
|
@@ -56,9 +58,6 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
56
58
|
serverReadyTimeout: MCPAgentClient._safeParseInt(process.env.MCP_SERVER_READY_TIMEOUT || options.serverReadyTimeout, 10000),
|
|
57
59
|
serverReadyRetries: MCPAgentClient._safeParseInt(process.env.MCP_SERVER_READY_RETRIES || options.serverReadyRetries, 5),
|
|
58
60
|
|
|
59
|
-
// 보안 설정: stdio 서버에서 실행 가능한 명령어 화이트리스트
|
|
60
|
-
allowedCommands: ['node', 'python', 'python3', 'npx', 'deno'],
|
|
61
|
-
|
|
62
61
|
// 보안 설정: 명령 인자에서 금지되는 셸 특수문자 (command injection 방지)
|
|
63
62
|
dangerousChars: ['&', ';', '|', '`', '$', '>', '<', '*', '?'],
|
|
64
63
|
|
|
@@ -76,9 +75,10 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
76
75
|
},
|
|
77
76
|
|
|
78
77
|
// MCP 프로토콜: 클라이언트 식별 정보
|
|
78
|
+
// options.clientInfo로 전달 가능, 없으면 기본값 사용
|
|
79
79
|
clientInfo: {
|
|
80
|
-
name:
|
|
81
|
-
version:
|
|
80
|
+
name: options.clientInfo?.name || 'mcp-agent-lib',
|
|
81
|
+
version: options.clientInfo?.version || '1.0.0'
|
|
82
82
|
},
|
|
83
83
|
|
|
84
84
|
// 사용자 메시지 템플릿 (다국어 지원용)
|
|
@@ -117,6 +117,12 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
117
117
|
// 연결 해제된 서버 정보를 주기적으로 정리 (interval 대신 on-demand 방식)
|
|
118
118
|
this.memoryCleanupEnabled = options.memoryCleanupEnabled ?? true;
|
|
119
119
|
this.lastCleanupTime = Date.now();
|
|
120
|
+
|
|
121
|
+
// RAW 메시지 로거 초기화
|
|
122
|
+
this.messageLogger = options.messageLogger || new MCPMessageLogger({
|
|
123
|
+
enabled: options.enableRawMessageLogging ?? false,
|
|
124
|
+
...options.messageLoggerOptions
|
|
125
|
+
});
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
/**
|
|
@@ -403,10 +409,9 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
403
409
|
* 서버 설정 보안 검증
|
|
404
410
|
*
|
|
405
411
|
* 연결 전에 서버 설정이 안전한지 검사:
|
|
406
|
-
* 1. stdio 서버:
|
|
407
|
-
* 2.
|
|
408
|
-
* 3.
|
|
409
|
-
* 4. 환경변수가 문자열 key-value인지 확인
|
|
412
|
+
* 1. stdio 서버: 인자에 위험한 셸 문자가 없는지 확인
|
|
413
|
+
* 2. http 서버: URL이 http/https 프로토콜인지 확인
|
|
414
|
+
* 3. 환경변수가 문자열 key-value인지 확인
|
|
410
415
|
*/
|
|
411
416
|
validateServerConfig(serverName, serverConfig) {
|
|
412
417
|
if (!serverName || typeof serverName !== 'string') {
|
|
@@ -419,13 +424,6 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
419
424
|
|
|
420
425
|
// stdio 서버 보안 검증
|
|
421
426
|
if (serverConfig.command) {
|
|
422
|
-
const allowedCommands = this.options.allowedCommands || ['node', 'python', 'python3', 'npx', 'deno'];
|
|
423
|
-
|
|
424
|
-
// 화이트리스트에 없는 명령어는 실행 불가
|
|
425
|
-
if (!allowedCommands.includes(serverConfig.command)) {
|
|
426
|
-
throw new Error(`Command '${serverConfig.command}' is not allowed. Allowed commands: ${allowedCommands.join(', ')}`);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
427
|
// 명령 인자에 셸 특수문자 포함 여부 검사 (command injection 방지)
|
|
430
428
|
if (serverConfig.args && Array.isArray(serverConfig.args)) {
|
|
431
429
|
const dangerousChars = this.options.dangerousChars || ['&', ';', '|', '`', '$', '>', '<', '*', '?'];
|
|
@@ -503,7 +501,7 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
503
501
|
|
|
504
502
|
} catch (error) {
|
|
505
503
|
// 보안 에러는 즉시 전파 (다른 서버 연결 중단)
|
|
506
|
-
if (error.message.includes('
|
|
504
|
+
if (error.message.includes('dangerous characters')) {
|
|
507
505
|
throw error;
|
|
508
506
|
}
|
|
509
507
|
// 일반 연결 에러는 로그만 남기고 다음 서버 계속 진행
|
|
@@ -588,6 +586,9 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
588
586
|
this.emit('serverDisconnected', serverName);
|
|
589
587
|
};
|
|
590
588
|
|
|
589
|
+
// RAW 메시지 로거 연결
|
|
590
|
+
attachLoggerToTransport(transport, serverName, this.messageLogger);
|
|
591
|
+
|
|
591
592
|
// MCP 프로토콜 핸드셰이크 수행
|
|
592
593
|
await client.connect(transport);
|
|
593
594
|
|
|
@@ -600,10 +601,10 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
600
601
|
this.clients.set(serverName, client);
|
|
601
602
|
|
|
602
603
|
// 서버가 완전히 준비될 때까지 대기 (재시도 로직 포함)
|
|
603
|
-
await this._waitForServerReady(client, serverName);
|
|
604
|
+
const readyData = await this._waitForServerReady(client, serverName);
|
|
604
605
|
|
|
605
606
|
// 사용 가능한 tools/resources/prompts 목록 조회 및 저장
|
|
606
|
-
await this.listServerCapabilities(serverName);
|
|
607
|
+
await this.listServerCapabilities(serverName, readyData);
|
|
607
608
|
|
|
608
609
|
// Log final server statistics without duplicate status setting
|
|
609
610
|
const updatedServer = this.servers.get(serverName);
|
|
@@ -685,6 +686,9 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
685
686
|
this.emit('serverDisconnected', serverName);
|
|
686
687
|
};
|
|
687
688
|
|
|
689
|
+
// RAW 메시지 로거 연결 (헤더 정보 포함)
|
|
690
|
+
attachLoggerToTransport(transport, serverName, this.messageLogger, serverConfig.headers);
|
|
691
|
+
|
|
688
692
|
// Connect using SDK
|
|
689
693
|
await client.connect(transport);
|
|
690
694
|
|
|
@@ -696,10 +700,10 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
696
700
|
this.clients.set(serverName, client);
|
|
697
701
|
|
|
698
702
|
// Wait for server to be ready before querying capabilities
|
|
699
|
-
await this._waitForServerReady(client, serverName);
|
|
703
|
+
const readyData = await this._waitForServerReady(client, serverName);
|
|
700
704
|
|
|
701
705
|
// List available capabilities
|
|
702
|
-
await this.listServerCapabilities(serverName);
|
|
706
|
+
await this.listServerCapabilities(serverName, readyData);
|
|
703
707
|
|
|
704
708
|
this._log('info', `✅ Successfully connected to HTTP server ${serverName}`);
|
|
705
709
|
return server;
|
|
@@ -763,6 +767,9 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
763
767
|
this.emit('serverDisconnected', name);
|
|
764
768
|
};
|
|
765
769
|
|
|
770
|
+
// RAW 메시지 로거 연결 (헤더 정보 포함)
|
|
771
|
+
attachLoggerToTransport(transport, name, this.messageLogger, config.headers);
|
|
772
|
+
|
|
766
773
|
await client.connect(transport);
|
|
767
774
|
server.capabilities = client.getServerCapabilities();
|
|
768
775
|
this._setServerStatus(name, 'connected');
|
|
@@ -771,9 +778,9 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
771
778
|
this.clients.set(name, client);
|
|
772
779
|
|
|
773
780
|
// Wait for server to be ready before querying capabilities
|
|
774
|
-
await this._waitForServerReady(client, name);
|
|
781
|
+
const readyData = await this._waitForServerReady(client, name);
|
|
775
782
|
|
|
776
|
-
await this.listServerCapabilities(name);
|
|
783
|
+
await this.listServerCapabilities(name, readyData);
|
|
777
784
|
|
|
778
785
|
this._log('info', `✅ ${name} SSE 연결됨`);
|
|
779
786
|
return server;
|
|
@@ -782,7 +789,7 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
782
789
|
/**
|
|
783
790
|
* List all capabilities of the connected server
|
|
784
791
|
*/
|
|
785
|
-
async listServerCapabilities(serverName) {
|
|
792
|
+
async listServerCapabilities(serverName, readyData = null) {
|
|
786
793
|
const server = this.servers.get(serverName);
|
|
787
794
|
if (!server) return;
|
|
788
795
|
|
|
@@ -795,56 +802,79 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
795
802
|
return;
|
|
796
803
|
}
|
|
797
804
|
|
|
798
|
-
//
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
if (
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
805
|
+
// Check capabilities to determine what to query
|
|
806
|
+
const capabilities = server.capabilities || {};
|
|
807
|
+
|
|
808
|
+
// Query tools only if capability is declared
|
|
809
|
+
if (capabilities.tools) {
|
|
810
|
+
try {
|
|
811
|
+
let toolsResponse;
|
|
812
|
+
if (readyData && readyData.tools) {
|
|
813
|
+
// Reuse data from _waitForServerReady
|
|
814
|
+
toolsResponse = readyData.tools;
|
|
815
|
+
this._log('debug', `♻️ Reusing tools data from readiness check`);
|
|
816
|
+
} else {
|
|
817
|
+
// Fetch tools if not available from readiness check
|
|
818
|
+
toolsResponse = await client.listTools();
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
server.tools = toolsResponse.tools || [];
|
|
822
|
+
this._log('info', `🔧 Available tools from ${serverName}:`);
|
|
823
|
+
server.tools.forEach((tool, index) => {
|
|
824
|
+
this._log('info', ` ${index + 1}. ${tool.name}`);
|
|
825
|
+
if (tool.description) this._log('info', ` 설명: ${tool.description}`);
|
|
826
|
+
});
|
|
827
|
+
} catch (toolsError) {
|
|
828
|
+
this._log('warn', `⚠️ Tools/list failed: ${toolsError.message}`);
|
|
829
|
+
server.tools = [];
|
|
830
|
+
// Mark server as partially connected if critical capabilities fail
|
|
831
|
+
if (toolsError.message.includes('timeout') || toolsError.message.includes('connection')) {
|
|
832
|
+
this._setServerStatus(serverName, 'partially_connected');
|
|
833
|
+
}
|
|
813
834
|
}
|
|
835
|
+
} else {
|
|
836
|
+
this._log('debug', `ℹ️ Server ${serverName} does not declare tools capability`);
|
|
837
|
+
server.tools = [];
|
|
814
838
|
}
|
|
815
839
|
|
|
816
|
-
//
|
|
840
|
+
// Query resources only if capability is declared
|
|
817
841
|
let resources = [];
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
resources.
|
|
824
|
-
|
|
825
|
-
|
|
842
|
+
if (capabilities.resources) {
|
|
843
|
+
try {
|
|
844
|
+
const resourcesResponse = await client.listResources();
|
|
845
|
+
resources = resourcesResponse.resources || [];
|
|
846
|
+
this._log('info', `📄 Available resources from ${serverName}: ${resources.length} found`);
|
|
847
|
+
if (resources.length > 0) {
|
|
848
|
+
resources.forEach((resource, index) => {
|
|
849
|
+
this._log('info', ` ${index + 1}. ${resource.name} (${resource.uri})`);
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
} catch (resourcesError) {
|
|
853
|
+
this._log('debug', `ℹ️ Resources not available from ${serverName}: ${resourcesError.message}`);
|
|
854
|
+
resources = [];
|
|
826
855
|
}
|
|
827
|
-
}
|
|
828
|
-
this._log('debug', `ℹ️
|
|
829
|
-
resources = [];
|
|
830
|
-
// Don't mark as partially connected for resources as they're optional
|
|
856
|
+
} else {
|
|
857
|
+
this._log('debug', `ℹ️ Server ${serverName} does not declare resources capability`);
|
|
831
858
|
}
|
|
832
859
|
|
|
833
|
-
//
|
|
860
|
+
// Query prompts only if capability is declared
|
|
834
861
|
let prompts = [];
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
prompts.
|
|
841
|
-
|
|
842
|
-
|
|
862
|
+
if (capabilities.prompts) {
|
|
863
|
+
try {
|
|
864
|
+
const promptsResponse = await client.listPrompts();
|
|
865
|
+
prompts = promptsResponse.prompts || [];
|
|
866
|
+
this._log('info', `💬 Available prompts from ${serverName}: ${prompts.length} found`);
|
|
867
|
+
if (prompts.length > 0) {
|
|
868
|
+
prompts.forEach((prompt, index) => {
|
|
869
|
+
this._log('info', ` ${index + 1}. ${prompt.name}: ${prompt.description || 'No description'}`);
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
} catch (promptsError) {
|
|
873
|
+
this._log('debug', `ℹ️ Prompts not available from ${serverName}: ${promptsError.message}`);
|
|
874
|
+
prompts = [];
|
|
843
875
|
}
|
|
844
|
-
}
|
|
845
|
-
this._log('debug', `ℹ️
|
|
846
|
-
prompts = [];
|
|
847
|
-
// Don't mark as partially connected for prompts as they're optional
|
|
876
|
+
} else {
|
|
877
|
+
this._log('debug', `ℹ️ Server ${serverName} does not declare prompts capability`);
|
|
848
878
|
}
|
|
849
879
|
|
|
850
880
|
// 새로운 서버 객체 생성하여 확실히 업데이트
|
|
@@ -1578,7 +1608,12 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
1578
1608
|
toolsStatus: toolsResponse.status,
|
|
1579
1609
|
serverInfoStatus: serverInfo.status
|
|
1580
1610
|
});
|
|
1581
|
-
|
|
1611
|
+
|
|
1612
|
+
// Return tools data if available for reuse
|
|
1613
|
+
return {
|
|
1614
|
+
tools: toolsResponse.status === 'fulfilled' ? actualToolsResponse : null,
|
|
1615
|
+
serverInfo: serverInfo.status === 'fulfilled' ? actualServerInfo : null
|
|
1616
|
+
};
|
|
1582
1617
|
}
|
|
1583
1618
|
|
|
1584
1619
|
} catch (error) {
|
|
@@ -1614,7 +1649,7 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
1614
1649
|
|
|
1615
1650
|
// If we get here, server may be partially ready - don't fail completely
|
|
1616
1651
|
this.secureLog('warn', `Server ${serverName} may not be fully ready, continuing anyway`);
|
|
1617
|
-
return
|
|
1652
|
+
return null;
|
|
1618
1653
|
}
|
|
1619
1654
|
|
|
1620
1655
|
/**
|
|
@@ -1726,6 +1761,11 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
1726
1761
|
this.servers.clear();
|
|
1727
1762
|
this.clients.clear();
|
|
1728
1763
|
|
|
1764
|
+
// RAW 메시지 로거 종료
|
|
1765
|
+
if (this.messageLogger) {
|
|
1766
|
+
this.messageLogger.close();
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1729
1769
|
this.secureLog('info', 'MCP Agent Client cleanup completed');
|
|
1730
1770
|
} catch (error) {
|
|
1731
1771
|
this.secureLog('error', 'Error during cleanup', { error: error.message });
|
|
@@ -1750,6 +1790,25 @@ export class MCPAgentClient extends EventEmitter {
|
|
|
1750
1790
|
_categorizeTool(toolName) {
|
|
1751
1791
|
return 'tool';
|
|
1752
1792
|
}
|
|
1793
|
+
|
|
1794
|
+
/**
|
|
1795
|
+
* RAW 메시지 로거 통계 조회
|
|
1796
|
+
*/
|
|
1797
|
+
getMessageLoggerStats() {
|
|
1798
|
+
if (!this.messageLogger) {
|
|
1799
|
+
return null;
|
|
1800
|
+
}
|
|
1801
|
+
return this.messageLogger.getStats();
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
/**
|
|
1805
|
+
* RAW 메시지 로거 통계 출력
|
|
1806
|
+
*/
|
|
1807
|
+
printMessageLoggerStats() {
|
|
1808
|
+
if (this.messageLogger) {
|
|
1809
|
+
this.messageLogger.printStats();
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1753
1812
|
}
|
|
1754
1813
|
|
|
1755
1814
|
// ========================================
|
|
@@ -1794,5 +1853,8 @@ export async function quickStart(config = {}, options = {}) {
|
|
|
1794
1853
|
return agent;
|
|
1795
1854
|
}
|
|
1796
1855
|
|
|
1856
|
+
// RAW 메시지 로거도 export
|
|
1857
|
+
export { MCPMessageLogger, attachLoggerToTransport } from './mcp_message_logger.js';
|
|
1858
|
+
|
|
1797
1859
|
// 기본 export
|
|
1798
1860
|
export default MCPAgentClient;
|