Skip to content

Commit 114df8a

Browse files
feat: add copy config button
1 parent bbe4924 commit 114df8a

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

client/src/components/Sidebar.tsx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
Settings,
1313
HelpCircle,
1414
RefreshCwOff,
15+
Copy,
16+
CheckCheck,
1517
} from "lucide-react";
1618
import { Button } from "@/components/ui/button";
1719
import { Input } from "@/components/ui/input";
@@ -36,6 +38,7 @@ import {
3638
TooltipTrigger,
3739
TooltipContent,
3840
} from "@/components/ui/tooltip";
41+
import { useToast } from "@/hooks/use-toast";
3942

4043
interface SidebarProps {
4144
connectionStatus: ConnectionStatus;
@@ -95,6 +98,56 @@ const Sidebar = ({
9598
const [showBearerToken, setShowBearerToken] = useState(false);
9699
const [showConfig, setShowConfig] = useState(false);
97100
const [shownEnvVars, setShownEnvVars] = useState<Set<string>>(new Set());
101+
const [copiedConfig, setCopiedConfig] = useState(false);
102+
const { toast } = useToast();
103+
104+
// Generate MCP configuration JSON
105+
const generateMCPConfig = () => {
106+
if (transportType === "stdio") {
107+
// Generate only the server config without the mcpServers wrapper
108+
const serverConfig = {
109+
command,
110+
args: args.trim() ? args.split(/\s+/) : [],
111+
env: { ...env },
112+
};
113+
114+
return JSON.stringify(serverConfig, null, 2);
115+
} else {
116+
// For SSE connections
117+
return JSON.stringify({
118+
// SSE configuration doesn't go in mcp.json, but provide the URL info
119+
"type": "sse",
120+
"url": sseUrl,
121+
"note": "For SSE connections, add this URL directly in Cursor"
122+
}, null, 2);
123+
}
124+
};
125+
126+
// Handle copy config
127+
const handleCopyConfig = () => {
128+
try {
129+
const configJson = generateMCPConfig();
130+
navigator.clipboard.writeText(configJson);
131+
setCopiedConfig(true);
132+
133+
toast({
134+
title: "Config copied",
135+
description: transportType === "stdio"
136+
? "Server configuration has been copied to clipboard. Add this to your mcp.json inside the 'mcpServers' object with your preferred server name."
137+
: "SSE URL has been copied. Use this URL in Cursor directly.",
138+
});
139+
140+
setTimeout(() => {
141+
setCopiedConfig(false);
142+
}, 2000);
143+
} catch (error) {
144+
toast({
145+
title: "Error",
146+
description: `Failed to copy config: ${error instanceof Error ? error.message : String(error)}`,
147+
variant: "destructive",
148+
});
149+
}
150+
};
98151

99152
return (
100153
<div className="w-80 bg-card border-r border-border flex flex-col h-full">
@@ -160,6 +213,22 @@ const Sidebar = ({
160213
className="font-mono"
161214
/>
162215
</div>
216+
<div className="flex justify-end">
217+
<Button
218+
variant="outline"
219+
size="sm"
220+
onClick={handleCopyConfig}
221+
className="mt-1"
222+
title="Copy Server Configuration for mcp.json"
223+
>
224+
{copiedConfig ? (
225+
<CheckCheck className="h-4 w-4 mr-2" />
226+
) : (
227+
<Copy className="h-4 w-4 mr-2" />
228+
)}
229+
Copy Config
230+
</Button>
231+
</div>
163232
</>
164233
) : (
165234
<>
@@ -175,6 +244,22 @@ const Sidebar = ({
175244
className="font-mono"
176245
/>
177246
</div>
247+
<div className="flex justify-end">
248+
<Button
249+
variant="outline"
250+
size="sm"
251+
onClick={handleCopyConfig}
252+
className="mt-1"
253+
title="Copy SSE URL Configuration"
254+
>
255+
{copiedConfig ? (
256+
<CheckCheck className="h-4 w-4 mr-2" />
257+
) : (
258+
<Copy className="h-4 w-4 mr-2" />
259+
)}
260+
Copy URL
261+
</Button>
262+
</div>
178263
<div className="space-y-2">
179264
<Button
180265
variant="outline"

0 commit comments

Comments
 (0)