@mcpjam/inspector 0.3.5 → 0.3.7

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 CHANGED
@@ -14,6 +14,7 @@
14
14
 
15
15
  [![npm version](https://img.shields.io/npm/v/@mcpjam/inspector?style=for-the-badge&color=blue)](https://www.npmjs.com/package/@mcpjam/inspector)
16
16
  [![npm downloads](https://img.shields.io/npm/dm/@mcpjam/inspector?style=for-the-badge&color=green)](https://www.npmjs.com/package/@mcpjam/inspector)
17
+ [![Docker Pulls](https://img.shields.io/docker/pulls/mcpjam/mcp-inspector?style=for-the-badge)](https://hub.docker.com/r/mcpjam/mcp-inspector)
17
18
  [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=for-the-badge)](https://opensource.org/licenses/Apache-2.0)
18
19
  [![Node.js](https://img.shields.io/badge/Node.js-22.7.5+-green.svg?style=for-the-badge&logo=node.js)](https://nodejs.org/)
19
20
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.8+-blue.svg?style=for-the-badge&logo=typescript)](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,
@@ -136,6 +139,28 @@ function loadConfigFile(configPath, serverName) {
136
139
  throw err;
137
140
  }
138
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
+ }
139
164
  function parseKeyValuePair(value, previous = {}) {
140
165
  const parts = value.split("=");
141
166
  const key = parts[0];
@@ -168,22 +193,33 @@ function parseArgs() {
168
193
  const remainingArgs = program.args;
169
194
  // Add back any arguments that came after --
170
195
  const finalArgs = [...remainingArgs, ...postArgs];
171
- // Validate that config and server are provided together
172
- if ((options.config && !options.server) ||
173
- (!options.config && options.server)) {
174
- throw new Error("Both --config and --server must be provided together. If you specify one, you must specify the other.");
175
- }
176
- // If config file is specified, load and use the options from the file. We must merge the args
177
- // from the command line and the file together, or we will miss the method options (--method,
178
- // etc.)
179
- if (options.config && options.server) {
180
- const config = loadConfigFile(options.config, options.server);
181
- return {
182
- command: config.command,
183
- args: [...(config.args || []), ...finalArgs],
184
- envArgs: { ...(config.env || {}), ...(options.e || {}) },
185
- cli: options.cli || false,
186
- };
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
+ }
187
223
  }
188
224
  // Otherwise use command line arguments
189
225
  const command = finalArgs[0] || "";
@@ -1,4 +1,4 @@
1
- import { u as useToast, r as reactExports, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-DQYTYcqe.js";
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-BG-3VNs4.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]);
@@ -1,4 +1,4 @@
1
- import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-DQYTYcqe.js";
1
+ import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-BG-3VNs4.js";
2
2
  const OAuthDebugCallback = ({ onConnect }) => {
3
3
  reactExports.useEffect(() => {
4
4
  let isProcessed = false;