@@ -12,6 +12,8 @@ import {
12
12
Settings ,
13
13
HelpCircle ,
14
14
RefreshCwOff ,
15
+ Copy ,
16
+ CheckCheck ,
15
17
} from "lucide-react" ;
16
18
import { Button } from "@/components/ui/button" ;
17
19
import { Input } from "@/components/ui/input" ;
@@ -36,6 +38,7 @@ import {
36
38
TooltipTrigger ,
37
39
TooltipContent ,
38
40
} from "@/components/ui/tooltip" ;
41
+ import { useToast } from "@/hooks/use-toast" ;
39
42
40
43
interface SidebarProps {
41
44
connectionStatus : ConnectionStatus ;
@@ -95,6 +98,56 @@ const Sidebar = ({
95
98
const [ showBearerToken , setShowBearerToken ] = useState ( false ) ;
96
99
const [ showConfig , setShowConfig ] = useState ( false ) ;
97
100
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
+ } ;
98
151
99
152
return (
100
153
< div className = "w-80 bg-card border-r border-border flex flex-col h-full" >
@@ -160,6 +213,22 @@ const Sidebar = ({
160
213
className = "font-mono"
161
214
/>
162
215
</ 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 >
163
232
</ >
164
233
) : (
165
234
< >
@@ -175,6 +244,22 @@ const Sidebar = ({
175
244
className = "font-mono"
176
245
/>
177
246
</ 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 >
178
263
< div className = "space-y-2" >
179
264
< Button
180
265
variant = "outline"
0 commit comments