This document outlines the implementation plan for the MCI CLI Tool (mci-uvx), a uvx-based command-line interface for managing MCI (Model Context Interface) schemas and dynamically running MCP servers. The implementation is divided into 10 logical stages, building from core dependencies to full CLI functionality.
- click (15.5k+ stars) - Modern Python CLI framework with excellent developer experience
- rich (48k+ stars) - Beautiful terminal formatting, tables, and progress bars
- pyyaml (2.5k+ stars) - YAML parsing and serialization
- mci-py - MCI Python adapter for schema parsing and tool execution (includes Pydantic models)
- mcp - Official Python SDK for Model Context Protocol
- pytest - Testing framework (already in dependencies)
- pytest-asyncio - Async test support for MCP integration
- pytest-mock - Mocking utilities for tests
- pytest-cov - Coverage reporting
- Pydantic is NOT needed as a separate dependency - it's already included in
mci-pywhich provides all necessary Pydantic models for tool definitions, schemas, and validation - The CLI tool should use mci-py's models directly rather than creating new ones
Set up project structure, install dependencies, and configure build system.
src/mci/
├── __init__.py # Package initialization
├── mci.py # Main CLI entry point
├── cli/ # CLI command modules
│ └── __init__.py
├── core/ # Core business logic
│ └── __init__.py
└── utils/ # Utility functions
└── __init__.py
- pyproject.toml - Add core dependencies (click, rich, pyyaml, mci-py, mcp) - Note: Pydantic not needed separately as it's in mci-py
- src/mci/init.py - Export main CLI entry point
- src/mci/mci.py - Basic Click application structure
- src/mci/cli/init.py - CLI command group initialization
- src/mci/core/init.py - Core module initialization
- src/mci/utils/init.py - Utilities initialization
main()inmci.py- Main CLI entry point with Click group
tests/unit/test_cli_init.py- Test CLI initializationtests/unit/test_imports.py- Test package imports
tests/test_cli_help.py- Test CLI help output and command discovery
None for this stage.
- All dependencies installed via
uv sync -
uv run mci --helpdisplays help text - All tests pass with
make test - Code passes linting with
make lint
Implement logic to find and load MCI configuration files (JSON/YAML) using mci-py's MCIClient for validation.
src/mci/core/
├── config.py # Configuration loading and validation
└── file_finder.py # File discovery logic
- src/mci/core/config.py - Config class for managing MCI file paths, validation using MCIClient
- src/mci/core/file_finder.py - Logic to find mci.json/mci.yaml in directory
- src/mci/utils/validation.py - File validation utilities
MCIFileFinderclass with methods:find_mci_file(directory: str = ".") -> str | None- Find mci.json or mci.yamlvalidate_file_exists(path: str) -> bool- Check if file existsget_file_format(path: str) -> str- Determine if JSON or YAML
MCIConfigclass with methods:load(file_path: str) -> MCIClient- Load and parse MCI file using MCIClient in try blockvalidate_schema(file_path: str) -> tuple[bool, str]- Validate using MCIClient, return (is_valid, error_message)
- MCI schema validation is already built into
mci-py, so use MCIClient in a try block to parse the file - If MCIClient initialization fails, catch the exception and extract error details for user-friendly messages
- This approach leverages mci-py's built-in validation instead of duplicating validation logic
tests/unit/core/test_file_finder.pytest_find_json_file()- Find mci.json in directorytest_find_yaml_file()- Find mci.yaml in directorytest_find_priority_json_over_yaml()- JSON takes prioritytest_no_file_found()- Return None when no file exists
tests/unit/core/test_config.pytest_load_valid_schema_with_mciclient()- Load valid schema using MCIClienttest_invalid_schema_caught_by_mciclient()- MCIClient catches invalid schematest_missing_file_error()- Handle missing file errorstest_error_message_extraction()- Extract user-friendly error messages from MCIClient exceptions
tests/test_config_loading.py- Test end-to-end config loading with sample files using MCIClient
None for this stage.
- Can find mci.json and mci.yaml files
- Can load and validate files using MCIClient
- Proper error handling using MCIClient's validation
- User-friendly error messages extracted from MCIClient exceptions
- All tests pass
Implement the install command to initialize MCI project structure.
src/mci/cli/
├── install.py # Install command implementation
└── templates/ # Template files for initialization
├── mci_json_template.py
├── mci_yaml_template.py
└── example_template.py
- src/mci/cli/install.py - Install command implementation
- src/mci/cli/templates/mci_json_template.py - Template for mci.json
- src/mci/cli/templates/mci_yaml_template.py - Template for mci.yaml
- src/mci/cli/templates/example_template.py - Template for example.mci.json
- src/mci/mci.py - Register install command
install_command(yaml: bool = False)- Click command formcix installcreate_mci_file(format: str) -> None- Create main MCI filecreate_mci_directory() -> None- Create ./mci directory structurecreate_example_toolset() -> None- Create example.mci.json
The mci.json template should create this starting structure:
{
"schemaVersion": "1.0",
"metadata": {
"name": "Example Project",
"description": "Example MCI configuration"
},
"tools": [
{
"name": "echo_test",
"description": "Simple echo test tool",
"inputSchema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "Message to echo"
}
},
"required": ["message"]
},
"execution": {
"type": "text",
"text": "Echo: {{props.message}}"
}
}
],
"toolsets": [],
"mcp_servers": {}
}The mci.yaml template should have the equivalent YAML structure.
tests/unit/cli/test_install.pytest_create_json_file()- Create mci.json filetest_create_yaml_file()- Create mci.yaml file with --yaml flagtest_file_already_exists()- Handle existing file gracefullytest_create_mci_directory()- Create ./mci directorytest_create_gitignore()- Create .gitignore with ./mcp entry
tests/test_install_command.py- Test full install workflow in temp directory
testsManual/test_install.py- Run install in real directory, verify all files
-
uvx mcix installcreates mci.json with proper structure -
uvx mcix install --yamlcreates mci.yaml - Creates ./mci directory with example.mci.json
- Creates ./mci/.gitignore with ./mcp entry
- Handles existing files gracefully
- All tests pass
Integrate mci-py library for loading and managing MCI tools using MCIClient.
src/mci/core/
├── mci_client.py # Wrapper around mci-py MCIClient
└── tool_manager.py # Tool management and filtering logic
- src/mci/core/mci_client.py - Wrapper for MCIClient with error handling
- src/mci/core/tool_manager.py - Tool filtering and listing logic
- src/mci/utils/error_handler.py - Error handling utilities
IMPORTANT: Use MCIClient from mci-py for all tool loading and filtering operations.
- The
MCIClientclass from mci-py already provides all necessary functionality:- Loading tools from schema files (JSON/YAML)
- Built-in filtering methods:
only(),except_(),tags(),withoutTags() - Environment variable templating
- Pydantic models for tool definitions
- Check mci-docs for full MCIClient API reference and usage examples
- Do NOT reimplement filtering logic - use MCIClient's built-in methods
- The wrapper should primarily handle CLI-specific error handling and formatting
- MCIClient already includes all needed Pydantic models for validation
MCIClientWrapperclass with methods:__init__(file_path: str, env_vars: dict = None)- Initialize MCIClientget_tools() -> list[Tool]- Get all tools using MCIClient.tools()filter_only(tool_names: list[str]) -> list[Tool]- Use MCIClient.only()filter_except(tool_names: list[str]) -> list[Tool]- Use MCIClient.except_()filter_tags(tags: list[str]) -> list[Tool]- Use MCIClient.tags()filter_without_tags(tags: list[str]) -> list[Tool]- Use MCIClient.withoutTags()
ToolManagerclass with methods:apply_filter_spec(client: MCIClient, filter_spec: str) -> list[Tool]parse_filter_spec(filter_spec: str) -> tuple[str, list[str]]- Parse CLI filter string
tests/unit/core/test_mci_client.pytest_load_valid_schema()- Load schema successfully using MCIClienttest_invalid_schema_error()- Handle invalid schema from MCIClienttest_missing_file_error()- Handle missing filetest_env_var_substitution()- Test environment variable templatingtest_use_mciclient_filtering()- Verify MCIClient filter methods are used
tests/unit/core/test_tool_manager.pytest_parse_filter_spec()- Parse CLI filter specificationtest_apply_filter_only()- Apply "only" filter via MCIClienttest_apply_filter_except()- Apply "except" filter via MCIClienttest_apply_filter_tags()- Apply "tags" filter via MCIClient
tests/test_mci_integration.py- Test mci-py integration with sample schemas
testsManual/test_tool_loading.py- Load real MCI files and display tools
- Uses MCIClient from mci-py for all operations
- Leverages MCIClient's built-in filtering methods
- Environment variable templating works via MCIClient
- Proper error messages for invalid schemas
- No reimplementation of mci-py functionality
- All tests pass
Implement the list command to display available tools.
IMPORTANT: The list command should use the same modules that will be used in the run command.
- The
listcommand is designed to test and preview what tools theruncommand will return - Both commands should share the same tool loading and filtering logic
- This ensures consistency between what
listshows and whatrunactually provides - Use the same MCIClient wrapper and filtering logic that
runwill use
src/mci/cli/
├── list.py # List command implementation
└── formatters/ # Output formatters
├── __init__.py
├── table_formatter.py
├── json_formatter.py
└── yaml_formatter.py
- src/mci/cli/list.py - List command implementation (reuse tool loading from Stage 4)
- src/mci/cli/formatters/table_formatter.py - Rich table formatter
- src/mci/cli/formatters/json_formatter.py - JSON output formatter
- src/mci/cli/formatters/yaml_formatter.py - YAML output formatter
- src/mci/utils/timestamp.py - Timestamp generation utilities
- src/mci/mci.py - Register list command
list_command(file: str, filter: str, format: str, verbose: bool)- Click commandTableFormatterclass with methods:format(tools: list[Tool], verbose: bool) -> strformat_verbose(tools: list[Tool]) -> str
JSONFormatterclass with methods:format_to_file(tools: list[Tool], verbose: bool) -> str- Returns filename
YAMLFormatterclass with methods:format_to_file(tools: list[Tool], verbose: bool) -> str- Returns filename
generate_timestamp_filename(format: str) -> str- Generate tools_YYYYMMDD_HHMMSS.{format}
tests/unit/cli/test_list.pytest_list_default_format()- Default table formattest_list_json_format()- JSON file outputtest_list_yaml_format()- YAML file outputtest_list_with_filter()- Apply filterstest_list_verbose()- Verbose outputtest_list_uses_same_loading_as_run()- Verify shared logic with run command
tests/unit/cli/formatters/test_table_formatter.pytest_basic_table()- Basic table outputtest_verbose_table()- Verbose table with parameters
tests/unit/cli/formatters/test_json_formatter.pytest_json_output_structure()- Verify JSON structuretest_timestamp_in_json()- Verify timestamp field
tests/unit/cli/formatters/test_yaml_formatter.pytest_yaml_output_structure()- Verify YAML structure
tests/test_list_command.py- Test full list command with various options
testsManual/test_list_output.py- Run list command, verify table output visually
-
uvx mcix listdisplays table of tools -
uvx mcix list --format=jsoncreates timestamped JSON file -
uvx mcix list --format=yamlcreates timestamped YAML file -
uvx mcix list --verboseshows detailed tool info -
uvx mcix list --filter=tags:Tag1,Tag2filters correctly - Uses same tool loading/filtering logic as run command
- Beautiful output with Rich tables
- All tests pass
Implement the validate command to check MCI schema correctness using mci-py's built-in validation.
IMPORTANT: Use mci-py's built-in validation since it already validates the schema.
- mci-py's
MCIClientperforms comprehensive schema validation during initialization - Leverage this built-in validation instead of reimplementing validation logic
- Additional checks (toolset file existence, MCP command availability) can be added as warnings
- Use try/except with MCIClient to catch validation errors
src/mci/core/
└── validator.py # Schema validation logic using mci-py
- src/mci/core/validator.py - Schema validation using MCIClient
- src/mci/cli/validate.py - Validate command implementation
- src/mci/utils/error_formatter.py - Format validation errors nicely
- src/mci/mci.py - Register validate command
validate_command(file: str)- Click command formcix validateMCIValidatorclass with methods:validate_schema(file_path: str) -> ValidationResult- Validate using MCIClientcheck_toolset_files() -> list[ValidationWarning]- Check toolset file existencecheck_mcp_commands() -> list[ValidationWarning]- Check MCP commands in PATH
ValidationResultdataclass with fields:errors: list[ValidationError]- From MCIClient exceptionswarnings: list[ValidationWarning]- Additional checksis_valid: bool
tests/unit/core/test_validator.pytest_valid_schema_via_mciclient()- Validate correct schema using MCIClienttest_invalid_schema_caught_by_mciclient()- MCIClient catches invalid schematest_missing_required_field()- Detect missing fields via MCIClienttest_invalid_toolset_reference()- Detect missing toolsets (warning)test_missing_mcp_command()- Detect missing MCP commands (warning)test_warning_collection()- Collect warnings without failing
tests/unit/cli/test_validate.pytest_validate_valid_file()- Validate successful schematest_validate_invalid_file()- Report validation errors from MCIClient
tests/test_validate_command.py- Test validation with various schema files
testsManual/test_validate.py- Run validate on real schemas, check output
-
uvx mcix validatechecks default mci.json/mci.yaml using MCIClient -
uvx mcix validate --file=custom.mci.jsonchecks custom file - Uses MCIClient for schema validation (no reimplementation)
- Shows warnings for missing toolsets and MCP commands
- Beautiful, color-coded output using Rich
- All tests pass
Implement the add command to add toolset references to MCI files.
src/mci/core/
└── schema_editor.py # Schema file editing logic
- src/mci/core/schema_editor.py - Edit MCI schema files programmatically
- src/mci/cli/add.py - Add command implementation
- src/mci/mci.py - Register add command
add_command(toolset_name: str, filter: str, path: str)- Click commandSchemaEditorclass with methods:load_schema(file_path: str) -> dictadd_toolset(toolset_name: str, filter_type: str = None, filter_value: str = None) -> Nonesave_schema(file_path: str) -> Nonepreserve_format() -> str- Remember if JSON or YAML
parse_add_filter(filter_spec: str) -> tuple[str, str]- Parse filter specification
tests/unit/core/test_schema_editor.pytest_add_simple_toolset()- Add toolset without filtertest_add_toolset_with_filter()- Add toolset with filtertest_add_duplicate_toolset()- Handle duplicate gracefullytest_preserve_json_format()- Save back as JSONtest_preserve_yaml_format()- Save back as YAML
tests/unit/cli/test_add.pytest_add_toolset_command()- Test add commandtest_add_with_filter()- Test add with filter optiontest_add_to_custom_path()- Test --path option
tests/test_add_command.py- Test full add workflow
testsManual/test_add.py- Add toolsets to real files, verify changes
-
uvx mcix add weather-toolsadds toolset to mci.json -
uvx mcix add analytics --filter=only:Tool1,Tool2adds with filter -
uvx mcix add toolset --path=custom.mci.jsonmodifies custom file - Preserves file format (JSON stays JSON, YAML stays YAML)
- Handles duplicates gracefully
- All tests pass
Set up infrastructure for creating MCP servers (not connecting to them) that can serve MCI tools.
IMPORTANT: This stage is about CREATING MCP servers.
- We create an MCP server that will serve tools from MCI schemas
- The server will expose MCI tools as MCP tools to MCP clients
- Check mcp-server-docs.md for examples of how to create MCP servers (to be added later)
- Use the official
mcpPython SDK to create the server - The server should handle tool listing and tool execution requests via MCP protocol
src/mci/core/
├── mcp_server.py # MCP server creation and management
└── tool_converter.py # Convert MCI tools to MCP tool format
- src/mci/core/mcp_server.py - Create and configure MCP server instances
- src/mci/core/tool_converter.py - Convert MCI Tool objects to MCP tool definitions
- pyproject.toml - Add pytest-asyncio for async tests
MCPServerBuilderclass with async methods:async create_server(name: str, version: str) -> Server- Create MCP server instanceasync register_tool(server: Server, mci_tool: Tool) -> None- Register MCI tool as MCP toolasync register_all_tools(server: Server, tools: list[Tool]) -> None- Register multiple tools
MCIToolConverterclass with methods:convert_to_mcp_tool(mci_tool: Tool) -> MCPTool- Convert MCI Tool to MCP formatconvert_input_schema(mci_schema: dict) -> dict- Convert inputSchema to MCP format
ServerInstanceclass:start() -> None- Start the MCP serverstop() -> None- Stop the MCP serverhandle_tool_call(name: str, arguments: dict) -> Any- Delegate to MCI execution
tests/unit/core/test_mcp_server.pytest_create_server()- Create MCP server instancetest_register_single_tool()- Register one MCI tooltest_register_multiple_tools()- Register multiple toolstest_server_metadata()- Verify server name and version
tests/unit/core/test_tool_converter.pytest_convert_mci_to_mcp_tool()- Convert tool definitiontest_convert_input_schema()- Convert inputSchema formattest_preserve_tool_description()- Ensure description is preserved
tests/test_mcp_server_creation.py- Test full MCP server creation workflow
testsManual/test_mcp_server.py- Create server, verify it can be queried
- Can create MCP server instances using
mcpSDK - Can register MCI tools as MCP tools
- Tool definitions properly converted to MCP format
- Server can handle tool listing requests
- Proper async handling
- All tests pass
Implement the run command to launch MCP servers via STDIO that serve MCI tools.
IMPORTANT: Integration flow for the run command:
- Fetch tools from MCI: Use MCIClient (from Stage 4) to load tools from MCI schema
- Build MCP tools: Convert MCI tools to MCP tool format (from Stage 8)
- Create MCP server: Use the MCP server infrastructure (from Stage 8)
- Handle execution: When a tool execution is requested via MCP, use MCI's execution logic
The run command creates a dynamic MCP server that:
- Loads MCI tools using MCIClient
- Converts them to MCP format
- Serves them via MCP protocol over STDIO
- Delegates execution back to MCI when tools are called
src/mci/core/
└── dynamic_server.py # Dynamic MCP server creation from MCI schema
- src/mci/core/dynamic_server.py - Create MCP server from MCI schema
- src/mci/cli/run.py - Run command implementation
- src/mci/mci.py - Register run command
run_command(file: str, filter: str)- Click command formcix runDynamicMCPServerclass with async methods:async create_from_mci_schema(schema_path: str, filter_spec: str = None) -> Server- Load tools using MCIClient from Stage 4
- Convert MCI tools to MCP format using Stage 8 converter
- Register tools with MCP server from Stage 8
async handle_tool_execution(name: str, arguments: dict) -> ToolResult- Use MCIClient.execute() to run the tool
- Return result in MCP format
async start_stdio() -> None- Start server on STDIO
run_server(schema_path: str, filter_spec: str) -> None- Main run function
tests/unit/core/test_dynamic_server.pytest_create_server_from_schema()- Create server from MCI schematest_load_tools_via_mciclient()- Verify MCIClient is used to load toolstest_convert_tools_to_mcp()- Verify tools are converted to MCP formattest_handle_execution_uses_mci()- Verify MCI's execute() is used
tests/unit/cli/test_run.pytest_run_default_file()- Run with default mci.jsontest_run_custom_file()- Run with --file optiontest_run_with_filter()- Run with --filter option
tests/test_run_command.py- Test full run command with mock MCP client
testsManual/test_run_stdio.py- Run actual MCP server, connect with MCP client
-
uvx mcix runstarts MCP server on STDIO - Uses MCIClient to fetch tools from MCI schema
- Converts MCI tools to MCP tool format
- Server responds to MCP protocol requests (list_tools)
- Tool execution requests delegate to MCI's execute()
-
uvx mcix run --file=custom.mci.jsonuses custom file -
uvx mcix run --filter=tags:Tag1,Tag2filters tools correctly - Graceful shutdown on Ctrl+C
- All tests pass
testsManual/test_run_stdio.py- Run actual MCP server, connect with MCP client
-
uvx mcix runstarts MCP server on STDIO -
uvx mcix run --file=custom.mci.jsonuses custom file -
uvx mcix run --filter=tags:Tag1,Tag2filters tools - Server responds to MCP protocol requests
- Tools execute correctly via mci-py
- Graceful shutdown on Ctrl+C
- All tests pass
Comprehensive error handling, user documentation, and final polish.
docs/
├── commands/ # Command documentation
│ ├── install.md
│ ├── list.md
│ ├── validate.md
│ ├── add.md
│ └── run.md
└── examples/ # Example MCI files
├── basic.mci.json
├── with-toolsets.mci.json
└── with-mcp-servers.mci.json
- README.md - Update with full usage documentation
- docs/commands/*.md - Detailed command documentation
- docs/examples/*.mci.json - Example configurations
- src/mci/utils/error_handler.py - Enhanced error handling
- src/mci/utils/logging.py - Logging utilities
- All CLI commands - Add comprehensive error handling
ErrorHandlerclass with methods:handle_mci_error(error: Exception) -> None- Handle MCI-specific errorshandle_file_error(error: Exception) -> None- Handle file errorshandle_validation_error(error: Exception) -> None- Handle validation errorsdisplay_user_friendly_error(error: Exception) -> None- Display errors nicely
setup_logging(verbose: bool) -> None- Configure logging
tests/unit/utils/test_error_handler.pytest_handle_mci_client_error()- Test MCI client error handlingtest_handle_file_not_found()- Test file error handlingtest_handle_validation_error()- Test validation error handlingtest_user_friendly_display()- Test error display formatting
tests/unit/test_all_commands.py- Integration tests for all commands with error scenarios
tests/test_error_scenarios.py- Test error handling end-to-endtests/test_user_experience.py- Test complete user workflows
testsManual/test_all_features.py- Complete manual test of all featurestestsManual/test_error_messages.py- Verify error messages are helpful
- Update README.md with installation and usage instructions
- Create comprehensive command documentation
- Add example MCI files with comments
- Implement --verbose flag for debugging
- Add --version flag to show version
- Create helpful error messages for common mistakes
- Add progress indicators for long operations
- Create CONTRIBUTING.md for contributors
- Update .gitignore to exclude common temporary files
- All commands have comprehensive error handling
- User-friendly error messages guide users to solutions
- Complete documentation for all commands
- Example files demonstrate all features
- All tests pass with >90% coverage
- README is clear and comprehensive
- Code is well-documented with docstrings
Each stage includes three types of tests:
- Unit Tests (tests/unit/) - Test individual functions and classes in isolation
- Feature Tests (tests/) - Test complete features end-to-end
- Manual Tests (testsManual/) - Manual verification for visual/interactive features
- Code Coverage: Target 90%+ coverage across all modules
- Test Count: Approximately 150-200 total automated tests
- Manual Tests: 10-15 manual verification scripts
- Test Organization: Mimic src/ directory structure in tests/unit/
# Run all automated tests
make test
# Run with coverage
make coverage
# Run specific test file
uv run pytest -s tests/test_list_command.py
# Run manual test
uv run python testsManual/test_run_stdio.pyThe 10 stages are ordered to build incrementally:
- Stage 1-2: Foundation - Set up infrastructure and configuration loading
- Stage 3: First user-facing feature - Initialize projects
- Stage 4-5: Core functionality - Load and display tools
- Stage 6-7: Schema management - Validate and modify schemas
- Stage 8-9: MCP integration - Connect and run MCP servers
- Stage 10: Polish - Error handling and documentation
Each stage builds on previous stages, ensuring:
- Early feedback on core functionality
- Incremental complexity
- Testable milestones
- Working software at each stage
Stage 1 (Setup)
↓
Stage 2 (Config Loading)
↓
├─→ Stage 3 (Install Command)
├─→ Stage 4 (MCI-PY Integration)
│ ↓
│ Stage 5 (List Command)
│ ↓
│ Stage 6 (Validate Command)
│ ↓
│ Stage 7 (Add Command)
│
└─→ Stage 8 (MCP Setup)
↓
Stage 9 (Run Command)
↓
Stage 10 (Polish & Docs)
These features are documented in PRD.md but not included in the initial 10 stages:
- Stage 11 (Future):
mcix run --portfor HTTP-based MCP servers - Stage 12 (Future):
mci testcommand to simulate tool execution - Stage 13 (Future): Plugin system for custom commands
- Stage 14 (Future): Interactive mode with prompts
- Stage 15 (Future): Tool marketplace integration
The implementation is considered complete when:
- ✅ All 10 stages are implemented
- ✅ All commands from PRD.md work correctly
- ✅ Test coverage > 90%
- ✅ Documentation is comprehensive
- ✅ Code passes all linting checks
- ✅ Manual testing validates user experience
- ✅ Can be installed via
uvx mciand used immediately
- This plan focuses on STDIO-based MCP servers for the initial implementation
- HTTP-based MCP servers (--port option) are deferred to future enhancements
- Each stage should take 1-3 days for an experienced developer
- Total estimated time: 2-3 weeks for full implementation
- Emphasis on test-driven development throughout
- Use Rich library for beautiful terminal output
- Follow the project's existing code style and documentation standards