Repository avatar
AI Tools
v1.1.1
active

rubber-duck

io.github.nesquikm/rubber-duck

An MCP server that bridges to multiple OpenAI-compatible LLMs - your AI rubber duck debugging panel

Documentation

๐Ÿฆ† MCP Rubber Duck

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!

npm version Docker Image MCP Registry

MCP Rubber Duck - AI ducks helping debug code

Table of Contents

Features

  • ๐Ÿ”Œ Universal OpenAI Compatibility: Works with any OpenAI-compatible API endpoint
  • ๐Ÿฆ† Multiple Ducks: Configure and query multiple LLM providers simultaneously
  • ๐Ÿ’ฌ Conversation Management: Maintain context across multiple messages
  • ๐Ÿ›๏ธ Duck Council: Get responses from all your configured LLMs at once
  • ๐Ÿ—ณ๏ธ Consensus Voting: Multi-duck voting with reasoning and confidence scores
  • โš–๏ธ LLM-as-Judge: Have ducks evaluate and rank each other's responses
  • ๐Ÿ”„ Iterative Refinement: Two ducks collaboratively improve responses
  • ๐ŸŽ“ Structured Debates: Oxford, Socratic, and adversarial debate formats
  • ๐Ÿ“ MCP Prompts: 8 reusable prompt templates for multi-LLM workflows (via / commands)
  • ๐Ÿ’พ Response Caching: Avoid duplicate API calls with intelligent caching
  • ๐Ÿ” Automatic Failover: Falls back to other providers if primary fails
  • ๐Ÿ“Š Health Monitoring: Real-time health checks for all providers
  • ๐Ÿ’ฐ Usage Tracking: Track requests, tokens, and estimated costs per provider
  • ๐Ÿ”— MCP Bridge: Connect ducks to other MCP servers for extended functionality
  • ๐Ÿ›ก๏ธ Guardrails: Pluggable safety layer with rate limiting, token limits, pattern blocking, and PII redaction
  • ๐Ÿ” Granular Security: Per-server approval controls with session-based approvals
  • ๐Ÿท๏ธ Tool Annotations: MCP-compliant hints for tool behavior (read-only, destructive, etc.)
  • ๐ŸŽจ Fun Duck Theme: Rubber duck debugging with personality!

Supported Providers

Any provider with an OpenAI-compatible API endpoint, including:

  • OpenAI (GPT-5.1, o3, o4-mini)
  • Google Gemini (Gemini 3, Gemini 2.5 Pro/Flash)
  • Anthropic (via OpenAI-compatible endpoints)
  • Groq (Llama 4, Llama 3.3)
  • Together AI (Llama 4, Qwen, and more)
  • Perplexity (Online models with web search)
  • Anyscale (Open source models)
  • Azure OpenAI (Microsoft-hosted OpenAI)
  • Ollama (Local models)
  • LM Studio (Local models)
  • Custom (Any OpenAI-compatible endpoint)

Quick Start

# Install globally
npm install -g mcp-rubber-duck

# Or use npx directly in Claude Desktop config
npx mcp-rubber-duck

Using Claude Desktop? Jump to Claude Desktop Configuration.

Installation

Prerequisites

  • Node.js 20 or higher
  • npm or yarn
  • At least one API key for a supported provider

Installation Methods

Option 1: Install from NPM

npm install -g mcp-rubber-duck

Option 2: Install from Source

# Clone the repository
git clone https://github.com/nesquikm/mcp-rubber-duck.git
cd mcp-rubber-duck

# Install dependencies
npm install

# Build the project
npm run build

# Run the server
npm start

Configuration

Method 1: Environment Variables

Create a .env file in the project root:

# OpenAI
OPENAI_API_KEY=sk-...
OPENAI_DEFAULT_MODEL=gpt-5.1  # Optional: defaults to gpt-5.1

# Google Gemini
GEMINI_API_KEY=...
GEMINI_DEFAULT_MODEL=gemini-2.5-flash  # Optional: defaults to gemini-2.5-flash

# Groq
GROQ_API_KEY=gsk_...
GROQ_DEFAULT_MODEL=llama-3.3-70b-versatile  # Optional: defaults to llama-3.3-70b-versatile

# Ollama (Local)
OLLAMA_BASE_URL=http://localhost:11434/v1  # Optional
OLLAMA_DEFAULT_MODEL=llama3.2  # Optional: defaults to llama3.2

# Together AI
TOGETHER_API_KEY=...

# Custom Providers (you can add multiple)
# Format: CUSTOM_{NAME}_* where NAME becomes the provider key (lowercase)

# Example: Add provider "myapi"
CUSTOM_MYAPI_API_KEY=...
CUSTOM_MYAPI_BASE_URL=https://api.example.com/v1
CUSTOM_MYAPI_DEFAULT_MODEL=custom-model  # Optional
CUSTOM_MYAPI_MODELS=model1,model2        # Optional: comma-separated list
CUSTOM_MYAPI_NICKNAME=My Custom Duck     # Optional: display name

# Example: Add provider "azure" 
CUSTOM_AZURE_API_KEY=...
CUSTOM_AZURE_BASE_URL=https://mycompany.openai.azure.com/v1

# Global Settings
DEFAULT_PROVIDER=openai
DEFAULT_TEMPERATURE=0.7
LOG_LEVEL=info

# MCP Bridge Settings (Optional)
MCP_BRIDGE_ENABLED=true                      # Enable ducks to access external MCP servers
MCP_APPROVAL_MODE=trusted                    # always, trusted, or never
MCP_APPROVAL_TIMEOUT=300                     # seconds

# MCP Server: Context7 Documentation (Example)
MCP_SERVER_CONTEXT7_TYPE=http
MCP_SERVER_CONTEXT7_URL=https://mcp.context7.com/mcp
MCP_SERVER_CONTEXT7_ENABLED=true

# Per-server trusted tools
MCP_TRUSTED_TOOLS_CONTEXT7=*                 # Trust all Context7 tools

# Optional: Custom Duck Nicknames (Have fun with these!)
OPENAI_NICKNAME="DUCK-4"              # Optional: defaults to "GPT Duck"
GEMINI_NICKNAME="Duckmini"            # Optional: defaults to "Gemini Duck"
GROQ_NICKNAME="Quackers"              # Optional: defaults to "Groq Duck"
OLLAMA_NICKNAME="Local Quacker"       # Optional: defaults to "Local Duck"
CUSTOM_NICKNAME="My Special Duck"     # Optional: defaults to "Custom Duck"

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.

Method 2: Configuration File

Create a config/config.json file based on the example:

cp config/config.example.json config/config.json
# Edit config/config.json with your API keys and preferences

Claude Desktop Configuration

This is the most common setup method for using MCP Rubber Duck with Claude Desktop.

Step 1: Install

Choose one of these options:

Option A: NPM (Recommended)

npm install -g mcp-rubber-duck

Option B: From Source (see Installation from Source)

Step 2: Configure Claude Desktop

Edit your Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add the MCP server configuration:

If installed via NPM:

{
  "mcpServers": {
    "rubber-duck": {
      "command": "mcp-rubber-duck",
      "env": {
        "MCP_SERVER": "true",
        "OPENAI_API_KEY": "your-openai-api-key-here",
        "GEMINI_API_KEY": "your-gemini-api-key-here",
        "DEFAULT_PROVIDER": "openai"
      }
    }
  }
}

If installed from source:

{
  "mcpServers": {
    "rubber-duck": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-rubber-duck/dist/index.js"],
      "env": {
        "MCP_SERVER": "true",
        "OPENAI_API_KEY": "your-openai-api-key-here",
        "GEMINI_API_KEY": "your-gemini-api-key-here",
        "DEFAULT_PROVIDER": "openai"
      }
    }
  }
}

Important: Replace the placeholder API keys with your actual keys:

  • your-openai-api-key-here โ†’ Your OpenAI API key (starts with sk-)
  • your-gemini-api-key-here โ†’ Your Gemini API key from Google AI Studio

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).

Tip: See Configuration for additional options like LOG_LEVEL, custom model defaults, and duck nicknames.

Step 3: Restart Claude Desktop

  1. Completely quit Claude Desktop (โŒ˜+Q on Mac)
  2. Launch Claude Desktop again
  3. The MCP server should connect automatically

Step 4: Test the Integration

Once restarted, test these commands in Claude:

Check Duck Health

Use the list_ducks tool with check_health: true

Should show:

  • โœ… GPT Duck (openai) - Healthy
  • โœ… Gemini Duck (gemini) - Healthy

List Available Models

Use the list_models tool

Ask a Specific Duck

Use the ask_duck tool with prompt: "What is rubber duck debugging?", provider: "openai"

Compare Multiple Ducks

Use the compare_ducks tool with prompt: "Explain async/await in JavaScript"

Test Specific Models

Use the ask_duck tool with prompt: "Hello", provider: "openai", model: "gpt-4o"

Troubleshooting Claude Desktop Setup

If Tools Don't Appear

  1. Check API Keys: Ensure your API keys are correctly entered without typos
  2. Verify Build: Run ls -la dist/index.js to confirm the project built successfully
  3. Check Logs: Look for errors in Claude Desktop's developer console
  4. Restart: Fully quit and restart Claude Desktop after config changes

Connection Issues

  1. Config File Path: Double-check you're editing the correct config file path
  2. JSON Syntax: Validate your JSON syntax (no trailing commas, proper quotes)
  3. Absolute Paths: Ensure you're using the full absolute path to dist/index.js
  4. File Permissions: Verify Claude Desktop can read the dist directory

Health Check Failures

If ducks show as unhealthy:

  1. API Keys: Verify keys are valid and have sufficient credits/quota
  2. Network: Check internet connection and firewall settings
  3. Rate Limits: Some providers have strict rate limits for new accounts

MCP Bridge - Connect to Other MCP Servers

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!

Note: This is different from the MCP server integration above:

  • MCP Bridge (MCP_BRIDGE_ENABLED): Ducks USE external MCP servers as clients
  • MCP Server (MCP_SERVER): Rubber-duck SERVES as an MCP server to any MCP client

Quick Setup

Add these environment variables to enable MCP Bridge:

# Basic MCP Bridge Configuration
MCP_BRIDGE_ENABLED="true"                # Enable ducks to access external MCP servers
MCP_APPROVAL_MODE="trusted"              # always, trusted, or never
MCP_APPROVAL_TIMEOUT="300"               # 5 minutes

# Example: Context7 Documentation Server
MCP_SERVER_CONTEXT7_TYPE="http"
MCP_SERVER_CONTEXT7_URL="https://mcp.context7.com/mcp"
MCP_SERVER_CONTEXT7_ENABLED="true"

# Trust all Context7 tools (no approval needed)
MCP_TRUSTED_TOOLS_CONTEXT7="*"

Approval Modes

always: Every tool call requires approval (with session-based memory)

  • First use of a tool โ†’ requires approval
  • Subsequent uses of the same tool โ†’ automatic (until restart)

trusted: Only untrusted tools require approval

  • Tools in trusted lists execute immediately
  • Unknown tools require approval

never: All tools execute immediately (use with caution)

Per-Server Trusted Tools

Configure trust levels per MCP server for granular security:

# Trust all tools from Context7 (documentation server)
MCP_TRUSTED_TOOLS_CONTEXT7="*"

# Trust specific filesystem operations only
MCP_TRUSTED_TOOLS_FILESYSTEM="read-file,list-directory"

# Trust specific GitHub tools
MCP_TRUSTED_TOOLS_GITHUB="get-repo-info,list-issues"

# Global fallback for servers without specific config
MCP_TRUSTED_TOOLS="common-safe-tool"

MCP Server Configuration

Configure MCP servers using environment variables:

HTTP Servers

MCP_SERVER_{NAME}_TYPE="http"
MCP_SERVER_{NAME}_URL="https://api.example.com/mcp"
MCP_SERVER_{NAME}_API_KEY="your-api-key"        # Optional
MCP_SERVER_{NAME}_ENABLED="true"

STDIO Servers

MCP_SERVER_{NAME}_TYPE="stdio"
MCP_SERVER_{NAME}_COMMAND="python"
MCP_SERVER_{NAME}_ARGS="/path/to/script.py,--arg1,--arg2"
MCP_SERVER_{NAME}_ENABLED="true"

Example: Enable Context7 Documentation

# Enable MCP Bridge
MCP_BRIDGE_ENABLED="true"
MCP_APPROVAL_MODE="trusted"

# Configure Context7 server
MCP_SERVER_CONTEXT7_TYPE="http"
MCP_SERVER_CONTEXT7_URL="https://mcp.context7.com/mcp"
MCP_SERVER_CONTEXT7_ENABLED="true"

# Trust all Context7 tools
MCP_TRUSTED_TOOLS_CONTEXT7="*"

Now your ducks can search and retrieve documentation from Context7:

Ask: "Can you find React hooks documentation from Context7 and return only the key concepts?"
Duck: *searches Context7 and returns focused, essential React hooks information*

Token Optimization Benefits

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:

  • Ask for specifics: "Find TypeScript interfaces documentation and return only the core concepts"
  • Duck processes full docs: Accesses complete documentation from Context7
  • Returns condensed results: Provides focused, relevant information while filtering out unnecessary details
  • Token savings: Reduces response size by 70-90% compared to raw documentation dumps

Example Workflow:

You: "Find Express.js routing concepts from Context7, keep it concise"
Duck: *Retrieves full Express docs, processes, and returns only routing essentials*
Result: 500 tokens instead of 5,000+ tokens of raw documentation

Session-Based Approvals

When using always mode, the system remembers your approvals:

  1. First time: "Duck wants to use search-docs - Approve? โœ…"
  2. Next time: Duck uses search-docs automatically (no new approval needed)
  3. Different tool: "Duck wants to use get-examples - Approve? โœ…"
  4. Restart: Session memory clears, start over

This eliminates approval fatigue while maintaining security!

Guardrails - Safety & Compliance Layer

Guardrails provide a pluggable safety and compliance layer that intercepts LLM requests and responses. Protect against rate abuse, limit token usage, block sensitive patterns, and automatically redact PII.

Quick Setup

# Enable guardrails with PII protection
GUARDRAILS_ENABLED="true"
GUARDRAILS_PII_REDACTOR_ENABLED="true"
GUARDRAILS_PII_REDACTOR_ALLOWLIST_DOMAINS="mycompany.com"

Global Settings

VariableTypeDefaultDescription
GUARDRAILS_ENABLEDbooleanfalseMaster switch for guardrails system
GUARDRAILS_LOG_VIOLATIONSbooleanfalseLog when guardrails detect violations
GUARDRAILS_LOG_MODIFICATIONSbooleanfalseLog when guardrails modify content
GUARDRAILS_FAIL_OPENbooleanfalseIf true, allow requests when guardrails error; if false, block on error

Rate Limiter

Prevent API abuse by limiting request frequency.

GUARDRAILS_RATE_LIMITER_ENABLED="true"
GUARDRAILS_RATE_LIMITER_REQUESTS_PER_MINUTE="60"
GUARDRAILS_RATE_LIMITER_REQUESTS_PER_HOUR="500"
GUARDRAILS_RATE_LIMITER_PER_PROVIDER="true"      # Track limits per provider
GUARDRAILS_RATE_LIMITER_BURST_ALLOWANCE="5"      # Extra requests for short bursts
VariableTypeDefaultDescription
GUARDRAILS_RATE_LIMITER_ENABLEDbooleanfalseEnable rate limiting
GUARDRAILS_RATE_LIMITER_REQUESTS_PER_MINUTEnumber60Max requests per minute
GUARDRAILS_RATE_LIMITER_REQUESTS_PER_HOURnumber1000Max requests per hour
GUARDRAILS_RATE_LIMITER_PER_PROVIDERbooleanfalseTrack limits per provider vs global
GUARDRAILS_RATE_LIMITER_BURST_ALLOWANCEnumber5Extra requests allowed for bursts

Token Limiter

Control token usage for cost management.

GUARDRAILS_TOKEN_LIMITER_ENABLED="true"
GUARDRAILS_TOKEN_LIMITER_MAX_INPUT_TOKENS="100000"
GUARDRAILS_TOKEN_LIMITER_MAX_OUTPUT_TOKENS="16000"
GUARDRAILS_TOKEN_LIMITER_WARN_AT_PERCENTAGE="80"
VariableTypeDefaultDescription
GUARDRAILS_TOKEN_LIMITER_ENABLEDbooleanfalseEnable token limiting
GUARDRAILS_TOKEN_LIMITER_MAX_INPUT_TOKENSnumber8192Max tokens in input prompt
GUARDRAILS_TOKEN_LIMITER_MAX_OUTPUT_TOKENSnumber-Max tokens in response
GUARDRAILS_TOKEN_LIMITER_WARN_AT_PERCENTAGEnumber80Warn when usage hits this %

Pattern Blocker

Block or redact sensitive patterns in requests.

GUARDRAILS_PATTERN_BLOCKER_ENABLED="true"
GUARDRAILS_PATTERN_BLOCKER_PATTERNS="confidential,internal-only"
GUARDRAILS_PATTERN_BLOCKER_PATTERNS_REGEX="secret-\\d{4}"
GUARDRAILS_PATTERN_BLOCKER_CASE_SENSITIVE="false"
GUARDRAILS_PATTERN_BLOCKER_ACTION="block"        # block, warn, or redact
VariableTypeDefaultDescription
GUARDRAILS_PATTERN_BLOCKER_ENABLEDbooleanfalseEnable pattern blocking
GUARDRAILS_PATTERN_BLOCKER_PATTERNSstring-Comma-separated literal patterns
GUARDRAILS_PATTERN_BLOCKER_PATTERNS_REGEXstring-Comma-separated regex patterns
GUARDRAILS_PATTERN_BLOCKER_CASE_SENSITIVEbooleanfalseCase-sensitive matching
GUARDRAILS_PATTERN_BLOCKER_ACTIONstringblockAction: block, warn, or redact

PII Redactor

Automatically detect and redact personally identifiable information.

GUARDRAILS_PII_REDACTOR_ENABLED="true"
GUARDRAILS_PII_REDACTOR_DETECT_EMAILS="true"
GUARDRAILS_PII_REDACTOR_DETECT_PHONES="true"
GUARDRAILS_PII_REDACTOR_DETECT_SSN="true"
GUARDRAILS_PII_REDACTOR_DETECT_API_KEYS="true"
GUARDRAILS_PII_REDACTOR_DETECT_CREDIT_CARDS="true"
GUARDRAILS_PII_REDACTOR_DETECT_IP_ADDRESSES="true"
GUARDRAILS_PII_REDACTOR_ALLOWLIST_DOMAINS="gmail.com,company.com"
GUARDRAILS_PII_REDACTOR_RESTORE_ON_RESPONSE="true"
VariableTypeDefaultDescription
GUARDRAILS_PII_REDACTOR_ENABLEDbooleanfalseEnable PII detection/redaction
GUARDRAILS_PII_REDACTOR_DETECT_EMAILSbooleantrueDetect email addresses
GUARDRAILS_PII_REDACTOR_DETECT_PHONESbooleantrueDetect phone numbers
GUARDRAILS_PII_REDACTOR_DETECT_SSNbooleantrueDetect US Social Security Numbers
GUARDRAILS_PII_REDACTOR_DETECT_API_KEYSbooleantrueDetect API keys (sk-, gsk_, etc.)
GUARDRAILS_PII_REDACTOR_DETECT_CREDIT_CARDSbooleantrueDetect credit card numbers
GUARDRAILS_PII_REDACTOR_DETECT_IP_ADDRESSESbooleanfalseDetect IPv4 addresses
GUARDRAILS_PII_REDACTOR_ALLOWLISTstring-Comma-separated exact values to skip
GUARDRAILS_PII_REDACTOR_ALLOWLIST_DOMAINSstring-Comma-separated email domains to skip
GUARDRAILS_PII_REDACTOR_RESTORE_ON_RESPONSEbooleanfalseRestore original PII in responses
GUARDRAILS_PII_REDACTOR_LOG_DETECTIONSbooleanfalseLog when PII is detected

How PII Redaction Works:

  1. User sends: "Contact john@secret.com for details"
  2. Pre-request: Redacted to "Contact [EMAIL_1] for details"
  3. LLM processes the redacted text
  4. Post-response: If restore_on_response=true, [EMAIL_1] โ†’ john@secret.com

Example: Full Production Config

# Enable guardrails
GUARDRAILS_ENABLED="true"
GUARDRAILS_LOG_VIOLATIONS="true"

# Rate limiting
GUARDRAILS_RATE_LIMITER_ENABLED="true"
GUARDRAILS_RATE_LIMITER_REQUESTS_PER_MINUTE="60"
GUARDRAILS_RATE_LIMITER_REQUESTS_PER_HOUR="500"

# Token limits
GUARDRAILS_TOKEN_LIMITER_ENABLED="true"
GUARDRAILS_TOKEN_LIMITER_MAX_INPUT_TOKENS="100000"
GUARDRAILS_TOKEN_LIMITER_MAX_OUTPUT_TOKENS="16000"

# Block sensitive patterns
GUARDRAILS_PATTERN_BLOCKER_ENABLED="true"
GUARDRAILS_PATTERN_BLOCKER_PATTERNS="confidential,internal-only"
GUARDRAILS_PATTERN_BLOCKER_ACTION="warn"

# PII protection
GUARDRAILS_PII_REDACTOR_ENABLED="true"
GUARDRAILS_PII_REDACTOR_ALLOWLIST_DOMAINS="gmail.com,company.com"
GUARDRAILS_PII_REDACTOR_RESTORE_ON_RESPONSE="true"

Guardrail Phases

Guardrails intercept at multiple points in the request lifecycle:

PhaseDescriptionPlugins
pre_requestBefore sending to LLMRate limiter, Token limiter, Pattern blocker, PII redactor
post_responseAfter receiving from LLMToken limiter, PII redactor (restore)
pre_tool_inputBefore MCP tool executionPII redactor
post_tool_outputAfter MCP tool returnsPII redactor (restore)

Available Tools

Basic Tools

๐Ÿฆ† ask_duck

Ask a single question to a specific LLM provider. When MCP Bridge is enabled, ducks can automatically access tools from connected MCP servers.

{
  "prompt": "What is rubber duck debugging?",
  "provider": "openai",  // Optional, uses default if not specified
  "temperature": 0.7     // Optional
}

๐Ÿ’ฌ chat_with_duck

Have a conversation with context maintained across messages.

{
  "conversation_id": "debug-session-1",
  "message": "Can you help me debug this code?",
  "provider": "groq"  // Optional, can switch providers mid-conversation
}

๐Ÿงน clear_conversations

Clear all conversation history and start fresh. Useful when switching topics or when context becomes too large.

{
  // No parameters required
}

๐Ÿ“‹ list_ducks

List all configured providers and their health status.

{
  "check_health": true  // Optional, performs fresh health check
}

๐Ÿ“Š list_models

List available models for LLM providers.

{
  "provider": "openai",     // Optional, lists all if not specified
  "fetch_latest": false     // Optional, fetch latest from API vs cached
}

๐Ÿ” compare_ducks

Ask the same question to multiple providers simultaneously.

{
  "prompt": "What's the best programming language?",
  "providers": ["openai", "groq", "ollama"]  // Optional, uses all if not specified
}

๐Ÿ›๏ธ duck_council

Get responses from all configured ducks - like a panel discussion!

{
  "prompt": "How should I architect a microservices application?"
}

๐Ÿ“Š get_usage_stats

Get usage statistics and estimated costs for your duck queries.

{
  "period": "today"  // Optional: "today", "7d", "30d", or "all"
}

Returns requests, tokens (prompt/completion), cache hits, errors, and estimated costs broken down by provider and model.

Usage data is stored in ~/.mcp-rubber-duck/data/usage.json.

Multi-Agent Consensus & Debate Tools

Research-backed tools for multi-agent coordination.

๐Ÿ—ณ๏ธ duck_vote

Have multiple ducks vote on options with reasoning and confidence scores.

{
  "question": "Best approach for error handling?",
  "options": ["try-catch", "Result type", "Either monad"],
  "voters": ["openai", "gemini"],     // Optional, uses all if not specified
  "require_reasoning": true            // Optional, default: true
}

Returns vote tally, confidence scores, and consensus level (unanimous, majority, plurality, split, none).

โš–๏ธ duck_judge

Have one duck evaluate and rank other ducks' responses. Use after duck_council.

{
  "responses": [/* responses from duck_council */],
  "judge": "openai",                   // Optional, uses first available
  "criteria": ["accuracy", "completeness", "clarity"],  // Optional
  "persona": "senior engineer"         // Optional, e.g., "security expert"
}

๐Ÿ”„ duck_iterate

Iteratively refine a response between two ducks.

{
  "prompt": "Write a function to validate email addresses",
  "providers": ["openai", "gemini"],   // Exactly 2 providers
  "mode": "critique-improve",          // or "refine"
  "iterations": 3                      // Optional, default: 3, max: 10
}

Modes:

  • refine: Each duck improves the previous response
  • critique-improve: Alternates between critiquing and improving

๐ŸŽ“ duck_debate

Structured multi-round debate between ducks.

{
  "prompt": "Should startups use microservices or monolith for MVP?",
  "format": "oxford",                  // "oxford", "socratic", or "adversarial"
  "rounds": 2,                         // Optional, default: 3
  "providers": ["openai", "gemini"],   // Optional, uses all if not specified
  "synthesizer": "openai"              // Optional, duck to synthesize debate
}

Formats:

  • oxford: Structured pro/con arguments
  • socratic: Question-based philosophical exploration
  • adversarial: One defends, others attack weaknesses

MCP Bridge Tools

Tools for managing MCP server connections and tool approvals.

๐Ÿ”— mcp_status

Get status of MCP Bridge, connected servers, and pending approvals.

{
  // No parameters required
}

โœ… get_pending_approvals

Get list of pending MCP tool approvals from ducks.

{
  "duck": "openai"  // Optional, filter by duck name
}

๐Ÿ›ก๏ธ approve_mcp_request

Approve or deny a duck's MCP tool request.

{
  "approval_id": "abc123",       // Required
  "decision": "approve",         // "approve" or "deny"
  "reason": "Not needed"         // Optional, reason for denial
}

Available Prompts

MCP Prompts are reusable templates that help you structure questions for multi-LLM analysis. Access them via / commands in Claude Desktop or other MCP clients.

Key Concept: Unlike tools (which execute actions), prompts help you frame your questions to get better multi-perspective responses from multiple LLMs.

PromptPurposeRequired Arguments
๐Ÿ“Š perspectivesMulti-angle analysis with assigned lensesproblem, perspectives
๐Ÿ” assumptionsSurface hidden assumptions in plansplan
๐Ÿ‘๏ธ blindspotsHunt for overlooked risks and gapsproposal
โš–๏ธ tradeoffsStructured option comparisonoptions, criteria
๐Ÿ›ก๏ธ red_teamSecurity/risk analysis from multiple anglestarget
๐Ÿ”„ reframeProblem reframing at different levelsproblem
๐Ÿ—๏ธ architectureDesign review across concernsdesign, workloads, priorities
๐Ÿ’ก diverge_convergeDivergent exploration then convergencechallenge

Example: Using perspectives with Duck Council

The most reliable way to use prompts is as templates with duck tools:

Use duck_council with this prompt:

"Analyze this problem from multiple perspectives:

**PROBLEM:** Review this authentication middleware for our API

**PERSPECTIVES:** security, performance, maintainability, error handling

**CONTEXT:** [paste your code here]

Each LLM should adopt ONE lens and provide targeted analysis from that viewpoint."

Example: Using tradeoffs with Compare Ducks

Use compare_ducks with this prompt:

"Analyze these technical options:

**OPTIONS:** PostgreSQL, MongoDB, Redis

**CRITERIA:** scalability, query flexibility, operational complexity, cost

**CONTEXT:** Real-time analytics dashboard with 10k concurrent users

Score each option against each criterion (1-5) and identify the biggest trade-off."

This approach works reliably and leverages multi-LLM analysis.

Known Limitations (Claude Code)

MCP prompts are correctly implemented per the MCP specification, but Claude Code's support for MCP prompts has limitations:

IssueStatusWorkaround
Must type (MCP) suffixRequiredUse /rubber-duck:reframe (MCP) not /rubber-duck:reframe
Arguments with spaces brokenWon't fixUse single words: problem="checkout-abandonment"
Argument hints not shownMissingSee table above for required arguments
Optional-only prompts need inputWon't fixType at least one character

Example that works:

/rubber-duck:reframe (MCP) problem="slow-api-responses"

Example that fails:

/rubber-duck:reframe (MCP) problem="Users abandon checkout at payment"
                                    โ†‘ spaces break argument parsing

Recommended: Use Prompts as Templates

For the best experience, use prompts as templates with duck tools directly. Copy the prompt structure and send to duck_council, compare_ducks, or ask_duck:

Use duck_council with this prompt:

"Analyze this problem from multiple perspectives:

**PROBLEM:** Users abandon checkout at payment step

**PERSPECTIVES:** security, UX, performance, reliability

Each LLM should adopt ONE lens and provide targeted analysis."

This approach:

  • โœ… Works reliably with full argument text
  • โœ… Leverages multi-LLM tools (council, compare, vote)
  • โœ… No Claude Code parsing issues

Usage Examples

Basic Query

// Ask the default duck
await ask_duck({ 
  prompt: "Explain async/await in JavaScript" 
});

Conversation

// Start a conversation
await chat_with_duck({
  conversation_id: "learning-session",
  message: "What is TypeScript?"
});

// Continue the conversation
await chat_with_duck({
  conversation_id: "learning-session", 
  message: "How does it differ from JavaScript?"
});

Compare Responses

// Get different perspectives
await compare_ducks({
  prompt: "What's the best way to handle errors in Node.js?",
  providers: ["openai", "groq", "ollama"]
});

Duck Council

// Convene the council for important decisions
await duck_council({
  prompt: "Should I use REST or GraphQL for my API?"
});

Multi-Agent Voting

// Have ducks vote on a decision
await duck_vote({
  question: "Best database for a real-time chat app?",
  options: ["PostgreSQL", "MongoDB", "Redis", "Cassandra"]
});
// Returns: Winner with consensus level (unanimous/majority/split)

Judge Responses

// First, get responses from council
const responses = await duck_council({
  prompt: "Implement a rate limiter"
});

// Then have a duck judge them
await duck_judge({
  responses: responses,
  criteria: ["correctness", "efficiency", "readability"],
  persona: "senior backend engineer"
});

Iterative Refinement

// Two ducks collaborate to improve a solution
await duck_iterate({
  prompt: "Write a TypeScript function to deep clone objects",
  providers: ["openai", "gemini"],
  mode: "critique-improve",
  iterations: 3
});

Structured Debate

// Oxford-style debate on architecture
await duck_debate({
  prompt: "Monorepo vs polyrepo for a growing startup",
  format: "oxford",
  rounds: 3
});

Check Usage Stats

// See today's usage
await get_usage_stats({ period: "today" });

// See last 7 days with cost breakdown
await get_usage_stats({ period: "7d" });

Provider-Specific Setup

Ollama (Local)

# Install Ollama
curl -fsSL https://ollama.ai/install.sh | sh

# Pull a model
ollama pull llama3.2

# Ollama automatically provides OpenAI-compatible endpoint at localhost:11434/v1

LM Studio (Local)

  1. Download LM Studio from https://lmstudio.ai/
  2. Load a model in LM Studio
  3. Start the local server (provides OpenAI-compatible endpoint at localhost:1234/v1)

Google Gemini

  1. Get API key from Google AI Studio
  2. Add to environment: GEMINI_API_KEY=...
  3. Uses OpenAI-compatible endpoint (beta)

Groq

  1. Get API key from https://console.groq.com/keys
  2. Add to environment: GROQ_API_KEY=gsk_...

Together AI

  1. Get API key from https://api.together.xyz/
  2. Add to environment: TOGETHER_API_KEY=...

Verifying OpenAI Compatibility

To check if a provider is OpenAI-compatible:

  1. Look for /v1/chat/completions endpoint in their API docs
  2. Check if they support the OpenAI SDK
  3. Test with curl:
curl -X POST "https://api.provider.com/v1/chat/completions" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "model-name",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Development

Run in Development Mode

npm run dev

Run Tests

npm test

Lint Code

npm run lint

Type Checking

npm run typecheck

Docker Support

MCP Rubber Duck provides multi-platform Docker support, working on macOS (Intel & Apple Silicon), Linux (x86_64 & ARM64), Windows (WSL2), and Raspberry Pi 3+.

Quick Start with Pre-built Image

The easiest way to get started is with our pre-built multi-architecture image:

# Pull the image (works on all platforms)
docker pull ghcr.io/nesquikm/mcp-rubber-duck:latest

# Create environment file
cp .env.template .env
# Edit .env and add your API keys

# Run with Docker Compose (recommended)
docker compose up -d

Platform-Specific Deployment

Desktop/Server (macOS, Linux, Windows)

# Use desktop-optimized settings
./scripts/deploy.sh --platform desktop

# Or with more resources and local AI
./scripts/deploy.sh --platform desktop --profile with-ollama

Raspberry Pi

# Use Pi-optimized settings (memory limits, etc.)
./scripts/deploy.sh --platform pi

# Or copy optimized config directly
cp .env.pi.example .env
# Edit .env and add your API keys
docker compose up -d

Remote Deployment via SSH

# Deploy to remote Raspberry Pi
./scripts/deploy.sh --mode ssh --ssh-host pi@192.168.1.100

Universal Deployment Script

The scripts/deploy.sh script auto-detects your platform and applies optimal settings:

# Auto-detect platform and deploy
./scripts/deploy.sh

# Options:
./scripts/deploy.sh --help

Available options:

  • --mode: docker (default), local, or ssh
  • --platform: pi, desktop, or auto (default)
  • --profile: lightweight, desktop, with-ollama
  • --ssh-host: For remote deployment

Platform-Specific Configuration

Raspberry Pi (Memory-Optimized)

# .env.pi.example - Optimized for Pi 3+
DOCKER_CPU_LIMIT=1.5
DOCKER_MEMORY_LIMIT=512M
NODE_OPTIONS=--max-old-space-size=256

Desktop/Server (High-Performance)

# .env.desktop.example - Optimized for powerful systems
DOCKER_CPU_LIMIT=4.0
DOCKER_MEMORY_LIMIT=2G
NODE_OPTIONS=--max-old-space-size=1024

Docker Compose Profiles

# Default profile (lightweight, good for Pi)
docker compose up -d

# Desktop profile (higher resource limits)
docker compose --profile desktop up -d

# With local Ollama AI
docker compose --profile with-ollama up -d

Build Multi-Architecture Images

For developers who want to build and publish their own multi-architecture images:

# Build for AMD64 + ARM64
./scripts/build-multiarch.sh --platforms linux/amd64,linux/arm64

# Build and push to GitHub Container Registry
./scripts/gh-deploy.sh --public

Claude Desktop with Remote Docker

Connect Claude Desktop to MCP Rubber Duck running on a remote system:

{
  "mcpServers": {
    "rubber-duck-remote": {
      "command": "ssh",
      "args": [
        "user@remote-host",
        "docker exec -i mcp-rubber-duck node /app/dist/index.js"
      ]
    }
  }
}

Platform Compatibility

PlatformArchitectureStatusNotes
macOS IntelAMD64โœ… FullVia Docker Desktop
macOS Apple SiliconARM64โœ… FullNative ARM64 support
Linux x86_64AMD64โœ… FullDirect Docker support
Linux ARM64ARM64โœ… FullServers, Pi 4+
Raspberry Pi 3+ARM64โœ… OptimizedMemory-limited config
WindowsAMD64โœ… FullVia Docker Desktop + WSL2

Manual Docker Commands

If you prefer not to use docker-compose:

# Raspberry Pi
docker run -d \
  --name mcp-rubber-duck \
  --memory=512m --cpus=1.5 \
  --env-file .env \
  --restart unless-stopped \
  ghcr.io/nesquikm/mcp-rubber-duck:latest

# Desktop/Server
docker run -d \
  --name mcp-rubber-duck \
  --memory=2g --cpus=4 \
  --env-file .env \
  --restart unless-stopped \
  ghcr.io/nesquikm/mcp-rubber-duck:latest

Architecture

mcp-rubber-duck/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ server.ts           # MCP server implementation
โ”‚   โ”œโ”€โ”€ config/             # Configuration management
โ”‚   โ”œโ”€โ”€ providers/          # OpenAI client wrapper
โ”‚   โ”œโ”€โ”€ tools/              # MCP tool implementations
โ”‚   โ”œโ”€โ”€ prompts/            # MCP prompt templates
โ”‚   โ”œโ”€โ”€ services/           # Health, cache, conversations
โ”‚   โ””โ”€โ”€ utils/              # Logging, ASCII art
โ”œโ”€โ”€ config/                 # Configuration examples
โ””โ”€โ”€ tests/                  # Test suites

Tool Annotations

All tools include MCP-compliant annotations that describe their behavioral characteristics:

AnnotationMeaning
readOnlyHintTool doesn't modify any state
destructiveHintTool performs irreversible operations
idempotentHintTool is safe to retry multiple times
openWorldHintTool accesses external systems (APIs, network)

These help MCP clients make informed decisions about tool execution and user confirmations.

Troubleshooting

Provider Not Working

  1. Check API key is correctly set
  2. Verify endpoint URL is correct
  3. Run health check: list_ducks({ check_health: true })
  4. Check logs for detailed error messages

Connection Issues

  • For local providers (Ollama, LM Studio), ensure they're running
  • Check firewall settings for local endpoints
  • Verify network connectivity to cloud providers

Rate Limiting

  • Enable caching to reduce API calls
  • Configure failover to alternate providers
  • Adjust max_retries and timeout settings

Contributing

     __
   <(o )___
    ( ._> /
     `---'  Quack! Ready to debug!

๐Ÿฆ† Want to help make our duck pond better?

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.

Check out our Contributing Guide to get started. We promise it's more fun than a regular contributing guide - it has ducks! ๐Ÿฆ†

Quick start for contributors:

  1. Fork the repository
  2. Create a feature branch
  3. Follow our conventional commit guidelines
  4. Add tests for new functionality
  5. Submit a pull request

License

MIT License - see LICENSE file for details

Acknowledgments

  • Inspired by the rubber duck debugging method
  • Built on the Model Context Protocol (MCP)
  • Uses OpenAI SDK for universal compatibility

Changelog

See CHANGELOG.md for a detailed history of changes and releases.

Registry & Directory

MCP Rubber Duck is available through multiple channels:

Support


๐Ÿฆ† Happy Debugging with your AI Duck Panel! ๐Ÿฆ†