Skip to content

Commit 7df305d

Browse files
author
LittleCoinCoin
committed
feat: implement ALL host-specific CLI arguments with new reporting
- Remove incorrect pre-validation logic that rejected host-specific arguments - Add ALL missing CLI arguments: * --http-url (Gemini HTTP streaming endpoint) * --include-tools (Gemini tool allowlist) * --exclude-tools (Gemini tool blocklist) * --inputs (VS Code input variable definitions) - Implement parse_inputs() helper for VS Code inputs parsing - Update handle_mcp_configure() signature with all new parameters - Update argument parser with all host-specific arguments - Update function call in main() to pass all new parameters - Replace validation tests with UNSUPPORTED reporting tests - All 260 MCP tests passing (100% success rate) Design principle: Accept all host-specific arguments for all hosts. The reporting system shows unsupported fields as 'UNSUPPORTED' in conversion reports rather than rejecting them upfront with errors. Example: hatch mcp configure demo --host vscode --command python --timeout 30000 Output: name: UPDATED None --> 'demo' command: UPDATED None --> 'python' timeout: UNSUPPORTED (not supported by vscode)
1 parent 668d382 commit 7df305d

File tree

4 files changed

+383
-343
lines changed

4 files changed

+383
-343
lines changed

hatch/cli_hatch.py

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -582,13 +582,53 @@ def parse_headers(headers_list: Optional[list]) -> dict:
582582

583583
return headers_dict
584584

585+
def parse_inputs(inputs_list: Optional[list]) -> Optional[list]:
586+
"""Parse VS Code input variable definitions from command line format.
587+
588+
Format: type,id,description[,password=true]
589+
Example: promptString,api-key,GitHub Personal Access Token,password=true
590+
591+
Returns:
592+
List of input variable definition dictionaries, or None if no inputs provided.
593+
"""
594+
if not inputs_list:
595+
return None
596+
597+
parsed_inputs = []
598+
for input_str in inputs_list:
599+
parts = [p.strip() for p in input_str.split(',')]
600+
if len(parts) < 3:
601+
print(f"Warning: Invalid input format '{input_str}'. Expected: type,id,description[,password=true]")
602+
continue
603+
604+
input_def = {
605+
'type': parts[0],
606+
'id': parts[1],
607+
'description': parts[2]
608+
}
609+
610+
# Check for optional password flag
611+
if len(parts) > 3 and parts[3].lower() == 'password=true':
612+
input_def['password'] = True
613+
614+
parsed_inputs.append(input_def)
615+
616+
return parsed_inputs if parsed_inputs else None
617+
585618
def handle_mcp_configure(host: str, server_name: str, command: str, args: list,
586619
env: Optional[list] = None, url: Optional[str] = None,
587620
headers: Optional[list] = None, timeout: Optional[int] = None,
588621
trust: bool = False, cwd: Optional[str] = None,
589-
env_file: Optional[str] = None, no_backup: bool = False,
622+
env_file: Optional[str] = None, http_url: Optional[str] = None,
623+
include_tools: Optional[list] = None, exclude_tools: Optional[list] = None,
624+
inputs: Optional[list] = None, no_backup: bool = False,
590625
dry_run: bool = False, auto_approve: bool = False):
591-
"""Handle 'hatch mcp configure' command with host-specific arguments."""
626+
"""Handle 'hatch mcp configure' command with ALL host-specific arguments.
627+
628+
Host-specific arguments are accepted for all hosts. The reporting system will
629+
show unsupported fields as "UNSUPPORTED" in the conversion report rather than
630+
rejecting them upfront.
631+
"""
592632
try:
593633
# Validate host type
594634
try:
@@ -606,26 +646,14 @@ def handle_mcp_configure(host: str, server_name: str, command: str, args: list,
606646
print("Error: --args can only be used with --command (local servers), not with --url (remote servers)")
607647
return 1
608648

609-
# Validate host-specific arguments
610-
if timeout is not None and host_type != MCPHostType.GEMINI:
611-
print(f"Error: --timeout is only supported for Gemini host, not '{host}'")
612-
return 1
613-
614-
if trust and host_type != MCPHostType.GEMINI:
615-
print(f"Error: --trust is only supported for Gemini host, not '{host}'")
616-
return 1
617-
618-
if cwd is not None and host_type != MCPHostType.GEMINI:
619-
print(f"Error: --cwd is only supported for Gemini host, not '{host}'")
620-
return 1
649+
# NOTE: We do NOT validate host-specific arguments here.
650+
# The reporting system will show unsupported fields as "UNSUPPORTED" in the conversion report.
651+
# This allows users to see which fields are not supported by their target host without blocking the operation.
621652

622-
if env_file is not None and host_type not in (MCPHostType.CURSOR, MCPHostType.VSCODE, MCPHostType.LMSTUDIO):
623-
print(f"Error: --env-file is only supported for Cursor, VS Code, and LM Studio hosts, not '{host}'")
624-
return 1
625-
626-
# Parse environment variables and headers
653+
# Parse environment variables, headers, and inputs
627654
env_dict = parse_env_vars(env)
628655
headers_dict = parse_headers(headers)
656+
inputs_list = parse_inputs(inputs)
629657

630658
# Create Omni configuration (universal model)
631659
# Only include fields that have actual values to ensure model_dump(exclude_unset=True) works correctly
@@ -642,16 +670,28 @@ def handle_mcp_configure(host: str, server_name: str, command: str, args: list,
642670
if url and headers_dict:
643671
omni_config_data['headers'] = headers_dict
644672

645-
# Host-specific fields
673+
# Host-specific fields (Gemini)
646674
if timeout is not None:
647675
omni_config_data['timeout'] = timeout
648676
if trust:
649677
omni_config_data['trust'] = trust
650678
if cwd is not None:
651679
omni_config_data['cwd'] = cwd
680+
if http_url is not None:
681+
omni_config_data['httpUrl'] = http_url
682+
if include_tools is not None:
683+
omni_config_data['includeTools'] = include_tools
684+
if exclude_tools is not None:
685+
omni_config_data['excludeTools'] = exclude_tools
686+
687+
# Host-specific fields (Cursor/VS Code/LM Studio)
652688
if env_file is not None:
653689
omni_config_data['envFile'] = env_file
654690

691+
# Host-specific fields (VS Code)
692+
if inputs_list is not None:
693+
omni_config_data['inputs'] = inputs_list
694+
655695
# Create Omni model
656696
omni_config = MCPServerConfigOmni(**omni_config_data)
657697

@@ -1174,11 +1214,19 @@ def main():
11741214
mcp_configure_parser.add_argument("--env-var", action="append", help="Environment variables (format: KEY=VALUE)")
11751215
mcp_configure_parser.add_argument("--headers", action="append", help="HTTP headers for remote servers (format: KEY=VALUE, only with --url)")
11761216

1177-
# Host-specific arguments
1178-
mcp_configure_parser.add_argument("--timeout", type=int, help="Request timeout in milliseconds (Gemini only)")
1179-
mcp_configure_parser.add_argument("--trust", action="store_true", help="Bypass tool call confirmations (Gemini only)")
1180-
mcp_configure_parser.add_argument("--cwd", help="Working directory for stdio transport (Gemini only)")
1181-
mcp_configure_parser.add_argument("--env-file", help="Path to environment file (Cursor, VS Code only)")
1217+
# Host-specific arguments (Gemini)
1218+
mcp_configure_parser.add_argument("--timeout", type=int, help="Request timeout in milliseconds (Gemini)")
1219+
mcp_configure_parser.add_argument("--trust", action="store_true", help="Bypass tool call confirmations (Gemini)")
1220+
mcp_configure_parser.add_argument("--cwd", help="Working directory for stdio transport (Gemini)")
1221+
mcp_configure_parser.add_argument("--http-url", help="HTTP streaming endpoint URL (Gemini)")
1222+
mcp_configure_parser.add_argument("--include-tools", nargs="*", help="Tool allowlist - only these tools will be available (Gemini)")
1223+
mcp_configure_parser.add_argument("--exclude-tools", nargs="*", help="Tool blocklist - these tools will be excluded (Gemini)")
1224+
1225+
# Host-specific arguments (Cursor/VS Code/LM Studio)
1226+
mcp_configure_parser.add_argument("--env-file", help="Path to environment file (Cursor, VS Code, LM Studio)")
1227+
1228+
# Host-specific arguments (VS Code)
1229+
mcp_configure_parser.add_argument("--inputs", action="append", help="Input variable definitions in format: type,id,description[,password=true] (VS Code)")
11821230

11831231
mcp_configure_parser.add_argument("--no-backup", action="store_true", help="Skip backup creation before configuration")
11841232
mcp_configure_parser.add_argument("--dry-run", action="store_true", help="Preview configuration without execution")
@@ -1977,6 +2025,8 @@ def main():
19772025
getattr(args, 'env_var', None), args.url, args.headers,
19782026
getattr(args, 'timeout', None), getattr(args, 'trust', False),
19792027
getattr(args, 'cwd', None), getattr(args, 'env_file', None),
2028+
getattr(args, 'http_url', None), getattr(args, 'include_tools', None),
2029+
getattr(args, 'exclude_tools', None), getattr(args, 'inputs', None),
19802030
args.no_backup, args.dry_run, args.auto_approve
19812031
)
19822032

0 commit comments

Comments
 (0)