@@ -93,6 +93,7 @@ const ServerCard: React.FC<ServerCardProps> = ({ server, onToggle, onEdit, canMo
93
93
const [ loadingTools , setLoadingTools ] = useState ( false ) ;
94
94
const [ showTools , setShowTools ] = useState ( false ) ;
95
95
const [ showConfig , setShowConfig ] = useState ( false ) ;
96
+ const [ selectedIDE , setSelectedIDE ] = useState < 'vscode' | 'cursor' | 'cline' | 'windsurf' | 'agents' > ( 'vscode' ) ;
96
97
const [ loadingRefresh , setLoadingRefresh ] = useState ( false ) ;
97
98
98
99
const getStatusIcon = ( ) => {
@@ -186,21 +187,92 @@ const ServerCard: React.FC<ServerCardProps> = ({ server, onToggle, onEdit, canMo
186
187
const currentUrl = new URL ( window . location . origin ) ;
187
188
const baseUrl = `${ currentUrl . protocol } //${ currentUrl . hostname } ` ;
188
189
189
- return {
190
- mcpServers : {
191
- [ serverName ] : {
192
- type : "streamable-http" ,
193
- url : `${ baseUrl } ${ server . path } /mcp` ,
194
- headers : {
195
- "Authorization" : "Bearer [YOUR_AUTH_TOKEN]" ,
196
- "X-Client-Id" : "[YOUR_CLIENT_ID]"
190
+ // Clean up server path - remove trailing slashes and ensure single leading slash
191
+ const cleanPath = server . path . replace ( / \/ + $ / , '' ) . replace ( / ^ \/ + / , '/' ) ;
192
+ const url = `${ baseUrl } ${ cleanPath } /mcp` ;
193
+
194
+ // Generate different config formats for different IDEs
195
+ switch ( selectedIDE ) {
196
+ // https://code.visualstudio.com/docs/copilot/customization/mcp-servers
197
+ case 'vscode' :
198
+ return {
199
+ "servers" : {
200
+ [ serverName ] : {
201
+ "type" : "http" ,
202
+ "url" : url ,
203
+ "headers" : {
204
+ "Authorization" : "Bearer [YOUR_AUTH_TOKEN]"
205
+ }
206
+ }
197
207
} ,
198
- disabled : false ,
199
- alwaysAllow : [ ]
200
- }
201
- }
202
- } ;
203
- } , [ server . name , server . path ] ) ;
208
+ "inputs" : [
209
+ {
210
+ "type" : "promptString" ,
211
+ "id" : "auth-token" ,
212
+ "description" : "Gateway Authentication Token"
213
+ }
214
+ ]
215
+ } ;
216
+
217
+ // https://cursor.com/docs/context/mcp
218
+ case 'cursor' :
219
+ return {
220
+ "mcpServers" : {
221
+ [ serverName ] : {
222
+ "url" : url ,
223
+ "headers" : {
224
+ "Authorization" : "Bearer [YOUR_AUTH_TOKEN]"
225
+ }
226
+ }
227
+ }
228
+ } ;
229
+
230
+ // https://docs.cline.bot/mcp/configuring-mcp-servers
231
+ case 'cline' :
232
+ return {
233
+ "mcpServers" : {
234
+ [ serverName ] : {
235
+ "command" : "curl" ,
236
+ "args" : [ "-X" , "POST" , url , "-H" , "Authorization: Bearer [YOUR_AUTH_TOKEN]" ] ,
237
+ "env" : {
238
+ "AUTH_TOKEN" : "[YOUR_AUTH_TOKEN]"
239
+ } ,
240
+ "alwaysAllow" : [ ] ,
241
+ "disabled" : false
242
+ }
243
+ }
244
+ } ;
245
+
246
+ // https://docs.windsurf.com/windsurf/cascade/mcp
247
+ case 'windsurf' :
248
+ return {
249
+ "mcpServers" : {
250
+ [ serverName ] : {
251
+ "serverUrl" : url
252
+ }
253
+ }
254
+ } ;
255
+
256
+ case 'agents' :
257
+ default :
258
+ return {
259
+ "mcpServers" : {
260
+ [ serverName ] : {
261
+ "type" : "streamable-http" ,
262
+ "url" : url ,
263
+ "headers" : {
264
+ "X-Authorization" : "Bearer [INGRESS_AUTH_TOKEN]" ,
265
+ "X-User-Pool-Id" : "" ,
266
+ "X-Client-Id" : "[YOUR_CLIENT_ID]" ,
267
+ "X-Region" : "us-east-1"
268
+ } ,
269
+ "disabled" : false ,
270
+ "alwaysAllow" : [ ]
271
+ }
272
+ }
273
+ } ;
274
+ }
275
+ } , [ server . name , server . path , selectedIDE ] ) ;
204
276
205
277
// Copy configuration to clipboard
206
278
const copyConfigToClipboard = useCallback ( async ( ) => {
@@ -505,6 +577,71 @@ const ServerCard: React.FC<ServerCardProps> = ({ server, onToggle, onEdit, canMo
505
577
</ p >
506
578
</ div >
507
579
580
+ { /* IDE Selection */ }
581
+ < div className = "bg-gray-50 dark:bg-gray-900 border dark:border-gray-700 rounded-lg p-4" >
582
+ < h4 className = "font-medium text-gray-900 dark:text-white mb-3" >
583
+ Select your IDE/Tool:
584
+ </ h4 >
585
+ < div className = "flex flex-wrap gap-2" >
586
+ < button
587
+ onClick = { ( ) => setSelectedIDE ( 'vscode' ) }
588
+ className = { `px-3 py-2 rounded-lg text-sm font-medium transition-colors ${
589
+ selectedIDE === 'vscode'
590
+ ? 'bg-blue-600 text-white'
591
+ : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
592
+ } `}
593
+ >
594
+ VS Code
595
+ </ button >
596
+ < button
597
+ onClick = { ( ) => setSelectedIDE ( 'cursor' ) }
598
+ className = { `px-3 py-2 rounded-lg text-sm font-medium transition-colors ${
599
+ selectedIDE === 'cursor'
600
+ ? 'bg-blue-600 text-white'
601
+ : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
602
+ } `}
603
+ >
604
+ Cursor
605
+ </ button >
606
+ < button
607
+ onClick = { ( ) => setSelectedIDE ( 'cline' ) }
608
+ className = { `px-3 py-2 rounded-lg text-sm font-medium transition-colors ${
609
+ selectedIDE === 'cline'
610
+ ? 'bg-blue-600 text-white'
611
+ : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
612
+ } `}
613
+ >
614
+ Cline
615
+ </ button >
616
+ < button
617
+ onClick = { ( ) => setSelectedIDE ( 'windsurf' ) }
618
+ className = { `px-3 py-2 rounded-lg text-sm font-medium transition-colors ${
619
+ selectedIDE === 'windsurf'
620
+ ? 'bg-blue-600 text-white'
621
+ : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
622
+ } `}
623
+ >
624
+ Windsurf
625
+ </ button >
626
+ < button
627
+ onClick = { ( ) => setSelectedIDE ( 'agents' ) }
628
+ className = { `px-3 py-2 rounded-lg text-sm font-medium transition-colors ${
629
+ selectedIDE === 'agents'
630
+ ? 'bg-blue-600 text-white'
631
+ : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
632
+ } `}
633
+ >
634
+ AI Agents
635
+ </ button >
636
+ </ div >
637
+ < p className = "text-xs text-gray-600 dark:text-gray-400 mt-2" >
638
+ { selectedIDE === 'agents'
639
+ ? 'Uses "streamable-http" transport type for AI agent compatibility'
640
+ : 'Uses "sse" (Server-Sent Events) transport type for IDE compatibility'
641
+ }
642
+ </ p >
643
+ </ div >
644
+
508
645
{ /* Configuration JSON */ }
509
646
< div className = "space-y-2" >
510
647
< div className = "flex items-center justify-between" >
@@ -528,20 +665,49 @@ const ServerCard: React.FC<ServerCardProps> = ({ server, onToggle, onEdit, canMo
528
665
{ /* Usage Examples */ }
529
666
< div className = "bg-gray-50 dark:bg-gray-900 border dark:border-gray-700 rounded-lg p-4" >
530
667
< h4 className = "font-medium text-gray-900 dark:text-white mb-2" >
531
- Compatible with:
668
+ Configuration for: {
669
+ selectedIDE === 'vscode' ? 'VS Code' :
670
+ selectedIDE === 'cursor' ? 'Cursor' :
671
+ selectedIDE === 'cline' ? 'Cline' :
672
+ selectedIDE === 'windsurf' ? 'Windsurf' :
673
+ 'AI Agents'
674
+ }
532
675
</ h4 >
533
676
< div className = "flex flex-wrap gap-2" >
534
- < span className = "px-2 py-1 bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 rounded text-sm" >
535
- VS Code
677
+ < span className = { `px-2 py-1 rounded text-sm ${
678
+ selectedIDE === 'vscode'
679
+ ? 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200'
680
+ : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400'
681
+ } `} >
682
+ VS Code { selectedIDE === 'vscode' ? '(Selected)' : '' }
536
683
</ span >
537
- < span className = "px-2 py-1 bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 rounded text-sm" >
538
- Cursor
684
+ < span className = { `px-2 py-1 rounded text-sm ${
685
+ selectedIDE === 'cursor'
686
+ ? 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200'
687
+ : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400'
688
+ } `} >
689
+ Cursor { selectedIDE === 'cursor' ? '(Selected)' : '' }
539
690
</ span >
540
- < span className = "px-2 py-1 bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 rounded text-sm" >
541
- Claude Code
691
+ < span className = { `px-2 py-1 rounded text-sm ${
692
+ selectedIDE === 'cline'
693
+ ? 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200'
694
+ : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400'
695
+ } `} >
696
+ Cline { selectedIDE === 'cline' ? '(Selected)' : '' }
542
697
</ span >
543
- < span className = "px-2 py-1 bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 rounded text-sm" >
544
- AI Agents
698
+ < span className = { `px-2 py-1 rounded text-sm ${
699
+ selectedIDE === 'windsurf'
700
+ ? 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200'
701
+ : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400'
702
+ } `} >
703
+ Windsurf { selectedIDE === 'windsurf' ? '(Selected)' : '' }
704
+ </ span >
705
+ < span className = { `px-2 py-1 rounded text-sm ${
706
+ selectedIDE === 'agents'
707
+ ? 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200'
708
+ : 'bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400'
709
+ } `} >
710
+ AI Agents { selectedIDE === 'agents' ? '(Selected)' : '' }
545
711
</ span >
546
712
</ div >
547
713
</ div >
0 commit comments