Files
basecamp-mcp-server/generate_cursor_config.py
2025-06-06 10:23:50 +01:00

138 lines
4.4 KiB
Python

#!/usr/bin/env python3
"""
Generate the correct Cursor MCP configuration for this Basecamp MCP server.
"""
import json
import os
import sys
from pathlib import Path
from dotenv import load_dotenv
def get_project_root():
"""Get the absolute path to the project root."""
return str(Path(__file__).parent.absolute())
def get_python_path():
"""Get the path to the Python executable in the virtual environment."""
project_root = get_project_root()
venv_python = os.path.join(project_root, "venv", "bin", "python")
if os.path.exists(venv_python):
return venv_python
# Fallback to system Python
return sys.executable
def generate_config():
"""Generate the MCP configuration for Cursor."""
project_root = get_project_root()
python_path = get_python_path()
# Use absolute path to the MCP CLI script to avoid double-slash issues
script_path = os.path.join(project_root, "mcp_server_cli.py")
# Load .env file from project root 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")
env_vars = {
"PYTHONPATH": project_root,
"VIRTUAL_ENV": os.path.join(project_root, "venv")
}
if basecamp_account_id:
env_vars["BASECAMP_ACCOUNT_ID"] = basecamp_account_id
else:
print("⚠️ WARNING: BASECAMP_ACCOUNT_ID not found in .env file. MCP server might not work correctly.")
print(f" Attempted to load .env from: {dotenv_path}")
config = {
"mcpServers": {
"basecamp": {
"command": python_path,
"args": [script_path],
"cwd": project_root,
"env": env_vars
}
}
}
return config
def get_cursor_config_path():
"""Get the path to the Cursor MCP configuration file."""
home = Path.home()
if sys.platform == "darwin": # macOS
return home / ".cursor" / "mcp.json"
elif sys.platform == "win32": # Windows
return Path(os.environ.get("APPDATA", home)) / "Cursor" / "mcp.json"
else: # Linux
return home / ".cursor" / "mcp.json"
def main():
"""Main function."""
config = generate_config()
config_path = get_cursor_config_path()
print("🔧 Generated Cursor MCP Configuration:")
print(json.dumps(config, indent=2))
print()
print(f"📁 Configuration should be saved to: {config_path}")
print()
# Check if the file exists and offer to update it
if config_path.exists():
print("⚠️ Configuration file already exists.")
response = input("Do you want to update it? (y/N): ").lower().strip()
if response in ['y', 'yes']:
# Read existing config
try:
with open(config_path, 'r') as f:
existing_config = json.load(f)
# Update the basecamp server configuration
if "mcpServers" not in existing_config:
existing_config["mcpServers"] = {}
existing_config["mcpServers"]["basecamp"] = config["mcpServers"]["basecamp"]
# Write back the updated config
config_path.parent.mkdir(parents=True, exist_ok=True)
with open(config_path, 'w') as f:
json.dump(existing_config, f, indent=2)
print("✅ Configuration updated successfully!")
except Exception as e:
print(f"❌ Error updating configuration: {e}")
else:
print("Configuration not updated.")
else:
response = input("Do you want to create the configuration file? (y/N): ").lower().strip()
if response in ['y', 'yes']:
try:
config_path.parent.mkdir(parents=True, exist_ok=True)
with open(config_path, 'w') as f:
json.dump(config, f, indent=2)
print("✅ Configuration file created successfully!")
except Exception as e:
print(f"❌ Error creating configuration file: {e}")
else:
print("Configuration file not created.")
print()
print("📋 Next steps:")
print("1. Make sure you've authenticated with Basecamp: python oauth_app.py")
print("2. Restart Cursor completely (quit and reopen)")
print("3. Check Cursor Settings → MCP for a green checkmark next to 'basecamp'")
if __name__ == "__main__":
main()