1- """ 
2- Install command for adding MCP servers to the global configuration 
3- """ 
1+ """Install command for adding MCP servers to the global configuration""" 
42
53import  json 
4+ import  logging 
65import  os 
76import  re 
87from  enum  import  Enum 
8+ from  typing  import  Optional 
99
1010from  prompt_toolkit  import  PromptSession 
1111from  prompt_toolkit .formatted_text  import  HTML 
2424from  mcpm .utils .rich_click_config  import  click 
2525
2626console  =  Console ()
27+ logger  =  logging .getLogger (__name__ )
2728repo_manager  =  RepositoryManager ()
2829profile_config_manager  =  ProfileConfigManager ()
2930global_config_manager  =  GlobalConfigManager ()
3031
31- # Create a prompt session with custom styling 
32- prompt_session  =  PromptSession ()
32+ # Create a prompt session with custom styling (lazy to support headless Windows runs) 
33+ prompt_session : Optional [PromptSession ] =  None 
34+ _prompt_session_error : Optional [Exception ] =  None 
35+ 
36+ 
37+ def  _get_prompt_session () ->  Optional [PromptSession ]:
38+     """Lazily create a PromptSession, tolerating environments without a console.""" 
39+ 
40+     global  prompt_session , _prompt_session_error   # noqa: PLW0603 - shared module state 
41+ 
42+     if  prompt_session  is  not   None :
43+         return  prompt_session 
44+ 
45+     if  _prompt_session_error  is  not   None :
46+         return  None 
47+ 
48+     try :
49+         prompt_session  =  PromptSession ()
50+     except  Exception  as  exc :  # prompt_toolkit raises NoConsoleScreenBufferError on Windows 
51+         _prompt_session_error  =  exc 
52+         logger .debug ("Falling back to basic input prompts: %s" , exc )
53+         prompt_session  =  None 
54+ 
55+     return  prompt_session 
56+ 
3357style  =  Style .from_dict (
3458    {
3559        "prompt" : "ansicyan bold" ,
@@ -88,14 +112,24 @@ def prompt_with_default(prompt_text, default="", hide_input=False, required=Fals
88112    #     console.print(f"Default: [yellow]{default}[/]") 
89113
90114    # Get user input 
115+     session  =  _get_prompt_session ()
116+ 
91117    try :
92-         result  =  prompt_session .prompt (
93-             message = HTML (f"<prompt>{ prompt_text }  </prompt> > " ),
94-             style = style ,
95-             default = default ,
96-             is_password = hide_input ,
97-             key_bindings = kb ,
98-         )
118+         if  session  is  not   None :
119+             result  =  session .prompt (
120+                 message = HTML (f"<prompt>{ prompt_text }  </prompt> > " ),
121+                 style = style ,
122+                 default = default ,
123+                 is_password = hide_input ,
124+                 key_bindings = kb ,
125+             )
126+         else :
127+             # Basic fallback for environments without an interactive console (e.g., headless Windows) 
128+             prompt_parts  =  [prompt_text ]
129+             if  default :
130+                 prompt_parts .append (f"[{ default }  ]" )
131+             prompt_display  =  " " .join (prompt_parts ) +  " > " 
132+             result  =  input (prompt_display )  # noqa: PLW1513 - suppressed by KeyboardInterrupt handling 
99133
100134        # Empty result for non-required field means leave it empty 
101135        if  not  result .strip () and  not  required :
@@ -111,7 +145,7 @@ def prompt_with_default(prompt_text, default="", hide_input=False, required=Fals
111145            return  prompt_with_default (prompt_text , default , hide_input , required )
112146
113147        return  result 
114-     except  KeyboardInterrupt :
148+     except  ( KeyboardInterrupt ,  EOFError ) :
115149        raise  click .Abort ()
116150
117151
0 commit comments