Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed
- **CLI**: Restructured argument parser to make `--config` a true global option

## [0.11.1] - 2026-01-16

### Fixed
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,19 @@ itential-mcp run --transport sse --host 0.0.0.0 --port 8000

### General Options

Global options can be specified before or after the command name.

| Option | Description | Default |
|------------|-------------------------|---------|
| `--config` | Path to the config file | none |

**Examples:**
```bash
# Both of these work identically:
itential-mcp --config config.conf run
itential-mcp run --config config.conf
```

### Server Options

| Option | Description | Default |
Expand Down
3 changes: 1 addition & 2 deletions src/itential_mcp/runtime/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class CommandConfig:
CommandConfig(
name="run",
description="Run the MCP server",
arguments={"--config": {"help": CONFIG_HELP_MESSAGE}},
arguments={},
add_platform_group=True,
add_server_group=True,
),
Expand Down Expand Up @@ -80,7 +80,6 @@ class CommandConfig:
name="test",
description="Test connection to Itential Platform",
arguments={
"--config": {"help": CONFIG_HELP_MESSAGE},
"--timeout": {
"type": int,
"default": 30,
Expand Down
42 changes: 35 additions & 7 deletions src/itential_mcp/runtime/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,31 @@
from .handlers import get_command_handler


def _create_main_parser() -> cli.Parser:
def _create_global_options_parser() -> cli.Parser:
"""
Create parser for global options that apply to all commands.

This parser is used as a parent parser for all subcommands to ensure
global options like --config are available to all commands.

Returns:
cli.Parser: Parser with global options (add_help=False for parent)

Raises:
None
"""
parser = cli.Parser(add_help=False)
parser.add_argument("--config", metavar="FILE", help=constants.CONFIG_HELP_MESSAGE)
return parser


def _create_main_parser(global_options_parser: cli.Parser) -> cli.Parser:
"""
Create and configure the main argument parser.

Args:
global_options_parser: Parser with global options to inherit

Returns:
cli.Parser: The configured main parser

Expand All @@ -32,22 +53,23 @@ def _create_main_parser() -> cli.Parser:
prog=constants.APP_NAME,
add_help=False,
description=constants.APP_DESCRIPTION,
parents=[global_options_parser],
)

parser.add_argument("--config", help=constants.CONFIG_HELP_MESSAGE)
parser.add_argument(
"-h", "--help", action="store_true", help=constants.GLOBAL_HELP_MESSAGE
)

return parser


def _create_subparsers(parser: cli.Parser) -> None:
def _create_subparsers(parser: cli.Parser, global_options_parser: cli.Parser) -> None:
"""
Create and configure subparsers for different commands using configuration.

Args:
parser (cli.Parser): The main parser to add subparsers to
parser: The main parser to add subparsers to
global_options_parser: Parser with global options to inherit

Returns:
None
Expand All @@ -59,11 +81,16 @@ def _create_subparsers(parser: cli.Parser) -> None:

for command_config in constants.COMMANDS:
cmd = subparsers.add_parser(
command_config.name, description=command_config.description
command_config.name,
description=command_config.description,
parents=[global_options_parser],
)

# Add command-specific arguments
for arg_name, arg_config in command_config.arguments.items():
# Skip --config as it comes from parent parser
if arg_name == "--config":
continue
if arg_name.startswith("--"):
cmd.add_argument(arg_name, **arg_config)
else:
Expand Down Expand Up @@ -143,8 +170,9 @@ def parse_args(args: Sequence) -> Tuple[Callable, Tuple[Any, ...], dict]:
TypeError: If the command handler is invalid
AttributeError: If the command doesn't exist
"""
parser = _create_main_parser()
_create_subparsers(parser)
global_options_parser = _create_global_options_parser()
parser = _create_main_parser(global_options_parser)
_create_subparsers(parser, global_options_parser)

parsed_args = parser.parse_args(args=args)

Expand Down