137 lines
4.8 KiB
Python
137 lines
4.8 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
Generate Claude Desktop configuration for Basecamp MCP Integration.
|
||
|
|
Based on official MCP quickstart guide: https://modelcontextprotocol.io/quickstart/server
|
||
|
|
"""
|
||
|
|
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
import json
|
||
|
|
import platform
|
||
|
|
from pathlib import Path
|
||
|
|
from dotenv import load_dotenv
|
||
|
|
|
||
|
|
def get_project_root():
|
||
|
|
"""Get the absolute path to the project root."""
|
||
|
|
return os.path.abspath(os.path.dirname(__file__))
|
||
|
|
|
||
|
|
def get_python_path():
|
||
|
|
"""Get the Python executable path from virtual environment."""
|
||
|
|
project_root = get_project_root()
|
||
|
|
|
||
|
|
if platform.system() == "Windows":
|
||
|
|
python_path = os.path.join(project_root, "venv", "Scripts", "python.exe")
|
||
|
|
else:
|
||
|
|
python_path = os.path.join(project_root, "venv", "bin", "python")
|
||
|
|
|
||
|
|
# Convert to absolute path
|
||
|
|
return os.path.abspath(python_path)
|
||
|
|
|
||
|
|
def get_claude_desktop_config_path():
|
||
|
|
"""Get the Claude Desktop configuration file path."""
|
||
|
|
if platform.system() == "Windows":
|
||
|
|
return os.path.expanduser("~/AppData/Roaming/Claude/claude_desktop_config.json")
|
||
|
|
elif platform.system() == "Darwin": # macOS
|
||
|
|
return os.path.expanduser("~/Library/Application Support/Claude/claude_desktop_config.json")
|
||
|
|
else: # Linux
|
||
|
|
return os.path.expanduser("~/.config/claude-desktop/claude_desktop_config.json")
|
||
|
|
|
||
|
|
def generate_config():
|
||
|
|
"""Generate the Claude Desktop configuration for Basecamp MCP server."""
|
||
|
|
project_root = get_project_root()
|
||
|
|
python_path = get_python_path()
|
||
|
|
script_path = os.path.join(project_root, "basecamp_fastmcp.py")
|
||
|
|
|
||
|
|
# Load .env file to get BASECAMP_ACCOUNT_ID
|
||
|
|
dotenv_path = os.path.join(project_root, ".env")
|
||
|
|
load_dotenv(dotenv_path)
|
||
|
|
basecamp_account_id = os.getenv("BASECAMP_ACCOUNT_ID")
|
||
|
|
|
||
|
|
if not basecamp_account_id:
|
||
|
|
print("⚠️ Warning: BASECAMP_ACCOUNT_ID not found in .env file")
|
||
|
|
print(" Add BASECAMP_ACCOUNT_ID to your .env file for proper configuration")
|
||
|
|
basecamp_account_id = "YOUR_ACCOUNT_ID_HERE"
|
||
|
|
|
||
|
|
# Verify Python executable exists
|
||
|
|
if not os.path.exists(python_path):
|
||
|
|
print(f"❌ Python executable not found at {python_path}")
|
||
|
|
print(" Run 'python setup.py' first to create the virtual environment")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Verify FastMCP server exists
|
||
|
|
if not os.path.exists(script_path):
|
||
|
|
print(f"❌ FastMCP server not found at {script_path}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Create configuration
|
||
|
|
config = {
|
||
|
|
"mcpServers": {
|
||
|
|
"basecamp": {
|
||
|
|
"command": python_path,
|
||
|
|
"args": [script_path],
|
||
|
|
"env": {
|
||
|
|
"PYTHONPATH": project_root,
|
||
|
|
"VIRTUAL_ENV": os.path.join(project_root, "venv"),
|
||
|
|
"BASECAMP_ACCOUNT_ID": basecamp_account_id
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
config_path = get_claude_desktop_config_path()
|
||
|
|
config_dir = os.path.dirname(config_path)
|
||
|
|
|
||
|
|
# Create config directory if it doesn't exist
|
||
|
|
os.makedirs(config_dir, exist_ok=True)
|
||
|
|
|
||
|
|
# Load existing config if it exists
|
||
|
|
existing_config = {}
|
||
|
|
if os.path.exists(config_path):
|
||
|
|
try:
|
||
|
|
with open(config_path, 'r') as f:
|
||
|
|
existing_config = json.load(f)
|
||
|
|
except json.JSONDecodeError:
|
||
|
|
print(f"⚠️ Warning: Existing config at {config_path} has invalid JSON")
|
||
|
|
existing_config = {}
|
||
|
|
|
||
|
|
# Merge with existing mcpServers
|
||
|
|
if "mcpServers" not in existing_config:
|
||
|
|
existing_config["mcpServers"] = {}
|
||
|
|
|
||
|
|
# Add or update Basecamp server
|
||
|
|
existing_config["mcpServers"]["basecamp"] = config["mcpServers"]["basecamp"]
|
||
|
|
|
||
|
|
# Write configuration
|
||
|
|
try:
|
||
|
|
with open(config_path, 'w') as f:
|
||
|
|
json.dump(existing_config, f, indent=2)
|
||
|
|
|
||
|
|
print("✅ Claude Desktop configuration updated successfully!")
|
||
|
|
print(f"📍 Config file: {config_path}")
|
||
|
|
print("\n📋 Configuration details:")
|
||
|
|
print(f" • Server name: basecamp")
|
||
|
|
print(f" • Python path: {python_path}")
|
||
|
|
print(f" • Server script: {script_path}")
|
||
|
|
print(f" • Account ID: {basecamp_account_id}")
|
||
|
|
print("\n🔄 Next steps:")
|
||
|
|
print(" 1. Restart Claude Desktop completely")
|
||
|
|
print(" 2. Look for the MCP tools icon in Claude Desktop")
|
||
|
|
print(" 3. Enable Basecamp tools in your conversation")
|
||
|
|
print("\n💡 Tip: Check ~/Library/Logs/Claude/mcp*.log for troubleshooting")
|
||
|
|
|
||
|
|
return True
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print(f"❌ Error writing configuration: {str(e)}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
def main():
|
||
|
|
"""Main function."""
|
||
|
|
print("🚀 Generating Claude Desktop Configuration for Basecamp MCP")
|
||
|
|
print("=" * 60)
|
||
|
|
|
||
|
|
if not generate_config():
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|