Skip to content

Commit c99e80d

Browse files
committed
add mcp inspector
1 parent 62aa171 commit c99e80d

File tree

3 files changed

+236
-8
lines changed

3 files changed

+236
-8
lines changed

pages/index.html

Lines changed: 99 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,45 @@
132132
font-size: 1.5rem;
133133
}
134134

135+
.code-block {
136+
position: relative;
137+
margin: 1rem 0;
138+
}
139+
135140
code {
136141
background-color: var(--code-bg);
137142
padding: 0.75rem 1rem;
138143
border-radius: 8px;
139144
font-family: 'Fira Code', monospace;
140145
display: block;
141-
margin: 1rem 0;
142146
overflow-x: auto;
143147
border-left: 3px solid var(--accent-color);
148+
padding-right: 40px; /* Space for the copy button */
149+
}
150+
151+
.copy-button {
152+
position: absolute;
153+
top: 50%;
154+
right: 10px;
155+
transform: translateY(-50%);
156+
background-color: var(--accent-dark);
157+
color: var(--text-primary);
158+
border: none;
159+
border-radius: 4px;
160+
padding: 4px 8px;
161+
font-size: 0.8rem;
162+
cursor: pointer;
163+
opacity: 0.7;
164+
transition: opacity 0.2s, background-color 0.2s;
165+
}
166+
167+
.copy-button:hover {
168+
opacity: 1;
169+
background-color: var(--accent-color);
170+
}
171+
172+
.copy-success {
173+
background-color: var(--success) !important;
144174
}
145175

146176
.clients {
@@ -218,7 +248,10 @@ <h1>MCP</h1>
218248
<div class="coming-soon">
219249
<h2>🚀 Quick Installation</h2>
220250
<p>Install MCP with a single command:</p>
221-
<code><span class="command-prompt">$</span> curl -sSL https://getmcp.sh/install | bash</code>
251+
<div class="code-block">
252+
<code><span class="command-prompt">$</span> curl -sSL https://getmcp.sh/install | bash</code>
253+
<button class="copy-button" data-command="curl -sSL https://getmcp.sh/install | bash">Copy</button>
254+
</div>
222255
<p>MCP Manager is a Homebrew-like service for managing Model Context Protocol (MCP) servers across clients.</p>
223256
</div>
224257

@@ -228,25 +261,37 @@ <h2>Available Features</h2>
228261
<div class="feature">
229262
<h3><span>👥</span> Client Management</h3>
230263
<p>Easily switch between and manage MCP clients:</p>
231-
<code><span class="command-prompt">$</span> mcp client claude-desktop</code>
264+
<div class="code-block">
265+
<code><span class="command-prompt">$</span> mcp client claude-desktop</code>
266+
<button class="copy-button" data-command="mcp client claude-desktop">Copy</button>
267+
</div>
232268
</div>
233269

234270
<div class="feature">
235271
<h3><span>📋</span> Server Listing</h3>
236272
<p>View all your installed MCP servers:</p>
237-
<code><span class="command-prompt">$</span> mcp list</code>
273+
<div class="code-block">
274+
<code><span class="command-prompt">$</span> mcp list</code>
275+
<button class="copy-button" data-command="mcp list">Copy</button>
276+
</div>
238277
</div>
239278

240279
<div class="feature">
241280
<h3><span>⚙️</span> Server Management</h3>
242281
<p>Control your MCP server processes with ease:</p>
243-
<code><span class="command-prompt">$</span> mcp server start my-server</code>
282+
<div class="code-block">
283+
<code><span class="command-prompt">$</span> mcp server start my-server</code>
284+
<button class="copy-button" data-command="mcp server start my-server">Copy</button>
285+
</div>
244286
</div>
245287

246288
<div class="feature">
247289
<h3><span>🔀</span> Server Toggling</h3>
248290
<p>Enable or disable servers for specific clients:</p>
249-
<code><span class="command-prompt">$</span> mcp toggle my-server</code>
291+
<div class="code-block">
292+
<code><span class="command-prompt">$</span> mcp toggle my-server</code>
293+
<button class="copy-button" data-command="mcp toggle my-server">Copy</button>
294+
</div>
250295
</div>
251296
</div>
252297

@@ -255,13 +300,19 @@ <h2>Coming Soon</h2>
255300
<div class="feature">
256301
<h3><span>🧩</span> Simple Server Installation</h3>
257302
<p>Install MCP servers with a single command:</p>
258-
<code><span class="command-prompt">$</span> mcp install claude-config</code>
303+
<div class="code-block">
304+
<code><span class="command-prompt">$</span> mcp install claude-config</code>
305+
<button class="copy-button" data-command="mcp install claude-config">Copy</button>
306+
</div>
259307
</div>
260308

261309
<div class="feature">
262310
<h3><span>🔍</span> Server Discovery</h3>
263311
<p>Find available Model Context Protocol servers:</p>
264-
<code><span class="command-prompt">$</span> mcp search</code>
312+
<div class="code-block">
313+
<code><span class="command-prompt">$</span> mcp search</code>
314+
<button class="copy-button" data-command="mcp search">Copy</button>
315+
</div>
265316
</div>
266317
</div>
267318

@@ -280,5 +331,45 @@ <h2>Supported Clients</h2>
280331
<p>© 2025 MCP Manager | <a href="https://github.com/pathintegral-xyz/getmcp.sh">GitHub</a></p>
281332
</footer>
282333
</div>
334+
335+
<script>
336+
document.addEventListener('DOMContentLoaded', function() {
337+
// Add click event listeners to all copy buttons
338+
const copyButtons = document.querySelectorAll('.copy-button');
339+
340+
copyButtons.forEach(button => {
341+
button.addEventListener('click', function() {
342+
// Get the command to copy from the data attribute
343+
const command = this.getAttribute('data-command');
344+
345+
// Create a temporary textarea element to copy from
346+
const textarea = document.createElement('textarea');
347+
textarea.value = command;
348+
textarea.setAttribute('readonly', '');
349+
textarea.style.position = 'absolute';
350+
textarea.style.left = '-9999px';
351+
document.body.appendChild(textarea);
352+
353+
// Select and copy the text
354+
textarea.select();
355+
document.execCommand('copy');
356+
357+
// Remove the temporary textarea
358+
document.body.removeChild(textarea);
359+
360+
// Visual feedback that copy was successful
361+
const originalText = this.textContent;
362+
this.textContent = 'Copied!';
363+
this.classList.add('copy-success');
364+
365+
// Reset button after a delay
366+
setTimeout(() => {
367+
this.textContent = originalText;
368+
this.classList.remove('copy-success');
369+
}, 2000);
370+
});
371+
});
372+
});
373+
</script>
283374
</body>
284375
</html>

src/mcp/cli.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
toggle,
2020
server,
2121
client,
22+
inspector,
2223
)
2324

2425
console = Console()
@@ -105,6 +106,7 @@ def main(ctx, help_flag):
105106
commands_table = Table(show_header=False, box=None, padding=(0, 2, 0, 0))
106107
commands_table.add_row(" [cyan]client[/]", "Manage the active MCP client.")
107108
commands_table.add_row(" [cyan]edit[/]", "View or edit the active MCP client's configuration file.")
109+
commands_table.add_row(" [cyan]inspector[/]", "Launch the MCP Inspector UI to examine servers.")
108110
commands_table.add_row(" [cyan]list[/]", "List all installed MCP servers.")
109111
commands_table.add_row(" [cyan]remove[/]", "Remove an installed MCP server.")
110112
commands_table.add_row(" [cyan]server[/]", "Manage MCP server processes.")
@@ -134,6 +136,7 @@ def main(ctx, help_flag):
134136
main.add_command(toggle.toggle)
135137
main.add_command(server.server)
136138
main.add_command(client.client)
139+
main.add_command(inspector.inspector, name="inspector")
137140

138141
if __name__ == "__main__":
139142
main()

src/mcp/commands/inspector.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
"""
2+
MCP Inspector command for examining MCP servers through a user interface
3+
"""
4+
5+
import click
6+
import os
7+
import subprocess
8+
import shlex
9+
import sys
10+
from rich.console import Console
11+
from rich.panel import Panel
12+
13+
console = Console()
14+
15+
# Define context settings to handle help flag properly
16+
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
17+
18+
@click.command(context_settings=CONTEXT_SETTINGS)
19+
@click.argument("args", nargs=-1)
20+
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation prompt")
21+
@click.help_option("-h", "--help")
22+
def inspector(args, yes):
23+
"""Launch the MCP Inspector UI to examine servers.
24+
25+
EXAMPLES:
26+
27+
Launch the Inspector UI with no arguments:
28+
mcp inspector
29+
30+
Launch the Inspector with custom arguments:
31+
mcp inspector npx my-server --port 3000
32+
33+
Use with NPM packages:
34+
mcp inspector npx server-postgres
35+
36+
Use with Python packages:
37+
mcp inspector uvx mcp-server-git
38+
"""
39+
# Show header
40+
console.print(Panel.fit(
41+
"[bold green]MCP Inspector[/]\n"
42+
"Model Context Protocol Inspection Tool",
43+
border_style="cyan"
44+
))
45+
46+
try:
47+
# Construct command from args
48+
if args:
49+
# Pass all arguments directly to the inspector
50+
arg_string = " ".join(args)
51+
cmd = f"npx @modelcontextprotocol/inspector {arg_string}"
52+
console.print(f"[bold]Running MCP Inspector with arguments:[/] {arg_string}")
53+
else:
54+
# No arguments provided, prompt for confirmation
55+
if not yes:
56+
click.echo("\nStarting MCP Inspector with no arguments.")
57+
click.echo("This will launch the Inspector UI without a target server.")
58+
if not click.confirm("Continue?", default=True):
59+
console.print("[yellow]Inspector cancelled.[/]")
60+
return
61+
62+
cmd = "npx @modelcontextprotocol/inspector"
63+
64+
console.print("[cyan]Starting MCP Inspector...[/]")
65+
console.print("The Inspector UI will open in your web browser.")
66+
console.print("[yellow]Press Ctrl+C to stop the Inspector.[/]")
67+
68+
# Split the command into components for subprocess, properly handling quoted arguments
69+
cmd_parts = shlex.split(cmd)
70+
71+
try:
72+
# Execute the command
73+
console.print(f"[dim]Executing: {cmd}[/]")
74+
75+
# Create environment with NODE_PATH if needed
76+
env = os.environ.copy()
77+
78+
try:
79+
# Use subprocess.call for direct terminal I/O
80+
# This is the simplest way to execute a command with inherited stdio
81+
console.print("[bold green]Starting MCP Inspector...[/]")
82+
console.print("[cyan]Press Ctrl+C to exit[/]")
83+
sys.stdout.flush()
84+
85+
# Execute the command with direct terminal access
86+
# The Python process will wait here until the command completes
87+
returncode = subprocess.call(cmd_parts, env=env)
88+
89+
except KeyboardInterrupt:
90+
# When using subprocess.call, the KeyboardInterrupt is automatically
91+
# forwarded to the child process, so we just need to acknowledge it
92+
console.print("\n[bold yellow]Inspector process terminated by keyboard interrupt.[/]")
93+
returncode = 130 # Standard exit code for SIGINT
94+
95+
# Check exit code
96+
if returncode == 0:
97+
console.print("[bold green]Inspector process completed successfully.[/]")
98+
elif returncode in (130, -2): # Exit codes for keyboard interrupt
99+
console.print("[bold yellow]Inspector process was terminated.[/]")
100+
else:
101+
console.print(f"[bold red]Inspector process exited with code {returncode}[/]")
102+
103+
except FileNotFoundError:
104+
console.print("[bold red]Error:[/] Could not find npx. Please make sure Node.js is installed.")
105+
console.print("Install Node.js from https://nodejs.org/")
106+
except PermissionError:
107+
console.print("[bold red]Error:[/] Permission denied while trying to execute the command.")
108+
109+
except Exception as e:
110+
console.print(f"[bold red]Error launching Inspector:[/] {str(e)}")
111+
112+
113+
def show_inspector_help():
114+
"""Display detailed help for the inspector."""
115+
console.print(Panel.fit(
116+
"[bold]MCP Inspector[/]\n\n"
117+
"The Inspector is a web UI tool that allows you to:\n"
118+
"- View server connections\n"
119+
"- Explore resources provided by the server\n"
120+
"- Test prompts with custom arguments\n"
121+
"- Execute tools with custom inputs\n"
122+
"- View server logs and notifications",
123+
title="MCP Inspector Help",
124+
border_style="cyan"
125+
))
126+
127+
console.print("\n[bold]Documentation:[/] https://modelcontextprotocol.io/docs/tools/inspector")
128+
console.print("[bold]Usage examples:[/]\n")
129+
console.print(" [cyan]mcp inspector filesystem[/]")
130+
console.print(" Launch Inspector for an installed server")
131+
console.print("\n [cyan]mcp inspector --package server-postgres --package-args \"postgres://127.0.0.1/testdb\"[/]")
132+
console.print(" Inspect an NPM package with arguments")
133+
console.print("\n [cyan]mcp inspector --python --package mcp-server-git[/]")
134+
console.print(" Inspect a PyPI package")

0 commit comments

Comments
 (0)