claude-mpm 4.4.12__py3-none-any.whl → 4.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -48,26 +48,26 @@ class MCPConfigManager:
48
48
  "kuzu-memory": {
49
49
  "type": "stdio",
50
50
  "command": "kuzu-memory", # Will be resolved to full path
51
- "args": ["mcp", "serve"] # v1.1.0+ uses 'mcp serve' command
51
+ "args": ["mcp", "serve"], # v1.1.0+ uses 'mcp serve' command
52
52
  },
53
53
  "mcp-ticketer": {
54
54
  "type": "stdio",
55
55
  "command": "mcp-ticketer", # Will be resolved to full path
56
- "args": ["mcp"]
56
+ "args": ["mcp"],
57
57
  },
58
58
  "mcp-browser": {
59
59
  "type": "stdio",
60
60
  "command": "mcp-browser", # Will be resolved to full path
61
61
  "args": ["mcp"],
62
- "env": {"MCP_BROWSER_HOME": str(Path.home() / ".mcp-browser")}
62
+ "env": {"MCP_BROWSER_HOME": str(Path.home() / ".mcp-browser")},
63
63
  },
64
64
  "mcp-vector-search": {
65
65
  "type": "stdio",
66
66
  # Special handling: needs Python interpreter from pipx venv
67
67
  "command": "python", # Will be resolved to pipx venv Python
68
68
  "args": ["-m", "mcp_vector_search.mcp.server", "{project_root}"],
69
- "env": {}
70
- }
69
+ "env": {},
70
+ },
71
71
  }
72
72
 
73
73
  def __init__(self):
@@ -265,7 +265,11 @@ class MCPConfigManager:
265
265
  test_args = config["args"].copy()
266
266
  # Replace project root placeholder for testing
267
267
  test_args = [
268
- arg.replace("{project_root}", str(self.project_root)) if "{project_root}" in arg else arg
268
+ (
269
+ arg.replace("{project_root}", str(self.project_root))
270
+ if "{project_root}" in arg
271
+ else arg
272
+ )
269
273
  for arg in test_args
270
274
  ]
271
275
 
@@ -287,13 +291,16 @@ class MCPConfigManager:
287
291
  text=True,
288
292
  timeout=5,
289
293
  check=False,
290
- env=config.get("env", {})
294
+ env=config.get("env", {}),
291
295
  )
292
296
 
293
297
  # Check if command executed (exit code 0 or 1 for help)
294
298
  if result.returncode in [0, 1]:
295
299
  # Additional check for import errors in stderr
296
- if "ModuleNotFoundError" in result.stderr or "ImportError" in result.stderr:
300
+ if (
301
+ "ModuleNotFoundError" in result.stderr
302
+ or "ImportError" in result.stderr
303
+ ):
297
304
  self.logger.debug(f"Service {service_name} has import errors")
298
305
  return False
299
306
  return True
@@ -306,7 +313,9 @@ class MCPConfigManager:
306
313
 
307
314
  return False
308
315
 
309
- def get_static_service_config(self, service_name: str, project_path: Optional[str] = None) -> Optional[Dict]:
316
+ def get_static_service_config(
317
+ self, service_name: str, project_path: Optional[str] = None
318
+ ) -> Optional[Dict]:
310
319
  """
311
320
  Get the static, known-good configuration for an MCP service.
312
321
 
@@ -329,7 +338,15 @@ class MCPConfigManager:
329
338
  binary_name = config["command"]
330
339
 
331
340
  # First check pipx location
332
- pipx_bin = Path.home() / ".local" / "pipx" / "venvs" / service_name / "bin" / binary_name
341
+ pipx_bin = (
342
+ Path.home()
343
+ / ".local"
344
+ / "pipx"
345
+ / "venvs"
346
+ / service_name
347
+ / "bin"
348
+ / binary_name
349
+ )
333
350
  if pipx_bin.exists():
334
351
  binary_path = str(pipx_bin)
335
352
  else:
@@ -352,7 +369,9 @@ class MCPConfigManager:
352
369
  config["command"] = binary_path
353
370
  else:
354
371
  # Fall back to pipx run method if binary not found
355
- self.logger.debug(f"Could not find {binary_name}, using pipx run fallback")
372
+ self.logger.debug(
373
+ f"Could not find {binary_name}, using pipx run fallback"
374
+ )
356
375
  config["command"] = "pipx"
357
376
  config["args"] = ["run", service_name] + config["args"]
358
377
 
@@ -377,7 +396,15 @@ class MCPConfigManager:
377
396
  if service_name == "mcp-vector-search":
378
397
  # Get the correct pipx venv path for the current user
379
398
  home = Path.home()
380
- python_path = home / ".local" / "pipx" / "venvs" / "mcp-vector-search" / "bin" / "python"
399
+ python_path = (
400
+ home
401
+ / ".local"
402
+ / "pipx"
403
+ / "venvs"
404
+ / "mcp-vector-search"
405
+ / "bin"
406
+ / "python"
407
+ )
381
408
 
382
409
  # Check if the Python interpreter exists
383
410
  if python_path.exists():
@@ -403,12 +430,24 @@ class MCPConfigManager:
403
430
  config["command"] = "pipx" # Hope it's in PATH
404
431
 
405
432
  # Use pipx run with the spec argument
406
- config["args"] = ["run", "--spec", "mcp-vector-search", "python", "-m", "mcp_vector_search.mcp.server", "{project_root}"]
433
+ config["args"] = [
434
+ "run",
435
+ "--spec",
436
+ "mcp-vector-search",
437
+ "python",
438
+ "-m",
439
+ "mcp_vector_search.mcp.server",
440
+ "{project_root}",
441
+ ]
407
442
 
408
443
  # Use provided project path or current project
409
444
  project_root = project_path if project_path else str(self.project_root)
410
445
  config["args"] = [
411
- arg.replace("{project_root}", project_root) if "{project_root}" in arg else arg
446
+ (
447
+ arg.replace("{project_root}", project_root)
448
+ if "{project_root}" in arg
449
+ else arg
450
+ )
412
451
  for arg in config["args"]
413
452
  ]
414
453
 
@@ -432,10 +471,13 @@ class MCPConfigManager:
432
471
  if static_config:
433
472
  # Validate that the static config actually works
434
473
  if self.test_service_command(service_name, static_config):
435
- self.logger.debug(f"Static config for {service_name} validated successfully")
474
+ self.logger.debug(
475
+ f"Static config for {service_name} validated successfully"
476
+ )
436
477
  return static_config
437
- else:
438
- self.logger.warning(f"Static config for {service_name} failed validation, trying fallback")
478
+ self.logger.warning(
479
+ f"Static config for {service_name} failed validation, trying fallback"
480
+ )
439
481
 
440
482
  # Fall back to detection-based configuration for unknown services
441
483
  import shutil
@@ -563,7 +605,9 @@ class MCPConfigManager:
563
605
 
564
606
  # Standard version detection - look for "mcp serve" command (v1.1.0+)
565
607
  # This is the correct format for kuzu-memory v1.1.0 and later
566
- if "mcp serve" in help_output or ("mcp" in help_output and "serve" in help_output):
608
+ if "mcp serve" in help_output or (
609
+ "mcp" in help_output and "serve" in help_output
610
+ ):
567
611
  # Standard v1.1.0+ version with mcp serve command
568
612
  kuzu_args = ["mcp", "serve"]
569
613
  # Legacy version detection - only "serve" without "mcp"
@@ -672,10 +716,14 @@ class MCPConfigManager:
672
716
  # Check and fix each service configuration
673
717
  for service_name in self.PIPX_SERVICES:
674
718
  # Get the correct static configuration with project-specific paths
675
- correct_config = self.get_static_service_config(service_name, project_key)
719
+ correct_config = self.get_static_service_config(
720
+ service_name, project_key
721
+ )
676
722
 
677
723
  if not correct_config:
678
- self.logger.warning(f"No static config available for {service_name}")
724
+ self.logger.warning(
725
+ f"No static config available for {service_name}"
726
+ )
679
727
  continue
680
728
 
681
729
  # Check if service exists and has correct configuration
@@ -687,13 +735,15 @@ class MCPConfigManager:
687
735
  # Service is missing
688
736
  needs_update = True
689
737
  added_services.append(f"{service_name} in {Path(project_key).name}")
690
- else:
691
- # Service exists, check if configuration is correct
692
- # Compare command and args (the most critical parts)
693
- if (existing_config.get("command") != correct_config.get("command") or
694
- existing_config.get("args") != correct_config.get("args")):
695
- needs_update = True
696
- fixed_services.append(f"{service_name} in {Path(project_key).name}")
738
+ # Service exists, check if configuration is correct
739
+ # Compare command and args (the most critical parts)
740
+ elif existing_config.get("command") != correct_config.get(
741
+ "command"
742
+ ) or existing_config.get("args") != correct_config.get("args"):
743
+ needs_update = True
744
+ fixed_services.append(
745
+ f"{service_name} in {Path(project_key).name}"
746
+ )
697
747
 
698
748
  # Update configuration if needed
699
749
  if needs_update:
@@ -714,6 +764,7 @@ class MCPConfigManager:
714
764
  f".backup.{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}.json"
715
765
  )
716
766
  import shutil
767
+
717
768
  shutil.copy2(self.claude_config_path, backup_path)
718
769
  self.logger.debug(f"Created backup: {backup_path}")
719
770
 
@@ -723,9 +774,13 @@ class MCPConfigManager:
723
774
 
724
775
  messages = []
725
776
  if added_services:
726
- messages.append(f"Added MCP services: {', '.join(added_services[:3])}")
777
+ messages.append(
778
+ f"Added MCP services: {', '.join(added_services[:3])}"
779
+ )
727
780
  if fixed_services:
728
- messages.append(f"Fixed MCP services: {', '.join(fixed_services[:3])}")
781
+ messages.append(
782
+ f"Fixed MCP services: {', '.join(fixed_services[:3])}"
783
+ )
729
784
 
730
785
  if messages:
731
786
  return True, "; ".join(messages)
@@ -993,11 +1048,12 @@ class MCPConfigManager:
993
1048
  )
994
1049
 
995
1050
  if inject_result.returncode == 0:
996
- self.logger.info("✅ Successfully injected gql dependency into mcp-ticketer")
1051
+ self.logger.info(
1052
+ "✅ Successfully injected gql dependency into mcp-ticketer"
1053
+ )
997
1054
  return True
998
- else:
999
- self.logger.warning(f"Failed to inject gql: {inject_result.stderr}")
1000
- return False
1055
+ self.logger.warning(f"Failed to inject gql: {inject_result.stderr}")
1056
+ return False
1001
1057
 
1002
1058
  return False
1003
1059
 
@@ -1048,7 +1104,9 @@ class MCPConfigManager:
1048
1104
 
1049
1105
  elif issue_type == "import_error":
1050
1106
  # Reinstall to fix corrupted installation
1051
- self.logger.info(f" Reinstalling {service_name} to fix import errors...")
1107
+ self.logger.info(
1108
+ f" Reinstalling {service_name} to fix import errors..."
1109
+ )
1052
1110
  success = self._reinstall_service(service_name)
1053
1111
  if success:
1054
1112
  # Special handling for mcp-ticketer - inject missing gql dependency
@@ -1064,13 +1122,17 @@ class MCPConfigManager:
1064
1122
  if self._check_and_fix_mcp_ticketer_dependencies():
1065
1123
  fixed_services.append(f"{service_name} (dependency fixed)")
1066
1124
  else:
1067
- failed_services.append(f"{service_name} (dependency fix failed)")
1125
+ failed_services.append(
1126
+ f"{service_name} (dependency fix failed)"
1127
+ )
1068
1128
  else:
1069
1129
  failed_services.append(f"{service_name} (unknown dependency issue)")
1070
1130
 
1071
1131
  elif issue_type == "path_issue":
1072
1132
  # Path issues are handled by config updates
1073
- self.logger.info(f" Path issue for {service_name} will be fixed by config update")
1133
+ self.logger.info(
1134
+ f" Path issue for {service_name} will be fixed by config update"
1135
+ )
1074
1136
  fixed_services.append(f"{service_name} (config updated)")
1075
1137
 
1076
1138
  # Build result message
@@ -1114,7 +1176,7 @@ class MCPConfigManager:
1114
1176
  capture_output=True,
1115
1177
  text=True,
1116
1178
  timeout=10,
1117
- check=False
1179
+ check=False,
1118
1180
  )
1119
1181
 
1120
1182
  # Check for specific error patterns
@@ -1123,11 +1185,17 @@ class MCPConfigManager:
1123
1185
  combined_output = stderr_lower + stdout_lower
1124
1186
 
1125
1187
  # Not installed
1126
- if "no apps associated" in combined_output or "not found" in combined_output:
1188
+ if (
1189
+ "no apps associated" in combined_output
1190
+ or "not found" in combined_output
1191
+ ):
1127
1192
  return "not_installed"
1128
1193
 
1129
1194
  # Import errors (like mcp-ticketer's corrupted state)
1130
- if "modulenotfounderror" in combined_output or "importerror" in combined_output:
1195
+ if (
1196
+ "modulenotfounderror" in combined_output
1197
+ or "importerror" in combined_output
1198
+ ):
1131
1199
  # Check if it's specifically the gql dependency for mcp-ticketer
1132
1200
  if service_name == "mcp-ticketer" and "gql" in combined_output:
1133
1201
  return "missing_dependency"
@@ -1138,7 +1206,11 @@ class MCPConfigManager:
1138
1206
  return "path_issue"
1139
1207
 
1140
1208
  # If help text appears, service is working
1141
- if "usage:" in combined_output or "help" in combined_output or result.returncode in [0, 1]:
1209
+ if (
1210
+ "usage:" in combined_output
1211
+ or "help" in combined_output
1212
+ or result.returncode in [0, 1]
1213
+ ):
1142
1214
  return None # Service is working
1143
1215
 
1144
1216
  # Unknown issue
@@ -1173,7 +1245,7 @@ class MCPConfigManager:
1173
1245
  capture_output=True,
1174
1246
  text=True,
1175
1247
  timeout=30,
1176
- check=False
1248
+ check=False,
1177
1249
  )
1178
1250
 
1179
1251
  # Don't check return code - uninstall might fail if partially corrupted
@@ -1186,7 +1258,7 @@ class MCPConfigManager:
1186
1258
  capture_output=True,
1187
1259
  text=True,
1188
1260
  timeout=120,
1189
- check=False
1261
+ check=False,
1190
1262
  )
1191
1263
 
1192
1264
  if install_result.returncode == 0:
@@ -1195,12 +1267,14 @@ class MCPConfigManager:
1195
1267
  if issue is None:
1196
1268
  self.logger.info(f"✅ Successfully reinstalled {service_name}")
1197
1269
  return True
1198
- else:
1199
- self.logger.warning(f"Reinstalled {service_name} but still has issue: {issue}")
1200
- return False
1201
- else:
1202
- self.logger.error(f"Failed to reinstall {service_name}: {install_result.stderr}")
1270
+ self.logger.warning(
1271
+ f"Reinstalled {service_name} but still has issue: {issue}"
1272
+ )
1203
1273
  return False
1274
+ self.logger.error(
1275
+ f"Failed to reinstall {service_name}: {install_result.stderr}"
1276
+ )
1277
+ return False
1204
1278
 
1205
1279
  except Exception as e:
1206
1280
  self.logger.error(f"Error reinstalling {service_name}: {e}")
@@ -1282,7 +1356,9 @@ class MCPConfigManager:
1282
1356
 
1283
1357
  return False
1284
1358
 
1285
- def _get_fallback_config(self, service_name: str, project_path: str) -> Optional[Dict]:
1359
+ def _get_fallback_config(
1360
+ self, service_name: str, project_path: str
1361
+ ) -> Optional[Dict]:
1286
1362
  """
1287
1363
  Get a fallback configuration for a service if the primary config fails.
1288
1364
 
@@ -1298,8 +1374,16 @@ class MCPConfigManager:
1298
1374
  return {
1299
1375
  "type": "stdio",
1300
1376
  "command": "pipx",
1301
- "args": ["run", "--spec", "mcp-vector-search", "python", "-m", "mcp_vector_search.mcp.server", project_path],
1302
- "env": {}
1377
+ "args": [
1378
+ "run",
1379
+ "--spec",
1380
+ "mcp-vector-search",
1381
+ "python",
1382
+ "-m",
1383
+ "mcp_vector_search.mcp.server",
1384
+ project_path,
1385
+ ],
1386
+ "env": {},
1303
1387
  }
1304
1388
 
1305
1389
  # For other services, try pipx run