@mcpjam/inspector 0.3.8 → 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/.next/BUILD_ID +1 -0
- package/.next/app-build-manifest.json +89 -0
- package/.next/app-path-routes-manifest.json +13 -0
- package/.next/build-manifest.json +33 -0
- package/.next/cache/.previewinfo +1 -0
- package/.next/cache/.rscinfo +1 -0
- package/.next/cache/.tsbuildinfo +1 -0
- package/.next/cache/eslint/.cache_11b5ofe +1 -0
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/diagnostics/build-diagnostics.json +6 -0
- package/.next/diagnostics/framework.json +1 -0
- package/.next/export-marker.json +6 -0
- package/.next/images-manifest.json +57 -0
- package/.next/next-minimal-server.js.nft.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/package.json +1 -0
- package/.next/prerender-manifest.json +41 -0
- package/.next/react-loadable-manifest.json +1 -0
- package/.next/required-server-files.json +318 -0
- package/.next/routes-manifest.json +65 -0
- package/.next/server/app/_not-found/page.js +2 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/.next/server/app/api/mcp/chat/route.js +45 -0
- package/.next/server/app/api/mcp/chat/route.js.nft.json +1 -0
- package/.next/server/app/api/mcp/chat/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/mcp/connect/route.js +1 -0
- package/.next/server/app/api/mcp/connect/route.js.nft.json +1 -0
- package/.next/server/app/api/mcp/connect/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/mcp/prompts/get/route.js +1 -0
- package/.next/server/app/api/mcp/prompts/get/route.js.nft.json +1 -0
- package/.next/server/app/api/mcp/prompts/get/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/mcp/prompts/list/route.js +1 -0
- package/.next/server/app/api/mcp/prompts/list/route.js.nft.json +1 -0
- package/.next/server/app/api/mcp/prompts/list/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/mcp/resources/list/route.js +1 -0
- package/.next/server/app/api/mcp/resources/list/route.js.nft.json +1 -0
- package/.next/server/app/api/mcp/resources/list/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/mcp/resources/read/route.js +1 -0
- package/.next/server/app/api/mcp/resources/read/route.js.nft.json +1 -0
- package/.next/server/app/api/mcp/resources/read/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/mcp/tools/route.js +21 -0
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -0
- package/.next/server/app/api/mcp/tools/route_client-reference-manifest.js +1 -0
- package/.next/server/app/favicon.ico/route.js +1 -0
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -0
- package/.next/server/app/favicon.ico.body +0 -0
- package/.next/server/app/favicon.ico.meta +1 -0
- package/.next/server/app/oauth/callback/page.js +2 -0
- package/.next/server/app/oauth/callback/page.js.nft.json +1 -0
- package/.next/server/app/oauth/callback/page_client-reference-manifest.js +1 -0
- package/.next/server/app/page.js +16 -0
- package/.next/server/app/page.js.nft.json +1 -0
- package/.next/server/app/page_client-reference-manifest.js +1 -0
- package/.next/server/app-paths-manifest.json +13 -0
- package/.next/server/chunks/175.js +8 -0
- package/.next/server/chunks/260.js +82 -0
- package/.next/server/chunks/546.js +1 -0
- package/.next/server/chunks/548.js +6 -0
- package/.next/server/chunks/55.js +1 -0
- package/.next/server/chunks/985.js +22 -0
- package/.next/server/functions-config-manifest.json +4 -0
- package/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -0
- package/.next/server/middleware-manifest.json +6 -0
- package/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/.next/server/next-font-manifest.js +1 -0
- package/.next/server/next-font-manifest.json +1 -0
- package/.next/server/pages/500.html +1 -0
- package/.next/server/pages/_app.js +1 -0
- package/.next/server/pages/_app.js.nft.json +1 -0
- package/.next/server/pages/_document.js +1 -0
- package/.next/server/pages/_document.js.nft.json +1 -0
- package/.next/server/pages/_error.js +19 -0
- package/.next/server/pages/_error.js.nft.json +1 -0
- package/.next/server/pages-manifest.json +5 -0
- package/.next/server/server-reference-manifest.js +1 -0
- package/.next/server/server-reference-manifest.json +1 -0
- package/.next/server/webpack-runtime.js +1 -0
- package/.next/static/chunks/14-ae3a01e72ea53777.js +1 -0
- package/.next/static/chunks/214-cc4c35d88f2695ed.js +1 -0
- package/.next/static/chunks/4bd1b696-cf72ae8a39fa05aa.js +1 -0
- package/.next/static/chunks/866-04c19dda4c52f2bf.js +1 -0
- package/.next/static/chunks/964-eda38e26c0391a47.js +1 -0
- package/.next/static/chunks/app/_not-found/page-d7e832b54474da82.js +1 -0
- package/.next/static/chunks/app/api/mcp/chat/route-0341498a8bf5f2da.js +1 -0
- package/.next/static/chunks/app/api/mcp/connect/route-0341498a8bf5f2da.js +1 -0
- package/.next/static/chunks/app/api/mcp/prompts/get/route-0341498a8bf5f2da.js +1 -0
- package/.next/static/chunks/app/api/mcp/prompts/list/route-0341498a8bf5f2da.js +1 -0
- package/.next/static/chunks/app/api/mcp/resources/list/route-0341498a8bf5f2da.js +1 -0
- package/.next/static/chunks/app/api/mcp/resources/read/route-0341498a8bf5f2da.js +1 -0
- package/.next/static/chunks/app/api/mcp/tools/route-0341498a8bf5f2da.js +1 -0
- package/.next/static/chunks/app/layout-fb6e1ad5933381f3.js +1 -0
- package/.next/static/chunks/app/oauth/callback/page-d8b3908ea67ba3e3.js +1 -0
- package/.next/static/chunks/app/page-81e35b2a61edb363.js +1 -0
- package/.next/static/chunks/framework-7c95b8e5103c9e90.js +1 -0
- package/.next/static/chunks/main-app-7d61da15faa6c1af.js +1 -0
- package/.next/static/chunks/main-bbdafee21a7bd1d6.js +1 -0
- package/.next/static/chunks/pages/_app-0a0020ddd67f79cf.js +1 -0
- package/.next/static/chunks/pages/_error-03529f2c21436739.js +1 -0
- package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/.next/static/chunks/webpack-cdfccaf38062dd25.js +1 -0
- package/.next/static/css/1e852d83e9c1d0c6.css +1 -0
- package/.next/static/css/f30152c0704fba31.css +1 -0
- package/.next/static/css/fe751fdbe975e9ca.css +1 -0
- package/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
- package/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- package/.next/static/media/ollama_dark.9af45ac0.png +0 -0
- package/.next/static/media/ollama_logo.9f08a95b.svg +7 -0
- package/.next/static/media/openai_logo.3f83154a.png +0 -0
- package/.next/static/wgHmsxKAquUu9gOMW6Qd5/_buildManifest.js +1 -0
- package/.next/static/wgHmsxKAquUu9gOMW6Qd5/_ssgManifest.js +1 -0
- package/.next/trace +35 -0
- package/.next/types/app/api/mcp/chat/route.ts +347 -0
- package/.next/types/app/api/mcp/connect/route.ts +347 -0
- package/.next/types/app/api/mcp/prompts/get/route.ts +347 -0
- package/.next/types/app/api/mcp/prompts/list/route.ts +347 -0
- package/.next/types/app/api/mcp/resources/list/route.ts +347 -0
- package/.next/types/app/api/mcp/resources/read/route.ts +347 -0
- package/.next/types/app/api/mcp/tools/route.ts +347 -0
- package/.next/types/app/layout.ts +84 -0
- package/.next/types/app/oauth/callback/page.ts +84 -0
- package/.next/types/app/page.ts +84 -0
- package/.next/types/cache-life.d.ts +141 -0
- package/.next/types/package.json +1 -0
- package/README.md +76 -161
- package/bin/start.js +504 -0
- package/next.config.ts +7 -0
- package/package.json +71 -54
- package/public/claude_logo.png +0 -0
- package/public/demo_1.png +0 -0
- package/public/demo_2.png +0 -0
- package/public/demo_3.png +0 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/mcp.svg +1 -0
- package/public/next.svg +1 -0
- package/public/ollama_dark.png +0 -0
- package/public/ollama_logo.svg +7 -0
- package/public/openai_logo.png +0 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/LICENSE +0 -200
- package/cli/build/cli.js +0 -251
- package/cli/build/client/connection.js +0 -33
- package/cli/build/client/index.js +0 -6
- package/cli/build/client/prompts.js +0 -23
- package/cli/build/client/resources.js +0 -30
- package/cli/build/client/tools.js +0 -64
- package/cli/build/client/types.js +0 -1
- package/cli/build/error-handler.js +0 -18
- package/cli/build/index.js +0 -166
- package/cli/build/transport.js +0 -47
- package/client/bin/client.js +0 -71
- package/client/bin/start.js +0 -143
- package/client/dist/assets/OAuthCallback-Dovy-wwC.js +0 -56
- package/client/dist/assets/OAuthDebugCallback-CP9EZ76u.js +0 -44
- package/client/dist/assets/index-CWDemo1t.css +0 -4168
- package/client/dist/assets/index-DTD8_Uq7.js +0 -63318
- package/client/dist/index.html +0 -14
- package/client/dist/ollama_logo.png +0 -0
- package/client/dist/openai_logo.png +0 -0
- package/server/build/database/DatabaseManager.js +0 -108
- package/server/build/database/index.js +0 -8
- package/server/build/database/routes.js +0 -86
- package/server/build/database/types.js +0 -27
- package/server/build/database/utils.js +0 -86
- package/server/build/index.js +0 -331
- package/server/build/mcpProxy.js +0 -54
- package/server/build/shared/MCPProxyService.js +0 -221
- package/server/build/shared/TransportFactory.js +0 -130
- package/server/build/shared/index.js +0 -4
- package/server/build/shared/types.js +0 -1
- package/server/build/shared/utils.js +0 -27
- package/server/build/test-server.js +0 -145
- package/server/build/testing/HealthCheck.js +0 -42
- package/server/build/testing/TestExecutor.js +0 -240
- package/server/build/testing/TestRunner.js +0 -198
- package/server/build/testing/TestServer.js +0 -440
- package/server/build/testing/types.js +0 -1
- /package/{client/dist/claude_logo.png → .next/static/media/claude_logo.d33b25b0.png} +0 -0
- /package/{client/dist → public}/mcp_jam.svg +0 -0
- /package/{client/dist → public}/mcp_jam_dark.png +0 -0
- /package/{client/dist → public}/mcp_jam_light.png +0 -0
package/cli/build/index.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
|
-
import { Command } from "commander";
|
|
4
|
-
import { callTool, connect, disconnect, getPrompt, listPrompts, listResources, listResourceTemplates, listTools, readResource, setLoggingLevel, validLogLevels, } from "./client/index.js";
|
|
5
|
-
import { handleError } from "./error-handler.js";
|
|
6
|
-
import { createTransport } from "./transport.js";
|
|
7
|
-
function createTransportOptions(target) {
|
|
8
|
-
if (target.length === 0) {
|
|
9
|
-
throw new Error("Target is required. Specify a URL or a command to execute.");
|
|
10
|
-
}
|
|
11
|
-
const [command, ...commandArgs] = target;
|
|
12
|
-
if (!command) {
|
|
13
|
-
throw new Error("Command is required.");
|
|
14
|
-
}
|
|
15
|
-
const isUrl = command.startsWith("http://") || command.startsWith("https://");
|
|
16
|
-
if (isUrl && commandArgs.length > 0) {
|
|
17
|
-
throw new Error("Arguments cannot be passed to a URL-based MCP server.");
|
|
18
|
-
}
|
|
19
|
-
return {
|
|
20
|
-
transportType: isUrl ? "sse" : "stdio",
|
|
21
|
-
command: isUrl ? undefined : command,
|
|
22
|
-
args: isUrl ? undefined : commandArgs,
|
|
23
|
-
url: isUrl ? command : undefined,
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
async function callMethod(args) {
|
|
27
|
-
const transportOptions = createTransportOptions(args.target);
|
|
28
|
-
const transport = createTransport(transportOptions);
|
|
29
|
-
const client = new Client({
|
|
30
|
-
name: "inspector-cli",
|
|
31
|
-
version: "0.5.1",
|
|
32
|
-
});
|
|
33
|
-
try {
|
|
34
|
-
await connect(client, transport);
|
|
35
|
-
let result;
|
|
36
|
-
// Tools methods
|
|
37
|
-
if (args.method === "tools/list") {
|
|
38
|
-
result = await listTools(client);
|
|
39
|
-
}
|
|
40
|
-
else if (args.method === "tools/call") {
|
|
41
|
-
if (!args.toolName) {
|
|
42
|
-
throw new Error("Tool name is required for tools/call method. Use --tool-name to specify the tool name.");
|
|
43
|
-
}
|
|
44
|
-
result = await callTool(client, args.toolName, args.toolArg || {});
|
|
45
|
-
}
|
|
46
|
-
// Resources methods
|
|
47
|
-
else if (args.method === "resources/list") {
|
|
48
|
-
result = await listResources(client);
|
|
49
|
-
}
|
|
50
|
-
else if (args.method === "resources/read") {
|
|
51
|
-
if (!args.uri) {
|
|
52
|
-
throw new Error("URI is required for resources/read method. Use --uri to specify the resource URI.");
|
|
53
|
-
}
|
|
54
|
-
result = await readResource(client, args.uri);
|
|
55
|
-
}
|
|
56
|
-
else if (args.method === "resources/templates/list") {
|
|
57
|
-
result = await listResourceTemplates(client);
|
|
58
|
-
}
|
|
59
|
-
// Prompts methods
|
|
60
|
-
else if (args.method === "prompts/list") {
|
|
61
|
-
result = await listPrompts(client);
|
|
62
|
-
}
|
|
63
|
-
else if (args.method === "prompts/get") {
|
|
64
|
-
if (!args.promptName) {
|
|
65
|
-
throw new Error("Prompt name is required for prompts/get method. Use --prompt-name to specify the prompt name.");
|
|
66
|
-
}
|
|
67
|
-
result = await getPrompt(client, args.promptName, args.promptArgs || {});
|
|
68
|
-
}
|
|
69
|
-
// Logging methods
|
|
70
|
-
else if (args.method === "logging/setLevel") {
|
|
71
|
-
if (!args.logLevel) {
|
|
72
|
-
throw new Error("Log level is required for logging/setLevel method. Use --log-level to specify the log level.");
|
|
73
|
-
}
|
|
74
|
-
result = await setLoggingLevel(client, args.logLevel);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
throw new Error(`Unsupported method: ${args.method}. Supported methods include: tools/list, tools/call, resources/list, resources/read, resources/templates/list, prompts/list, prompts/get, logging/setLevel`);
|
|
78
|
-
}
|
|
79
|
-
console.log(JSON.stringify(result, null, 2));
|
|
80
|
-
}
|
|
81
|
-
finally {
|
|
82
|
-
try {
|
|
83
|
-
await disconnect(transport);
|
|
84
|
-
}
|
|
85
|
-
catch (disconnectError) {
|
|
86
|
-
throw disconnectError;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
function parseKeyValuePair(value, previous = {}) {
|
|
91
|
-
const parts = value.split("=");
|
|
92
|
-
const key = parts[0];
|
|
93
|
-
const val = parts.slice(1).join("=");
|
|
94
|
-
if (val === undefined || val === "") {
|
|
95
|
-
throw new Error(`Invalid parameter format: ${value}. Use key=value format.`);
|
|
96
|
-
}
|
|
97
|
-
return { ...previous, [key]: val };
|
|
98
|
-
}
|
|
99
|
-
function parseArgs() {
|
|
100
|
-
const program = new Command();
|
|
101
|
-
// Find if there's a -- in the arguments and split them
|
|
102
|
-
const argSeparatorIndex = process.argv.indexOf("--");
|
|
103
|
-
let preArgs = process.argv;
|
|
104
|
-
let postArgs = [];
|
|
105
|
-
if (argSeparatorIndex !== -1) {
|
|
106
|
-
preArgs = process.argv.slice(0, argSeparatorIndex);
|
|
107
|
-
postArgs = process.argv.slice(argSeparatorIndex + 1);
|
|
108
|
-
}
|
|
109
|
-
program
|
|
110
|
-
.name("inspector-cli")
|
|
111
|
-
.allowUnknownOption()
|
|
112
|
-
.argument("<target...>", "Command and arguments or URL of the MCP server")
|
|
113
|
-
//
|
|
114
|
-
// Method selection
|
|
115
|
-
//
|
|
116
|
-
.option("--method <method>", "Method to invoke")
|
|
117
|
-
//
|
|
118
|
-
// Tool-related options
|
|
119
|
-
//
|
|
120
|
-
.option("--tool-name <toolName>", "Tool name (for tools/call method)")
|
|
121
|
-
.option("--tool-arg <pairs...>", "Tool argument as key=value pair", parseKeyValuePair, {})
|
|
122
|
-
//
|
|
123
|
-
// Resource-related options
|
|
124
|
-
//
|
|
125
|
-
.option("--uri <uri>", "URI of the resource (for resources/read method)")
|
|
126
|
-
//
|
|
127
|
-
// Prompt-related options
|
|
128
|
-
//
|
|
129
|
-
.option("--prompt-name <promptName>", "Name of the prompt (for prompts/get method)")
|
|
130
|
-
.option("--prompt-args <pairs...>", "Prompt arguments as key=value pairs", parseKeyValuePair, {})
|
|
131
|
-
//
|
|
132
|
-
// Logging options
|
|
133
|
-
//
|
|
134
|
-
.option("--log-level <level>", "Logging level (for logging/setLevel method)", (value) => {
|
|
135
|
-
if (!validLogLevels.includes(value)) {
|
|
136
|
-
throw new Error(`Invalid log level: ${value}. Valid levels are: ${validLogLevels.join(", ")}`);
|
|
137
|
-
}
|
|
138
|
-
return value;
|
|
139
|
-
});
|
|
140
|
-
// Parse only the arguments before --
|
|
141
|
-
program.parse(preArgs);
|
|
142
|
-
const options = program.opts();
|
|
143
|
-
let remainingArgs = program.args;
|
|
144
|
-
// Add back any arguments that came after --
|
|
145
|
-
const finalArgs = [...remainingArgs, ...postArgs];
|
|
146
|
-
if (!options.method) {
|
|
147
|
-
throw new Error("Method is required. Use --method to specify the method to invoke.");
|
|
148
|
-
}
|
|
149
|
-
return {
|
|
150
|
-
target: finalArgs,
|
|
151
|
-
...options,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
async function main() {
|
|
155
|
-
process.on("uncaughtException", (error) => {
|
|
156
|
-
handleError(error);
|
|
157
|
-
});
|
|
158
|
-
try {
|
|
159
|
-
const args = parseArgs();
|
|
160
|
-
await callMethod(args);
|
|
161
|
-
}
|
|
162
|
-
catch (error) {
|
|
163
|
-
handleError(error);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
main();
|
package/cli/build/transport.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
2
|
-
import { getDefaultEnvironment, StdioClientTransport, } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
3
|
-
import { findActualExecutable } from "spawn-rx";
|
|
4
|
-
function createSSETransport(options) {
|
|
5
|
-
const baseUrl = new URL(options.url ?? "");
|
|
6
|
-
const sseUrl = new URL("/sse", baseUrl);
|
|
7
|
-
return new SSEClientTransport(sseUrl);
|
|
8
|
-
}
|
|
9
|
-
function createStdioTransport(options) {
|
|
10
|
-
let args = [];
|
|
11
|
-
if (options.args !== undefined) {
|
|
12
|
-
args = options.args;
|
|
13
|
-
}
|
|
14
|
-
const processEnv = {};
|
|
15
|
-
for (const [key, value] of Object.entries(process.env)) {
|
|
16
|
-
if (value !== undefined) {
|
|
17
|
-
processEnv[key] = value;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
const defaultEnv = getDefaultEnvironment();
|
|
21
|
-
const env = {
|
|
22
|
-
...processEnv,
|
|
23
|
-
...defaultEnv,
|
|
24
|
-
};
|
|
25
|
-
const { cmd: actualCommand, args: actualArgs } = findActualExecutable(options.command ?? "", args);
|
|
26
|
-
return new StdioClientTransport({
|
|
27
|
-
command: actualCommand,
|
|
28
|
-
args: actualArgs,
|
|
29
|
-
env,
|
|
30
|
-
stderr: "pipe",
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
export function createTransport(options) {
|
|
34
|
-
const { transportType } = options;
|
|
35
|
-
try {
|
|
36
|
-
if (transportType === "stdio") {
|
|
37
|
-
return createStdioTransport(options);
|
|
38
|
-
}
|
|
39
|
-
if (transportType === "sse") {
|
|
40
|
-
return createSSETransport(options);
|
|
41
|
-
}
|
|
42
|
-
throw new Error(`Unsupported transport type: ${transportType}`);
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
throw new Error(`Failed to create transport: ${error instanceof Error ? error.message : String(error)}`);
|
|
46
|
-
}
|
|
47
|
-
}
|
package/client/bin/client.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { join, dirname } from "path";
|
|
4
|
-
import { fileURLToPath } from "url";
|
|
5
|
-
import handler from "serve-handler";
|
|
6
|
-
import http from "http";
|
|
7
|
-
import open from "open";
|
|
8
|
-
|
|
9
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
-
const distPath = join(__dirname, "../dist");
|
|
11
|
-
|
|
12
|
-
const server = http.createServer((request, response) => {
|
|
13
|
-
const handlerOptions = {
|
|
14
|
-
public: distPath,
|
|
15
|
-
rewrites: [{ source: "/**", destination: "/index.html" }],
|
|
16
|
-
headers: [
|
|
17
|
-
{
|
|
18
|
-
// Ensure index.html is never cached
|
|
19
|
-
source: "index.html",
|
|
20
|
-
headers: [
|
|
21
|
-
{
|
|
22
|
-
key: "Cache-Control",
|
|
23
|
-
value: "no-cache, no-store, max-age=0",
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
// Allow long-term caching for hashed assets
|
|
29
|
-
source: "assets/**",
|
|
30
|
-
headers: [
|
|
31
|
-
{
|
|
32
|
-
key: "Cache-Control",
|
|
33
|
-
value: "public, max-age=31536000, immutable",
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
return handler(request, response, handlerOptions);
|
|
41
|
-
});
|
|
42
|
-
|
|
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
|
-
|
|
57
|
-
server.on("listening", () => {
|
|
58
|
-
const url = `http://127.0.0.1:${port}`;
|
|
59
|
-
console.log(
|
|
60
|
-
`🔍 MCPJam Inspector is up and running at \u001B]8;;${url}\u0007${url}\u001B]8;;\u0007 🚀`,
|
|
61
|
-
);
|
|
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`,
|
|
66
|
-
);
|
|
67
|
-
open(url);
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
server.listen(port);
|
package/client/bin/start.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { resolve, dirname } from "path";
|
|
4
|
-
import { spawnPromise } from "spawn-rx";
|
|
5
|
-
import { fileURLToPath } from "url";
|
|
6
|
-
|
|
7
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
|
|
9
|
-
const MCP_BANNER = `
|
|
10
|
-
███╗ ███╗ ██████╗██████╗ ██╗ █████╗ ███╗ ███╗
|
|
11
|
-
████╗ ████║██╔════╝██╔══██╗ ██║██╔══██╗████╗ ████║
|
|
12
|
-
██╔████╔██║██║ ██████╔╝ ██║███████║██╔████╔██║
|
|
13
|
-
██║╚██╔╝██║██║ ██╔═══╝██ ██║██╔══██║██║╚██╔╝██║
|
|
14
|
-
██║ ╚═╝ ██║╚██████╗██║ ╚█████╔╝██║ ██║██║ ╚═╝ ██║
|
|
15
|
-
╚═╝ ╚═╝ ╚═════╝╚═╝ ╚════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
|
|
16
|
-
`;
|
|
17
|
-
|
|
18
|
-
function delay(ms) {
|
|
19
|
-
return new Promise((resolve) => setTimeout(resolve, ms, true));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async function main() {
|
|
23
|
-
// Clear console and display banner
|
|
24
|
-
console.clear();
|
|
25
|
-
console.log("\x1b[36m%s\x1b[0m", MCP_BANNER); // Cyan color
|
|
26
|
-
console.log("\x1b[33m%s\x1b[0m", "🚀 Launching MCP Inspector...\n"); // Yellow color
|
|
27
|
-
|
|
28
|
-
// Parse command line arguments
|
|
29
|
-
const args = process.argv.slice(2);
|
|
30
|
-
const envVars = {};
|
|
31
|
-
const mcpServerArgs = [];
|
|
32
|
-
let command = null;
|
|
33
|
-
let parsingFlags = true;
|
|
34
|
-
|
|
35
|
-
for (let i = 0; i < args.length; i++) {
|
|
36
|
-
const arg = args[i];
|
|
37
|
-
|
|
38
|
-
if (parsingFlags && arg === "--") {
|
|
39
|
-
parsingFlags = false;
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (parsingFlags && arg === "-e" && i + 1 < args.length) {
|
|
44
|
-
const envVar = args[++i];
|
|
45
|
-
const equalsIndex = envVar.indexOf("=");
|
|
46
|
-
|
|
47
|
-
if (equalsIndex !== -1) {
|
|
48
|
-
const key = envVar.substring(0, equalsIndex);
|
|
49
|
-
const value = envVar.substring(equalsIndex + 1);
|
|
50
|
-
envVars[key] = value;
|
|
51
|
-
} else {
|
|
52
|
-
envVars[envVar] = "";
|
|
53
|
-
}
|
|
54
|
-
} else if (!command) {
|
|
55
|
-
command = arg;
|
|
56
|
-
} else {
|
|
57
|
-
mcpServerArgs.push(arg);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const inspectorServerPath = resolve(
|
|
62
|
-
__dirname,
|
|
63
|
-
"../..",
|
|
64
|
-
"server",
|
|
65
|
-
"build",
|
|
66
|
-
"index.js",
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
// Path to the client entry point
|
|
70
|
-
const inspectorClientPath = resolve(
|
|
71
|
-
__dirname,
|
|
72
|
-
"../..",
|
|
73
|
-
"client",
|
|
74
|
-
"bin",
|
|
75
|
-
"client.js",
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
const CLIENT_PORT = process.env.CLIENT_PORT ?? "6274";
|
|
79
|
-
const SERVER_PORT = process.env.SERVER_PORT ?? "6277";
|
|
80
|
-
|
|
81
|
-
const abort = new AbortController();
|
|
82
|
-
|
|
83
|
-
let cancelled = false;
|
|
84
|
-
process.on("SIGINT", () => {
|
|
85
|
-
cancelled = true;
|
|
86
|
-
abort.abort();
|
|
87
|
-
console.log("\n\x1b[31m%s\x1b[0m", "⚠️ Shutting down MCP Inspector..."); // Red color
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
let server, serverOk;
|
|
91
|
-
try {
|
|
92
|
-
server = spawnPromise(
|
|
93
|
-
"node",
|
|
94
|
-
[
|
|
95
|
-
inspectorServerPath,
|
|
96
|
-
...(command ? [`--env`, command] : []),
|
|
97
|
-
...(mcpServerArgs ? [`--args=${mcpServerArgs.join(" ")}`] : []),
|
|
98
|
-
],
|
|
99
|
-
{
|
|
100
|
-
env: {
|
|
101
|
-
...process.env,
|
|
102
|
-
PORT: SERVER_PORT,
|
|
103
|
-
MCP_ENV_VARS: JSON.stringify(envVars),
|
|
104
|
-
},
|
|
105
|
-
signal: abort.signal,
|
|
106
|
-
echoOutput: true,
|
|
107
|
-
},
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
// Make sure server started before starting client
|
|
111
|
-
serverOk = await Promise.race([server, delay(2 * 1000)]);
|
|
112
|
-
} catch (error) {
|
|
113
|
-
console.log("\x1b[31m%s\x1b[0m", "❌ Server initialization failed"); // Red color
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (serverOk) {
|
|
117
|
-
try {
|
|
118
|
-
console.log("\x1b[32m%s\x1b[0m", "✅ Server initialized successfully"); // Green color
|
|
119
|
-
console.log("\x1b[33m%s\x1b[0m", "🖥️ Starting client interface...");
|
|
120
|
-
|
|
121
|
-
await spawnPromise("node", [inspectorClientPath], {
|
|
122
|
-
env: {
|
|
123
|
-
...process.env,
|
|
124
|
-
PORT: CLIENT_PORT,
|
|
125
|
-
MCP_AUTO_OPEN_ENABLED: process.env.MCP_AUTO_OPEN_ENABLED ?? "true",
|
|
126
|
-
},
|
|
127
|
-
signal: abort.signal,
|
|
128
|
-
echoOutput: true,
|
|
129
|
-
});
|
|
130
|
-
} catch (e) {
|
|
131
|
-
if (!cancelled || process.env.DEBUG) throw e;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return 0;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
main()
|
|
139
|
-
.then((_) => process.exit(0))
|
|
140
|
-
.catch((e) => {
|
|
141
|
-
console.error("\x1b[31m%s\x1b[0m", "❌ Error:", e); // Red color
|
|
142
|
-
process.exit(1);
|
|
143
|
-
});
|
|
@@ -1,56 +0,0 @@
|
|
|
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-DTD8_Uq7.js";
|
|
2
|
-
const OAuthCallback = ({ onConnect }) => {
|
|
3
|
-
const { toast } = useToast();
|
|
4
|
-
const hasProcessedRef = reactExports.useRef(false);
|
|
5
|
-
reactExports.useEffect(() => {
|
|
6
|
-
const handleCallback = async () => {
|
|
7
|
-
if (hasProcessedRef.current) {
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
hasProcessedRef.current = true;
|
|
11
|
-
const notifyError = (description) => void toast({
|
|
12
|
-
title: "OAuth Authorization Error",
|
|
13
|
-
description,
|
|
14
|
-
variant: "destructive"
|
|
15
|
-
});
|
|
16
|
-
const params = parseOAuthCallbackParams(window.location.search);
|
|
17
|
-
if (!params.successful) {
|
|
18
|
-
return notifyError(generateOAuthErrorDescription(params));
|
|
19
|
-
}
|
|
20
|
-
const serverUrl = sessionStorage.getItem(SESSION_KEYS.SERVER_URL);
|
|
21
|
-
if (!serverUrl) {
|
|
22
|
-
return notifyError("Missing Server URL");
|
|
23
|
-
}
|
|
24
|
-
let result;
|
|
25
|
-
try {
|
|
26
|
-
const serverAuthProvider = new InspectorOAuthClientProvider(serverUrl);
|
|
27
|
-
result = await auth(serverAuthProvider, {
|
|
28
|
-
serverUrl,
|
|
29
|
-
authorizationCode: params.code
|
|
30
|
-
});
|
|
31
|
-
} catch (error) {
|
|
32
|
-
console.error("OAuth callback error:", error);
|
|
33
|
-
return notifyError(`Unexpected error occurred: ${error}`);
|
|
34
|
-
}
|
|
35
|
-
if (result !== "AUTHORIZED") {
|
|
36
|
-
return notifyError(
|
|
37
|
-
`Expected to be authorized after providing auth code, got: ${result}`
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
toast({
|
|
41
|
-
title: "Success",
|
|
42
|
-
description: "Successfully authenticated with OAuth",
|
|
43
|
-
variant: "default"
|
|
44
|
-
});
|
|
45
|
-
onConnect(serverUrl);
|
|
46
|
-
};
|
|
47
|
-
handleCallback().finally(() => {
|
|
48
|
-
sessionStorage.removeItem(SESSION_KEYS.TRANSPORT_TYPE);
|
|
49
|
-
window.history.replaceState({}, document.title, "/");
|
|
50
|
-
});
|
|
51
|
-
}, [toast, onConnect]);
|
|
52
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-screen", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-lg text-gray-500", children: "Processing OAuth callback..." }) });
|
|
53
|
-
};
|
|
54
|
-
export {
|
|
55
|
-
OAuthCallback as default
|
|
56
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-DTD8_Uq7.js";
|
|
2
|
-
const OAuthDebugCallback = ({ onConnect }) => {
|
|
3
|
-
reactExports.useEffect(() => {
|
|
4
|
-
let isProcessed = false;
|
|
5
|
-
const handleCallback = async () => {
|
|
6
|
-
if (isProcessed) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
isProcessed = true;
|
|
10
|
-
const params = parseOAuthCallbackParams(window.location.search);
|
|
11
|
-
if (!params.successful) {
|
|
12
|
-
const errorMsg = generateOAuthErrorDescription(params);
|
|
13
|
-
onConnect({ errorMsg });
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
const serverUrl = sessionStorage.getItem(SESSION_KEYS.SERVER_URL);
|
|
17
|
-
if (!serverUrl) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
if (!params.code) {
|
|
21
|
-
onConnect({ errorMsg: "Missing authorization code" });
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
onConnect({ authorizationCode: params.code });
|
|
25
|
-
};
|
|
26
|
-
handleCallback().finally(() => {
|
|
27
|
-
if (sessionStorage.getItem(SESSION_KEYS.SERVER_URL)) {
|
|
28
|
-
window.history.replaceState({}, document.title, "/");
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
return () => {
|
|
32
|
-
isProcessed = true;
|
|
33
|
-
};
|
|
34
|
-
}, [onConnect]);
|
|
35
|
-
const callbackParams = parseOAuthCallbackParams(window.location.search);
|
|
36
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-screen", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 p-4 bg-secondary rounded-md max-w-md", children: [
|
|
37
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mb-2 text-sm", children: "Please copy this authorization code and return to the Auth Debugger:" }),
|
|
38
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "block p-2 bg-muted rounded-sm overflow-x-auto text-xs", children: callbackParams.successful && "code" in callbackParams ? callbackParams.code : `No code found: ${callbackParams.error}, ${callbackParams.error_description}` }),
|
|
39
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-4 text-xs text-muted-foreground", children: "Close this tab and paste the code in the OAuth flow to complete authentication." })
|
|
40
|
-
] }) });
|
|
41
|
-
};
|
|
42
|
-
export {
|
|
43
|
-
OAuthDebugCallback as default
|
|
44
|
-
};
|