44
55# Import rich-click configuration before anything else
66from rich .console import Console
7- from rich .table import Table
87from rich .traceback import Traceback
98
109from mcpm import __version__
1716 edit ,
1817 info ,
1918 inspect ,
20- inspector ,
2119 list ,
2220 migrate ,
2321 profile ,
3735# Setup Rich logging early - this runs when the module is imported
3836setup_logging ()
3937
40- # Set -h as an alias for --help but we'll handle it ourselves
41- CONTEXT_SETTINGS = dict (help_option_names = [])
42-
43-
44- def create_deprecated_command (command_name : str , replacement_suggestions = None ):
45- """Create a deprecated command that shows v2.0 migration guidance."""
46- if replacement_suggestions is None :
47- replacement_suggestions = [
48- "mcpm install <server> # Install servers globally" ,
49- "mcpm profile add <profile> <server> # Tag servers with profiles" ,
50- "mcpm run <server> # Run servers directly" ,
51- ]
52-
53- @click .command (context_settings = dict (ignore_unknown_options = True , help_option_names = []))
54- @click .option ("--help" , "-h" , "help_requested" , is_flag = True , help = "Show deprecation message." )
55- @click .argument ("args" , nargs = - 1 , type = click .UNPROCESSED )
56- def deprecated_command (help_requested , args ):
57- f"""The '{ command_name } ' command has been removed in MCPM v2.0."""
58- console .print (f"[bold red]Error:[/] The 'mcpm { command_name } ' command has been removed in MCPM v2.0." )
59- console .print ("[yellow]Use the new global configuration model instead:[/]" )
60- console .print ()
61- console .print ("[cyan]New approach:[/]" )
62- for suggestion in replacement_suggestions :
63- console .print (f" [dim]{ suggestion } [/]" )
64- console .print ()
65- raise click .ClickException ("Command has been removed in v2.0" )
66-
67- # Set the name properly on the command
68- deprecated_command .name = command_name
69- return deprecated_command
38+ # Let rich-click handle help display
39+ CONTEXT_SETTINGS = dict (help_option_names = ["-h" , "--help" ])
7040
7141
7242def print_logo ():
73- # Create bold ASCII art with thicker characters for a more striking appearance
74- logo = [
75- " ███╗ ███╗ ██████╗██████╗ ███╗ ███╗ " ,
76- " ████╗ ████║██╔════╝██╔══██╗████╗ ████║ " ,
77- " ██╔████╔██║██║ ██████╔╝██╔████╔██║ " ,
78- " ██║╚██╔╝██║██║ ██╔═══╝ ██║╚██╔╝██║ " ,
79- " ██║ ╚═╝ ██║╚██████╗██║ ██║ ╚═╝ ██║ " ,
80- " ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ " ,
81- "" ,
82- f"v{ __version__ } " ,
83- "Open Source. Forever Free." ,
84- "Built with ❤️ by Path Integral Institute" ,
85- ]
86-
87- # Define terminal width for centering
88- terminal_width = 80 # Standard terminal width
89-
90- # Print separator line
91- console .print ("[bold cyan]" + "=" * terminal_width + "[/]" )
92-
93- # Calculate base padding for ASCII art
94- base_padding = " " * ((terminal_width - len (logo [0 ])) // 2 )
43+ """Print an elegant gradient logo with invisible Panel for width control"""
44+ from rich import box
45+ from rich .console import Group
46+ from rich .panel import Panel
47+ from rich .text import Text
48+ from rich_gradient import Gradient
49+
50+ # Clean ASCII art design - simplified with light shades
51+ logo_text = """
52+ ███░ ███░ ██████░ ██████░ ███░ ███░
53+ ████░ ████░ ██░░░░░░ ██░░░██░████░ ████░
54+ ██░████░██░ ██░ ██████░░██░████░██░
55+ ██░░██░░██░ ██░ ██░░░░░ ██░░██░░██░
56+ ██░ ░░░ ██░ ░██████░ ██░ ██░ ░░░ ██░
57+ ░░░ ░░░ ░░░░░░░ ░░░ ░░░ ░░░
9558
96- # Center the ASCII art (except last line)
97- for i in range (5 ): # First 5 lines of the ASCII art
98- console .print (f"{ base_padding } [bold green]{ logo [i ]} [/]" )
99-
100- # Print last line with version, using the same base padding
101- version_text = f"v{ __version__ } "
102- console .print (f"{ base_padding } [bold green]{ logo [5 ]} [/] [bold yellow]{ version_text } [/]" )
103-
104- # Center the taglines
105- tagline1 = logo [8 ] # "Open Source. Forever Free."
106- tagline2 = logo [9 ] # "Built with ❤️ by Path Integral Institute"
59+ """
10760
108- # Calculate center padding for each tagline
109- tagline1_padding = " " * ((terminal_width - len (tagline1 )) // 2 )
110- tagline2_padding = " " * ((terminal_width - len (tagline2 )) // 2 )
61+ # Purple-to-pink gradient palette
62+ primary_colors = ["#8F87F1" , "#C68EFD" , "#E9A5F1" , "#FED2E2" ]
63+ accent_colors = ["#3B82F6" , "#EF4444" ] # Blue to red
64+ warm_colors = ["#10B981" , "#F59E0B" ] # Green to orange
65+ tagline_colors = ["#06B6D4" , "#EF4444" ] # Cyan to red
66+
67+ # Create gradient using rich-gradient with narrow console for better gradient distribution
68+ temp_console = Console (width = 50 ) # Close to ASCII art width
69+ logo_gradient_obj = Gradient (logo_text , colors = primary_colors )
70+
71+ # Capture the rendered gradient
72+ with temp_console .capture () as capture :
73+ temp_console .print (logo_gradient_obj , justify = "center" )
74+ logo_gradient = Text .from_ansi (capture .get ())
75+
76+ # Create solid color text for title and tagline - harmonized with gradient
77+ title_text = Text ()
78+ title_text .append ("Model Context Protocol Manager" , style = "#8F87F1 bold" )
79+ title_text .append (" v" , style = "#C68EFD" )
80+ title_text .append (__version__ , style = "#E9A5F1 bold" )
81+
82+ tagline_text = Text ()
83+ tagline_text .append ("Open Source with " , style = "#FED2E2" )
84+ tagline_text .append ("♥" , style = "#E9A5F1" )
85+ tagline_text .append (" by Path Integral Institute" , style = "#FED2E2" )
86+
87+ # Create content group with proper spacing - all left aligned for consistency
88+ content = Group (
89+ "" , # Empty line at top
90+ logo_gradient ,
91+ "" ,
92+ title_text ,
93+ "" ,
94+ tagline_text ,
95+ "" , # Empty line at bottom
96+ )
11197
112- # Print centered taglines
113- console .print (tagline1_padding + "[bold magenta]" + tagline1 + "[/]" )
114- console .print (tagline2_padding + "[bold cyan]" + tagline2 + "[/]" )
98+ # Create invisible panel for width constraint only
99+ invisible_panel = Panel (
100+ content ,
101+ width = 120 ,
102+ box = box .SIMPLE , # Simple box style
103+ border_style = "dim" , # Very dim border
104+ padding = (0 , 1 ),
105+ )
115106
116- # Print separator line
117- console .print ("[bold cyan]" + "=" * terminal_width + "[/]" )
107+ console .print (invisible_panel )
118108
119109
120110def handle_exceptions (func ):
@@ -134,17 +124,20 @@ def wrapper(*args, **kwargs):
134124 return wrapper
135125
136126
137- @click .group (context_settings = CONTEXT_SETTINGS , invoke_without_command = True )
138- @click .option ("-h" , "--help" , "help_flag" , is_flag = True , help = "Show this message and exit." )
127+ @click .group (
128+ name = "mcpm" ,
129+ context_settings = CONTEXT_SETTINGS ,
130+ invoke_without_command = True ,
131+ help = """
132+ A simplified tool for managing MCP servers in a global configuration.
133+ Install servers, organize them with profiles, and run them directly.
134+ """ ,
135+ )
139136@click .option ("-v" , "--version" , is_flag = True , help = "Show version and exit." )
140137@click .pass_context
141138@handle_exceptions
142- def main (ctx , help_flag , version ):
143- """MCPM - Model Context Protocol Manager.
144-
145- A simplified tool for managing MCP servers in a global configuration.
146- Install servers, organize them with profiles, and run them directly.
147- """
139+ def main (ctx , version ):
140+ """Main entry point for MCPM CLI."""
148141 if version :
149142 print_logo ()
150143 return
@@ -162,84 +155,9 @@ def main(ctx, help_flag, version):
162155 # Continue to execute the subcommand
163156 # If "ignore", continue to subcommand without migration
164157
165- # v2.0 simplified model - no active target system
166- # If no command was invoked or help is requested, show our custom help
167- if ctx .invoked_subcommand is None or help_flag :
168- print_logo ()
169-
170- # Display usage info for new simplified model
171- console .print ("[bold green]Usage:[/] [white]mcpm [OPTIONS] COMMAND [ARGS]...[/]" )
172- console .print ("" )
173- console .print (
174- "[bold green]Description:[/] [white]Manage MCP servers in a global configuration with profile organization.[/]"
175- )
176- console .print ("" )
177-
178- # Show quick start examples
179- console .print ("[bold cyan]Quick Start:[/]" )
180- console .print (" [dim]mcpm search browser # Find available servers[/]" )
181- console .print (" [dim]mcpm install mcp-server-browse # Install a server[/]" )
182- console .print (" [dim]mcpm run mcp-server-browse # Run server directly[/]" )
183- console .print (" [dim]mcpm profile create web-dev # Create a profile[/]" )
184- console .print (" [dim]mcpm profile add web-dev mcp-server-browse # Tag server[/]" )
185- console .print ("" )
186-
187- # Display options
188- console .print ("[bold]Options:[/]" )
189- console .print (" --version Show the version and exit." )
190- console .print (" -h, --help Show this message and exit." )
191- console .print ("" )
192-
193- # Display available commands in a table
194- console .print ("[bold]Commands:[/]" )
195- commands_table = Table (show_header = False , box = None , padding = (0 , 2 , 0 , 0 ))
196-
197- commands_table .add_row ("[yellow]Server Management[/]" )
198- commands_table .add_row (" [cyan]search[/]" , "Search available MCP servers from registry." )
199- commands_table .add_row (" [cyan]info[/]" , "Show detailed registry information for a server." )
200- commands_table .add_row (" [cyan]install[/]" , "Install a server from registry, local file, or URL." )
201- commands_table .add_row (" [cyan]uninstall[/]" , "Remove a server from configuration." )
202- commands_table .add_row (" [cyan]ls[/]" , "List all installed servers and profile assignments." )
203- commands_table .add_row (" [cyan]edit[/]" , "Edit server configuration properties." )
204- commands_table .add_row (" [cyan]inspect[/]" , "Launch MCP Inspector to test/debug a server." )
205-
206- commands_table .add_row ("[yellow]Server Execution[/]" )
207- commands_table .add_row (" [cyan]run[/]" , "Execute a single server over stdio." )
208-
209- commands_table .add_row ("[yellow]Profile Management[/]" )
210- commands_table .add_row (" [cyan]profile[/]" , "Manage server profiles and tags." )
211-
212- commands_table .add_row ("[yellow]Server Sharing[/]" )
213- commands_table .add_row (" [cyan]share[/]" , "Share a single server through secure tunnel." )
214-
215- commands_table .add_row ("[yellow]System & Configuration[/]" )
216- commands_table .add_row (" [cyan]doctor[/]" , "Check system health and server status." )
217- commands_table .add_row (" [cyan]usage[/]" , "Display analytics and usage data." )
218- commands_table .add_row (" [cyan]config[/]" , "Manage MCPM configuration and settings." )
219-
220- commands_table .add_row ("[yellow]Client Management[/]" )
221- commands_table .add_row (" [cyan]client[/]" , "Manage MCP client configurations and import server configs." )
222-
223- commands_table .add_row ("[yellow]Legacy Aliases[/]" )
224- commands_table .add_row (" [cyan]add[/]" , "Alias for 'install'." )
225- commands_table .add_row (" [cyan]rm[/]" , "Alias for 'uninstall'." )
226- console .print (commands_table )
227-
228- # Additional helpful information
229- console .print ("" )
230- console .print ("[italic]Run [bold]mcpm COMMAND -h[/] for more information on a command.[/]" )
231- console .print ("" )
232-
233- # Add links for feedback and support
234- console .print ("[bold]Feedback and Support:[/]" )
235- console .print (
236- " [dim]🐛 Report a bug or request a feature: "
237- "[link=https://github.com/pathintegral-institute/mcpm.sh/issues]https://github.com/pathintegral-institute/mcpm.sh/issues[/link]"
238- )
239- console .print (
240- " [dim]💬 Join the discussion: "
241- "[link=https://github.com/pathintegral-institute/mcpm.sh/discussions]https://github.com/pathintegral-institute/mcpm.sh/discussions[/link]"
242- )
158+ # If no command was invoked, show help
159+ if ctx .invoked_subcommand is None :
160+ click .echo (ctx .get_help ())
243161
244162
245163# Register v2.0 commands
@@ -258,38 +176,9 @@ def main(ctx, help_flag, version):
258176main .add_command (migrate .migrate )
259177main .add_command (share )
260178
261- # Legacy command aliases that still work
262- main .add_command (add .add , name = "add" ) # Legacy alias for install
263- main .add_command (remove .remove , name = "rm" ) # Legacy alias for uninstall
264-
265- # Deprecated v1 commands - show migration guidance
266- main .add_command (create_deprecated_command ("stash" ), name = "stash" )
267- main .add_command (create_deprecated_command ("pop" ), name = "pop" )
268- main .add_command (
269- create_deprecated_command (
270- "mv" ,
271- [
272- "mcpm profile add <profile> <server> # Tag servers with profiles" ,
273- "mcpm profile remove <profile> <server> # Remove tags from servers" ,
274- ],
275- ),
276- name = "mv" ,
277- )
278- main .add_command (
279- create_deprecated_command (
280- "cp" ,
281- [
282- "mcpm profile add <profile> <server> # Tag servers with profiles" ,
283- "mcpm profile remove <profile> <server> # Remove tags from servers" ,
284- ],
285- ),
286- name = "cp" ,
287- )
288- main .add_command (create_deprecated_command ("target" ), name = "target" )
289179
290180# Keep these for now but they could be simplified later
291181main .add_command (client .client )
292- main .add_command (inspector .inspector , name = "inspector" )
293182
294183if __name__ == "__main__" :
295184 main ()
0 commit comments