|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | 3 | import ast |
| 4 | +import json |
4 | 5 | import os |
5 | 6 | import re |
6 | 7 | import subprocess |
@@ -130,6 +131,9 @@ def init_codeflash() -> None: |
130 | 131 | ) |
131 | 132 | console.print(completion_panel) |
132 | 133 |
|
| 134 | + # Ask about adding MCP server to Claude configuration |
| 135 | + prompt_claude_mcp_setup() |
| 136 | + |
133 | 137 | ph("cli-installation-successful", {"did_add_new_key": did_add_new_key}) |
134 | 138 | sys.exit(0) |
135 | 139 | except KeyboardInterrupt: |
@@ -1215,3 +1219,113 @@ def ask_for_telemetry() -> bool: |
1215 | 1219 | default=True, |
1216 | 1220 | show_default=True, |
1217 | 1221 | ) |
| 1222 | + |
| 1223 | + |
| 1224 | +def prompt_claude_mcp_setup() -> None: |
| 1225 | + """Prompt user to add Codeflash MCP server to their Claude configuration.""" |
| 1226 | + from rich.prompt import Confirm |
| 1227 | + |
| 1228 | + mcp_panel = Panel( |
| 1229 | + Text( |
| 1230 | + "🤖 Claude Code Integration\n\n" |
| 1231 | + "Would you like to add the Codeflash MCP server to your Claude Code configuration?\n" |
| 1232 | + "This will allow Claude Code to use Codeflash's optimization tools directly.", |
| 1233 | + style="bright_blue", |
| 1234 | + ), |
| 1235 | + title="🚀 Claude Code MCP Setup", |
| 1236 | + border_style="bright_blue", |
| 1237 | + ) |
| 1238 | + console.print(mcp_panel) |
| 1239 | + console.print() |
| 1240 | + |
| 1241 | + setup_mcp = Confirm.ask("Add Codeflash MCP server to Claude Code configuration?", default=True, show_default=True) |
| 1242 | + |
| 1243 | + if setup_mcp: |
| 1244 | + try: |
| 1245 | + add_mcp_server_to_claude_config() |
| 1246 | + except Exception as e: |
| 1247 | + logger.error(f"Failed to add MCP server to Claude configuration: {e}") |
| 1248 | + console.print( |
| 1249 | + Panel( |
| 1250 | + Text( |
| 1251 | + "❌ Failed to add MCP server to Claude configuration.\n\n" |
| 1252 | + "You can manually add it later by updating your Claude Code settings.", |
| 1253 | + style="red", |
| 1254 | + ), |
| 1255 | + title="⚠️ Setup Failed", |
| 1256 | + border_style="red", |
| 1257 | + ) |
| 1258 | + ) |
| 1259 | + else: |
| 1260 | + skip_panel = Panel( |
| 1261 | + Text("⏩️ Skipping Claude Code MCP setup.", style="yellow"), title="⏩️ Skipped", border_style="yellow" |
| 1262 | + ) |
| 1263 | + console.print(skip_panel) |
| 1264 | + |
| 1265 | + |
| 1266 | +def add_mcp_server_to_claude_config() -> None: |
| 1267 | + """Add the Codeflash MCP server to Claude Code configuration.""" |
| 1268 | + # Try to find Claude Code config directory |
| 1269 | + home_dir = Path.home() |
| 1270 | + claude_config_dirs = [ |
| 1271 | + home_dir / ".config" / "claude-code", |
| 1272 | + home_dir / ".claude-code", |
| 1273 | + home_dir / "Library" / "Application Support" / "claude-code", # macOS |
| 1274 | + ] |
| 1275 | + |
| 1276 | + claude_config_dir = None |
| 1277 | + for config_dir in claude_config_dirs: |
| 1278 | + if config_dir.exists(): |
| 1279 | + claude_config_dir = config_dir |
| 1280 | + break |
| 1281 | + |
| 1282 | + # If no existing config directory found, create one |
| 1283 | + if not claude_config_dir: |
| 1284 | + claude_config_dir = home_dir / ".config" / "claude-code" |
| 1285 | + claude_config_dir.mkdir(parents=True, exist_ok=True) |
| 1286 | + console.print(f"📁 Created Claude Code config directory: {claude_config_dir}") |
| 1287 | + |
| 1288 | + config_file = claude_config_dir / "mcp_servers.json" |
| 1289 | + |
| 1290 | + # Get the absolute path to myserver.py |
| 1291 | + myserver_path = Path.cwd() / "myserver.py" |
| 1292 | + |
| 1293 | + # Create MCP server configuration |
| 1294 | + server_config = {"codeflash": {"command": "python", "args": [str(myserver_path.absolute())], "env": {}}} |
| 1295 | + |
| 1296 | + # Read existing config or create new one |
| 1297 | + if config_file.exists(): |
| 1298 | + try: |
| 1299 | + with config_file.open("r", encoding="utf8") as f: |
| 1300 | + existing_config = json.load(f) |
| 1301 | + existing_config.update(server_config) |
| 1302 | + updated_config = existing_config |
| 1303 | + except (json.JSONDecodeError, OSError) as e: |
| 1304 | + logger.warning(f"Could not read existing MCP config: {e}") |
| 1305 | + updated_config = server_config |
| 1306 | + else: |
| 1307 | + updated_config = server_config |
| 1308 | + |
| 1309 | + # Write the updated configuration |
| 1310 | + try: |
| 1311 | + with config_file.open("w", encoding="utf8") as f: |
| 1312 | + json.dump(updated_config, f, indent=2) |
| 1313 | + |
| 1314 | + success_panel = Panel( |
| 1315 | + Text( |
| 1316 | + f"✅ Successfully added Codeflash MCP server to Claude Code configuration!\n\n" |
| 1317 | + f"Configuration saved to: {config_file}\n\n" |
| 1318 | + f"You can now use Codeflash optimization tools directly in Claude Code.", |
| 1319 | + style="green", |
| 1320 | + justify="left", |
| 1321 | + ), |
| 1322 | + title="🎉 MCP Setup Complete!", |
| 1323 | + border_style="bright_green", |
| 1324 | + ) |
| 1325 | + console.print(success_panel) |
| 1326 | + |
| 1327 | + except OSError as e: |
| 1328 | + error_str = f"Failed to write Claude Code MCP configuration: {e}" |
| 1329 | + raise RuntimeError(error_str) from e |
| 1330 | + |
| 1331 | + console.print() |
0 commit comments