update_claudemd
Update CLAUDE.md file with learned user preferences by creating a backup first, then applying detected patterns from repeated corrections to maintain consistent AI configuration standards.
Instructions
Update CLAUDE.md file with learned preferences (creates backup first)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | Yes | Path to CLAUDE.md file | |
| min_confidence | No | Minimum confidence threshold | |
| project_path | No | Project path for project-specific content (optional) |
Implementation Reference
- src/mcp_standards/server.py:599-689 (handler)Main handler for 'update_claudemd' tool: performs security validation on file paths, audits the operation, calls ClaudeMdManager to update the file, logs the episode if successful.async def _update_claudemd( self, file_path: str, project_path: Optional[str] = None, min_confidence: float = 0.7 ) -> Dict[str, Any]: """Update CLAUDE.md file with learned preferences""" try: file_path_obj = Path(file_path).resolve() # Security: Explicit path whitelist allowed_dirs = [ Path.cwd(), # Current working directory Path.home() / ".claude", # Global Claude config Path.home(), # User home (for any project) ] # Check if path is within allowed directories is_allowed = any( file_path_obj.is_relative_to(allowed_dir) for allowed_dir in allowed_dirs ) if not is_allowed: # Audit failed attempt self._audit_log( action="update_claudemd", target_type="file", target_path=str(file_path_obj), details="Path not in whitelist", success=False ) return { "success": False, "error": f"Path not in allowed directories. File must be in: {', '.join(str(d) for d in allowed_dirs)}" } # Additional check: Only allow CLAUDE.md or .claude.md files allowed_names = ["CLAUDE.md", "CLAUDE.local.md", ".claude.md"] if file_path_obj.name not in allowed_names: # Audit failed attempt self._audit_log( action="update_claudemd", target_type="file", target_path=str(file_path_obj), details=f"Invalid filename: {file_path_obj.name}", success=False ) return { "success": False, "error": f"Only {', '.join(allowed_names)} files can be updated. Got: {file_path_obj.name}" } # Update the file success, message = self.claudemd_manager.update_claudemd_file( file_path_obj, project_path=project_path, min_confidence=min_confidence ) # Audit the update attempt self._audit_log( action="update_claudemd", target_type="file", target_path=str(file_path_obj), details=f"min_confidence={min_confidence}, project_path={project_path or 'global'}", success=success ) if success: # Store in memory that we updated CLAUDE.md await self._add_episode( name=f"CLAUDE.md Updated - {file_path_obj.name}", content=f"Updated {file_path} with learned preferences (min confidence: {min_confidence})", source="claudemd_update" ) return { "success": success, "message": message, "file_path": str(file_path_obj), "project_path": project_path or "global" } except Exception as e: # Audit exception self._audit_log( action="update_claudemd", target_type="file", target_path=file_path, details=f"Exception: {str(e)}", success=False ) return {"success": False, "error": str(e)}
- src/mcp_standards/server.py:226-238 (registration)Tool registration in list_tools(), including name, description, and input schema definition.Tool( name="update_claudemd", description="Update CLAUDE.md file with learned preferences (creates backup first)", inputSchema={ "type": "object", "properties": { "file_path": {"type": "string", "description": "Path to CLAUDE.md file"}, "project_path": {"type": "string", "description": "Project path for project-specific content (optional)"}, "min_confidence": {"type": "number", "description": "Minimum confidence threshold", "default": 0.7}, }, "required": ["file_path"], }, ),
- src/mcp_standards/server.py:231-237 (schema)Input schema validation for the 'update_claudemd' tool parameters."properties": { "file_path": {"type": "string", "description": "Path to CLAUDE.md file"}, "project_path": {"type": "string", "description": "Project path for project-specific content (optional)"}, "min_confidence": {"type": "number", "description": "Minimum confidence threshold", "default": 0.7}, }, "required": ["file_path"], },
- Core helper function that generates CLAUDE.md content from database preferences, performs smart merging with existing file content, creates backups, and preserves manual edits.def update_claudemd_file( self, file_path: Path, project_path: Optional[str] = None, min_confidence: float = 0.7 ) -> Tuple[bool, str]: """ Update CLAUDE.md file with learned preferences Performs smart merging: 1. Preserves manual edits 2. Updates auto-generated sections 3. Handles conflicts gracefully Args: file_path: Path to CLAUDE.md file project_path: Project path for project-specific file min_confidence: Minimum confidence for inclusion Returns: (success, message) tuple """ # Generate new content new_content = self.generate_claudemd_content(project_path, min_confidence) # Check if file exists if not file_path.exists(): # Create new file file_path.parent.mkdir(parents=True, exist_ok=True) file_path.write_text(new_content) return (True, f"Created {file_path}") # File exists - smart merge existing_content = file_path.read_text() # Check for manual edits marker if "<!-- MANUAL EDITS BELOW -->" in existing_content: # Preserve everything after the marker manual_section = existing_content.split("<!-- MANUAL EDITS BELOW -->")[1] merged_content = new_content + "\n<!-- MANUAL EDITS BELOW -->\n" + manual_section else: # No manual edits marker - append manual edits warning merged_content = ( new_content + "\n<!-- MANUAL EDITS BELOW -->\n" "<!-- Your manual edits will be preserved below this line -->\n\n" + self._extract_manual_sections(existing_content, new_content) ) # Write merged content # Create backup first backup_path = file_path.with_suffix(f".{datetime.now().strftime('%Y%m%d_%H%M%S')}.bak") backup_path.write_text(existing_content) file_path.write_text(merged_content) return (True, f"Updated {file_path} (backup: {backup_path})")