#!/usr/bin/env python3
"""Diagnose Claude Desktop MCP server connection issues."""
import json
import os
import sys
import subprocess
import time
from pathlib import Path
def get_claude_desktop_config_path():
"""Get the Claude Desktop configuration file path for the current OS."""
if sys.platform == "darwin": # macOS
return Path.home() / "Library/Application Support/Claude/claude_desktop_config.json"
elif sys.platform == "win32": # Windows
return Path.home() / "AppData/Roaming/Claude/claude_desktop_config.json"
else: # Linux
return Path.home() / ".config/Claude/claude_desktop_config.json"
def test_server_standalone():
"""Test if the MCP server can run standalone."""
print("š Testing MCP Server Standalone...")
try:
# Set up environment
current_dir = "/Users/alex/claude/11-mcp"
env = os.environ.copy()
env["ELEVENLABS_API_KEY"] = "sk_ed46dad18de349f00aa80a7d4605e66a7556818f724da8c2"
env["PYTHONPATH"] = "/Users/alex/claude/11-mcp/src"
env["LOG_LEVEL"] = "DEBUG"
# Try to run the server with a timeout
print(f"Running: python -m elevenlabs_mcp.server")
print(f"Working directory: {current_dir}")
print(f"PYTHONPATH: {env['PYTHONPATH']}")
process = subprocess.Popen(
["python", "-m", "elevenlabs_mcp.server"],
cwd=current_dir,
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# Wait a bit for startup
time.sleep(5)
# Check if process is still running
if process.poll() is None:
print("ā
Server started successfully and is running")
# Send a test message
test_message = '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}}\n'
try:
stdout, stderr = process.communicate(input=test_message, timeout=5)
print(f"ā
Server responded to test message")
if stdout:
print(f"š¤ Server output: {stdout[:200]}...")
if stderr:
print(f"ā ļø Server errors: {stderr[:200]}...")
except subprocess.TimeoutExpired:
print("ā
Server is running (timeout on communication is expected)")
# Terminate the process
process.terminate()
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
process.kill()
process.wait()
return True
else:
# Process exited, get output
stdout, stderr = process.communicate()
print(f"ā Server exited with code: {process.returncode}")
if stdout:
print(f"š¤ Server output: {stdout}")
if stderr:
print(f"ā Server errors: {stderr}")
return False
except Exception as e:
print(f"ā Error testing server: {e}")
return False
def check_claude_desktop_logs():
"""Check Claude Desktop logs for errors."""
print("\nš Checking Claude Desktop Logs...")
# Common log locations
log_locations = [
Path.home() / "Library/Logs/Claude",
Path.home() / "Library/Application Support/Claude/logs",
Path.home() / ".claude/logs"
]
for log_dir in log_locations:
if log_dir.exists():
print(f"ā
Found log directory: {log_dir}")
# Look for recent log files
try:
log_files = list(log_dir.glob("*.log"))
if log_files:
# Get the most recent log file
latest_log = max(log_files, key=lambda f: f.stat().st_mtime)
print(f"š Latest log file: {latest_log}")
# Read last few lines
try:
with open(latest_log, 'r') as f:
lines = f.readlines()
last_lines = lines[-20:] if len(lines) > 20 else lines
print("š Last 20 lines of log:")
for line in last_lines:
print(f" {line.strip()}")
except Exception as e:
print(f"ā Error reading log file: {e}")
else:
print("ā ļø No log files found")
except Exception as e:
print(f"ā Error checking log directory: {e}")
else:
print(f"ā ļø Log directory not found: {log_dir}")
def check_python_path_resolution():
"""Check if Python can resolve the module correctly."""
print("\nš Testing Python Path Resolution...")
try:
# Test exactly what Claude Desktop will run
env = os.environ.copy()
env["PYTHONPATH"] = "/Users/alex/claude/11-mcp/src"
# Test import
result = subprocess.run([
"python", "-c",
"import sys; sys.path.insert(0, '/Users/alex/claude/11-mcp/src'); import elevenlabs_mcp.server; print('ā
Import successful')"
], capture_output=True, text=True, env=env, cwd="/Users/alex/claude/11-mcp")
if result.returncode == 0:
print("ā
Python can import the module")
print(f"š¤ Output: {result.stdout}")
else:
print("ā Python cannot import the module")
print(f"ā Error: {result.stderr}")
# Test module execution
result = subprocess.run([
"python", "-c",
"import sys; sys.path.insert(0, '/Users/alex/claude/11-mcp/src'); from elevenlabs_mcp.server import main; print('ā
Main function found')"
], capture_output=True, text=True, env=env, cwd="/Users/alex/claude/11-mcp")
if result.returncode == 0:
print("ā
Main function accessible")
else:
print("ā Main function not accessible")
print(f"ā Error: {result.stderr}")
except Exception as e:
print(f"ā Error testing Python path: {e}")
def suggest_fixes():
"""Suggest potential fixes for common issues."""
print("\nš§ Suggested Fixes:")
print("=" * 50)
print("1. **Use absolute Python path**:")
print(" Change 'python' to full path in config:")
print(" '/Users/alex/claude/11-mcp/venv/bin/python'")
print("\n2. **Simplify the configuration**:")
print(" Try removing PYTHONPATH and using -m differently")
print("\n3. **Check Claude Desktop version**:")
print(" Ensure you have the latest version of Claude Desktop")
print("\n4. **Use a wrapper script**:")
print(" Create a simple bash script to run the server")
print("\n5. **Check process permissions**:")
print(" Ensure Claude Desktop can execute Python scripts")
def create_fixed_config():
"""Create a fixed configuration file."""
print("\nš§ Creating Fixed Configuration...")
# Get the venv python path
venv_python = "/Users/alex/claude/11-mcp/venv/bin/python"
config = {
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/alex/Documents"
]
},
"elevenlabs": {
"command": venv_python,
"args": ["-m", "elevenlabs_mcp.server"],
"cwd": "/Users/alex/claude/11-mcp",
"env": {
"ELEVENLABS_API_KEY": "sk_ed46dad18de349f00aa80a7d4605e66a7556818f724da8c2",
"PYTHONPATH": "/Users/alex/claude/11-mcp/src",
"LOG_LEVEL": "DEBUG"
}
}
}
}
# Write the fixed config
config_path = get_claude_desktop_config_path()
try:
with open(config_path, 'w') as f:
json.dump(config, f, indent=2)
print(f"ā
Fixed configuration written to: {config_path}")
print(f"š Using Python path: {venv_python}")
print(f"š Set LOG_LEVEL to DEBUG for better diagnostics")
return True
except Exception as e:
print(f"ā Error writing fixed config: {e}")
return False
def main():
"""Main diagnostic function."""
print("š Claude Desktop MCP Server Diagnostics")
print("=" * 60)
# Test server standalone
server_works = test_server_standalone()
# Check Claude Desktop logs
check_claude_desktop_logs()
# Check Python path resolution
check_python_path_resolution()
# Suggest fixes
suggest_fixes()
# Create fixed config
create_fixed_config()
print("\n" + "=" * 60)
if server_works:
print("ā
MCP Server works standalone!")
print("š Try restarting Claude Desktop with the fixed configuration")
print("š Check Claude Desktop logs for any remaining issues")
else:
print("ā MCP Server has issues running standalone")
print("š§ Fix the server issues before testing with Claude Desktop")
print("\nš Additional steps:")
print("1. Completely quit and restart Claude Desktop")
print("2. Wait 30 seconds for MCP server to initialize")
print("3. Look for MCP connection indicator")
print("4. Check logs if still not working")
if __name__ == "__main__":
main()