mcp-rubber-duck 1.1.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.
Files changed (184) hide show
  1. package/.dockerignore +19 -0
  2. package/.env.desktop.example +145 -0
  3. package/.env.example +45 -0
  4. package/.env.pi.example +106 -0
  5. package/.env.template +165 -0
  6. package/.eslintrc.json +40 -0
  7. package/.github/ISSUE_TEMPLATE/bug_report.md +65 -0
  8. package/.github/ISSUE_TEMPLATE/feature_request.md +58 -0
  9. package/.github/ISSUE_TEMPLATE/question.md +67 -0
  10. package/.github/pull_request_template.md +111 -0
  11. package/.github/workflows/docker-build.yml +138 -0
  12. package/.github/workflows/release.yml +182 -0
  13. package/.github/workflows/security.yml +141 -0
  14. package/.github/workflows/semantic-release.yml +89 -0
  15. package/.prettierrc +10 -0
  16. package/.releaserc.json +66 -0
  17. package/CHANGELOG.md +95 -0
  18. package/CONTRIBUTING.md +242 -0
  19. package/Dockerfile +62 -0
  20. package/LICENSE +21 -0
  21. package/README.md +803 -0
  22. package/audit-ci.json +8 -0
  23. package/config/claude_desktop.json +14 -0
  24. package/config/config.example.json +91 -0
  25. package/dist/config/config.d.ts +51 -0
  26. package/dist/config/config.d.ts.map +1 -0
  27. package/dist/config/config.js +301 -0
  28. package/dist/config/config.js.map +1 -0
  29. package/dist/config/types.d.ts +356 -0
  30. package/dist/config/types.d.ts.map +1 -0
  31. package/dist/config/types.js +41 -0
  32. package/dist/config/types.js.map +1 -0
  33. package/dist/index.d.ts +3 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +109 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/providers/duck-provider-enhanced.d.ts +29 -0
  38. package/dist/providers/duck-provider-enhanced.d.ts.map +1 -0
  39. package/dist/providers/duck-provider-enhanced.js +230 -0
  40. package/dist/providers/duck-provider-enhanced.js.map +1 -0
  41. package/dist/providers/enhanced-manager.d.ts +54 -0
  42. package/dist/providers/enhanced-manager.d.ts.map +1 -0
  43. package/dist/providers/enhanced-manager.js +217 -0
  44. package/dist/providers/enhanced-manager.js.map +1 -0
  45. package/dist/providers/manager.d.ts +28 -0
  46. package/dist/providers/manager.d.ts.map +1 -0
  47. package/dist/providers/manager.js +204 -0
  48. package/dist/providers/manager.js.map +1 -0
  49. package/dist/providers/provider.d.ts +29 -0
  50. package/dist/providers/provider.d.ts.map +1 -0
  51. package/dist/providers/provider.js +179 -0
  52. package/dist/providers/provider.js.map +1 -0
  53. package/dist/providers/types.d.ts +69 -0
  54. package/dist/providers/types.d.ts.map +1 -0
  55. package/dist/providers/types.js +2 -0
  56. package/dist/providers/types.js.map +1 -0
  57. package/dist/server.d.ts +24 -0
  58. package/dist/server.d.ts.map +1 -0
  59. package/dist/server.js +501 -0
  60. package/dist/server.js.map +1 -0
  61. package/dist/services/approval.d.ts +44 -0
  62. package/dist/services/approval.d.ts.map +1 -0
  63. package/dist/services/approval.js +159 -0
  64. package/dist/services/approval.js.map +1 -0
  65. package/dist/services/cache.d.ts +21 -0
  66. package/dist/services/cache.d.ts.map +1 -0
  67. package/dist/services/cache.js +63 -0
  68. package/dist/services/cache.js.map +1 -0
  69. package/dist/services/conversation.d.ts +24 -0
  70. package/dist/services/conversation.d.ts.map +1 -0
  71. package/dist/services/conversation.js +108 -0
  72. package/dist/services/conversation.js.map +1 -0
  73. package/dist/services/function-bridge.d.ts +41 -0
  74. package/dist/services/function-bridge.d.ts.map +1 -0
  75. package/dist/services/function-bridge.js +259 -0
  76. package/dist/services/function-bridge.js.map +1 -0
  77. package/dist/services/health.d.ts +17 -0
  78. package/dist/services/health.d.ts.map +1 -0
  79. package/dist/services/health.js +77 -0
  80. package/dist/services/health.js.map +1 -0
  81. package/dist/services/mcp-client-manager.d.ts +49 -0
  82. package/dist/services/mcp-client-manager.d.ts.map +1 -0
  83. package/dist/services/mcp-client-manager.js +279 -0
  84. package/dist/services/mcp-client-manager.js.map +1 -0
  85. package/dist/tools/approve-mcp-request.d.ts +9 -0
  86. package/dist/tools/approve-mcp-request.d.ts.map +1 -0
  87. package/dist/tools/approve-mcp-request.js +111 -0
  88. package/dist/tools/approve-mcp-request.js.map +1 -0
  89. package/dist/tools/ask-duck.d.ts +9 -0
  90. package/dist/tools/ask-duck.d.ts.map +1 -0
  91. package/dist/tools/ask-duck.js +43 -0
  92. package/dist/tools/ask-duck.js.map +1 -0
  93. package/dist/tools/chat-duck.d.ts +9 -0
  94. package/dist/tools/chat-duck.d.ts.map +1 -0
  95. package/dist/tools/chat-duck.js +57 -0
  96. package/dist/tools/chat-duck.js.map +1 -0
  97. package/dist/tools/clear-conversations.d.ts +8 -0
  98. package/dist/tools/clear-conversations.d.ts.map +1 -0
  99. package/dist/tools/clear-conversations.js +17 -0
  100. package/dist/tools/clear-conversations.js.map +1 -0
  101. package/dist/tools/compare-ducks.d.ts +8 -0
  102. package/dist/tools/compare-ducks.d.ts.map +1 -0
  103. package/dist/tools/compare-ducks.js +49 -0
  104. package/dist/tools/compare-ducks.js.map +1 -0
  105. package/dist/tools/duck-council.d.ts +8 -0
  106. package/dist/tools/duck-council.d.ts.map +1 -0
  107. package/dist/tools/duck-council.js +69 -0
  108. package/dist/tools/duck-council.js.map +1 -0
  109. package/dist/tools/get-pending-approvals.d.ts +15 -0
  110. package/dist/tools/get-pending-approvals.d.ts.map +1 -0
  111. package/dist/tools/get-pending-approvals.js +74 -0
  112. package/dist/tools/get-pending-approvals.js.map +1 -0
  113. package/dist/tools/list-ducks.d.ts +9 -0
  114. package/dist/tools/list-ducks.d.ts.map +1 -0
  115. package/dist/tools/list-ducks.js +47 -0
  116. package/dist/tools/list-ducks.js.map +1 -0
  117. package/dist/tools/list-models.d.ts +8 -0
  118. package/dist/tools/list-models.d.ts.map +1 -0
  119. package/dist/tools/list-models.js +72 -0
  120. package/dist/tools/list-models.js.map +1 -0
  121. package/dist/tools/mcp-status.d.ts +17 -0
  122. package/dist/tools/mcp-status.d.ts.map +1 -0
  123. package/dist/tools/mcp-status.js +100 -0
  124. package/dist/tools/mcp-status.js.map +1 -0
  125. package/dist/utils/ascii-art.d.ts +19 -0
  126. package/dist/utils/ascii-art.d.ts.map +1 -0
  127. package/dist/utils/ascii-art.js +73 -0
  128. package/dist/utils/ascii-art.js.map +1 -0
  129. package/dist/utils/logger.d.ts +3 -0
  130. package/dist/utils/logger.d.ts.map +1 -0
  131. package/dist/utils/logger.js +86 -0
  132. package/dist/utils/logger.js.map +1 -0
  133. package/dist/utils/safe-logger.d.ts +23 -0
  134. package/dist/utils/safe-logger.d.ts.map +1 -0
  135. package/dist/utils/safe-logger.js +145 -0
  136. package/dist/utils/safe-logger.js.map +1 -0
  137. package/docker-compose.yml +161 -0
  138. package/jest.config.js +26 -0
  139. package/package.json +65 -0
  140. package/scripts/build-multiarch.sh +290 -0
  141. package/scripts/deploy-raspbian.sh +410 -0
  142. package/scripts/deploy.sh +322 -0
  143. package/scripts/gh-deploy.sh +343 -0
  144. package/scripts/setup-docker-raspbian.sh +530 -0
  145. package/server.json +8 -0
  146. package/src/config/config.ts +357 -0
  147. package/src/config/types.ts +89 -0
  148. package/src/index.ts +114 -0
  149. package/src/providers/duck-provider-enhanced.ts +294 -0
  150. package/src/providers/enhanced-manager.ts +290 -0
  151. package/src/providers/manager.ts +257 -0
  152. package/src/providers/provider.ts +207 -0
  153. package/src/providers/types.ts +78 -0
  154. package/src/server.ts +603 -0
  155. package/src/services/approval.ts +225 -0
  156. package/src/services/cache.ts +79 -0
  157. package/src/services/conversation.ts +146 -0
  158. package/src/services/function-bridge.ts +329 -0
  159. package/src/services/health.ts +107 -0
  160. package/src/services/mcp-client-manager.ts +362 -0
  161. package/src/tools/approve-mcp-request.ts +126 -0
  162. package/src/tools/ask-duck.ts +74 -0
  163. package/src/tools/chat-duck.ts +82 -0
  164. package/src/tools/clear-conversations.ts +24 -0
  165. package/src/tools/compare-ducks.ts +67 -0
  166. package/src/tools/duck-council.ts +88 -0
  167. package/src/tools/get-pending-approvals.ts +90 -0
  168. package/src/tools/list-ducks.ts +65 -0
  169. package/src/tools/list-models.ts +101 -0
  170. package/src/tools/mcp-status.ts +117 -0
  171. package/src/utils/ascii-art.ts +85 -0
  172. package/src/utils/logger.ts +116 -0
  173. package/src/utils/safe-logger.ts +165 -0
  174. package/systemd/mcp-rubber-duck-with-ollama.service +55 -0
  175. package/systemd/mcp-rubber-duck.service +58 -0
  176. package/test-functionality.js +147 -0
  177. package/test-mcp-interface.js +221 -0
  178. package/tests/ascii-art.test.ts +36 -0
  179. package/tests/config.test.ts +239 -0
  180. package/tests/conversation.test.ts +308 -0
  181. package/tests/mcp-bridge.test.ts +291 -0
  182. package/tests/providers.test.ts +269 -0
  183. package/tests/tools/clear-conversations.test.ts +163 -0
  184. package/tsconfig.json +26 -0
@@ -0,0 +1,259 @@
1
+ import { logger } from '../utils/logger.js';
2
+ import Ajv from 'ajv';
3
+ export class FunctionBridge {
4
+ mcpManager;
5
+ approvalService;
6
+ trustedTools = new Set();
7
+ trustedToolsByServer = new Map();
8
+ ajv;
9
+ toolSchemas = new Map();
10
+ approvalMode;
11
+ constructor(mcpManager, approvalService, trustedTools = [], approvalMode = 'always', trustedToolsByServer = {}) {
12
+ this.mcpManager = mcpManager;
13
+ this.approvalService = approvalService;
14
+ this.trustedTools = new Set(trustedTools);
15
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
16
+ this.ajv = new Ajv({ allErrors: true, removeAdditional: 'all' });
17
+ this.approvalMode = approvalMode;
18
+ // Initialize per-server trusted tools
19
+ Object.entries(trustedToolsByServer).forEach(([serverName, tools]) => {
20
+ this.trustedToolsByServer.set(serverName, new Set(tools));
21
+ });
22
+ }
23
+ async getFunctionDefinitions() {
24
+ try {
25
+ const mcpTools = await this.mcpManager.listAllTools();
26
+ const functionDefinitions = mcpTools.map(tool => {
27
+ const functionDef = this.convertMCPToolToFunction(tool);
28
+ // Cache the tool schema for validation
29
+ const toolKey = `${tool.serverName}:${tool.name}`;
30
+ this.toolSchemas.set(toolKey, tool.inputSchema);
31
+ return functionDef;
32
+ });
33
+ logger.debug(`Generated ${functionDefinitions.length} function definitions from MCP tools`);
34
+ return functionDefinitions;
35
+ }
36
+ catch (error) {
37
+ const errorMessage = error instanceof Error ? error.message : String(error);
38
+ logger.error('Failed to generate function definitions:', errorMessage);
39
+ return [];
40
+ }
41
+ }
42
+ convertMCPToolToFunction(mcpTool) {
43
+ return {
44
+ name: `mcp__${mcpTool.serverName}__${mcpTool.name}`,
45
+ description: `[${mcpTool.serverName}] ${mcpTool.description}`,
46
+ parameters: {
47
+ type: 'object',
48
+ properties: {
49
+ // Include the MCP tool's original parameters
50
+ ...(mcpTool.inputSchema?.properties || {}),
51
+ // Add our internal parameters
52
+ _mcp_server: {
53
+ type: 'string',
54
+ description: 'Internal: MCP server name',
55
+ default: mcpTool.serverName,
56
+ },
57
+ _mcp_tool: {
58
+ type: 'string',
59
+ description: 'Internal: MCP tool name',
60
+ default: mcpTool.name,
61
+ },
62
+ _approval_id: {
63
+ type: 'string',
64
+ description: 'Internal: Approval ID if pre-approved',
65
+ },
66
+ },
67
+ required: (mcpTool.inputSchema?.required || []),
68
+ },
69
+ };
70
+ }
71
+ validateToolArguments(toolKey, args) {
72
+ const schema = this.toolSchemas.get(toolKey);
73
+ if (!schema) {
74
+ return { valid: true }; // No schema available, skip validation
75
+ }
76
+ try {
77
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
78
+ const validate = this.ajv.compile(schema);
79
+ const valid = validate(args);
80
+ if (!valid && validate.errors) {
81
+ const errors = validate.errors.map(err => `${err.instancePath || 'root'}: ${err.message || 'validation error'}`);
82
+ return { valid: false, errors };
83
+ }
84
+ return { valid: true };
85
+ }
86
+ catch (error) {
87
+ const errorMessage = error instanceof Error ? error.message : String(error);
88
+ logger.warn(`Failed to validate schema for ${toolKey}:`, errorMessage);
89
+ return { valid: true }; // Skip validation on error
90
+ }
91
+ }
92
+ async handleFunctionCall(duckName, functionName, args) {
93
+ try {
94
+ logger.info(`FunctionBridge.handleFunctionCall called: ${duckName} -> ${functionName}`);
95
+ logger.debug(`Approval mode: ${this.approvalMode}, Function: ${functionName}`);
96
+ // Validate that this is an MCP function
97
+ if (!functionName.startsWith('mcp__')) {
98
+ logger.warn(`Invalid function name format: ${functionName}`);
99
+ return {
100
+ success: false,
101
+ error: `Invalid function name: ${functionName}`,
102
+ };
103
+ }
104
+ // Extract MCP server and tool names from args or function name
105
+ const mcpServer = args._mcp_server || this.extractServerFromFunctionName(functionName);
106
+ const mcpTool = args._mcp_tool || this.extractToolFromFunctionName(functionName);
107
+ const approvalId = args._approval_id;
108
+ if (!mcpServer || !mcpTool) {
109
+ return {
110
+ success: false,
111
+ error: `Could not determine MCP server/tool from function: ${functionName}`,
112
+ };
113
+ }
114
+ // Clean up internal parameters from args
115
+ const cleanArgs = { ...args };
116
+ delete cleanArgs._mcp_server;
117
+ delete cleanArgs._mcp_tool;
118
+ delete cleanArgs._approval_id;
119
+ // Validate arguments against tool schema
120
+ const toolKey = `${mcpServer}:${mcpTool}`;
121
+ const validation = this.validateToolArguments(toolKey, cleanArgs);
122
+ if (!validation.valid) {
123
+ return {
124
+ success: false,
125
+ error: `Invalid arguments for ${toolKey}: ${validation.errors?.join(', ')}`,
126
+ };
127
+ }
128
+ // Check if approval is needed based on approval mode
129
+ let isTrusted = false;
130
+ // First check server-specific trusted tools
131
+ const serverTrustedTools = this.trustedToolsByServer.get(mcpServer);
132
+ if (serverTrustedTools) {
133
+ isTrusted = serverTrustedTools.has('*') || // Wildcard for all tools from server
134
+ serverTrustedTools.has(mcpTool) || // Tool name only
135
+ serverTrustedTools.has(toolKey); // Full server:tool format
136
+ logger.debug(`Server-specific trust check for ${mcpServer}: ${Array.from(serverTrustedTools).join(', ')} - isTrusted: ${isTrusted}`);
137
+ }
138
+ else {
139
+ // Fall back to global trusted tools
140
+ isTrusted = this.trustedTools.has(toolKey) || this.trustedTools.has(mcpTool);
141
+ logger.debug(`Global trust check - isTrusted: ${isTrusted}`);
142
+ }
143
+ const isAlreadyApprovedForSession = this.approvalService.isToolApprovedForSession(duckName, mcpServer, mcpTool);
144
+ let needsApproval = false;
145
+ logger.debug(`Approval check - Mode: ${this.approvalMode}, Trusted: ${isTrusted}, SessionApproved: ${isAlreadyApprovedForSession}, ToolKey: ${toolKey}, Server: ${mcpServer}, ApprovalId: ${approvalId}`);
146
+ if (this.approvalMode === 'always') {
147
+ // Always require approval unless already approved or approved for session
148
+ needsApproval = !approvalId && !isAlreadyApprovedForSession;
149
+ logger.debug(`Always mode: needsApproval = ${needsApproval}`);
150
+ }
151
+ else if (this.approvalMode === 'trusted') {
152
+ // Only untrusted tools need approval, unless already approved for session
153
+ needsApproval = !isTrusted && !approvalId && !isAlreadyApprovedForSession;
154
+ logger.debug(`Trusted mode: needsApproval = ${needsApproval}`);
155
+ }
156
+ else if (this.approvalMode === 'never') {
157
+ // Never require approval
158
+ needsApproval = false;
159
+ logger.debug(`Never mode: needsApproval = ${needsApproval}`);
160
+ }
161
+ if (needsApproval) {
162
+ // Create approval request
163
+ const request = this.approvalService.createApprovalRequest(duckName, mcpServer, mcpTool, cleanArgs);
164
+ return {
165
+ success: false,
166
+ needsApproval: true,
167
+ approvalId: request.id,
168
+ message: `🔒 Approval needed for ${duckName} to call ${mcpServer}:${mcpTool}. Request ID: ${request.id}`,
169
+ };
170
+ }
171
+ // If approval ID provided, verify it (except in 'never' mode)
172
+ if (approvalId && this.approvalMode !== 'never') {
173
+ const approvalStatus = this.approvalService.getApprovalStatus(approvalId);
174
+ if (approvalStatus !== 'approved') {
175
+ return {
176
+ success: false,
177
+ error: `Request not approved or expired (status: ${approvalStatus})`,
178
+ };
179
+ }
180
+ }
181
+ // Execute the MCP tool
182
+ logger.info(`Executing MCP tool ${mcpServer}:${mcpTool} for ${duckName}`);
183
+ const result = await this.mcpManager.callTool(mcpServer, mcpTool, cleanArgs);
184
+ return {
185
+ success: true,
186
+ data: result,
187
+ };
188
+ }
189
+ catch (error) {
190
+ const errorMessage = error instanceof Error ? error.message : String(error);
191
+ logger.error(`Function call failed for ${functionName}:`, errorMessage);
192
+ return {
193
+ success: false,
194
+ error: `MCP tool execution failed: ${errorMessage}`,
195
+ };
196
+ }
197
+ }
198
+ extractServerFromFunctionName(functionName) {
199
+ // Function name format: mcp__{server}__{tool}
200
+ const match = functionName.match(/^mcp__([^_]+(?:_[^_]+)*)__/);
201
+ return match ? match[1] : null;
202
+ }
203
+ extractToolFromFunctionName(functionName) {
204
+ // Function name format: mcp__{server}__{tool}
205
+ const match = functionName.match(/^mcp__[^_]+(?:_[^_]+)*__(.+)$/);
206
+ return match ? match[1] : null;
207
+ }
208
+ // Check if a specific MCP tool is available
209
+ async isToolAvailable(serverName, toolName) {
210
+ try {
211
+ const tools = await this.mcpManager.listServerTools(serverName);
212
+ return tools.some(tool => tool.name === toolName);
213
+ }
214
+ catch (error) {
215
+ return false;
216
+ }
217
+ }
218
+ // Get available MCP tools grouped by server
219
+ async getAvailableToolsByServer() {
220
+ try {
221
+ const allTools = await this.mcpManager.listAllTools();
222
+ const toolsByServer = {};
223
+ allTools.forEach(tool => {
224
+ if (!toolsByServer[tool.serverName]) {
225
+ toolsByServer[tool.serverName] = [];
226
+ }
227
+ toolsByServer[tool.serverName].push(tool);
228
+ });
229
+ return toolsByServer;
230
+ }
231
+ catch (error) {
232
+ const errorMessage = error instanceof Error ? error.message : String(error);
233
+ logger.error('Failed to get tools by server:', errorMessage);
234
+ return {};
235
+ }
236
+ }
237
+ // Update trusted tools list
238
+ updateTrustedTools(trustedTools, trustedToolsByServer) {
239
+ this.trustedTools = new Set(trustedTools);
240
+ logger.info(`Updated global trusted tools list: ${Array.from(this.trustedTools).join(', ')}`);
241
+ if (trustedToolsByServer) {
242
+ this.trustedToolsByServer.clear();
243
+ Object.entries(trustedToolsByServer).forEach(([serverName, tools]) => {
244
+ this.trustedToolsByServer.set(serverName, new Set(tools));
245
+ logger.info(`Updated trusted tools for server ${serverName}: ${tools.join(', ')}`);
246
+ });
247
+ }
248
+ }
249
+ // Get statistics about function calls
250
+ getStats() {
251
+ return {
252
+ totalFunctions: 0, // Will be populated when tools are loaded
253
+ serverCount: this.mcpManager.getConnectedServers().length,
254
+ trustedToolCount: this.trustedTools.size,
255
+ connectedServers: this.mcpManager.getConnectedServers(),
256
+ };
257
+ }
258
+ }
259
+ //# sourceMappingURL=function-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-bridge.js","sourceRoot":"","sources":["../../src/services/function-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { ProviderManager } from '../providers/manager.js';
2
+ import { ProviderHealth } from '../config/types.js';
3
+ export declare class HealthMonitor {
4
+ private providerManager;
5
+ private healthCheckInterval;
6
+ private healthCache;
7
+ constructor(providerManager: ProviderManager);
8
+ performHealthChecks(): Promise<Map<string, ProviderHealth>>;
9
+ startMonitoring(intervalMs?: number): void;
10
+ stopMonitoring(): void;
11
+ getHealthStatus(): Map<string, ProviderHealth>;
12
+ getHealthyProviders(): string[];
13
+ isProviderHealthy(providerName: string): boolean;
14
+ getProviderLatency(providerName: string): number | undefined;
15
+ waitForHealthyProvider(maxWaitMs?: number, checkIntervalMs?: number): Promise<string | null>;
16
+ }
17
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/services/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,WAAW,CAA0C;gBAEjD,eAAe,EAAE,eAAe;IAItC,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAuBjE,eAAe,CAAC,UAAU,GAAE,MAAc,GAAG,IAAI;IAoBjD,cAAc,IAAI,IAAI;IAQtB,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAI9C,mBAAmB,IAAI,MAAM,EAAE;IAM/B,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAKhD,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKtD,sBAAsB,CAC1B,SAAS,GAAE,MAAc,EACzB,eAAe,GAAE,MAAa,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAmB1B"}
@@ -0,0 +1,77 @@
1
+ import { logger } from '../utils/logger.js';
2
+ export class HealthMonitor {
3
+ providerManager;
4
+ healthCheckInterval = null;
5
+ healthCache = new Map();
6
+ constructor(providerManager) {
7
+ this.providerManager = providerManager;
8
+ }
9
+ async performHealthChecks() {
10
+ logger.info('🦆 Performing health checks on all ducks...');
11
+ const results = await this.providerManager.checkHealth();
12
+ for (const result of results) {
13
+ this.healthCache.set(result.provider, result);
14
+ const statusEmoji = result.healthy ? '✅' : '❌';
15
+ const latencyInfo = result.latency ? ` (${result.latency}ms)` : '';
16
+ logger.info(`${statusEmoji} ${result.provider}: ${result.healthy ? 'Healthy' : 'Unhealthy'}${latencyInfo}`);
17
+ if (result.error) {
18
+ logger.warn(` Error: ${result.error}`);
19
+ }
20
+ }
21
+ return this.healthCache;
22
+ }
23
+ startMonitoring(intervalMs = 60000) {
24
+ if (this.healthCheckInterval) {
25
+ this.stopMonitoring();
26
+ }
27
+ // Initial check
28
+ this.performHealthChecks().catch(error => {
29
+ logger.error('Initial health check failed:', error);
30
+ });
31
+ // Set up periodic checks
32
+ this.healthCheckInterval = setInterval(() => {
33
+ this.performHealthChecks().catch(error => {
34
+ logger.error('Periodic health check failed:', error);
35
+ });
36
+ }, intervalMs);
37
+ logger.info(`Started health monitoring with ${intervalMs}ms interval`);
38
+ }
39
+ stopMonitoring() {
40
+ if (this.healthCheckInterval) {
41
+ clearInterval(this.healthCheckInterval);
42
+ this.healthCheckInterval = null;
43
+ logger.info('Stopped health monitoring');
44
+ }
45
+ }
46
+ getHealthStatus() {
47
+ return new Map(this.healthCache);
48
+ }
49
+ getHealthyProviders() {
50
+ return Array.from(this.healthCache.entries())
51
+ .filter(([_, health]) => health.healthy)
52
+ .map(([provider, _]) => provider);
53
+ }
54
+ isProviderHealthy(providerName) {
55
+ const health = this.healthCache.get(providerName);
56
+ return health?.healthy || false;
57
+ }
58
+ getProviderLatency(providerName) {
59
+ const health = this.healthCache.get(providerName);
60
+ return health?.latency;
61
+ }
62
+ async waitForHealthyProvider(maxWaitMs = 30000, checkIntervalMs = 1000) {
63
+ const startTime = Date.now();
64
+ while (Date.now() - startTime < maxWaitMs) {
65
+ const healthyProviders = this.getHealthyProviders();
66
+ if (healthyProviders.length > 0) {
67
+ return healthyProviders[0];
68
+ }
69
+ // Perform a fresh health check
70
+ await this.performHealthChecks();
71
+ // Wait before next check
72
+ await new Promise(resolve => setTimeout(resolve, checkIntervalMs));
73
+ }
74
+ return null;
75
+ }
76
+ }
77
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/services/health.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ export interface MCPServerConfig {
3
+ name: string;
4
+ type: 'stdio' | 'http';
5
+ command?: string;
6
+ args?: string[];
7
+ url?: string;
8
+ apiKey?: string;
9
+ enabled?: boolean;
10
+ retryAttempts?: number;
11
+ retryDelay?: number;
12
+ }
13
+ export interface MCPTool {
14
+ serverName: string;
15
+ name: string;
16
+ description: string;
17
+ inputSchema: Record<string, unknown>;
18
+ }
19
+ export declare class MCPClientManager {
20
+ private clients;
21
+ private configs;
22
+ private connectionStatus;
23
+ private retryInfo;
24
+ constructor(configs?: MCPServerConfig[]);
25
+ initialize(): Promise<void>;
26
+ private connectToServer;
27
+ private sleep;
28
+ disconnectAll(): Promise<void>;
29
+ getClient(serverName: string): Client | undefined;
30
+ getConnectionStatus(serverName: string): 'connected' | 'connecting' | 'disconnected' | 'error' | 'unknown';
31
+ getConnectedServers(): string[];
32
+ listAllTools(): Promise<MCPTool[]>;
33
+ listServerTools(serverName: string): Promise<MCPTool[]>;
34
+ callTool(serverName: string, toolName: string, args: Record<string, unknown>): Promise<unknown>;
35
+ healthCheck(): Promise<Record<string, boolean>>;
36
+ getStatus(): Record<string, {
37
+ status: string;
38
+ type: string;
39
+ toolCount?: number;
40
+ retryAttempts?: number;
41
+ lastAttempt?: number;
42
+ }>;
43
+ getRetryInfo(serverName: string): {
44
+ attempts: number;
45
+ lastAttempt: number;
46
+ } | undefined;
47
+ retryConnection(serverName: string): Promise<boolean>;
48
+ }
49
+ //# sourceMappingURL=mcp-client-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client-manager.d.ts","sourceRoot":"","sources":["../../src/services/mcp-client-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,gBAAgB,CAAiF;IACzG,OAAO,CAAC,SAAS,CAAqE;gBAE1E,OAAO,GAAE,eAAe,EAAO;IAIrC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAuBnB,eAAe;IAgG7B,OAAO,CAAC,KAAK;IAIP,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBpC,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAWjD,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,OAAO,GAAG,SAAS;IAI1G,mBAAmB,IAAI,MAAM,EAAE;IAMzB,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAgClC,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAyBvD,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAwB/F,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoBrD,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE;QAC1B,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IAwBF,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAKjF,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CA0B5D"}