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.

Files changed (50) hide show
  1. package/README.md +1 -0
  2. package/index.js +13 -11
  3. package/mcp-agent-lib/init.sh +3 -0
  4. package/mcp-agent-lib/package-lock.json +14 -1
  5. package/mcp-agent-lib/package.json +4 -6
  6. package/mcp-agent-lib/sampleFastMCPClient/client.py +25 -0
  7. package/mcp-agent-lib/sampleFastMCPClient/run.sh +3 -0
  8. package/mcp-agent-lib/sampleFastMCPServer/run.sh +3 -0
  9. package/mcp-agent-lib/sampleFastMCPServer/server.py +12 -0
  10. package/mcp-agent-lib/sampleFastMCPServerElicitationRequest/run.sh +3 -0
  11. package/mcp-agent-lib/sampleFastMCPServerElicitationRequest/server.py +43 -0
  12. package/mcp-agent-lib/sampleFastMCPServerRootsRequest/server.py +63 -0
  13. package/mcp-agent-lib/sampleMCPHost/index.js +182 -63
  14. package/mcp-agent-lib/sampleMCPHost/mcp_config.json +7 -1
  15. package/mcp-agent-lib/sampleMCPHostFeatures/elicitation.js +151 -0
  16. package/mcp-agent-lib/sampleMCPHostFeatures/index.js +166 -0
  17. package/mcp-agent-lib/sampleMCPHostFeatures/roots.js +197 -0
  18. package/mcp-agent-lib/src/mcp_client.js +129 -67
  19. package/mcp-agent-lib/src/mcp_message_logger.js +516 -0
  20. package/package.json +3 -1
  21. package/payload_viewer/out/404/index.html +1 -1
  22. package/payload_viewer/out/404.html +1 -1
  23. package/payload_viewer/out/index.html +1 -1
  24. package/payload_viewer/out/index.txt +1 -1
  25. package/src/LLMClient/client.js +992 -0
  26. package/src/LLMClient/converters/input-normalizer.js +238 -0
  27. package/src/LLMClient/converters/responses-to-claude.js +454 -0
  28. package/src/LLMClient/converters/responses-to-gemini.js +648 -0
  29. package/src/LLMClient/converters/responses-to-ollama.js +348 -0
  30. package/src/LLMClient/errors.js +372 -0
  31. package/src/LLMClient/index.js +31 -0
  32. package/src/commands/apikey.js +10 -22
  33. package/src/commands/model.js +28 -28
  34. package/src/commands/reasoning_effort.js +9 -23
  35. package/src/config/ai_models.js +212 -0
  36. package/src/config/feature_flags.js +1 -1
  37. package/src/frontend/App.js +5 -10
  38. package/src/frontend/components/CurrentModelView.js +0 -33
  39. package/src/frontend/components/Footer.js +3 -3
  40. package/src/frontend/components/ModelListView.js +30 -87
  41. package/src/frontend/components/ModelUpdatedView.js +7 -142
  42. package/src/frontend/components/SetupWizard.js +37 -32
  43. package/src/system/ai_request.js +57 -42
  44. package/src/util/config.js +26 -4
  45. package/src/util/setup_wizard.js +1 -6
  46. package/mcp-agent-lib/.claude/settings.local.json +0 -9
  47. package/src/config/openai_models.js +0 -152
  48. /package/payload_viewer/out/_next/static/{w4dMVYalgk7djrLxRxWiE → d0-fu2rgYnshgGFPxr1CR}/_buildManifest.js +0 -0
  49. /package/payload_viewer/out/_next/static/{w4dMVYalgk7djrLxRxWiE → d0-fu2rgYnshgGFPxr1CR}/_clientMiddlewareManifest.json +0 -0
  50. /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: process.env.MCP_CLIENT_NAME || 'mcp-agent-lib',
81
- version: process.env.MCP_CLIENT_VERSION || '1.0.0'
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. stdio 서버: 인자에 위험한 문자가 없는지 확인
408
- * 3. http 서버: URL이 http/https 프로토콜인지 확인
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('not allowed') || error.message.includes('dangerous characters')) {
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
- // Always try to list tools (even if capability is not explicitly declared)
799
- try {
800
- const toolsResponse = await client.listTools();
801
- server.tools = toolsResponse.tools || [];
802
- this._log('info', `🔧 Available tools from ${serverName}:`);
803
- server.tools.forEach((tool, index) => {
804
- this._log('info', ` ${index + 1}. ${tool.name}`);
805
- if (tool.description) this._log('info', ` 설명: ${tool.description}`);
806
- });
807
- } catch (toolsError) {
808
- this._log('warn', `⚠️ Tools/list failed: ${toolsError.message}`);
809
- server.tools = [];
810
- // Mark server as partially connected if critical capabilities fail
811
- if (toolsError.message.includes('timeout') || toolsError.message.includes('connection')) {
812
- this._setServerStatus(serverName, 'partially_connected');
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
- // Always try to list resources
840
+ // Query resources only if capability is declared
817
841
  let resources = [];
818
- try {
819
- const resourcesResponse = await client.listResources();
820
- resources = resourcesResponse.resources || [];
821
- this._log('info', `📄 Available resources from ${serverName}: ${resources.length} found`);
822
- if (resources.length > 0) {
823
- resources.forEach((resource, index) => {
824
- this._log('info', ` ${index + 1}. ${resource.name} (${resource.uri})`);
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
- } catch (resourcesError) {
828
- this._log('debug', `ℹ️ Resources not available from ${serverName}: ${resourcesError.message}`);
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
- // Always try to list prompts
860
+ // Query prompts only if capability is declared
834
861
  let prompts = [];
835
- try {
836
- const promptsResponse = await client.listPrompts();
837
- prompts = promptsResponse.prompts || [];
838
- this._log('info', `💬 Available prompts from ${serverName}: ${prompts.length} found`);
839
- if (prompts.length > 0) {
840
- prompts.forEach((prompt, index) => {
841
- this._log('info', ` ${index + 1}. ${prompt.name}: ${prompt.description || 'No description'}`);
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
- } catch (promptsError) {
845
- this._log('debug', `ℹ️ Prompts not available from ${serverName}: ${promptsError.message}`);
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
- return true;
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 false;
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;