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
package/README.md ADDED
@@ -0,0 +1,803 @@
1
+ # 🦆 MCP Rubber Duck
2
+
3
+ An MCP (Model Context Protocol) server that acts as a bridge to query multiple OpenAI-compatible LLMs. Just like rubber duck debugging, explain your problems to various AI "ducks" and get different perspectives!
4
+
5
+ ```
6
+ __
7
+ <(o )___
8
+ ( ._> /
9
+ `---' Quack! Ready to debug!
10
+ ```
11
+
12
+ ## Features
13
+
14
+ - 🔌 **Universal OpenAI Compatibility**: Works with any OpenAI-compatible API endpoint
15
+ - 🦆 **Multiple Ducks**: Configure and query multiple LLM providers simultaneously
16
+ - 💬 **Conversation Management**: Maintain context across multiple messages
17
+ - 🏛️ **Duck Council**: Get responses from all your configured LLMs at once
18
+ - 💾 **Response Caching**: Avoid duplicate API calls with intelligent caching
19
+ - 🔄 **Automatic Failover**: Falls back to other providers if primary fails
20
+ - 📊 **Health Monitoring**: Real-time health checks for all providers
21
+ - 🔗 **MCP Bridge**: Connect ducks to other MCP servers for extended functionality
22
+ - 🛡️ **Granular Security**: Per-server approval controls with session-based approvals
23
+ - 🎨 **Fun Duck Theme**: Rubber duck debugging with personality!
24
+
25
+ ## Supported Providers
26
+
27
+ Any provider with an OpenAI-compatible API endpoint, including:
28
+
29
+ - **OpenAI** (GPT-4, GPT-3.5)
30
+ - **Google Gemini** (Gemini 2.5 Flash, Gemini 2.0 Flash)
31
+ - **Anthropic** (via OpenAI-compatible endpoints)
32
+ - **Groq** (Llama, Mixtral, Gemma)
33
+ - **Together AI** (Llama, Mixtral, and more)
34
+ - **Perplexity** (Online models with web search)
35
+ - **Anyscale** (Open source models)
36
+ - **Azure OpenAI** (Microsoft-hosted OpenAI)
37
+ - **Ollama** (Local models)
38
+ - **LM Studio** (Local models)
39
+ - **Custom** (Any OpenAI-compatible endpoint)
40
+
41
+ ## Quick Start
42
+
43
+ ### For Claude Desktop Users
44
+ 👉 **Complete Claude Desktop setup instructions below in [Claude Desktop Configuration](#claude-desktop-configuration)**
45
+
46
+ ## Installation
47
+
48
+ ### Prerequisites
49
+
50
+ - Node.js 20 or higher
51
+ - npm or yarn
52
+ - At least one API key for a supported provider
53
+
54
+ ### Install from Source
55
+
56
+ ```bash
57
+ # Clone the repository
58
+ git clone https://github.com/nesquikm/mcp-rubber-duck.git
59
+ cd mcp-rubber-duck
60
+
61
+ # Install dependencies
62
+ npm install
63
+
64
+ # Build the project
65
+ npm run build
66
+
67
+ # Run the server
68
+ npm start
69
+ ```
70
+
71
+ ## Configuration
72
+
73
+ ### Method 1: Environment Variables
74
+
75
+ Create a `.env` file in the project root:
76
+
77
+ ```env
78
+ # OpenAI
79
+ OPENAI_API_KEY=sk-...
80
+ OPENAI_DEFAULT_MODEL=gpt-4o-mini # Optional: defaults to gpt-4o-mini
81
+
82
+ # Google Gemini
83
+ GEMINI_API_KEY=...
84
+ GEMINI_DEFAULT_MODEL=gemini-2.5-flash # Optional: defaults to gemini-2.5-flash
85
+
86
+ # Groq
87
+ GROQ_API_KEY=gsk_...
88
+ GROQ_DEFAULT_MODEL=llama-3.3-70b-versatile # Optional: defaults to llama-3.3-70b-versatile
89
+
90
+ # Ollama (Local)
91
+ OLLAMA_BASE_URL=http://localhost:11434/v1 # Optional
92
+ OLLAMA_DEFAULT_MODEL=llama3.2 # Optional: defaults to llama3.2
93
+
94
+ # Together AI
95
+ TOGETHER_API_KEY=...
96
+
97
+ # Custom Providers (you can add multiple)
98
+ # Format: CUSTOM_{NAME}_* where NAME becomes the provider key (lowercase)
99
+
100
+ # Example: Add provider "myapi"
101
+ CUSTOM_MYAPI_API_KEY=...
102
+ CUSTOM_MYAPI_BASE_URL=https://api.example.com/v1
103
+ CUSTOM_MYAPI_DEFAULT_MODEL=custom-model # Optional
104
+ CUSTOM_MYAPI_MODELS=model1,model2 # Optional: comma-separated list
105
+ CUSTOM_MYAPI_NICKNAME=My Custom Duck # Optional: display name
106
+
107
+ # Example: Add provider "azure"
108
+ CUSTOM_AZURE_API_KEY=...
109
+ CUSTOM_AZURE_BASE_URL=https://mycompany.openai.azure.com/v1
110
+
111
+ # Global Settings
112
+ DEFAULT_PROVIDER=openai
113
+ DEFAULT_TEMPERATURE=0.7
114
+ LOG_LEVEL=info
115
+
116
+ # MCP Bridge Settings (Optional)
117
+ MCP_BRIDGE_ENABLED=true # Enable ducks to access external MCP servers
118
+ MCP_APPROVAL_MODE=trusted # always, trusted, or never
119
+ MCP_APPROVAL_TIMEOUT=300 # seconds
120
+
121
+ # MCP Server: Context7 Documentation (Example)
122
+ MCP_SERVER_CONTEXT7_TYPE=http
123
+ MCP_SERVER_CONTEXT7_URL=https://mcp.context7.com/mcp
124
+ MCP_SERVER_CONTEXT7_ENABLED=true
125
+
126
+ # Per-server trusted tools
127
+ MCP_TRUSTED_TOOLS_CONTEXT7=* # Trust all Context7 tools
128
+
129
+ # Optional: Custom Duck Nicknames (Have fun with these!)
130
+ OPENAI_NICKNAME="DUCK-4" # Optional: defaults to "GPT Duck"
131
+ GEMINI_NICKNAME="Duckmini" # Optional: defaults to "Gemini Duck"
132
+ GROQ_NICKNAME="Quackers" # Optional: defaults to "Groq Duck"
133
+ OLLAMA_NICKNAME="Local Quacker" # Optional: defaults to "Local Duck"
134
+ CUSTOM_NICKNAME="My Special Duck" # Optional: defaults to "Custom Duck"
135
+ ```
136
+
137
+ **Note:** Duck nicknames are completely optional! If you don't set them, you'll get the charming defaults (GPT Duck, Gemini Duck, etc.). If you use a `config.json` file, those nicknames take priority over environment variables.
138
+
139
+ ### Method 2: Configuration File
140
+
141
+ Create a `config/config.json` file based on the example:
142
+
143
+ ```bash
144
+ cp config/config.example.json config/config.json
145
+ # Edit config/config.json with your API keys and preferences
146
+ ```
147
+
148
+ ## Claude Desktop Configuration
149
+
150
+ This is the most common setup method for using MCP Rubber Duck with Claude Desktop.
151
+
152
+ ### Step 1: Build the Project
153
+
154
+ First, ensure the project is built:
155
+
156
+ ```bash
157
+ # Clone the repository
158
+ git clone https://github.com/nesquikm/mcp-rubber-duck.git
159
+ cd mcp-rubber-duck
160
+
161
+ # Install dependencies and build
162
+ npm install
163
+ npm run build
164
+ ```
165
+
166
+ ### Step 2: Configure Claude Desktop
167
+
168
+ Edit your Claude Desktop config file:
169
+
170
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
171
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
172
+
173
+ Add the MCP server configuration:
174
+
175
+ ```json
176
+ {
177
+ "mcpServers": {
178
+ "rubber-duck": {
179
+ "command": "node",
180
+ "args": ["/absolute/path/to/mcp-rubber-duck/dist/index.js"],
181
+ "env": {
182
+ "MCP_SERVER": "true",
183
+ "OPENAI_API_KEY": "your-openai-api-key-here",
184
+ "OPENAI_DEFAULT_MODEL": "gpt-4o-mini",
185
+ "GEMINI_API_KEY": "your-gemini-api-key-here",
186
+ "GEMINI_DEFAULT_MODEL": "gemini-2.5-flash",
187
+ "DEFAULT_PROVIDER": "openai",
188
+ "LOG_LEVEL": "info"
189
+ }
190
+ }
191
+ }
192
+ }
193
+ ```
194
+
195
+ **Important**: Replace the placeholder API keys with your actual keys:
196
+ - `your-openai-api-key-here` → Your OpenAI API key (starts with `sk-`)
197
+ - `your-gemini-api-key-here` → Your Gemini API key from [Google AI Studio](https://aistudio.google.com/apikey)
198
+
199
+ **Note**: `MCP_SERVER: "true"` is required - this tells rubber-duck to run as an MCP server for any MCP client (not related to the MCP Bridge feature).
200
+
201
+ ### Step 3: Restart Claude Desktop
202
+
203
+ 1. Completely quit Claude Desktop (⌘+Q on Mac)
204
+ 2. Launch Claude Desktop again
205
+ 3. The MCP server should connect automatically
206
+
207
+ ### Step 4: Test the Integration
208
+
209
+ Once restarted, test these commands in Claude:
210
+
211
+ #### Check Duck Health
212
+ ```
213
+ Use the list_ducks tool with check_health: true
214
+ ```
215
+ Should show:
216
+ - ✅ **GPT Duck** (openai) - Healthy
217
+ - ✅ **Gemini Duck** (gemini) - Healthy
218
+
219
+ #### List Available Models
220
+ ```
221
+ Use the list_models tool
222
+ ```
223
+
224
+ #### Ask a Specific Duck
225
+ ```
226
+ Use the ask_duck tool with prompt: "What is rubber duck debugging?", provider: "openai"
227
+ ```
228
+
229
+ #### Compare Multiple Ducks
230
+ ```
231
+ Use the compare_ducks tool with prompt: "Explain async/await in JavaScript"
232
+ ```
233
+
234
+ #### Test Specific Models
235
+ ```
236
+ Use the ask_duck tool with prompt: "Hello", provider: "openai", model: "gpt-4"
237
+ ```
238
+
239
+ ### Troubleshooting Claude Desktop Setup
240
+
241
+ #### If Tools Don't Appear
242
+ 1. **Check API Keys**: Ensure your API keys are correctly entered without typos
243
+ 2. **Verify Build**: Run `ls -la dist/index.js` to confirm the project built successfully
244
+ 3. **Check Logs**: Look for errors in Claude Desktop's developer console
245
+ 4. **Restart**: Fully quit and restart Claude Desktop after config changes
246
+
247
+ #### Connection Issues
248
+ 1. **Config File Path**: Double-check you're editing the correct config file path
249
+ 2. **JSON Syntax**: Validate your JSON syntax (no trailing commas, proper quotes)
250
+ 3. **Absolute Paths**: Ensure you're using the full absolute path to `dist/index.js`
251
+ 4. **File Permissions**: Verify Claude Desktop can read the dist directory
252
+
253
+ #### Health Check Failures
254
+ If ducks show as unhealthy:
255
+ 1. **API Keys**: Verify keys are valid and have sufficient credits/quota
256
+ 2. **Network**: Check internet connection and firewall settings
257
+ 3. **Rate Limits**: Some providers have strict rate limits for new accounts
258
+
259
+ ## MCP Bridge - Connect to Other MCP Servers
260
+
261
+ The MCP Bridge allows your ducks to access tools from other MCP servers, extending their capabilities beyond just chat. Your ducks can now search documentation, access files, query APIs, and much more!
262
+
263
+ **Note**: This is different from the MCP server integration above:
264
+ - **MCP Bridge** (`MCP_BRIDGE_ENABLED`): Ducks USE external MCP servers as clients
265
+ - **MCP Server** (`MCP_SERVER`): Rubber-duck SERVES as an MCP server to any MCP client
266
+
267
+ ### Quick Setup
268
+
269
+ Add these environment variables to enable MCP Bridge:
270
+
271
+ ```bash
272
+ # Basic MCP Bridge Configuration
273
+ MCP_BRIDGE_ENABLED="true" # Enable ducks to access external MCP servers
274
+ MCP_APPROVAL_MODE="trusted" # always, trusted, or never
275
+ MCP_APPROVAL_TIMEOUT="300" # 5 minutes
276
+
277
+ # Example: Context7 Documentation Server
278
+ MCP_SERVER_CONTEXT7_TYPE="http"
279
+ MCP_SERVER_CONTEXT7_URL="https://mcp.context7.com/mcp"
280
+ MCP_SERVER_CONTEXT7_ENABLED="true"
281
+
282
+ # Trust all Context7 tools (no approval needed)
283
+ MCP_TRUSTED_TOOLS_CONTEXT7="*"
284
+ ```
285
+
286
+ ### Approval Modes
287
+
288
+ **`always`**: Every tool call requires approval (with session-based memory)
289
+ - First use of a tool → requires approval
290
+ - Subsequent uses of the same tool → automatic (until restart)
291
+
292
+ **`trusted`**: Only untrusted tools require approval
293
+ - Tools in trusted lists execute immediately
294
+ - Unknown tools require approval
295
+
296
+ **`never`**: All tools execute immediately (use with caution)
297
+
298
+ ### Per-Server Trusted Tools
299
+
300
+ Configure trust levels per MCP server for granular security:
301
+
302
+ ```bash
303
+ # Trust all tools from Context7 (documentation server)
304
+ MCP_TRUSTED_TOOLS_CONTEXT7="*"
305
+
306
+ # Trust specific filesystem operations only
307
+ MCP_TRUSTED_TOOLS_FILESYSTEM="read-file,list-directory"
308
+
309
+ # Trust specific GitHub tools
310
+ MCP_TRUSTED_TOOLS_GITHUB="get-repo-info,list-issues"
311
+
312
+ # Global fallback for servers without specific config
313
+ MCP_TRUSTED_TOOLS="common-safe-tool"
314
+ ```
315
+
316
+ ### MCP Server Configuration
317
+
318
+ Configure MCP servers using environment variables:
319
+
320
+ #### HTTP Servers
321
+ ```bash
322
+ MCP_SERVER_{NAME}_TYPE="http"
323
+ MCP_SERVER_{NAME}_URL="https://api.example.com/mcp"
324
+ MCP_SERVER_{NAME}_API_KEY="your-api-key" # Optional
325
+ MCP_SERVER_{NAME}_ENABLED="true"
326
+ ```
327
+
328
+ #### STDIO Servers
329
+ ```bash
330
+ MCP_SERVER_{NAME}_TYPE="stdio"
331
+ MCP_SERVER_{NAME}_COMMAND="python"
332
+ MCP_SERVER_{NAME}_ARGS="/path/to/script.py,--arg1,--arg2"
333
+ MCP_SERVER_{NAME}_ENABLED="true"
334
+ ```
335
+
336
+ ### Example: Enable Context7 Documentation
337
+
338
+ ```bash
339
+ # Enable MCP Bridge
340
+ MCP_BRIDGE_ENABLED="true"
341
+ MCP_APPROVAL_MODE="trusted"
342
+
343
+ # Configure Context7 server
344
+ MCP_SERVER_CONTEXT7_TYPE="http"
345
+ MCP_SERVER_CONTEXT7_URL="https://mcp.context7.com/mcp"
346
+ MCP_SERVER_CONTEXT7_ENABLED="true"
347
+
348
+ # Trust all Context7 tools
349
+ MCP_TRUSTED_TOOLS_CONTEXT7="*"
350
+ ```
351
+
352
+ Now your ducks can search and retrieve documentation from Context7:
353
+
354
+ ```
355
+ Ask: "Can you find React hooks documentation from Context7 and return only the key concepts?"
356
+ Duck: *searches Context7 and returns focused, essential React hooks information*
357
+ ```
358
+
359
+ ### 💡 Token Optimization Benefits
360
+
361
+ **Smart Token Management**: Ducks can retrieve comprehensive data from MCP servers but return only the essential information you need, saving tokens in your host LLM conversations:
362
+
363
+ - **Ask for specifics**: "Find TypeScript interfaces documentation and return only the core concepts"
364
+ - **Duck processes full docs**: Accesses complete documentation from Context7
365
+ - **Returns condensed results**: Provides focused, relevant information while filtering out unnecessary details
366
+ - **Token savings**: Reduces response size by 70-90% compared to raw documentation dumps
367
+
368
+ **Example Workflow:**
369
+ ```
370
+ You: "Find Express.js routing concepts from Context7, keep it concise"
371
+ Duck: *Retrieves full Express docs, processes, and returns only routing essentials*
372
+ Result: 500 tokens instead of 5,000+ tokens of raw documentation
373
+ ```
374
+
375
+ ### Session-Based Approvals
376
+
377
+ When using `always` mode, the system remembers your approvals:
378
+
379
+ 1. **First time**: "Duck wants to use `search-docs` - Approve? ✅"
380
+ 2. **Next time**: Duck uses `search-docs` automatically (no new approval needed)
381
+ 3. **Different tool**: "Duck wants to use `get-examples` - Approve? ✅"
382
+ 4. **Restart**: Session memory clears, start over
383
+
384
+ This eliminates approval fatigue while maintaining security!
385
+
386
+ ### Available Tools (Enhanced with MCP)
387
+
388
+ ### 🦆 ask_duck
389
+ Ask a single question to a specific LLM provider. When MCP Bridge is enabled, ducks can automatically access tools from connected MCP servers.
390
+
391
+ ```typescript
392
+ {
393
+ "prompt": "What is rubber duck debugging?",
394
+ "provider": "openai", // Optional, uses default if not specified
395
+ "temperature": 0.7 // Optional
396
+ }
397
+ ```
398
+
399
+ ### 💬 chat_with_duck
400
+ Have a conversation with context maintained across messages.
401
+
402
+ ```typescript
403
+ {
404
+ "conversation_id": "debug-session-1",
405
+ "message": "Can you help me debug this code?",
406
+ "provider": "groq" // Optional, can switch providers mid-conversation
407
+ }
408
+ ```
409
+
410
+ ### 🧹 clear_conversations
411
+ Clear all conversation history and start fresh. Useful when switching topics or when context becomes too large.
412
+
413
+ ```typescript
414
+ {
415
+ // No parameters required
416
+ }
417
+ ```
418
+
419
+ ### 📋 list_ducks
420
+ List all configured providers and their health status.
421
+
422
+ ```typescript
423
+ {
424
+ "check_health": true // Optional, performs fresh health check
425
+ }
426
+ ```
427
+
428
+ ### 📊 list_models
429
+ List available models for LLM providers.
430
+
431
+ ```typescript
432
+ {
433
+ "provider": "openai", // Optional, lists all if not specified
434
+ "fetch_latest": false // Optional, fetch latest from API vs cached
435
+ }
436
+ ```
437
+
438
+ ### 🔍 compare_ducks
439
+ Ask the same question to multiple providers simultaneously.
440
+
441
+ ```typescript
442
+ {
443
+ "prompt": "What's the best programming language?",
444
+ "providers": ["openai", "groq", "ollama"] // Optional, uses all if not specified
445
+ }
446
+ ```
447
+
448
+ ### 🏛️ duck_council
449
+ Get responses from all configured ducks - like a panel discussion!
450
+
451
+ ```typescript
452
+ {
453
+ "prompt": "How should I architect a microservices application?"
454
+ }
455
+ ```
456
+
457
+ ## Usage Examples
458
+
459
+ ### Basic Query
460
+ ```javascript
461
+ // Ask the default duck
462
+ await ask_duck({
463
+ prompt: "Explain async/await in JavaScript"
464
+ });
465
+ ```
466
+
467
+ ### Conversation
468
+ ```javascript
469
+ // Start a conversation
470
+ await chat_with_duck({
471
+ conversation_id: "learning-session",
472
+ message: "What is TypeScript?"
473
+ });
474
+
475
+ // Continue the conversation
476
+ await chat_with_duck({
477
+ conversation_id: "learning-session",
478
+ message: "How does it differ from JavaScript?"
479
+ });
480
+ ```
481
+
482
+ ### Compare Responses
483
+ ```javascript
484
+ // Get different perspectives
485
+ await compare_ducks({
486
+ prompt: "What's the best way to handle errors in Node.js?",
487
+ providers: ["openai", "groq", "ollama"]
488
+ });
489
+ ```
490
+
491
+ ### Duck Council
492
+ ```javascript
493
+ // Convene the council for important decisions
494
+ await duck_council({
495
+ prompt: "Should I use REST or GraphQL for my API?"
496
+ });
497
+ ```
498
+
499
+ ## Provider-Specific Setup
500
+
501
+ ### Ollama (Local)
502
+ ```bash
503
+ # Install Ollama
504
+ curl -fsSL https://ollama.ai/install.sh | sh
505
+
506
+ # Pull a model
507
+ ollama pull llama3.2
508
+
509
+ # Ollama automatically provides OpenAI-compatible endpoint at localhost:11434/v1
510
+ ```
511
+
512
+ ### LM Studio (Local)
513
+ 1. Download LM Studio from https://lmstudio.ai/
514
+ 2. Load a model in LM Studio
515
+ 3. Start the local server (provides OpenAI-compatible endpoint at localhost:1234/v1)
516
+
517
+ ### Google Gemini
518
+ 1. Get API key from [Google AI Studio](https://aistudio.google.com/apikey)
519
+ 2. Add to environment: `GEMINI_API_KEY=...`
520
+ 3. Uses OpenAI-compatible endpoint (beta)
521
+
522
+ ### Groq
523
+ 1. Get API key from https://console.groq.com/keys
524
+ 2. Add to environment: `GROQ_API_KEY=gsk_...`
525
+
526
+ ### Together AI
527
+ 1. Get API key from https://api.together.xyz/
528
+ 2. Add to environment: `TOGETHER_API_KEY=...`
529
+
530
+ ## Verifying OpenAI Compatibility
531
+
532
+ To check if a provider is OpenAI-compatible:
533
+
534
+ 1. Look for `/v1/chat/completions` endpoint in their API docs
535
+ 2. Check if they support the OpenAI SDK
536
+ 3. Test with curl:
537
+
538
+ ```bash
539
+ curl -X POST "https://api.provider.com/v1/chat/completions" \
540
+ -H "Authorization: Bearer YOUR_API_KEY" \
541
+ -H "Content-Type: application/json" \
542
+ -d '{
543
+ "model": "model-name",
544
+ "messages": [{"role": "user", "content": "Hello"}]
545
+ }'
546
+ ```
547
+
548
+ ## Development
549
+
550
+ ### Run in Development Mode
551
+ ```bash
552
+ npm run dev
553
+ ```
554
+
555
+ ### Run Tests
556
+ ```bash
557
+ npm test
558
+ ```
559
+
560
+ ### Lint Code
561
+ ```bash
562
+ npm run lint
563
+ ```
564
+
565
+ ### Type Checking
566
+ ```bash
567
+ npm run typecheck
568
+ ```
569
+
570
+ ## Docker Support
571
+
572
+ MCP Rubber Duck provides multi-platform Docker support, working on **macOS (Intel & Apple Silicon)**, **Linux (x86_64 & ARM64)**, **Windows (WSL2)**, and **Raspberry Pi 3+**.
573
+
574
+ ### Quick Start with Pre-built Image
575
+
576
+ The easiest way to get started is with our pre-built multi-architecture image:
577
+
578
+ ```bash
579
+ # Pull the image (works on all platforms)
580
+ docker pull ghcr.io/nesquikm/mcp-rubber-duck:latest
581
+
582
+ # Create environment file
583
+ cp .env.template .env
584
+ # Edit .env and add your API keys
585
+
586
+ # Run with Docker Compose (recommended)
587
+ docker compose up -d
588
+ ```
589
+
590
+ ### Platform-Specific Deployment
591
+
592
+ #### 🖥️ Desktop/Server (macOS, Linux, Windows)
593
+
594
+ ```bash
595
+ # Use desktop-optimized settings
596
+ ./scripts/deploy.sh --platform desktop
597
+
598
+ # Or with more resources and local AI
599
+ ./scripts/deploy.sh --platform desktop --profile with-ollama
600
+ ```
601
+
602
+ #### 🥧 Raspberry Pi
603
+
604
+ ```bash
605
+ # Use Pi-optimized settings (memory limits, etc.)
606
+ ./scripts/deploy.sh --platform pi
607
+
608
+ # Or copy optimized config directly
609
+ cp .env.pi.example .env
610
+ # Edit .env and add your API keys
611
+ docker compose up -d
612
+ ```
613
+
614
+ #### 🌐 Remote Deployment via SSH
615
+
616
+ ```bash
617
+ # Deploy to remote Raspberry Pi
618
+ ./scripts/deploy.sh --mode ssh --ssh-host pi@192.168.1.100
619
+ ```
620
+
621
+ ### Universal Deployment Script
622
+
623
+ The `scripts/deploy.sh` script auto-detects your platform and applies optimal settings:
624
+
625
+ ```bash
626
+ # Auto-detect platform and deploy
627
+ ./scripts/deploy.sh
628
+
629
+ # Options:
630
+ ./scripts/deploy.sh --help
631
+ ```
632
+
633
+ **Available options:**
634
+ - `--mode`: `docker` (default), `local`, or `ssh`
635
+ - `--platform`: `pi`, `desktop`, or `auto` (default)
636
+ - `--profile`: `lightweight`, `desktop`, `with-ollama`
637
+ - `--ssh-host`: For remote deployment
638
+
639
+ ### Platform-Specific Configuration
640
+
641
+ #### Raspberry Pi (Memory-Optimized)
642
+ ```env
643
+ # .env.pi.example - Optimized for Pi 3+
644
+ DOCKER_CPU_LIMIT=1.5
645
+ DOCKER_MEMORY_LIMIT=512M
646
+ NODE_OPTIONS=--max-old-space-size=256
647
+ ```
648
+
649
+ #### Desktop/Server (High-Performance)
650
+ ```env
651
+ # .env.desktop.example - Optimized for powerful systems
652
+ DOCKER_CPU_LIMIT=4.0
653
+ DOCKER_MEMORY_LIMIT=2G
654
+ NODE_OPTIONS=--max-old-space-size=1024
655
+ ```
656
+
657
+ ### Docker Compose Profiles
658
+
659
+ ```bash
660
+ # Default profile (lightweight, good for Pi)
661
+ docker compose up -d
662
+
663
+ # Desktop profile (higher resource limits)
664
+ docker compose --profile desktop up -d
665
+
666
+ # With local Ollama AI
667
+ docker compose --profile with-ollama up -d
668
+ ```
669
+
670
+ ### Build Multi-Architecture Images
671
+
672
+ For developers who want to build and publish their own multi-architecture images:
673
+
674
+ ```bash
675
+ # Build for AMD64 + ARM64
676
+ ./scripts/build-multiarch.sh --platforms linux/amd64,linux/arm64
677
+
678
+ # Build and push to GitHub Container Registry
679
+ ./scripts/gh-deploy.sh --public
680
+ ```
681
+
682
+ ### Claude Desktop with Remote Docker
683
+
684
+ Connect Claude Desktop to MCP Rubber Duck running on a remote system:
685
+
686
+ ```json
687
+ {
688
+ "mcpServers": {
689
+ "rubber-duck-remote": {
690
+ "command": "ssh",
691
+ "args": [
692
+ "user@remote-host",
693
+ "docker exec -i mcp-rubber-duck node /app/dist/index.js"
694
+ ]
695
+ }
696
+ }
697
+ }
698
+ ```
699
+
700
+ ### Platform Compatibility
701
+
702
+ | Platform | Architecture | Status | Notes |
703
+ |----------|-------------|---------|-------|
704
+ | **macOS Intel** | AMD64 | ✅ Full | Via Docker Desktop |
705
+ | **macOS Apple Silicon** | ARM64 | ✅ Full | Native ARM64 support |
706
+ | **Linux x86_64** | AMD64 | ✅ Full | Direct Docker support |
707
+ | **Linux ARM64** | ARM64 | ✅ Full | Servers, Pi 4+ |
708
+ | **Raspberry Pi 3+** | ARM64 | ✅ Optimized | Memory-limited config |
709
+ | **Windows** | AMD64 | ✅ Full | Via Docker Desktop + WSL2 |
710
+
711
+ ### Manual Docker Commands
712
+
713
+ If you prefer not to use docker-compose:
714
+
715
+ ```bash
716
+ # Raspberry Pi
717
+ docker run -d \
718
+ --name mcp-rubber-duck \
719
+ --memory=512m --cpus=1.5 \
720
+ --env-file .env \
721
+ --restart unless-stopped \
722
+ ghcr.io/nesquikm/mcp-rubber-duck:latest
723
+
724
+ # Desktop/Server
725
+ docker run -d \
726
+ --name mcp-rubber-duck \
727
+ --memory=2g --cpus=4 \
728
+ --env-file .env \
729
+ --restart unless-stopped \
730
+ ghcr.io/nesquikm/mcp-rubber-duck:latest
731
+ ```
732
+
733
+ ## Architecture
734
+
735
+ ```
736
+ mcp-rubber-duck/
737
+ ├── src/
738
+ │ ├── server.ts # MCP server implementation
739
+ │ ├── config/ # Configuration management
740
+ │ ├── providers/ # OpenAI client wrapper
741
+ │ ├── tools/ # MCP tool implementations
742
+ │ ├── services/ # Health, cache, conversations
743
+ │ └── utils/ # Logging, ASCII art
744
+ ├── config/ # Configuration examples
745
+ └── tests/ # Test suites
746
+ ```
747
+
748
+ ## Troubleshooting
749
+
750
+ ### Provider Not Working
751
+ 1. Check API key is correctly set
752
+ 2. Verify endpoint URL is correct
753
+ 3. Run health check: `list_ducks({ check_health: true })`
754
+ 4. Check logs for detailed error messages
755
+
756
+ ### Connection Issues
757
+ - For local providers (Ollama, LM Studio), ensure they're running
758
+ - Check firewall settings for local endpoints
759
+ - Verify network connectivity to cloud providers
760
+
761
+ ### Rate Limiting
762
+ - Enable caching to reduce API calls
763
+ - Configure failover to alternate providers
764
+ - Adjust `max_retries` and `timeout` settings
765
+
766
+ ## Contributing
767
+
768
+ 🦆 **Want to help make our duck pond better?**
769
+
770
+ We love contributions! Whether you're fixing bugs, adding features, or teaching our ducks new tricks, we'd love to have you join the flock.
771
+
772
+ Check out our [Contributing Guide](./CONTRIBUTING.md) to get started. We promise it's more fun than a regular contributing guide - it has ducks! 🦆
773
+
774
+ **Quick start for contributors:**
775
+ 1. Fork the repository
776
+ 2. Create a feature branch
777
+ 3. Follow our [conventional commit guidelines](./CONTRIBUTING.md#commit-messages-duck-communication-protocol)
778
+ 4. Add tests for new functionality
779
+ 5. Submit a pull request
780
+
781
+ ## License
782
+
783
+ MIT License - see LICENSE file for details
784
+
785
+ ## Acknowledgments
786
+
787
+ - Inspired by the rubber duck debugging method
788
+ - Built on the Model Context Protocol (MCP)
789
+ - Uses OpenAI SDK for universal compatibility
790
+
791
+ ## 📝 Changelog
792
+
793
+ See [CHANGELOG.md](./CHANGELOG.md) for a detailed history of changes and releases.
794
+
795
+ ## Support
796
+
797
+ - Report issues: https://github.com/nesquikm/mcp-rubber-duck/issues
798
+ - Documentation: https://github.com/nesquikm/mcp-rubber-duck/wiki
799
+ - Discussions: https://github.com/nesquikm/mcp-rubber-duck/discussions
800
+
801
+ ---
802
+
803
+ 🦆 **Happy Debugging with your AI Duck Panel!** 🦆