@mcp-use/inspector 0.3.2 → 0.3.5
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 +457 -129
- package/dist/cli/inspect.cjs +19 -129
- package/dist/client/assets/index-CObt6NY0.css +1 -0
- package/dist/client/assets/index-D8xpCgi7.js +1681 -0
- package/dist/client/index.html +2 -2
- package/dist/server/chunk-2CGL7VW4.js +75 -0
- package/dist/server/chunk-KT6SE3BW.js +125 -0
- package/dist/server/chunk-LLCPK3RJ.js +124 -0
- package/dist/server/chunk-PKBMQBKP.js +7 -0
- package/dist/server/index.js +8 -7
- package/dist/server/mcp-inspector.js +7 -132
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +8 -145
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +254 -233
- package/dist/server/shared-utils.d.ts +28 -0
- package/dist/server/shared-utils.d.ts.map +1 -0
- package/dist/server/shared-utils.js +13 -0
- package/package.json +36 -28
- package/dist/cli/inspect.js +0 -265
- package/dist/client/assets/index-BOon65c9.css +0 -1
- package/dist/client/assets/index-sdbH0tuu.js +0 -1656
- package/dist/index.js +0 -107
- package/dist/server/favicon-proxy.d.ts +0 -4
- package/dist/server/favicon-proxy.d.ts.map +0 -1
- package/dist/server/favicon-proxy.js +0 -123
- package/dist/server/standalone.d.ts +0 -9
- package/dist/server/standalone.d.ts.map +0 -1
- package/dist/server/standalone.js +0 -228
- package/dist/server/unified.d.ts +0 -9
- package/dist/server/unified.d.ts.map +0 -1
- package/dist/server/unified.js +0 -294
package/dist/client/index.html
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;500;700&display=swap" rel="stylesheet">
|
|
10
10
|
<title>MCP Inspector</title>
|
|
11
|
-
<script type="module" crossorigin src="/inspector/assets/index-
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/inspector/assets/index-
|
|
11
|
+
<script type="module" crossorigin src="/inspector/assets/index-D8xpCgi7.js"></script>
|
|
12
|
+
<link rel="stylesheet" crossorigin href="/inspector/assets/index-CObt6NY0.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkClientFiles,
|
|
3
|
+
getClientDistPath,
|
|
4
|
+
getContentType,
|
|
5
|
+
handleChatRequest
|
|
6
|
+
} from "./chunk-KT6SE3BW.js";
|
|
7
|
+
|
|
8
|
+
// src/server/middleware.ts
|
|
9
|
+
import { existsSync } from "fs";
|
|
10
|
+
import { join } from "path";
|
|
11
|
+
function mountInspector(app, path = "/inspector", mcpServerUrl) {
|
|
12
|
+
const basePath = path.startsWith("/") ? path : `/${path}`;
|
|
13
|
+
const clientDistPath = getClientDistPath();
|
|
14
|
+
if (!checkClientFiles(clientDistPath)) {
|
|
15
|
+
console.warn(`\u26A0\uFE0F MCP Inspector client files not found at ${clientDistPath}`);
|
|
16
|
+
console.warn(` Run 'yarn build' in the inspector package to build the UI`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
app.get(`${basePath}/config.json`, (_req, res) => {
|
|
20
|
+
res.json({
|
|
21
|
+
autoConnectUrl: mcpServerUrl || null
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
app.post(`${basePath}/api/chat`, async (req, res) => {
|
|
25
|
+
try {
|
|
26
|
+
const result = await handleChatRequest(req.body);
|
|
27
|
+
res.json(result);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error("Chat API error:", error);
|
|
30
|
+
res.status(500).json({
|
|
31
|
+
error: error instanceof Error ? error.message : "Failed to process chat request"
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
app.use(`${basePath}/assets`, (_req, res) => {
|
|
36
|
+
const assetPath = join(clientDistPath, "assets", _req.path);
|
|
37
|
+
if (existsSync(assetPath)) {
|
|
38
|
+
const contentType = getContentType(assetPath);
|
|
39
|
+
res.setHeader("Content-Type", contentType);
|
|
40
|
+
res.sendFile(assetPath);
|
|
41
|
+
} else {
|
|
42
|
+
res.status(404).send("Asset not found");
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
if (basePath !== "") {
|
|
46
|
+
app.get("/oauth/callback", (req, res) => {
|
|
47
|
+
const queryString = req.url.split("?")[1] || "";
|
|
48
|
+
const redirectUrl = queryString ? `${basePath}/oauth/callback?${queryString}` : `${basePath}/oauth/callback`;
|
|
49
|
+
res.redirect(302, redirectUrl);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
app.get(basePath, (_req, res) => {
|
|
53
|
+
const indexPath = join(clientDistPath, "index.html");
|
|
54
|
+
if (!existsSync(indexPath)) {
|
|
55
|
+
res.status(500).send("Inspector UI not found. Please build the inspector package.");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
res.sendFile(indexPath);
|
|
59
|
+
});
|
|
60
|
+
app.get(`${basePath}/`, (_req, res) => {
|
|
61
|
+
res.redirect(301, basePath);
|
|
62
|
+
});
|
|
63
|
+
app.get(`${basePath}/*`, (_req, res) => {
|
|
64
|
+
const indexPath = join(clientDistPath, "index.html");
|
|
65
|
+
if (!existsSync(indexPath)) {
|
|
66
|
+
res.status(500).send("Inspector UI not found. Please build the inspector package.");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
res.sendFile(indexPath);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export {
|
|
74
|
+
mountInspector
|
|
75
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// src/server/shared-utils.ts
|
|
2
|
+
import { Buffer } from "buffer";
|
|
3
|
+
import { existsSync } from "fs";
|
|
4
|
+
import { dirname, join } from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
async function handleChatRequest(requestBody) {
|
|
7
|
+
const { mcpServerUrl, llmConfig, authConfig, messages } = requestBody;
|
|
8
|
+
if (!mcpServerUrl || !llmConfig || !messages) {
|
|
9
|
+
throw new Error("Missing required fields: mcpServerUrl, llmConfig, messages");
|
|
10
|
+
}
|
|
11
|
+
const { MCPAgent, MCPClient } = await import("mcp-use");
|
|
12
|
+
let llm;
|
|
13
|
+
if (llmConfig.provider === "openai") {
|
|
14
|
+
const { ChatOpenAI } = await import("@langchain/openai");
|
|
15
|
+
llm = new ChatOpenAI({
|
|
16
|
+
model: llmConfig.model,
|
|
17
|
+
apiKey: llmConfig.apiKey
|
|
18
|
+
});
|
|
19
|
+
} else if (llmConfig.provider === "anthropic") {
|
|
20
|
+
const { ChatAnthropic } = await import("@langchain/anthropic");
|
|
21
|
+
llm = new ChatAnthropic({
|
|
22
|
+
model: llmConfig.model,
|
|
23
|
+
apiKey: llmConfig.apiKey
|
|
24
|
+
});
|
|
25
|
+
} else if (llmConfig.provider === "google") {
|
|
26
|
+
const { ChatGoogleGenerativeAI } = await import("@langchain/google-genai");
|
|
27
|
+
llm = new ChatGoogleGenerativeAI({
|
|
28
|
+
model: llmConfig.model,
|
|
29
|
+
apiKey: llmConfig.apiKey
|
|
30
|
+
});
|
|
31
|
+
} else {
|
|
32
|
+
throw new Error(`Unsupported LLM provider: ${llmConfig.provider}`);
|
|
33
|
+
}
|
|
34
|
+
const client = new MCPClient();
|
|
35
|
+
const serverName = `inspector-${Date.now()}`;
|
|
36
|
+
const serverConfig = { url: mcpServerUrl };
|
|
37
|
+
if (authConfig && authConfig.type !== "none") {
|
|
38
|
+
serverConfig.headers = {};
|
|
39
|
+
if (authConfig.type === "basic" && authConfig.username && authConfig.password) {
|
|
40
|
+
const auth = Buffer.from(`${authConfig.username}:${authConfig.password}`).toString("base64");
|
|
41
|
+
serverConfig.headers.Authorization = `Basic ${auth}`;
|
|
42
|
+
} else if (authConfig.type === "bearer" && authConfig.token) {
|
|
43
|
+
serverConfig.headers.Authorization = `Bearer ${authConfig.token}`;
|
|
44
|
+
} else if (authConfig.type === "oauth") {
|
|
45
|
+
if (authConfig.oauthTokens?.access_token) {
|
|
46
|
+
const tokenType = authConfig.oauthTokens.token_type ? authConfig.oauthTokens.token_type.charAt(0).toUpperCase() + authConfig.oauthTokens.token_type.slice(1) : "Bearer";
|
|
47
|
+
serverConfig.headers.Authorization = `${tokenType} ${authConfig.oauthTokens.access_token}`;
|
|
48
|
+
console.log("Using OAuth access token for MCP server authentication");
|
|
49
|
+
console.log("Authorization header:", `${tokenType} ${authConfig.oauthTokens.access_token.substring(0, 20)}...`);
|
|
50
|
+
} else {
|
|
51
|
+
console.warn("OAuth selected but no access token provided");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const url = new URL(mcpServerUrl);
|
|
57
|
+
if (url.username && url.password && (!authConfig || authConfig.type === "none")) {
|
|
58
|
+
const auth = Buffer.from(`${url.username}:${url.password}`).toString("base64");
|
|
59
|
+
serverConfig.headers = serverConfig.headers || {};
|
|
60
|
+
serverConfig.headers.Authorization = `Basic ${auth}`;
|
|
61
|
+
serverConfig.url = `${url.protocol}//${url.host}${url.pathname}${url.search}`;
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.warn("Failed to parse MCP server URL for auth:", error);
|
|
65
|
+
}
|
|
66
|
+
console.log("Adding server with config:", {
|
|
67
|
+
url: serverConfig.url,
|
|
68
|
+
hasHeaders: !!serverConfig.headers,
|
|
69
|
+
headers: serverConfig.headers
|
|
70
|
+
});
|
|
71
|
+
client.addServer(serverName, serverConfig);
|
|
72
|
+
const agent = new MCPAgent({
|
|
73
|
+
llm,
|
|
74
|
+
client,
|
|
75
|
+
maxSteps: 10,
|
|
76
|
+
memoryEnabled: true,
|
|
77
|
+
systemPrompt: "You are a helpful assistant with access to MCP tools, prompts, and resources. Help users interact with the MCP server."
|
|
78
|
+
});
|
|
79
|
+
const lastUserMessage = messages.filter((msg) => msg.role === "user").pop();
|
|
80
|
+
if (!lastUserMessage) {
|
|
81
|
+
throw new Error("No user message found");
|
|
82
|
+
}
|
|
83
|
+
const response = await agent.run(lastUserMessage.content);
|
|
84
|
+
await client.closeAllSessions();
|
|
85
|
+
return {
|
|
86
|
+
content: response,
|
|
87
|
+
toolCalls: []
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function getContentType(filePath) {
|
|
91
|
+
if (filePath.endsWith(".js")) {
|
|
92
|
+
return "application/javascript";
|
|
93
|
+
} else if (filePath.endsWith(".css")) {
|
|
94
|
+
return "text/css";
|
|
95
|
+
} else if (filePath.endsWith(".svg")) {
|
|
96
|
+
return "image/svg+xml";
|
|
97
|
+
} else if (filePath.endsWith(".html")) {
|
|
98
|
+
return "text/html";
|
|
99
|
+
} else if (filePath.endsWith(".json")) {
|
|
100
|
+
return "application/json";
|
|
101
|
+
} else if (filePath.endsWith(".png")) {
|
|
102
|
+
return "image/png";
|
|
103
|
+
} else if (filePath.endsWith(".jpg") || filePath.endsWith(".jpeg")) {
|
|
104
|
+
return "image/jpeg";
|
|
105
|
+
} else if (filePath.endsWith(".ico")) {
|
|
106
|
+
return "image/x-icon";
|
|
107
|
+
} else {
|
|
108
|
+
return "application/octet-stream";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function checkClientFiles(clientDistPath) {
|
|
112
|
+
return existsSync(clientDistPath);
|
|
113
|
+
}
|
|
114
|
+
function getClientDistPath() {
|
|
115
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
116
|
+
const __dirname = dirname(__filename);
|
|
117
|
+
return join(__dirname, "../../dist/client");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export {
|
|
121
|
+
handleChatRequest,
|
|
122
|
+
getContentType,
|
|
123
|
+
checkClientFiles,
|
|
124
|
+
getClientDistPath
|
|
125
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__publicField
|
|
3
|
+
} from "./chunk-PKBMQBKP.js";
|
|
4
|
+
|
|
5
|
+
// src/server/mcp-inspector.ts
|
|
6
|
+
import { MCPClient } from "mcp-use";
|
|
7
|
+
var MCPInspector = class {
|
|
8
|
+
constructor() {
|
|
9
|
+
__publicField(this, "servers", /* @__PURE__ */ new Map());
|
|
10
|
+
__publicField(this, "client");
|
|
11
|
+
this.client = new MCPClient();
|
|
12
|
+
}
|
|
13
|
+
async listServers() {
|
|
14
|
+
return Array.from(this.servers.values());
|
|
15
|
+
}
|
|
16
|
+
async connectToServer(url, command) {
|
|
17
|
+
const id = Date.now().toString();
|
|
18
|
+
const name = url || command || "Unknown Server";
|
|
19
|
+
try {
|
|
20
|
+
const serverName = `server_${id}`;
|
|
21
|
+
const serverConfig = url ? { url } : { command };
|
|
22
|
+
this.client.addServer(serverName, serverConfig);
|
|
23
|
+
const session = await this.client.createSession(serverName, true);
|
|
24
|
+
const tools = [
|
|
25
|
+
{
|
|
26
|
+
name: "get_weather",
|
|
27
|
+
description: "Get current weather for a location",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
location: { type: "string", description: "City name" }
|
|
32
|
+
},
|
|
33
|
+
required: ["location"]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
const resources = [
|
|
38
|
+
{
|
|
39
|
+
uri: "file:///home/user/documents",
|
|
40
|
+
name: "Documents",
|
|
41
|
+
description: "User documents directory",
|
|
42
|
+
mimeType: "application/x-directory"
|
|
43
|
+
}
|
|
44
|
+
];
|
|
45
|
+
const server = {
|
|
46
|
+
id,
|
|
47
|
+
name,
|
|
48
|
+
url,
|
|
49
|
+
command,
|
|
50
|
+
status: "connected",
|
|
51
|
+
session,
|
|
52
|
+
tools,
|
|
53
|
+
resources,
|
|
54
|
+
lastActivity: /* @__PURE__ */ new Date()
|
|
55
|
+
};
|
|
56
|
+
this.servers.set(id, server);
|
|
57
|
+
return server;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
const server = {
|
|
60
|
+
id,
|
|
61
|
+
name,
|
|
62
|
+
url,
|
|
63
|
+
command,
|
|
64
|
+
status: "error",
|
|
65
|
+
tools: [],
|
|
66
|
+
resources: [],
|
|
67
|
+
lastActivity: /* @__PURE__ */ new Date()
|
|
68
|
+
};
|
|
69
|
+
this.servers.set(id, server);
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async getServer(id) {
|
|
74
|
+
return this.servers.get(id) || null;
|
|
75
|
+
}
|
|
76
|
+
async executeTool(serverId, toolName, input) {
|
|
77
|
+
const server = this.servers.get(serverId);
|
|
78
|
+
if (!server || !server.session) {
|
|
79
|
+
throw new Error("Server not found or not connected");
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const result = {
|
|
83
|
+
tool: toolName,
|
|
84
|
+
input,
|
|
85
|
+
result: `Mock result for ${toolName} with input: ${JSON.stringify(input)}`,
|
|
86
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
87
|
+
};
|
|
88
|
+
server.lastActivity = /* @__PURE__ */ new Date();
|
|
89
|
+
return result;
|
|
90
|
+
} catch (error) {
|
|
91
|
+
server.status = "error";
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async getServerTools(serverId) {
|
|
96
|
+
const server = this.servers.get(serverId);
|
|
97
|
+
if (!server) {
|
|
98
|
+
throw new Error("Server not found");
|
|
99
|
+
}
|
|
100
|
+
return server.tools;
|
|
101
|
+
}
|
|
102
|
+
async getServerResources(serverId) {
|
|
103
|
+
const server = this.servers.get(serverId);
|
|
104
|
+
if (!server) {
|
|
105
|
+
throw new Error("Server not found");
|
|
106
|
+
}
|
|
107
|
+
return server.resources;
|
|
108
|
+
}
|
|
109
|
+
async disconnectServer(serverId) {
|
|
110
|
+
const server = this.servers.get(serverId);
|
|
111
|
+
if (server && server.session) {
|
|
112
|
+
try {
|
|
113
|
+
await server.session.disconnect();
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error("Error disconnecting from server:", error);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
this.servers.delete(serverId);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export {
|
|
123
|
+
MCPInspector
|
|
124
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
__publicField
|
|
7
|
+
};
|
package/dist/server/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import {
|
|
2
|
+
mountInspector
|
|
3
|
+
} from "./chunk-2CGL7VW4.js";
|
|
4
|
+
import "./chunk-KT6SE3BW.js";
|
|
5
|
+
import "./chunk-PKBMQBKP.js";
|
|
6
|
+
export {
|
|
7
|
+
mountInspector
|
|
8
|
+
};
|
|
@@ -1,132 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
value: new Map()
|
|
9
|
-
});
|
|
10
|
-
Object.defineProperty(this, "client", {
|
|
11
|
-
enumerable: true,
|
|
12
|
-
configurable: true,
|
|
13
|
-
writable: true,
|
|
14
|
-
value: void 0
|
|
15
|
-
});
|
|
16
|
-
this.client = new MCPClient();
|
|
17
|
-
}
|
|
18
|
-
async listServers() {
|
|
19
|
-
return Array.from(this.servers.values());
|
|
20
|
-
}
|
|
21
|
-
async connectToServer(url, command) {
|
|
22
|
-
const id = Date.now().toString();
|
|
23
|
-
const name = url || command || 'Unknown Server';
|
|
24
|
-
try {
|
|
25
|
-
// Configure server in MCP client
|
|
26
|
-
const serverName = `server_${id}`;
|
|
27
|
-
const serverConfig = url ? { url } : { command };
|
|
28
|
-
this.client.addServer(serverName, serverConfig);
|
|
29
|
-
// Create session
|
|
30
|
-
const session = await this.client.createSession(serverName, true);
|
|
31
|
-
// Mock tools and resources for now
|
|
32
|
-
const tools = [
|
|
33
|
-
{
|
|
34
|
-
name: 'get_weather',
|
|
35
|
-
description: 'Get current weather for a location',
|
|
36
|
-
inputSchema: {
|
|
37
|
-
type: 'object',
|
|
38
|
-
properties: {
|
|
39
|
-
location: { type: 'string', description: 'City name' },
|
|
40
|
-
},
|
|
41
|
-
required: ['location'],
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
];
|
|
45
|
-
const resources = [
|
|
46
|
-
{
|
|
47
|
-
uri: 'file:///home/user/documents',
|
|
48
|
-
name: 'Documents',
|
|
49
|
-
description: 'User documents directory',
|
|
50
|
-
mimeType: 'application/x-directory',
|
|
51
|
-
},
|
|
52
|
-
];
|
|
53
|
-
const server = {
|
|
54
|
-
id,
|
|
55
|
-
name,
|
|
56
|
-
url,
|
|
57
|
-
command,
|
|
58
|
-
status: 'connected',
|
|
59
|
-
session,
|
|
60
|
-
tools,
|
|
61
|
-
resources,
|
|
62
|
-
lastActivity: new Date(),
|
|
63
|
-
};
|
|
64
|
-
this.servers.set(id, server);
|
|
65
|
-
return server;
|
|
66
|
-
}
|
|
67
|
-
catch (error) {
|
|
68
|
-
const server = {
|
|
69
|
-
id,
|
|
70
|
-
name,
|
|
71
|
-
url,
|
|
72
|
-
command,
|
|
73
|
-
status: 'error',
|
|
74
|
-
tools: [],
|
|
75
|
-
resources: [],
|
|
76
|
-
lastActivity: new Date(),
|
|
77
|
-
};
|
|
78
|
-
this.servers.set(id, server);
|
|
79
|
-
throw error;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
async getServer(id) {
|
|
83
|
-
return this.servers.get(id) || null;
|
|
84
|
-
}
|
|
85
|
-
async executeTool(serverId, toolName, input) {
|
|
86
|
-
const server = this.servers.get(serverId);
|
|
87
|
-
if (!server || !server.session) {
|
|
88
|
-
throw new Error('Server not found or not connected');
|
|
89
|
-
}
|
|
90
|
-
try {
|
|
91
|
-
// Mock tool execution for now
|
|
92
|
-
const result = {
|
|
93
|
-
tool: toolName,
|
|
94
|
-
input,
|
|
95
|
-
result: `Mock result for ${toolName} with input: ${JSON.stringify(input)}`,
|
|
96
|
-
timestamp: new Date().toISOString(),
|
|
97
|
-
};
|
|
98
|
-
server.lastActivity = new Date();
|
|
99
|
-
return result;
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
server.status = 'error';
|
|
103
|
-
throw error;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
async getServerTools(serverId) {
|
|
107
|
-
const server = this.servers.get(serverId);
|
|
108
|
-
if (!server) {
|
|
109
|
-
throw new Error('Server not found');
|
|
110
|
-
}
|
|
111
|
-
return server.tools;
|
|
112
|
-
}
|
|
113
|
-
async getServerResources(serverId) {
|
|
114
|
-
const server = this.servers.get(serverId);
|
|
115
|
-
if (!server) {
|
|
116
|
-
throw new Error('Server not found');
|
|
117
|
-
}
|
|
118
|
-
return server.resources;
|
|
119
|
-
}
|
|
120
|
-
async disconnectServer(serverId) {
|
|
121
|
-
const server = this.servers.get(serverId);
|
|
122
|
-
if (server && server.session) {
|
|
123
|
-
try {
|
|
124
|
-
await server.session.disconnect();
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
console.error('Error disconnecting from server:', error);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
this.servers.delete(serverId);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
MCPInspector
|
|
3
|
+
} from "./chunk-LLCPK3RJ.js";
|
|
4
|
+
import "./chunk-PKBMQBKP.js";
|
|
5
|
+
export {
|
|
6
|
+
MCPInspector
|
|
7
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAqB,MAAM,SAAS,CAAA;AAKzD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE,MAAqB,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CA2FrG"}
|
|
@@ -1,145 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* Similar to how FastAPI mounts Swagger UI at /docs
|
|
10
|
-
*
|
|
11
|
-
* @param app - Express application instance
|
|
12
|
-
* @param path - Mount path (default: '/inspector')
|
|
13
|
-
* @param mcpServerUrl - Optional MCP server URL to auto-connect to
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```typescript
|
|
17
|
-
* import { createMCPServer } from 'mcp-use'
|
|
18
|
-
* import { mountInspector } from '@mcp-use/inspector'
|
|
19
|
-
*
|
|
20
|
-
* const server = createMCPServer('my-server')
|
|
21
|
-
* mountInspector(server) // Mounts at /inspector
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export function mountInspector(app, path = '/inspector', mcpServerUrl) {
|
|
25
|
-
// Ensure path starts with /
|
|
26
|
-
const basePath = path.startsWith('/') ? path : `/${path}`;
|
|
27
|
-
// Find the built client files
|
|
28
|
-
const clientDistPath = join(__dirname, '../../dist/client');
|
|
29
|
-
if (!existsSync(clientDistPath)) {
|
|
30
|
-
console.warn(`⚠️ MCP Inspector client files not found at ${clientDistPath}`);
|
|
31
|
-
console.warn(` Run 'yarn build' in the inspector package to build the UI`);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
// Serve inspector config endpoint
|
|
35
|
-
app.get(`${basePath}/config.json`, (_req, res) => {
|
|
36
|
-
res.json({
|
|
37
|
-
autoConnectUrl: mcpServerUrl || null,
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
// Favicon proxy endpoint
|
|
41
|
-
app.get(`${basePath}/api/favicon/:url`, async (req, res) => {
|
|
42
|
-
const url = req.params.url;
|
|
43
|
-
if (!url) {
|
|
44
|
-
res.status(400).json({ error: 'URL parameter is required' });
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
try {
|
|
48
|
-
// Decode the URL
|
|
49
|
-
const decodedUrl = decodeURIComponent(url);
|
|
50
|
-
// Add protocol if missing
|
|
51
|
-
let fullUrl = decodedUrl;
|
|
52
|
-
if (!decodedUrl.startsWith('http://') && !decodedUrl.startsWith('https://')) {
|
|
53
|
-
fullUrl = `https://${decodedUrl}`;
|
|
54
|
-
}
|
|
55
|
-
// Validate URL
|
|
56
|
-
const urlObj = new URL(fullUrl);
|
|
57
|
-
// Try to fetch favicon from common locations
|
|
58
|
-
const faviconUrls = [
|
|
59
|
-
`${urlObj.origin}/favicon.ico`,
|
|
60
|
-
`${urlObj.origin}/favicon.png`,
|
|
61
|
-
`${urlObj.origin}/apple-touch-icon.png`,
|
|
62
|
-
];
|
|
63
|
-
for (const faviconUrl of faviconUrls) {
|
|
64
|
-
try {
|
|
65
|
-
const response = await fetch(faviconUrl, {
|
|
66
|
-
headers: {
|
|
67
|
-
'User-Agent': 'Mozilla/5.0 (compatible; MCP-Inspector/1.0)',
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
if (response.ok) {
|
|
71
|
-
const contentType = response.headers.get('content-type') || 'image/x-icon';
|
|
72
|
-
const buffer = await response.arrayBuffer();
|
|
73
|
-
res.setHeader('Content-Type', contentType);
|
|
74
|
-
res.setHeader('Cache-Control', 'public, max-age=86400');
|
|
75
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
76
|
-
res.send(Buffer.from(buffer));
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
catch {
|
|
81
|
-
// Continue to next URL
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
// If no favicon found, return 404
|
|
86
|
-
res.status(404).json({ error: 'No favicon found' });
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
console.error('Favicon proxy error:', error);
|
|
90
|
-
res.status(400).json({ error: 'Invalid URL or fetch failed' });
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
// Serve static assets
|
|
94
|
-
app.use(`${basePath}/assets`, (_req, res) => {
|
|
95
|
-
const assetPath = join(clientDistPath, 'assets', _req.path);
|
|
96
|
-
if (existsSync(assetPath)) {
|
|
97
|
-
// Set appropriate content type
|
|
98
|
-
if (assetPath.endsWith('.js')) {
|
|
99
|
-
res.setHeader('Content-Type', 'application/javascript');
|
|
100
|
-
}
|
|
101
|
-
else if (assetPath.endsWith('.css')) {
|
|
102
|
-
res.setHeader('Content-Type', 'text/css');
|
|
103
|
-
}
|
|
104
|
-
res.sendFile(assetPath);
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
res.status(404).send('Asset not found');
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
// Handle OAuth callback redirects - redirect /oauth/callback to /inspector/oauth/callback
|
|
111
|
-
// This helps when OAuth providers are configured with the wrong redirect URL
|
|
112
|
-
if (basePath !== '') {
|
|
113
|
-
app.get('/oauth/callback', (req, res) => {
|
|
114
|
-
const queryString = req.url.split('?')[1] || '';
|
|
115
|
-
const redirectUrl = queryString
|
|
116
|
-
? `${basePath}/oauth/callback?${queryString}`
|
|
117
|
-
: `${basePath}/oauth/callback`;
|
|
118
|
-
res.redirect(302, redirectUrl);
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
// Serve the main HTML file for the root inspector path (exact match)
|
|
122
|
-
app.get(basePath, (_req, res) => {
|
|
123
|
-
const indexPath = join(clientDistPath, 'index.html');
|
|
124
|
-
if (!existsSync(indexPath)) {
|
|
125
|
-
res.status(500).send('Inspector UI not found. Please build the inspector package.');
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
// Serve the HTML file (Vite built with base: '/inspector')
|
|
129
|
-
res.sendFile(indexPath);
|
|
130
|
-
});
|
|
131
|
-
// Redirect /inspector/ to /inspector (remove trailing slash)
|
|
132
|
-
app.get(`${basePath}/`, (_req, res) => {
|
|
133
|
-
res.redirect(301, basePath);
|
|
134
|
-
});
|
|
135
|
-
// Serve the main HTML file for all other inspector routes (SPA routing)
|
|
136
|
-
app.get(`${basePath}/*`, (_req, res) => {
|
|
137
|
-
const indexPath = join(clientDistPath, 'index.html');
|
|
138
|
-
if (!existsSync(indexPath)) {
|
|
139
|
-
res.status(500).send('Inspector UI not found. Please build the inspector package.');
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
// Serve the HTML file (Vite built with base: '/inspector')
|
|
143
|
-
res.sendFile(indexPath);
|
|
144
|
-
});
|
|
145
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
mountInspector
|
|
3
|
+
} from "./chunk-2CGL7VW4.js";
|
|
4
|
+
import "./chunk-KT6SE3BW.js";
|
|
5
|
+
import "./chunk-PKBMQBKP.js";
|
|
6
|
+
export {
|
|
7
|
+
mountInspector
|
|
8
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAsVA,iBAAe,WAAW;;;GA8DzB;;;;AAOD,wBAA8B"}
|