@modelcontextprotocol/inspector 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/bin/cli.js +36 -38
- package/client/bin/cli.js +16 -2
- package/client/dist/assets/{OAuthCallback-C5xCfXlk.js → OAuthCallback-DrQsfqzq.js} +1 -1
- package/client/dist/assets/{index-Dt6l7sEy.css → index-BxIjx6su.css} +59 -12
- package/client/dist/assets/{index-D7o7JmLV.js → index-DrNN0pLZ.js} +464 -171
- package/client/dist/index.html +2 -2
- package/package.json +5 -3
- package/server/build/index.js +15 -13
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ npx @modelcontextprotocol/inspector -e KEY=value -e KEY2=$VALUE2 node build/inde
|
|
|
30
30
|
npx @modelcontextprotocol/inspector -e KEY=$VALUE -- node build/index.js -e server-flag
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
The inspector runs both
|
|
33
|
+
The inspector runs both an MCP Inspector (MCPI) client UI (default port 6274) and an MCP Proxy (MCPP) server (default port 6277). Open the MCPI client UI in your browser to use the inspector. (These ports are derived from the T9 dialpad mapping of MCPI and MCPP respectively, as a mnemonic). You can customize the ports if needed:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
36
|
CLIENT_PORT=8080 SERVER_PORT=9000 npx @modelcontextprotocol/inspector node build/index.js
|
|
@@ -42,6 +42,18 @@ For more details on ways to use the inspector, see the [Inspector section of the
|
|
|
42
42
|
|
|
43
43
|
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.
|
|
44
44
|
|
|
45
|
+
### Security Considerations
|
|
46
|
+
|
|
47
|
+
The MCP Inspector includes a proxy server that can run and communicate with local MCP processes. The proxy server should not be exposed to untrusted networks as it has permissions to spawn local processes and can connect to any specified MCP server.
|
|
48
|
+
|
|
49
|
+
### Configuration
|
|
50
|
+
|
|
51
|
+
The MCP Inspector supports the following configuration settings. To change them click on the `Configuration` button in the MCP Inspector UI :
|
|
52
|
+
|
|
53
|
+
| Name | Purpose | Default Value |
|
|
54
|
+
| -------------------------- | ----------------------------------------------------------------------------------------- | ------------- |
|
|
55
|
+
| MCP_SERVER_REQUEST_TIMEOUT | Maximum time in milliseconds to wait for a response from the MCP server before timing out | 10000 |
|
|
56
|
+
|
|
45
57
|
### From this repository
|
|
46
58
|
|
|
47
59
|
If you're working on the inspector itself:
|
package/bin/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
|
|
9
9
|
function delay(ms) {
|
|
10
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
10
|
+
return new Promise((resolve) => setTimeout(resolve, ms, true));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
async function main() {
|
|
@@ -61,8 +61,8 @@ async function main() {
|
|
|
61
61
|
"cli.js",
|
|
62
62
|
);
|
|
63
63
|
|
|
64
|
-
const CLIENT_PORT = process.env.CLIENT_PORT ?? "
|
|
65
|
-
const SERVER_PORT = process.env.SERVER_PORT ?? "
|
|
64
|
+
const CLIENT_PORT = process.env.CLIENT_PORT ?? "6274";
|
|
65
|
+
const SERVER_PORT = process.env.SERVER_PORT ?? "6277";
|
|
66
66
|
|
|
67
67
|
console.log("Starting MCP inspector...");
|
|
68
68
|
|
|
@@ -73,42 +73,40 @@ async function main() {
|
|
|
73
73
|
cancelled = true;
|
|
74
74
|
abort.abort();
|
|
75
75
|
});
|
|
76
|
-
|
|
77
|
-
const server = spawnPromise(
|
|
78
|
-
"node",
|
|
79
|
-
[
|
|
80
|
-
inspectorServerPath,
|
|
81
|
-
...(command ? [`--env`, command] : []),
|
|
82
|
-
...(mcpServerArgs ? [`--args=${mcpServerArgs.join(" ")}`] : []),
|
|
83
|
-
],
|
|
84
|
-
{
|
|
85
|
-
env: {
|
|
86
|
-
...process.env,
|
|
87
|
-
PORT: SERVER_PORT,
|
|
88
|
-
MCP_ENV_VARS: JSON.stringify(envVars),
|
|
89
|
-
},
|
|
90
|
-
signal: abort.signal,
|
|
91
|
-
echoOutput: true,
|
|
92
|
-
},
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const client = spawnPromise("node", [inspectorClientPath], {
|
|
96
|
-
env: { ...process.env, PORT: CLIENT_PORT },
|
|
97
|
-
signal: abort.signal,
|
|
98
|
-
echoOutput: true,
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// Make sure our server/client didn't immediately fail
|
|
102
|
-
await Promise.any([server, client, delay(2 * 1000)]);
|
|
103
|
-
const portParam = SERVER_PORT === "3000" ? "" : `?proxyPort=${SERVER_PORT}`;
|
|
104
|
-
console.log(
|
|
105
|
-
`\n🔍 MCP Inspector is up and running at http://localhost:${CLIENT_PORT}${portParam} 🚀`,
|
|
106
|
-
);
|
|
107
|
-
|
|
76
|
+
let server, serverOk;
|
|
108
77
|
try {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
78
|
+
server = spawnPromise(
|
|
79
|
+
"node",
|
|
80
|
+
[
|
|
81
|
+
inspectorServerPath,
|
|
82
|
+
...(command ? [`--env`, command] : []),
|
|
83
|
+
...(mcpServerArgs ? [`--args=${mcpServerArgs.join(" ")}`] : []),
|
|
84
|
+
],
|
|
85
|
+
{
|
|
86
|
+
env: {
|
|
87
|
+
...process.env,
|
|
88
|
+
PORT: SERVER_PORT,
|
|
89
|
+
MCP_ENV_VARS: JSON.stringify(envVars),
|
|
90
|
+
},
|
|
91
|
+
signal: abort.signal,
|
|
92
|
+
echoOutput: true,
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// Make sure server started before starting client
|
|
97
|
+
serverOk = await Promise.race([server, delay(2 * 1000)]);
|
|
98
|
+
} catch (error) {}
|
|
99
|
+
|
|
100
|
+
if (serverOk) {
|
|
101
|
+
try {
|
|
102
|
+
await spawnPromise("node", [inspectorClientPath], {
|
|
103
|
+
env: { ...process.env, PORT: CLIENT_PORT },
|
|
104
|
+
signal: abort.signal,
|
|
105
|
+
echoOutput: true,
|
|
106
|
+
});
|
|
107
|
+
} catch (e) {
|
|
108
|
+
if (!cancelled || process.env.DEBUG) throw e;
|
|
109
|
+
}
|
|
112
110
|
}
|
|
113
111
|
|
|
114
112
|
return 0;
|
package/client/bin/cli.js
CHANGED
|
@@ -15,5 +15,19 @@ const server = http.createServer((request, response) => {
|
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
const port = process.env.PORT ||
|
|
19
|
-
server.
|
|
18
|
+
const port = process.env.PORT || 6274;
|
|
19
|
+
server.on("listening", () => {
|
|
20
|
+
console.log(
|
|
21
|
+
`🔍 MCP Inspector is up and running at http://127.0.0.1:${port} 🚀`,
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
server.on("error", (err) => {
|
|
25
|
+
if (err.message.includes(`EADDRINUSE`)) {
|
|
26
|
+
console.error(
|
|
27
|
+
`❌ MCP Inspector PORT IS IN USE at http://127.0.0.1:${port} ❌ `,
|
|
28
|
+
);
|
|
29
|
+
} else {
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
server.listen(port);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, a as auth, b as authProvider } from "./index-
|
|
1
|
+
import { r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, a as auth, b as authProvider } from "./index-DrNN0pLZ.js";
|
|
2
2
|
const OAuthCallback = () => {
|
|
3
3
|
const hasProcessedRef = reactExports.useRef(false);
|
|
4
4
|
reactExports.useEffect(() => {
|
|
@@ -1443,6 +1443,12 @@ video {
|
|
|
1443
1443
|
white-space: nowrap;
|
|
1444
1444
|
border-width: 0;
|
|
1445
1445
|
}
|
|
1446
|
+
.visible {
|
|
1447
|
+
visibility: visible;
|
|
1448
|
+
}
|
|
1449
|
+
.collapse {
|
|
1450
|
+
visibility: collapse;
|
|
1451
|
+
}
|
|
1446
1452
|
.fixed {
|
|
1447
1453
|
position: fixed;
|
|
1448
1454
|
}
|
|
@@ -1511,9 +1517,15 @@ video {
|
|
|
1511
1517
|
.ml-2 {
|
|
1512
1518
|
margin-left: 0.5rem;
|
|
1513
1519
|
}
|
|
1520
|
+
.ml-4 {
|
|
1521
|
+
margin-left: 1rem;
|
|
1522
|
+
}
|
|
1514
1523
|
.ml-auto {
|
|
1515
1524
|
margin-left: auto;
|
|
1516
1525
|
}
|
|
1526
|
+
.mr-1 {
|
|
1527
|
+
margin-right: 0.25rem;
|
|
1528
|
+
}
|
|
1517
1529
|
.mr-2 {
|
|
1518
1530
|
margin-right: 0.5rem;
|
|
1519
1531
|
}
|
|
@@ -1559,9 +1571,6 @@ video {
|
|
|
1559
1571
|
.h-4 {
|
|
1560
1572
|
height: 1rem;
|
|
1561
1573
|
}
|
|
1562
|
-
.h-64 {
|
|
1563
|
-
height: 16rem;
|
|
1564
|
-
}
|
|
1565
1574
|
.h-8 {
|
|
1566
1575
|
height: 2rem;
|
|
1567
1576
|
}
|
|
@@ -1586,9 +1595,6 @@ video {
|
|
|
1586
1595
|
.h-screen {
|
|
1587
1596
|
height: 100vh;
|
|
1588
1597
|
}
|
|
1589
|
-
.max-h-64 {
|
|
1590
|
-
max-height: 16rem;
|
|
1591
|
-
}
|
|
1592
1598
|
.max-h-80 {
|
|
1593
1599
|
max-height: 20rem;
|
|
1594
1600
|
}
|
|
@@ -1755,8 +1761,8 @@ video {
|
|
|
1755
1761
|
.whitespace-pre-wrap {
|
|
1756
1762
|
white-space: pre-wrap;
|
|
1757
1763
|
}
|
|
1758
|
-
.break-
|
|
1759
|
-
|
|
1764
|
+
.break-all {
|
|
1765
|
+
word-break: break-all;
|
|
1760
1766
|
}
|
|
1761
1767
|
.rounded {
|
|
1762
1768
|
border-radius: 0.25rem;
|
|
@@ -1779,6 +1785,9 @@ video {
|
|
|
1779
1785
|
.border-b {
|
|
1780
1786
|
border-bottom-width: 1px;
|
|
1781
1787
|
}
|
|
1788
|
+
.border-l {
|
|
1789
|
+
border-left-width: 1px;
|
|
1790
|
+
}
|
|
1782
1791
|
.border-r {
|
|
1783
1792
|
border-right-width: 1px;
|
|
1784
1793
|
}
|
|
@@ -1964,6 +1973,10 @@ video {
|
|
|
1964
1973
|
.tracking-widest {
|
|
1965
1974
|
letter-spacing: 0.1em;
|
|
1966
1975
|
}
|
|
1976
|
+
.text-amber-600 {
|
|
1977
|
+
--tw-text-opacity: 1;
|
|
1978
|
+
color: rgb(217 119 6 / var(--tw-text-opacity, 1));
|
|
1979
|
+
}
|
|
1967
1980
|
.text-blue-500 {
|
|
1968
1981
|
--tw-text-opacity: 1;
|
|
1969
1982
|
color: rgb(59 130 246 / var(--tw-text-opacity, 1));
|
|
@@ -2004,10 +2017,6 @@ video {
|
|
|
2004
2017
|
--tw-text-opacity: 1;
|
|
2005
2018
|
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
|
2006
2019
|
}
|
|
2007
|
-
.text-gray-800 {
|
|
2008
|
-
--tw-text-opacity: 1;
|
|
2009
|
-
color: rgb(31 41 55 / var(--tw-text-opacity, 1));
|
|
2010
|
-
}
|
|
2011
2020
|
.text-gray-900 {
|
|
2012
2021
|
--tw-text-opacity: 1;
|
|
2013
2022
|
color: rgb(17 24 39 / var(--tw-text-opacity, 1));
|
|
@@ -2109,6 +2118,9 @@ video {
|
|
|
2109
2118
|
.duration-200 {
|
|
2110
2119
|
transition-duration: 200ms;
|
|
2111
2120
|
}
|
|
2121
|
+
.duration-300 {
|
|
2122
|
+
transition-duration: 300ms;
|
|
2123
|
+
}
|
|
2112
2124
|
@keyframes enter {
|
|
2113
2125
|
|
|
2114
2126
|
from {
|
|
@@ -2126,6 +2138,9 @@ video {
|
|
|
2126
2138
|
.duration-200 {
|
|
2127
2139
|
animation-duration: 200ms;
|
|
2128
2140
|
}
|
|
2141
|
+
.duration-300 {
|
|
2142
|
+
animation-duration: 300ms;
|
|
2143
|
+
}
|
|
2129
2144
|
|
|
2130
2145
|
:root {
|
|
2131
2146
|
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
@@ -2249,6 +2264,14 @@ button[role="checkbox"] {
|
|
|
2249
2264
|
background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1));
|
|
2250
2265
|
}
|
|
2251
2266
|
|
|
2267
|
+
.hover\:bg-gray-800\/10:hover {
|
|
2268
|
+
background-color: rgb(31 41 55 / 0.1);
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
.hover\:bg-gray-800\/20:hover {
|
|
2272
|
+
background-color: rgb(31 41 55 / 0.2);
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2252
2275
|
.hover\:bg-primary\/90:hover {
|
|
2253
2276
|
background-color: hsl(var(--primary) / 0.9);
|
|
2254
2277
|
}
|
|
@@ -2344,6 +2367,16 @@ button[role="checkbox"] {
|
|
|
2344
2367
|
opacity: 0.5;
|
|
2345
2368
|
}
|
|
2346
2369
|
|
|
2370
|
+
.group:hover .group-hover\:text-gray-400 {
|
|
2371
|
+
--tw-text-opacity: 1;
|
|
2372
|
+
color: rgb(156 163 175 / var(--tw-text-opacity, 1));
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
.group:hover .group-hover\:text-green-500 {
|
|
2376
|
+
--tw-text-opacity: 1;
|
|
2377
|
+
color: rgb(34 197 94 / var(--tw-text-opacity, 1));
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2347
2380
|
.peer:disabled ~ .peer-disabled\:cursor-not-allowed {
|
|
2348
2381
|
cursor: not-allowed;
|
|
2349
2382
|
}
|
|
@@ -2523,6 +2556,11 @@ button[role="checkbox"] {
|
|
|
2523
2556
|
color: rgb(209 213 219 / var(--tw-text-opacity, 1));
|
|
2524
2557
|
}
|
|
2525
2558
|
|
|
2559
|
+
.dark\:text-gray-400:is(.dark *) {
|
|
2560
|
+
--tw-text-opacity: 1;
|
|
2561
|
+
color: rgb(156 163 175 / var(--tw-text-opacity, 1));
|
|
2562
|
+
}
|
|
2563
|
+
|
|
2526
2564
|
.dark\:text-white:is(.dark *) {
|
|
2527
2565
|
--tw-text-opacity: 1;
|
|
2528
2566
|
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
|
|
@@ -2533,6 +2571,15 @@ button[role="checkbox"] {
|
|
|
2533
2571
|
background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));
|
|
2534
2572
|
}
|
|
2535
2573
|
|
|
2574
|
+
.dark\:hover\:bg-gray-800\/20:hover:is(.dark *) {
|
|
2575
|
+
background-color: rgb(31 41 55 / 0.2);
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
.group:hover .dark\:group-hover\:text-gray-100:is(.dark *) {
|
|
2579
|
+
--tw-text-opacity: 1;
|
|
2580
|
+
color: rgb(243 244 246 / var(--tw-text-opacity, 1));
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2536
2583
|
@media (min-width: 640px) {
|
|
2537
2584
|
|
|
2538
2585
|
.sm\:flex-row {
|