@mcpjam/inspector 0.3.4 → 0.3.6
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 +1 -0
- package/cli/build/cli.js +57 -23
- package/client/bin/client.js +23 -9
- package/client/bin/start.js +6 -11
- package/client/dist/assets/{OAuthCallback-59IQqASq.js → OAuthCallback-Bgz6lAmx.js} +2 -1
- package/client/dist/assets/{OAuthDebugCallback-Bm010sVQ.js → OAuthDebugCallback-Gd08QO37.js} +1 -1
- package/client/dist/assets/{index-B_8Xm9gw.js → index-Bgrnc5s2.js} +1727 -1151
- package/client/dist/assets/{index-BT47S2Qb.css → index-CWDemo1t.css} +85 -100
- package/client/dist/index.html +3 -3
- package/package.json +2 -1
- package/server/build/database/DatabaseManager.js +108 -0
- package/server/build/database/index.js +8 -0
- package/server/build/database/routes.js +86 -0
- package/server/build/database/types.js +27 -0
- package/server/build/database/utils.js +86 -0
- package/server/build/index.js +109 -131
- package/server/build/shared/MCPProxyService.js +221 -0
- package/server/build/shared/TransportFactory.js +130 -0
- package/server/build/shared/index.js +4 -0
- package/server/build/shared/types.js +1 -0
- package/server/build/shared/utils.js +27 -0
- package/server/build/test-server.js +145 -0
- package/server/build/testing/HealthCheck.js +42 -0
- package/server/build/testing/TestExecutor.js +240 -0
- package/server/build/testing/TestRunner.js +198 -0
- package/server/build/testing/TestServer.js +440 -0
- package/server/build/testing/types.js +1 -0
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
[](https://www.npmjs.com/package/@mcpjam/inspector)
|
|
16
16
|
[](https://www.npmjs.com/package/@mcpjam/inspector)
|
|
17
|
+
[](https://hub.docker.com/r/mcpjam/mcp-inspector)
|
|
17
18
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
18
19
|
[](https://nodejs.org/)
|
|
19
20
|
[](https://www.typescriptlang.org/)
|
package/cli/build/cli.js
CHANGED
|
@@ -60,6 +60,9 @@ async function runWebClient(args) {
|
|
|
60
60
|
...process.env,
|
|
61
61
|
PORT: SERVER_PORT,
|
|
62
62
|
MCP_ENV_VARS: JSON.stringify(args.envArgs),
|
|
63
|
+
MCP_SERVER_CONFIGS: args.serverConfigs
|
|
64
|
+
? JSON.stringify(args.serverConfigs)
|
|
65
|
+
: undefined,
|
|
63
66
|
},
|
|
64
67
|
signal: abort.signal,
|
|
65
68
|
echoOutput: true,
|
|
@@ -73,15 +76,13 @@ async function runWebClient(args) {
|
|
|
73
76
|
if (serverOk) {
|
|
74
77
|
try {
|
|
75
78
|
console.log("\x1b[32m%s\x1b[0m", "✅ Server initialized successfully"); // Green color
|
|
76
|
-
console.log("\x1b[36m%s\x1b[0m", `🌐 Opening browser at http://127.0.0.1:${CLIENT_PORT}`);
|
|
77
|
-
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
|
|
78
|
-
// Note: We need to import 'open' if we want to auto-open browser
|
|
79
|
-
// import open from "open";
|
|
80
|
-
// open(`http://127.0.0.1:${CLIENT_PORT}`);
|
|
81
|
-
}
|
|
82
79
|
console.log("\x1b[33m%s\x1b[0m", "🖥️ Starting client interface...");
|
|
83
80
|
await spawnPromise("node", [inspectorClientPath], {
|
|
84
|
-
env: {
|
|
81
|
+
env: {
|
|
82
|
+
...process.env,
|
|
83
|
+
PORT: CLIENT_PORT,
|
|
84
|
+
MCP_AUTO_OPEN_ENABLED: process.env.MCP_AUTO_OPEN_ENABLED ?? "true",
|
|
85
|
+
},
|
|
85
86
|
signal: abort.signal,
|
|
86
87
|
echoOutput: true,
|
|
87
88
|
});
|
|
@@ -138,6 +139,28 @@ function loadConfigFile(configPath, serverName) {
|
|
|
138
139
|
throw err;
|
|
139
140
|
}
|
|
140
141
|
}
|
|
142
|
+
function loadAllServersFromConfig(configPath) {
|
|
143
|
+
try {
|
|
144
|
+
const resolvedConfigPath = path.isAbsolute(configPath)
|
|
145
|
+
? configPath
|
|
146
|
+
: path.resolve(process.cwd(), configPath);
|
|
147
|
+
if (!fs.existsSync(resolvedConfigPath)) {
|
|
148
|
+
throw new Error(`Config file not found: ${resolvedConfigPath}`);
|
|
149
|
+
}
|
|
150
|
+
const configContent = fs.readFileSync(resolvedConfigPath, "utf8");
|
|
151
|
+
const parsedConfig = JSON.parse(configContent);
|
|
152
|
+
if (!parsedConfig.mcpServers) {
|
|
153
|
+
throw new Error("No 'mcpServers' section found in config file");
|
|
154
|
+
}
|
|
155
|
+
return parsedConfig.mcpServers;
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
if (err instanceof SyntaxError) {
|
|
159
|
+
throw new Error(`Invalid JSON in config file: ${err.message}`);
|
|
160
|
+
}
|
|
161
|
+
throw err;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
141
164
|
function parseKeyValuePair(value, previous = {}) {
|
|
142
165
|
const parts = value.split("=");
|
|
143
166
|
const key = parts[0];
|
|
@@ -170,22 +193,33 @@ function parseArgs() {
|
|
|
170
193
|
const remainingArgs = program.args;
|
|
171
194
|
// Add back any arguments that came after --
|
|
172
195
|
const finalArgs = [...remainingArgs, ...postArgs];
|
|
173
|
-
// Validate
|
|
174
|
-
if (
|
|
175
|
-
(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
196
|
+
// Validate server option
|
|
197
|
+
if (!options.config && options.server) {
|
|
198
|
+
throw new Error("--server option requires --config to be specified.");
|
|
199
|
+
}
|
|
200
|
+
// If config file is specified
|
|
201
|
+
if (options.config) {
|
|
202
|
+
if (options.server) {
|
|
203
|
+
// Single server mode: load specific server from config
|
|
204
|
+
const config = loadConfigFile(options.config, options.server);
|
|
205
|
+
return {
|
|
206
|
+
command: config.command,
|
|
207
|
+
args: [...(config.args || []), ...finalArgs],
|
|
208
|
+
envArgs: { ...(config.env || {}), ...(options.e || {}) },
|
|
209
|
+
cli: options.cli || false,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// Multiple servers mode: load all servers from config
|
|
214
|
+
const serverConfigs = loadAllServersFromConfig(options.config);
|
|
215
|
+
return {
|
|
216
|
+
command: "", // No single command in multi-server mode
|
|
217
|
+
args: finalArgs,
|
|
218
|
+
envArgs: options.e || {},
|
|
219
|
+
cli: options.cli || false,
|
|
220
|
+
serverConfigs,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
189
223
|
}
|
|
190
224
|
// Otherwise use command line arguments
|
|
191
225
|
const command = finalArgs[0] || "";
|
package/client/bin/client.js
CHANGED
|
@@ -4,6 +4,7 @@ import { join, dirname } from "path";
|
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
5
|
import handler from "serve-handler";
|
|
6
6
|
import http from "http";
|
|
7
|
+
import open from "open";
|
|
7
8
|
|
|
8
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
10
|
const distPath = join(__dirname, "../dist");
|
|
@@ -39,19 +40,32 @@ const server = http.createServer((request, response) => {
|
|
|
39
40
|
return handler(request, response, handlerOptions);
|
|
40
41
|
});
|
|
41
42
|
|
|
42
|
-
const
|
|
43
|
+
const defaultPort = process.env.PORT || 6274;
|
|
44
|
+
let port = Number(defaultPort);
|
|
45
|
+
|
|
46
|
+
// Try ports sequentially until one works
|
|
47
|
+
server.on("error", (err) => {
|
|
48
|
+
if (err.code === "EADDRINUSE") {
|
|
49
|
+
console.log(`⚠️ Port ${port} was in use, trying ${port + 1}`);
|
|
50
|
+
port++;
|
|
51
|
+
server.listen(port);
|
|
52
|
+
} else {
|
|
53
|
+
console.error(`❌ MCPJam Inspector failed to start: ${err.message}`);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
43
57
|
server.on("listening", () => {
|
|
58
|
+
const url = `http://127.0.0.1:${port}`;
|
|
44
59
|
console.log(
|
|
45
|
-
`🔍 MCPJam Inspector is up and running at
|
|
60
|
+
`🔍 MCPJam Inspector is up and running at \u001B]8;;${url}\u0007${url}\u001B]8;;\u0007 🚀`,
|
|
46
61
|
);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
`❌ MCPJam Inspector PORT IS IN USE at http://127.0.0.1:${port} ❌ `,
|
|
62
|
+
|
|
63
|
+
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
|
|
64
|
+
console.log(
|
|
65
|
+
`🌐 Opening browser at \u001B]8;;${url}\u0007${url}\u001B]8;;\u0007`,
|
|
52
66
|
);
|
|
53
|
-
|
|
54
|
-
throw err;
|
|
67
|
+
open(url);
|
|
55
68
|
}
|
|
56
69
|
});
|
|
70
|
+
|
|
57
71
|
server.listen(port);
|
package/client/bin/start.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import open from "open";
|
|
4
3
|
import { resolve, dirname } from "path";
|
|
5
4
|
import { spawnPromise } from "spawn-rx";
|
|
6
5
|
import { fileURLToPath } from "url";
|
|
@@ -87,6 +86,7 @@ async function main() {
|
|
|
87
86
|
abort.abort();
|
|
88
87
|
console.log("\n\x1b[31m%s\x1b[0m", "⚠️ Shutting down MCP Inspector..."); // Red color
|
|
89
88
|
});
|
|
89
|
+
|
|
90
90
|
let server, serverOk;
|
|
91
91
|
try {
|
|
92
92
|
server = spawnPromise(
|
|
@@ -116,19 +116,14 @@ async function main() {
|
|
|
116
116
|
if (serverOk) {
|
|
117
117
|
try {
|
|
118
118
|
console.log("\x1b[32m%s\x1b[0m", "✅ Server initialized successfully"); // Green color
|
|
119
|
-
console.log(
|
|
120
|
-
"\x1b[36m%s\x1b[0m",
|
|
121
|
-
`🌐 Opening browser at http://127.0.0.1:${CLIENT_PORT}`,
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
|
|
125
|
-
open(`http://127.0.0.1:${CLIENT_PORT}`);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
119
|
console.log("\x1b[33m%s\x1b[0m", "🖥️ Starting client interface...");
|
|
129
120
|
|
|
130
121
|
await spawnPromise("node", [inspectorClientPath], {
|
|
131
|
-
env: {
|
|
122
|
+
env: {
|
|
123
|
+
...process.env,
|
|
124
|
+
PORT: CLIENT_PORT,
|
|
125
|
+
MCP_AUTO_OPEN_ENABLED: process.env.MCP_AUTO_OPEN_ENABLED ?? "true",
|
|
126
|
+
},
|
|
132
127
|
signal: abort.signal,
|
|
133
128
|
echoOutput: true,
|
|
134
129
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as useToast, r as reactExports, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription,
|
|
1
|
+
import { u as useToast, r as reactExports, S as SESSION_KEYS, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription, I as InspectorOAuthClientProvider, a as auth } from "./index-Bgrnc5s2.js";
|
|
2
2
|
const OAuthCallback = ({ onConnect }) => {
|
|
3
3
|
const { toast } = useToast();
|
|
4
4
|
const hasProcessedRef = reactExports.useRef(false);
|
|
@@ -45,6 +45,7 @@ const OAuthCallback = ({ onConnect }) => {
|
|
|
45
45
|
onConnect(serverUrl);
|
|
46
46
|
};
|
|
47
47
|
handleCallback().finally(() => {
|
|
48
|
+
sessionStorage.removeItem(SESSION_KEYS.TRANSPORT_TYPE);
|
|
48
49
|
window.history.replaceState({}, document.title, "/");
|
|
49
50
|
});
|
|
50
51
|
}, [toast, onConnect]);
|
package/client/dist/assets/{OAuthDebugCallback-Bm010sVQ.js → OAuthDebugCallback-Gd08QO37.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-
|
|
1
|
+
import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-Bgrnc5s2.js";
|
|
2
2
|
const OAuthDebugCallback = ({ onConnect }) => {
|
|
3
3
|
reactExports.useEffect(() => {
|
|
4
4
|
let isProcessed = false;
|