From 65c31a739303bce305122baa42e4935315c02abf Mon Sep 17 00:00:00 2001 From: George Antonopoulos Date: Sun, 27 Jul 2025 19:33:01 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Add=20dual-run=20configuration?= =?UTF-8?q?=20support=20for=20FastMCP=20migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update generate_cursor_config.py to support both FastMCP and legacy servers - Add --legacy flag to switch to old mcp_server_cli.py during transition - Default to new FastMCP server (basecamp_fastmcp.py) - RECOMMENDED - Auto-cleanup old server configs when switching - Provide clear migration instructions and fallback options Usage: python generate_cursor_config.py # Use FastMCP (default) python generate_cursor_config.py --legacy # Use legacy server Following migration plan P-5: Safe dual-run deployment with easy rollback --- generate_cursor_config.py | 63 +++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/generate_cursor_config.py b/generate_cursor_config.py index 69f2a62..7378f6b 100644 --- a/generate_cursor_config.py +++ b/generate_cursor_config.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 """ Generate the correct Cursor MCP configuration for this Basecamp MCP server. +Supports both the new FastMCP server (default) and legacy server during migration. """ import json import os import sys +import argparse from pathlib import Path from dotenv import load_dotenv @@ -24,12 +26,25 @@ def get_python_path(): # Fallback to system Python return sys.executable -def generate_config(): - """Generate the MCP configuration for Cursor.""" +def generate_config(use_legacy=False): + """Generate the MCP configuration for Cursor. + + Args: + use_legacy: If True, use the legacy mcp_server_cli.py. If False, use new FastMCP server. + """ 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") + + if use_legacy: + # Use legacy server + script_path = os.path.join(project_root, "mcp_server_cli.py") + server_name = "basecamp-legacy" + print("๐Ÿ”„ Using LEGACY server (mcp_server_cli.py)") + else: + # Use new FastMCP server (default) + script_path = os.path.join(project_root, "basecamp_fastmcp.py") + server_name = "basecamp" + print("โœจ Using NEW FastMCP server (basecamp_fastmcp.py) - RECOMMENDED") # Load .env file from project root to get BASECAMP_ACCOUNT_ID dotenv_path = os.path.join(project_root, ".env") @@ -48,7 +63,7 @@ def generate_config(): config = { "mcpServers": { - "basecamp": { + server_name: { "command": python_path, "args": [script_path], "cwd": project_root, @@ -57,7 +72,7 @@ def generate_config(): } } - return config + return config, server_name def get_cursor_config_path(): """Get the path to the Cursor MCP configuration file.""" @@ -72,7 +87,12 @@ def get_cursor_config_path(): def main(): """Main function.""" - config = generate_config() + parser = argparse.ArgumentParser(description="Generate Cursor MCP configuration for Basecamp") + parser.add_argument("--legacy", action="store_true", + help="Use legacy mcp_server_cli.py instead of new FastMCP server") + args = parser.parse_args() + + config, server_name = generate_config(use_legacy=args.legacy) config_path = get_cursor_config_path() print("๐Ÿ”ง Generated Cursor MCP Configuration:") @@ -97,7 +117,15 @@ def main(): if "mcpServers" not in existing_config: existing_config["mcpServers"] = {} - existing_config["mcpServers"]["basecamp"] = config["mcpServers"]["basecamp"] + existing_config["mcpServers"][server_name] = config["mcpServers"][server_name] + + # Clean up old server entries if switching + if not args.legacy and "basecamp-legacy" in existing_config["mcpServers"]: + print("๐Ÿงน Removing legacy server configuration...") + del existing_config["mcpServers"]["basecamp-legacy"] + elif args.legacy and "basecamp" in existing_config["mcpServers"]: + print("๐Ÿงน Removing new FastMCP server configuration...") + del existing_config["mcpServers"]["basecamp"] # Write back the updated config config_path.parent.mkdir(parents=True, exist_ok=True) @@ -128,10 +156,21 @@ def main(): 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 args.legacy: + print("๐Ÿ“‹ Next steps (Legacy Server):") + 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-legacy'") + print() + print("๐Ÿ’ก TIP: Try the new FastMCP server by running without --legacy flag!") + else: + print("๐Ÿ“‹ Next steps (FastMCP Server):") + 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'") + print() + print("๐Ÿš€ You're using the new FastMCP server - enjoy the improved performance!") + print("๐Ÿ”„ If you encounter issues, you can switch back with: python generate_cursor_config.py --legacy") if __name__ == "__main__": main()