Skip to content

Commit be7fa9b

Browse files
changes:
- change button names - adding unit test cases - updated landing page image - updating README file as discussed here: #334 (comment)
1 parent e8e2dd0 commit be7fa9b

File tree

4 files changed

+294
-52
lines changed

4 files changed

+294
-52
lines changed

README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,74 @@ CLIENT_PORT=8080 SERVER_PORT=9000 npx @modelcontextprotocol/inspector node build
4242

4343
For more details on ways to use the inspector, see the [Inspector section of the MCP docs site](https://modelcontextprotocol.io/docs/tools/inspector). For help with debugging, see the [Debugging guide](https://modelcontextprotocol.io/docs/tools/debugging).
4444

45+
### Configuration Export
46+
47+
The MCP Inspector provides convenient buttons to export your server configuration:
48+
49+
- **Server Entry** - Copies a single server configuration entry to your clipboard. This can be added to your `mcp.json` file inside the `mcpServers` object with your preferred server name.
50+
51+
**STDIO transport example:**
52+
53+
```json
54+
{
55+
"command": "node",
56+
"args": ["build/index.js", "--debug"],
57+
"env": {
58+
"API_KEY": "your-api-key",
59+
"DEBUG": "true"
60+
}
61+
}
62+
```
63+
64+
**SSE transport example:**
65+
66+
```json
67+
{
68+
"type": "sse",
69+
"url": "http://localhost:3000/events",
70+
"note": "For SSE connections, add this URL directly in Client"
71+
}
72+
```
73+
74+
- **Servers File** - Copies a complete MCP configuration file structure to your clipboard, with your current server configuration added as `default-server`. This can be saved directly as `mcp.json`.
75+
76+
**STDIO transport example:**
77+
78+
```json
79+
{
80+
"mcpServers": {
81+
"default-server": {
82+
"command": "node",
83+
"args": ["build/index.js", "--debug"],
84+
"env": {
85+
"API_KEY": "your-api-key",
86+
"DEBUG": "true"
87+
}
88+
}
89+
}
90+
}
91+
```
92+
93+
**SSE transport example:**
94+
95+
```json
96+
{
97+
"mcpServers": {
98+
"default-server": {
99+
"type": "sse",
100+
"url": "http://localhost:3000/events",
101+
"note": "For SSE connections, add this URL directly in Client"
102+
}
103+
}
104+
}
105+
```
106+
107+
These buttons appear in the Inspector UI after you've configured your server settings, making it easy to save and reuse your configurations.
108+
109+
For SSE transport connections, the Inspector provides similar functionality for both buttons. The "Server Entry" button copies the SSE URL configuration that can be added to your existing configuration file, while the "Servers File" button creates a complete configuration file containing the SSE URL for direct use in clients.
110+
111+
You can paste the Server Entry into your existing `mcp.json` file under your chosen server name, or use the complete Servers File payload to create a new configuration file.
112+
45113
### Authentication
46114

47115
The inspector supports bearer token authentication for SSE connections. Enter your token in the UI when connecting to an MCP server, and it will be sent in the Authorization header. You can override the header name using the input field in the sidebar.
@@ -93,6 +161,8 @@ Example server configuration file:
93161
}
94162
```
95163

164+
> **Tip:** You can easily generate this configuration format using the **Server Entry** and **Servers File** buttons in the Inspector UI, as described in the Configuration Export section above.
165+
96166
### From this repository
97167

98168
If you're working on the inspector itself:

client/src/components/Sidebar.tsx

Lines changed: 68 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ const Sidebar = ({
9898
const [showBearerToken, setShowBearerToken] = useState(false);
9999
const [showConfig, setShowConfig] = useState(false);
100100
const [shownEnvVars, setShownEnvVars] = useState<Set<string>>(new Set());
101-
const [copiedConfigEntry, setCopiedConfigEntry] = useState(false);
102-
const [copiedConfigFile, setCopiedConfigFile] = useState(false);
101+
const [copiedServerEntry, setCopiedServerEntry] = useState(false);
102+
const [copiedServerFile, setCopiedServerFile] = useState(false);
103103
const { toast } = useToast();
104104

105105
// Shared utility function to generate server config
@@ -108,84 +108,105 @@ const Sidebar = ({
108108
return {
109109
command,
110110
args: args.trim() ? args.split(/\s+/) : [],
111-
env: { ...env }
111+
env: { ...env },
112112
};
113113
} else {
114114
return {
115115
type: "sse",
116116
url: sseUrl,
117-
note: "For SSE connections, add this URL directly in Client"
117+
note: "For SSE connections, add this URL directly in Client",
118118
};
119119
}
120120
}, [transportType, command, args, env, sseUrl]);
121121

122122
// Memoized config entry generator
123-
const generateMCPConfigEntry = useCallback(() => {
123+
const generateMCPServerEntry = useCallback(() => {
124124
return JSON.stringify(generateServerConfig(), null, 2);
125125
}, [generateServerConfig]);
126126

127127
// Memoized config file generator
128-
const generateMCPConfigFile = useCallback(() => {
128+
const generateMCPServerFile = useCallback(() => {
129129
return JSON.stringify(
130130
{
131131
mcpServers: {
132-
"default-server": generateServerConfig()
133-
}
132+
"default-server": generateServerConfig(),
133+
},
134134
},
135135
null,
136-
2
136+
2,
137137
);
138138
}, [generateServerConfig]);
139139

140140
// Memoized copy handlers
141-
const handleCopyConfigEntry = useCallback(() => {
141+
const handleCopyServerEntry = useCallback(() => {
142142
try {
143-
const configJson = generateMCPConfigEntry();
144-
navigator.clipboard.writeText(configJson);
145-
setCopiedConfigEntry(true);
143+
const configJson = generateMCPServerEntry();
144+
navigator.clipboard
145+
.writeText(configJson)
146+
.then(() => {
147+
setCopiedServerEntry(true);
146148

147-
toast({
148-
title: "Config entry copied",
149-
description:
150-
transportType === "stdio"
151-
? "Server configuration has been copied to clipboard. Add this to your mcp.json inside the 'mcpServers' object with your preferred server name."
152-
: "SSE URL has been copied. Use this URL in Cursor directly.",
153-
});
149+
toast({
150+
title: "Config entry copied",
151+
description:
152+
transportType === "stdio"
153+
? "Server configuration has been copied to clipboard. Add this to your mcp.json inside the 'mcpServers' object with your preferred server name."
154+
: "SSE URL has been copied. Use this URL in Cursor directly.",
155+
});
154156

155-
setTimeout(() => {
156-
setCopiedConfigEntry(false);
157-
}, 2000);
157+
setTimeout(() => {
158+
setCopiedServerEntry(false);
159+
}, 2000);
160+
})
161+
.catch((error) => {
162+
toast({
163+
title: "Error",
164+
description: `Failed to copy config: ${error instanceof Error ? error.message : String(error)}`,
165+
variant: "destructive",
166+
});
167+
});
158168
} catch (error) {
159169
toast({
160170
title: "Error",
161171
description: `Failed to copy config: ${error instanceof Error ? error.message : String(error)}`,
162172
variant: "destructive",
163173
});
164174
}
165-
}, [generateMCPConfigEntry, transportType, toast]);
175+
}, [generateMCPServerEntry, transportType, toast]);
166176

167-
const handleCopyConfigFile = useCallback(() => {
177+
const handleCopyServerFile = useCallback(() => {
168178
try {
169-
const configJson = generateMCPConfigFile();
170-
navigator.clipboard.writeText(configJson);
171-
setCopiedConfigFile(true);
179+
const configJson = generateMCPServerFile();
180+
navigator.clipboard
181+
.writeText(configJson)
182+
.then(() => {
183+
setCopiedServerFile(true);
172184

173-
toast({
174-
title: "Config file copied",
175-
description: "Server configuration has been copied to clipboard. Add this to your mcp.json file. Current testing server will be added as 'default-server'",
176-
});
185+
toast({
186+
title: "Servers file copied",
187+
description:
188+
"Servers configuration has been copied to clipboard. Add this to your mcp.json file. Current testing server will be added as 'default-server'",
189+
});
177190

178-
setTimeout(() => {
179-
setCopiedConfigFile(false);
180-
}, 2000);
191+
setTimeout(() => {
192+
setCopiedServerFile(false);
193+
}, 2000);
194+
})
195+
.catch((error) => {
196+
toast({
197+
title: "Error",
198+
description: `Failed to copy config: ${error instanceof Error ? error.message : String(error)}`,
199+
variant: "destructive",
200+
});
201+
});
181202
} catch (error) {
182203
toast({
183204
title: "Error",
184205
description: `Failed to copy config: ${error instanceof Error ? error.message : String(error)}`,
185206
variant: "destructive",
186207
});
187208
}
188-
}, [generateMCPConfigFile, toast]);
209+
}, [generateMCPServerFile, toast]);
189210

190211
return (
191212
<div className="w-80 bg-card border-r border-border flex flex-col h-full">
@@ -252,46 +273,41 @@ const Sidebar = ({
252273
/>
253274
</div>
254275
<div className="grid grid-cols-2 gap-2 mt-2">
255-
256276
<Tooltip>
257277
<TooltipTrigger asChild>
258278
<Button
259279
variant="outline"
260280
size="sm"
261-
onClick={handleCopyConfigEntry}
281+
onClick={handleCopyServerEntry}
262282
className="w-full"
263283
>
264-
{copiedConfigEntry ? (
284+
{copiedServerEntry ? (
265285
<CheckCheck className="h-4 w-4 mr-2" />
266286
) : (
267287
<Copy className="h-4 w-4 mr-2" />
268288
)}
269-
Config Entry
289+
Server Entry
270290
</Button>
271291
</TooltipTrigger>
272-
<TooltipContent>
273-
Copy Config Entry
274-
</TooltipContent>
292+
<TooltipContent>Copy Server Entry</TooltipContent>
275293
</Tooltip>
276294
<Tooltip>
277295
<TooltipTrigger asChild>
278296
<Button
279297
variant="outline"
280298
size="sm"
281-
onClick={handleCopyConfigFile}
299+
onClick={handleCopyServerFile}
282300
className="w-full"
283301
>
284-
{copiedConfigFile ? (
302+
{copiedServerFile ? (
285303
<CheckCheck className="h-4 w-4 mr-2" />
286304
) : (
287305
<Copy className="h-4 w-4 mr-2" />
288306
)}
289-
Config File
307+
Servers File
290308
</Button>
291309
</TooltipTrigger>
292-
<TooltipContent>
293-
Copy Config File
294-
</TooltipContent>
310+
<TooltipContent>Copy Servers File</TooltipContent>
295311
</Tooltip>
296312
</div>
297313
</>
@@ -313,16 +329,16 @@ const Sidebar = ({
313329
<Button
314330
variant="outline"
315331
size="sm"
316-
onClick={handleCopyConfigFile}
332+
onClick={handleCopyServerFile}
317333
className="w-full"
318334
title="Copy SSE URL Configuration"
319335
>
320-
{copiedConfigFile ? (
336+
{copiedServerFile ? (
321337
<CheckCheck className="h-4 w-4 mr-2" />
322338
) : (
323339
<Copy className="h-4 w-4 mr-2" />
324340
)}
325-
Copy URL
341+
Copy Servers File
326342
</Button>
327343
</div>
328344
<div className="space-y-2">

0 commit comments

Comments
 (0)