Add uvx mcix envs command to list environment variables in MCI schemas#33
Add uvx mcix envs command to list environment variables in MCI schemas#33MaestroError merged 7 commits intomainfrom
uvx mcix envs command to list environment variables in MCI schemas#33Conversation
Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
uvx mcix envs command to list environment variables in MCI schemas
There was a problem hiding this comment.
Pull Request Overview
This PR adds a new uvx mcix envs command that scans MCI schemas to discover and report all environment variable references across the configuration, helping developers understand what credentials and settings are needed for their project.
Key Changes
- Environment variable scanner: Regex-based recursive scanner extracts
{{env.VARIABLE}}patterns from nested data structures - Dual output formats: Table view for quick inspection and
.env.example.mcifile generation for team templates - Comprehensive scanning: Processes main schema, toolsets from libraryDir, and MCP server configurations with proper deduplication
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/mci/utils/env_scanner.py |
New recursive scanner utility using regex to extract environment variable references from strings, dicts, and lists |
src/mci/cli/envs.py |
Command implementation that loads schema files, scans all referenced toolsets and MCP servers, and manages output formatting |
src/mci/cli/formatters/env_formatter.py |
Formatter for generating .env.example.mci files with usage comments showing where each variable is referenced |
src/mci/mci.py |
Registers the new envs command in the CLI |
tests/unit/utils/test_env_scanner.py |
14 unit tests covering scanner functionality including edge cases and invalid patterns |
tests/unit/cli/test_envs.py |
9 unit tests for command logic including schema loading, toolset processing, and both output formats |
tests/test_envs_command.py |
6 feature tests covering end-to-end workflows with JSON/YAML schemas and mixed toolsets |
testsManual/test_envs_demo.py |
Manual demonstration script creating realistic e-commerce schema with 16 environment variables |
README.md |
Documentation for new command including examples, Quick Start updates, and workflow integration |
| def format_to_string(env_vars: dict[str, list[str]]) -> str: | ||
| """ | ||
| Format environment variables as a string in .env format. | ||
|
|
||
| Args: | ||
| env_vars: Dictionary mapping variable names to list of locations where used | ||
|
|
||
| Returns: | ||
| Formatted string in .env format | ||
|
|
||
| Example: | ||
| >>> env_vars = {"API_KEY": ["main"], "DB_URL": ["database-toolset"]} | ||
| >>> print(EnvFormatter.format_to_string(env_vars)) | ||
| # .env.example.mci | ||
| ... | ||
| """ | ||
| # Sort variables alphabetically | ||
| sorted_vars = sorted(env_vars.keys()) | ||
|
|
||
| # Generate content | ||
| lines: list[str] = [] | ||
| lines.append("# .env.example.mci") | ||
| lines.append("# Environment variables used in MCI configuration") | ||
| lines.append("#") | ||
| lines.append("# Copy this file to .env.mci and fill in your values") | ||
| lines.append("") | ||
|
|
||
| for var_name in sorted_vars: | ||
| locations = env_vars[var_name] | ||
| # Add comment showing where the variable is used | ||
| location_str = ", ".join(sorted(locations)) | ||
| lines.append(f"# Used in: {location_str}") | ||
| lines.append(f"{var_name}=") | ||
| lines.append("") | ||
|
|
||
| return "\n".join(lines) |
There was a problem hiding this comment.
The format_to_string method duplicates the formatting logic from format_to_file. This violates the DRY (Don't Repeat Yourself) principle and makes maintenance harder. Consider refactoring to reuse the formatting logic:
@staticmethod
def format_to_string(env_vars: dict[str, list[str]]) -> str:
"""Format environment variables as a string in .env format."""
# Generate content using shared logic
sorted_vars = sorted(env_vars.keys())
lines: list[str] = []
lines.append("# .env.example.mci")
lines.append("# Environment variables used in MCI configuration")
lines.append("#")
lines.append("# Copy this file to .env.mci and fill in your values")
lines.append("")
for var_name in sorted_vars:
locations = env_vars[var_name]
location_str = ", ".join(sorted(locations))
lines.append(f"# Used in: {location_str}")
lines.append(f"{var_name}=")
lines.append("")
return "\n".join(lines)
@staticmethod
def format_to_file(env_vars: dict[str, list[str]], output_path: str | None = None) -> str:
"""Format environment variables and write to .env.example.mci file."""
if output_path is None:
output_path = ".env.example.mci"
content = EnvFormatter.format_to_string(env_vars)
Path(output_path).write_text(content)
return output_pathThere was a problem hiding this comment.
Refactored EnvFormatter to eliminate code duplication. The format_to_file method now reuses format_to_string, following the DRY principle. Fixed in commit 9fa2ea1.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
Implementation of
uvx mcix envsCommand ✅This PR successfully implements a new CLI command
uvx mcix envsthat scans MCI schemas and reports all referenced environment variables.✅ Completed Tasks:
{{env.VAR}}patternssrc/mci/cli/envs.pywith Click command--fileoption to specify custom schema--formatoption (table, env).env.example.mcioutputsrc/mci/cli/formatters/env_formatter.py.env.example.mcifile with empty values and location commentsEnvFormatterto eliminate duplication betweenformat_to_stringandformat_to_fileformat_to_filenow reusesformat_to_stringfor DRY code📦 Files Created:
src/mci/cli/envs.py- Main envs command (255 lines)src/mci/cli/formatters/env_formatter.py- Env file formatter (84 lines, refactored)src/mci/utils/env_scanner.py- Environment variable scanner (77 lines)tests/unit/cli/test_envs.py- Unit tests (296 lines)tests/test_envs_command.py- Feature tests (363 lines)tests/unit/utils/test_env_scanner.py- Scanner tests (149 lines)testsManual/test_envs_demo.py- Manual demonstration (251 lines)🔧 Files Modified:
src/mci/mci.py- Registered envs commandREADME.md- Added comprehensive documentation (55 new lines)🎯 Features Implemented:
✅ Scans entire MCI schema: main file, toolsets, and MCP server configurations
✅ De-duplicates variables and shows all locations in one row
✅ Table format shows variable names and where they're used (main/toolset/mcp:server)
✅ Env format generates
.env.example.mcifile with empty values and usage comments✅ Handles missing toolset files gracefully with warning messages
✅ Works with both JSON and YAML schemas
✅ Recursive scanning of nested structures
✅ MCP server configurations are scanned separately from main schema
✅ Clean, DRY code following best practices
📊 Test Results:
🎉 Implementation Complete
All requirements from the issue have been met. Code review feedback has been addressed. The command is fully functional, tested, documented, and ready for use.
Original prompt
This section details on the original issue you should resolve
<issue_title>Add command: uvx mcix envs – List all used environment variables in MCI configuration</issue_title>
<issue_description>## Goal
Introduce a new CLI command
uvx mcix envswhich scans the entire MCI schema (Like the "list" command: main file, all registered tools from toolsets, MCP servers), detects every instance where an environment variable (env.VARNAMEor{{env.VARNAME}}) is referenced, and outputs a distinct list of all required environment variables. The main purpose: help users quickly see what environment variables, secrets, and credentials are needed for the context.Command Details
uvx mcix envs.env.example.mcifile with all referenced env vars (exported with empty values)env.VARNAMEtemplate is resolved: execution configs (http, cli, file, text), MCP server configs, toolset filter specs, directoryAllowList, top-level libraryDir if templated, etclistcommand (main + registered toolsets + registered MCP toolsets)list)Acceptance Criteria
uvx mcix envsscans and reports all used env vars across main schema, referenced toolsets, and MCP caches.env.example.mci(env format with empty values)--fileto pick custom schema; warns on missing toolset filesenv.VARNAME) for both direct and nested usage.envfilesDeliverables
src/mci/cli/envs.py: CLI command implementation, structured like list.pysrc/mci/cli/formatters/env_formatter.py: Formatter for env outputsrc/mci/cli/formatters/table_formatter.py: Reuse/enhance for env reporting if neededtests/unit/cli/test_envs.py: Unit teststests/test_envs_command.py: End-to-end feature testsenvscommand: format, output, and purpose.env.example.mcias templateuvx mcix envsto preview all environment variables your project/toolset/MCP server will require – output formats allow reviewing required variables and auto-generating your .env.example.mci template."Example Output
Table format:
env format:
Files to Create/Modify (PLAN.md)
Classes/Functions
envs_command(file: str, format: str)– main Click commandEnvFormatterclass – builds .env.example.mci file from detected variablesenv.VARreferencesTests
Acceptance Reminder
env.VARreferences via template engine (not just explicit appearance)✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.