Instruction file imported from PulkitXChadha/awesome-databricks-mcp (
.cursor/rules/code-quality.mdc). Copyright stays with the author.
Code Quality Standards
šØ SENIOR DEVELOPER GUIDELINES šØ
CRITICAL: This project follows SIMPLE, MAINTAINABLE patterns. DO NOT over-engineer!
Code Philosophy
- SIMPLE over CLEVER: Write obvious code that any developer can understand
- EXPLICIT over IMPLICIT: Prefer clear, direct implementations over abstractions
- FLAT over NESTED: Avoid deep inheritance, complex factories, or excessive abstraction layers
- FOCUSED over GENERIC: Write code for the specific use case, not hypothetical future needs
Forbidden Patterns (DO NOT ADD THESE)
ā Abstract base classes or complex inheritance hierarchies ā Factory patterns or dependency injection containers ā Decorators for cross-cutting concerns (logging, caching, performance monitoring) ā Complex configuration classes with nested structures ā Async/await patterns unless absolutely necessary ā Connection pooling or caching layers ā Generic "framework" code or reusable utilities ā Complex error handling systems or custom exceptions ā Performance optimization patterns (premature optimization) ā Enterprise patterns like singleton, observer, strategy, etc.
Required Patterns (ALWAYS USE THESE)
ā Direct function calls - no indirection or abstraction layers ā Simple classes with clear, single responsibilities ā Environment variables for configuration (no complex config objects) ā Explicit imports - import exactly what you need ā Basic error handling with try/catch and simple return dictionaries ā Straightforward control flow - avoid complex conditional logic ā Standard library first - only add dependencies when absolutely necessary
Implementation Rules
- One concept per file: Each module should have a single, clear purpose
- Functions over classes: Prefer functions unless you need state management
- Direct SDK calls: Call Databricks SDK directly, no wrapper layers
- Simple data structures: Use dicts and lists, avoid custom data classes
- Basic testing: Simple unit tests with basic mocking, no complex test frameworks
- Minimal dependencies: Only add new dependencies if critically needed
Code Review Questions
Before adding any code, ask yourself:
- "Is this the simplest way to solve this problem?"
- "Would a new developer understand this immediately?"
- "Am I adding abstraction for a real need or hypothetical flexibility?"
- "Can I solve this with standard library or existing dependencies?"
- "Does this follow the existing patterns in the codebase?"
Python Code Quality
Linting and Formatting
- Linter: ruff for fast Python linting and formatting
- Configuration: See pyproject.toml for ruff settings
- Line Length: Maximum 80 characters (CLAUDE.md standard)
- Indentation: Use tabs for indentation (CLAUDE.md standard)
- Quotes: Single quotes for strings (except to avoid escaping)
Code Style Rules
# ā
GOOD: Simple, direct implementation
def get_workspace_client() -> WorkspaceClient:
host = os.getenv('DATABRICKS_HOST')
token = os.getenv('DATABRICKS_TOKEN')
return WorkspaceClient(host=host, token=token)
# ā BAD: Over-engineered with abstractions
class AbstractDatabricksClientFactory(ABC):
@abstractmethod
def create_client(self) -> WorkspaceClient: ...
class ConfigurableDatabricksClientFactory(AbstractDatabricksClientFactory):
def __init__(self, config: DatabricksConfig): ...
Type Hints
- Required: Use type hints for all function parameters and return values
- Simple types: Use basic types (str, int, dict, list) over complex generics
- Avoid: Complex type hierarchies or custom type systems
- Import:
from typing import Optional, Union, Anyonly when necessary
Documentation
- Docstrings: Use simple, clear descriptions
- Function Docs: Document what the function does, not how it works
- Class Docs: Document class purpose only
- Module Docs: Document module purpose and exports
Tool System Architecture
The modular tools system (server/tools/) is organized into specialized modules:
core.py- Health checks and basic operationssql_operations.py- SQL warehouse and query toolsunity_catalog.py- Unity Catalog operations (catalogs, schemas, tables)jobs_pipelines.py- Job and DLT pipeline managementworkspace_files.py- Workspace file operationsdashboards.py- Comprehensive dashboard management tools (only Lakeview)repositories.py- Git repository integrationdata_management.py- DBFS and data operations (commented out)governance.py- Governance tools (commented out)
Adding New Tools
Tools are automatically registered when added to modules. Follow existing patterns:
def load_module_tools(mcp_server):
"""Register tools from this module."""
@mcp_server.tool
def your_new_tool(param: str) -> dict:
"""Tool description for Claude."""
# Implementation using Databricks SDK
return {"result": "data"}
Key principles:
- Direct Databricks SDK calls (no wrappers)
- Simple error handling with try/catch
- Return dictionaries with consistent structure
- No decorators, no abstractions, no magic
TypeScript Code Quality
Linting and Formatting
- Linter: ESLint with TypeScript support
- Formatter: Prettier for consistent code formatting
- Configuration: See client/package.json for scripts
Code Style Rules
// ā
GOOD: Simple, focused component
interface UserProfile {
id: string
name: string
email: string
}
const handleUserUpdate = (user: UserProfile): void => {
// Direct implementation
}
// ā BAD: Over-engineered with unnecessary abstractions
interface AbstractUserProfile<T extends string> {
id: T
name: string
email: string
}
class UserProfileManager<T extends string> {
private profile: AbstractUserProfile<T>
// Complex implementation
}
TypeScript Best Practices
- Strict Mode: Enable all strict TypeScript options
- Interface over Type: Prefer interfaces for object shapes
- Utility Types: Use Partial, Pick, Omit sparingly
- Generic Types: Use generics only when absolutely necessary
General Code Quality
Naming Conventions
- Python: snake_case for functions and variables, PascalCase for classes
- TypeScript: camelCase for variables and functions, PascalCase for components
- Constants: UPPERCASE for constants
- Files: kebab-case for file names
Code Organization
- Imports: Group imports (standard library, third-party, local)
- Functions: Keep functions focused and single-purpose
- Classes: Use simple classes with clear responsibilities
- Modules: Organize related functionality into modules
Error Handling
- Python: Use try-catch blocks with simple error handling
- TypeScript: Use proper error boundaries and error types
- Logging: Log errors with appropriate log levels
- User Experience: Provide meaningful error messages
Examples of Good vs Bad Code
ā BAD (Over-engineered):
class AbstractDatabricksClientFactory(ABC):
@abstractmethod
def create_client(self) -> WorkspaceClient: ...
class ConfigurableDatabricksClientFactory(AbstractDatabricksClientFactory):
def __init__(self, config: DatabricksConfig): ...
ā GOOD (Simple):
def get_workspace_client() -> WorkspaceClient:
host = os.getenv('DATABRICKS_HOST')
token = os.getenv('DATABRICKS_TOKEN')
return WorkspaceClient(host=host, token=token)
ā BAD (Complex configuration):
class DatabaseConfig(BaseModel):
host: str = Field(..., description="Database host")
class AppConfig(BaseSettings):
database: DatabaseConfig
security: SecurityConfig
monitoring: MonitoringConfig
ā GOOD (Direct environment variables):
class Config:
def __init__(self):
self.host = os.getenv('DATABRICKS_HOST')
self.token = os.getenv('DATABRICKS_TOKEN')
Summary: What Makes This Project "Senior Developer Approved"
ā Readable: Any developer can understand the code immediately ā Maintainable: Simple patterns that are easy to modify ā Focused: Each module has a single, clear responsibility ā Direct: No unnecessary abstractions or indirection ā Practical: Solves the specific problem without over-engineering
When in doubt, choose the simpler solution. Your future self (and your teammates) will thank you.