Files
gh-technicalpickles-pickled…/skills/mcpproxy-debug/references/debugging-examples.md
2025-11-30 09:00:29 +08:00

259 lines
6.5 KiB
Markdown

# Real-World MCPProxy Debugging Examples
This file contains detailed walkthroughs of actual debugging sessions, providing concrete examples of how to diagnose and fix MCPProxy issues.
## Example 1: Buildkite Server - Docker Isolation Conflict
**Date**: October 2025
**Symptom**: Buildkite MCP server failing to connect with "the input device is not a TTY" error
**Server Type**: Docker-based MCP server (`ghcr.io/buildkite/buildkite-mcp-server:latest`)
### Initial Configuration
```json
{
"name": "buildkite",
"protocol": "stdio",
"command": "docker",
"args": [
"run",
"--pull=always",
"-q",
"-i",
"--rm",
"-e",
"BUILDKITE_API_TOKEN",
"ghcr.io/buildkite/buildkite-mcp-server:latest",
"stdio"
],
"env": {
"BUILDKITE_API_TOKEN": "${keyring:buildkite_token}"
},
"enabled": true,
"quarantined": false
}
```
### Diagnostic Process
1. **Ran diagnostic script**:
```bash
~/.claude/skills/mcpproxy-debug/scripts/diagnose_server.sh buildkite
```
2. **Key findings from stderr**:
```
"the input device is not a TTY"
```
3. **Pattern recognition**: This error typically indicates:
- Either `-it` flags being used (but config showed `-i` only)
- OR Docker isolation wrapping a Docker command (Docker-in-Docker)
4. **Checked Docker isolation status**:
- Global `docker_isolation.enabled` was `true`
- Server had no explicit isolation override
- MCPProxy was wrapping the Docker command in another container
### Root Cause
Docker isolation was enabled globally, and MCPProxy was attempting to run:
```
docker run [isolation-wrapper-args] docker run [server-args] ...
```
This creates a Docker-in-Docker situation where the inner Docker command can't allocate a TTY because it's running inside a container.
### Solution
Added explicit isolation disable to the server configuration:
```json
{
"name": "buildkite",
"protocol": "stdio",
"command": "docker",
"args": [
"run",
"--pull=always",
"-q",
"-i",
"--rm",
"-e",
"BUILDKITE_API_TOKEN",
"ghcr.io/buildkite/buildkite-mcp-server:latest",
"stdio"
],
"env": {
"BUILDKITE_API_TOKEN": "${keyring:buildkite_token}"
},
"isolation": {
"enabled": false
},
"enabled": true,
"quarantined": false
}
```
### Verification
After restarting mcpproxy:
1. **Process inspection**:
```bash
ps aux | grep mcpproxy
```
Confirmed the buildkite server was now running directly:
```
docker run --cidfile ... --pull=always -q -i --rm -e BUILDKITE_API_TOKEN ghcr.io/buildkite/buildkite-mcp-server:latest stdio
```
2. **Connection verification**:
```bash
~/.claude/skills/mcpproxy-debug/scripts/diagnose_server.sh buildkite
```
Output showed:
```
Successfully connected and initialized
server_name: "buildkite-mcp-server"
server_version: "0.7.2"
tool_count: 28
```
3. **No more TTY errors** in recent logs
### Key Lessons
1. **Docker isolation auto-skip may fail**: The intended automatic skip for Docker commands didn't work in this case
2. **Always explicitly disable isolation for Docker commands**: Best practice to prevent Docker-in-Docker issues
3. **Stderr is the most revealing**: The "TTY" error in stderr immediately pointed to the issue
4. **The diagnostic script is highly effective**: Automated pattern detection caught the problem immediately
### Applicable to Other Servers
This same issue and solution applies to any Docker-based MCP server:
- `ghcr.io/github/github-mcp-server`
- `ghcr.io/sooperset/mcp-atlassian:latest`
- Any custom Docker image serving MCP
**Template solution**:
```json
{
"name": "any-docker-mcp-server",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "ENV_VAR", "image:tag"],
"isolation": {
"enabled": false
}
}
```
## Example 2: API Key Mismatch After Restart
**Symptom**: API calls return "Invalid or missing API key" after restarting mcpproxy
### Diagnostic Process
1. **Check config file API key**:
```bash
grep '"api_key"' ~/.mcpproxy/mcp_config.json
```
Result: `"api_key": "d380462e333f25a1c61bad1d5d3f673277d5167dcdba18954effc7d6f0401c37"`
2. **API call with config key fails**:
```bash
curl -H "X-API-Key: d380462e333f25a1c61bad1d5d3f673277d5167dcdba18954effc7d6f0401c37" \
http://127.0.0.1:8080/api/v1/servers
```
Result: `{"success": false, "error": "Invalid or missing API key"}`
3. **Check logs for API key source**:
```bash
grep -i "api.*key" ~/Library/Logs/mcpproxy/main.log | tail -10
```
Result: `API key authentication enabled | {"source": "environment variable", "api_key_prefix": "9fc1****ee1c"}`
### Root Cause
The `MCPPROXY_API_KEY` environment variable was set (likely by the tray app), which takes precedence over the config file. The actual API key was `9fc15eb0...` (different from config).
### Solution
Use the environment variable key or unset the environment variable:
**Option 1**: Use the actual key from logs
```bash
# Extract from log prefix
grep "api_key_prefix" ~/Library/Logs/mcpproxy/main.log | tail -1
```
**Option 2**: Unset environment variable to use config file
```bash
unset MCPPROXY_API_KEY
pkill mcpproxy
open /Applications/mcpproxy.app
```
### Key Lesson
Always check both environment variables and config file when debugging API authentication. Environment variables take precedence.
## Pattern: Missing Package Name in uvx/npx
**Error**: `unexpected argument '--some-flag' found`
**Example**:
```json
// WRONG
{"command": "uvx", "args": ["--local-timezone", "America/New_York"]}
// CORRECT
{"command": "uvx", "args": ["mcp-server-time", "--local-timezone", "America/New_York"]}
```
**Diagnostic**: Check stderr in server logs for "unexpected argument" errors, then verify args array has package name first.
## Pattern: Context Deadline Exceeded
**Error**: `MCP initialize failed: transport error: context deadline exceeded`
**Common Causes**:
1. Missing package name (uvx/npx) - check stderr for "unexpected argument"
2. Docker TTY issue - check stderr for "not a TTY"
3. Server crashed on startup - check stderr for stack traces
4. Environment variables missing - check stderr for "missing" or "required"
**Diagnostic Workflow**:
```bash
# 1. Check stderr for actual error
grep "stderr" ~/Library/Logs/mcpproxy/server-{SERVER_NAME}.log | tail -20
# 2. Check if server started at all
grep "Starting connection" ~/Library/Logs/mcpproxy/server-{SERVER_NAME}.log | tail -5
# 3. Check Docker container if isolation enabled
docker ps | grep mcpproxy
docker logs CONTAINER_ID
```