Skip to content

Commit b8cefbd

Browse files
baotlakeclaude
andcommitted
feat: add online sharing functionality and library build support
- Add SidebarShare component for copying shareable inspector links - Add library build configuration with Vite and DTS plugin - Update OAuth callback paths for online deployment (/inspector/oauth/callback) - Change default connection type from "proxy" to "direct" - Change default transport type from "stdio" to "sse" - Update app title to "Online MCP Inspector" - Add MCP Servers navigation button - Add getProxyMCPURL utility function for proxy URL generation - Export App component and TooltipProvider for library usage - Update GitHub repository reference to web-mcp/online-mcp-inspector 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent c7683b4 commit b8cefbd

File tree

12 files changed

+1136
-113
lines changed

12 files changed

+1136
-113
lines changed

client/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
],
1717
"scripts": {
1818
"dev": "vite --port 6274",
19+
"lib": "vite build -c vite.library.ts",
1920
"build": "tsc -b && vite build",
2021
"lint": "eslint .",
2122
"preview": "vite preview --port 6274",
@@ -77,6 +78,7 @@
7778
"ts-jest": "^29.4.0",
7879
"typescript": "^5.5.3",
7980
"typescript-eslint": "^8.38.0",
80-
"vite": "^7.1.11"
81+
"vite": "^7.1.11",
82+
"vite-plugin-dts": "^4.5.4"
8183
}
8284
}

client/src/App.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ const App = () => {
113113
() => {
114114
return (
115115
(localStorage.getItem("lastConnectionType") as "direct" | "proxy") ||
116-
"proxy"
116+
"direct"
117117
);
118118
},
119119
);
@@ -858,7 +858,7 @@ const App = () => {
858858
</TabsContent>
859859
);
860860

861-
if (window.location.pathname === "/oauth/callback") {
861+
if (window.location.pathname === "/inspector/oauth/callback") {
862862
const OAuthCallback = React.lazy(
863863
() => import("./components/OAuthCallback"),
864864
);
@@ -869,7 +869,7 @@ const App = () => {
869869
);
870870
}
871871

872-
if (window.location.pathname === "/oauth/callback/debug") {
872+
if (window.location.pathname === "/inspector/oauth/callback/debug") {
873873
const OAuthDebugCallback = React.lazy(
874874
() => import("./components/OAuthDebugCallback"),
875875
);

client/src/components/OAuthCallback.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const OAuthCallback = ({ onConnect }: OAuthCallbackProps) => {
7171
};
7272

7373
handleCallback().finally(() => {
74-
window.history.replaceState({}, document.title, "/");
74+
window.history.replaceState({}, document.title, "/inspector");
7575
});
7676
}, [toast, onConnect]);
7777

client/src/components/Sidebar.tsx

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
RefreshCwOff,
1515
Copy,
1616
CheckCheck,
17+
Compass,
1718
} from "lucide-react";
1819
import { Button } from "@/components/ui/button";
1920
import { Input } from "@/components/ui/input";
@@ -40,6 +41,7 @@ import {
4041
import CustomHeaders from "./CustomHeaders";
4142
import { CustomHeaders as CustomHeadersType } from "@/lib/types/customHeaders";
4243
import { useToast } from "../lib/hooks/useToast";
44+
import SidebarShare from "./SidebarShare";
4345

4446
interface SidebarProps {
4547
connectionStatus: ConnectionStatus;
@@ -233,7 +235,7 @@ const Sidebar = ({
233235
<div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-border">
234236
<div className="flex items-center">
235237
<h1 className="ml-2 text-lg font-semibold">
236-
MCP Inspector v{version}
238+
Online MCP Inspector v{version}
237239
</h1>
238240
</div>
239241
</div>
@@ -598,7 +600,9 @@ const Sidebar = ({
598600
<Input
599601
readOnly
600602
placeholder="Redirect URL"
601-
value={window.location.origin + "/oauth/callback"}
603+
value={
604+
window.location.origin + "/inspector/oauth/callback"
605+
}
602606
className="font-mono"
603607
/>
604608
<label className="text-sm font-medium">Scope</label>
@@ -803,6 +807,15 @@ const Sidebar = ({
803807
</Select>
804808
</div>
805809
)}
810+
811+
<SidebarShare
812+
sseUrl={sseUrl}
813+
transportType={transportType}
814+
command={command}
815+
args={args}
816+
connectionStatus={connectionStatus}
817+
connectionType={connectionType}
818+
/>
806819
</div>
807820
</div>
808821
</div>
@@ -839,17 +852,27 @@ const Sidebar = ({
839852
href="https://modelcontextprotocol.io/docs/tools/debugging"
840853
target="_blank"
841854
rel="noopener noreferrer"
855+
className="hidden"
842856
>
843857
<Bug className="w-4 h-4 text-foreground" />
844858
</a>
845859
</Button>
860+
<Button variant="ghost" title="MCP Servers" asChild>
861+
<a
862+
href="/docs/inspector/MCP-Servers"
863+
target="_blank"
864+
rel="noopener noreferrer"
865+
>
866+
<Compass className="w-4 h-4 text-foreground" />
867+
</a>
868+
</Button>
846869
<Button
847870
variant="ghost"
848871
title="Report bugs or contribute on GitHub"
849872
asChild
850873
>
851874
<a
852-
href="https://github.com/modelcontextprotocol/inspector"
875+
href="https://github.com/web-mcp/online-mcp-inspector"
853876
target="_blank"
854877
rel="noopener noreferrer"
855878
>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Button } from "@/components/ui/button";
2+
import { ConnectionStatus } from "@/lib/constants";
3+
import { cn } from "@/lib/utils";
4+
import { Copy, CheckCheck } from "lucide-react";
5+
import { useState } from "react";
6+
7+
type Props = {
8+
sseUrl: string;
9+
transportType: "stdio" | "sse" | "streamable-http";
10+
command?: string;
11+
args?: string;
12+
connectionStatus?: ConnectionStatus;
13+
connectionType?: "direct" | "proxy";
14+
};
15+
const SidebarShare = ({
16+
sseUrl,
17+
transportType,
18+
command,
19+
args,
20+
connectionStatus,
21+
connectionType,
22+
}: Props) => {
23+
const [copied, setCopied] = useState(false);
24+
25+
const handleCopy = () => {
26+
const u = new URL(location.origin + "/inspector");
27+
u.searchParams.set("serverUrl", sseUrl);
28+
u.searchParams.set("transport", transportType);
29+
if (transportType === "stdio") {
30+
u.searchParams.set("serverCommand", command || "");
31+
u.searchParams.set("serverArgs", args || "");
32+
}
33+
34+
navigator.clipboard.writeText(u.toString());
35+
setCopied(true);
36+
setTimeout(() => setCopied(false), 2000);
37+
};
38+
39+
return (
40+
<div className={cn("mt-5", {})}>
41+
<Button
42+
variant={
43+
connectionType == "direct" &&
44+
connectionStatus == "connected" &&
45+
sseUrl
46+
? "default"
47+
: "outline"
48+
}
49+
onClick={handleCopy}
50+
className="w-full"
51+
>
52+
{copied ? (
53+
<CheckCheck className="h-4 w-4 mr-2" />
54+
) : (
55+
<Copy className="h-4 w-4 mr-2" />
56+
)}
57+
Copy Shareable Link
58+
</Button>
59+
</div>
60+
);
61+
};
62+
63+
export default SidebarShare;

client/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import "./index.css";
2+
3+
export { default as App } from "./App";
4+
export { TooltipProvider } from "./components/ui/tooltip.tsx";

client/src/lib/auth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ export class InspectorOAuthClientProvider implements OAuthClientProvider {
114114
scope: string | undefined;
115115

116116
get redirectUrl() {
117-
return window.location.origin + "/oauth/callback";
117+
return window.location.origin + "/inspector/oauth/callback";
118118
}
119119

120120
get debugRedirectUrl() {
121-
return window.location.origin + "/oauth/callback/debug";
121+
return window.location.origin + "/inspector/oauth/callback/debug";
122122
}
123123

124124
get redirect_uris() {

client/src/lib/hooks/useConnection.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ export function useConnection({
394394
await checkProxyHealth();
395395
} catch {
396396
setConnectionStatus("error-connecting-to-proxy");
397-
return;
397+
// return;
398398
}
399399
}
400400

client/src/utils/configUtils.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,49 @@ export const getMCPProxyAddress = (config: InspectorConfig): string => {
2727
return `${window.location.protocol}//${window.location.hostname}:${proxyPort}`;
2828
};
2929

30+
export const getProxyMCPURL = (
31+
config: InspectorConfig,
32+
option: {
33+
transportType?: "stdio" | "sse" | "streamable-http";
34+
sseUrl?: string;
35+
command?: string;
36+
args?: string;
37+
env?: Record<string, string>;
38+
},
39+
) => {
40+
let mcpProxyServerUrl: URL;
41+
const { transportType = "sse", sseUrl, command, args, env } = option;
42+
43+
if (!config.MCP_PROXY_FULL_ADDRESS.value && transportType != "stdio") {
44+
mcpProxyServerUrl = new URL(sseUrl || "http://localhost:3000/sse");
45+
return mcpProxyServerUrl;
46+
}
47+
48+
switch (transportType) {
49+
case "stdio":
50+
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/stdio`);
51+
mcpProxyServerUrl.searchParams.append("command", command || "");
52+
mcpProxyServerUrl.searchParams.append("args", args || "");
53+
mcpProxyServerUrl.searchParams.append("env", JSON.stringify(env));
54+
break;
55+
case "sse":
56+
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/sse`);
57+
mcpProxyServerUrl.searchParams.append("url", sseUrl || "");
58+
break;
59+
case "streamable-http":
60+
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/mcp`);
61+
mcpProxyServerUrl.searchParams.append("url", sseUrl || "");
62+
break;
63+
default:
64+
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/sse`);
65+
mcpProxyServerUrl.searchParams.append("url", sseUrl || "");
66+
break;
67+
}
68+
69+
mcpProxyServerUrl.searchParams.append("transportType", transportType);
70+
return mcpProxyServerUrl;
71+
};
72+
3073
export const getMCPServerRequestTimeout = (config: InspectorConfig): number => {
3174
return config.MCP_SERVER_REQUEST_TIMEOUT.value as number;
3275
};
@@ -67,7 +110,7 @@ export const getInitialTransportType = ():
67110
(localStorage.getItem("lastTransportType") as
68111
| "stdio"
69112
| "sse"
70-
| "streamable-http") || "stdio"
113+
| "streamable-http") || "sse"
71114
);
72115
};
73116

client/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
],
77
"compilerOptions": {
88
"baseUrl": ".",
9+
"jsx": "react-jsx",
910
"paths": {
1011
"@/*": ["./src/*"]
1112
}

0 commit comments

Comments
 (0)