@@ -6397,6 +6397,298 @@ window.runToolTest = runToolTest;
63976397window . closeModal = closeModal ;
63986398window . testGateway = testGateway ;
63996399
6400+ // ===============================================
6401+ // CONFIG EXPORT FUNCTIONALITY
6402+ // ===============================================
6403+
6404+ /**
6405+ * Global variables to store current config data
6406+ */
6407+ let currentConfigData = null ;
6408+ let currentConfigType = null ;
6409+ let currentServerName = null ;
6410+ let currentServerId = null ;
6411+
6412+ /**
6413+ * Show the config selection modal
6414+ * @param {string } serverId - The server UUID
6415+ * @param {string } serverName - The server name
6416+ */
6417+ function showConfigSelectionModal ( serverId , serverName ) {
6418+ currentServerId = serverId ;
6419+ currentServerName = serverName ;
6420+
6421+ const serverNameDisplay = safeGetElement ( "server-name-display" ) ;
6422+ if ( serverNameDisplay ) {
6423+ serverNameDisplay . textContent = serverName ;
6424+ }
6425+
6426+ openModal ( "config-selection-modal" ) ;
6427+ }
6428+
6429+ /**
6430+ * Generate and show configuration for selected type
6431+ * @param {string } configType - Configuration type: 'stdio', 'sse', or 'http'
6432+ */
6433+ async function generateAndShowConfig ( configType ) {
6434+ try {
6435+ console . log (
6436+ `Generating ${ configType } config for server ${ currentServerId } ` ,
6437+ ) ;
6438+
6439+ // First, fetch the server details
6440+ const response = await fetchWithTimeout (
6441+ `${ window . ROOT_PATH } /admin/servers/${ currentServerId } ` ,
6442+ ) ;
6443+
6444+ if ( ! response . ok ) {
6445+ throw new Error ( `HTTP ${ response . status } : ${ response . statusText } ` ) ;
6446+ }
6447+
6448+ const server = await response . json ( ) ;
6449+
6450+ // Generate the configuration
6451+ const config = generateConfig ( server , configType ) ;
6452+
6453+ // Store data for modal
6454+ currentConfigData = config ;
6455+ currentConfigType = configType ;
6456+
6457+ // Close selection modal and show config display modal
6458+ closeModal ( "config-selection-modal" ) ;
6459+ showConfigDisplayModal ( server , configType , config ) ;
6460+
6461+ console . log ( "✓ Config generated successfully" ) ;
6462+ } catch ( error ) {
6463+ console . error ( "Error generating config:" , error ) ;
6464+ const errorMessage = handleFetchError ( error , "generate configuration" ) ;
6465+ showErrorMessage ( errorMessage ) ;
6466+ }
6467+ }
6468+
6469+ /**
6470+ * Export server configuration in specified format
6471+ * @param {string } serverId - The server UUID
6472+ * @param {string } configType - Configuration type: 'stdio', 'sse', or 'http'
6473+ */
6474+ async function exportServerConfig ( serverId , configType ) {
6475+ try {
6476+ console . log ( `Exporting ${ configType } config for server ${ serverId } ` ) ;
6477+
6478+ // First, fetch the server details
6479+ const response = await fetchWithTimeout (
6480+ `${ window . ROOT_PATH } /admin/servers/${ serverId } ` ,
6481+ ) ;
6482+
6483+ if ( ! response . ok ) {
6484+ throw new Error ( `HTTP ${ response . status } : ${ response . statusText } ` ) ;
6485+ }
6486+
6487+ const server = await response . json ( ) ;
6488+
6489+ // Generate the configuration
6490+ const config = generateConfig ( server , configType ) ;
6491+
6492+ // Store data for modal
6493+ currentConfigData = config ;
6494+ currentConfigType = configType ;
6495+ currentServerName = server . name ;
6496+
6497+ // Show the modal with the config
6498+ showConfigDisplayModal ( server , configType , config ) ;
6499+
6500+ console . log ( "✓ Config generated successfully" ) ;
6501+ } catch ( error ) {
6502+ console . error ( "Error generating config:" , error ) ;
6503+ const errorMessage = handleFetchError ( error , "generate configuration" ) ;
6504+ showErrorMessage ( errorMessage ) ;
6505+ }
6506+ }
6507+
6508+ /**
6509+ * Generate configuration object based on server and type
6510+ * @param {Object } server - Server object from API
6511+ * @param {string } configType - Configuration type
6512+ * @returns {Object } - Generated configuration object
6513+ */
6514+ function generateConfig ( server , configType ) {
6515+ const currentHost = window . location . hostname ;
6516+ const currentPort =
6517+ window . location . port ||
6518+ ( window . location . protocol === "https:" ? "443" : "80" ) ;
6519+ const protocol = window . location . protocol ;
6520+ const baseUrl = `${ protocol } //${ currentHost } ${ currentPort !== "80" && currentPort !== "443" ? ":" + currentPort : "" } ` ;
6521+
6522+ // Clean server name for use as config key (alphanumeric and hyphens only)
6523+ const cleanServerName = server . name
6524+ . toLowerCase ( )
6525+ . replace ( / [ ^ a - z 0 - 9 - ] / g, "-" )
6526+ . replace ( / - + / g, "-" )
6527+ . replace ( / ^ - | - $ / g, "" ) ;
6528+
6529+ switch ( configType ) {
6530+ case "stdio" :
6531+ return {
6532+ mcpServers : {
6533+ [ cleanServerName ] : {
6534+ command : "python" ,
6535+ args : [ "-m" , "mcpgateway.wrapper" ] ,
6536+ env : {
6537+ MCP_AUTH_TOKEN : "your-token-here" ,
6538+ MCP_SERVER_CATALOG_URLS : `${ baseUrl } /servers/${ server . id } ` ,
6539+ MCP_TOOL_CALL_TIMEOUT : "120" ,
6540+ } ,
6541+ } ,
6542+ } ,
6543+ } ;
6544+
6545+ case "sse" :
6546+ return {
6547+ mcpServers : {
6548+ [ cleanServerName ] : {
6549+ type : "sse" ,
6550+ url : `${ baseUrl } /servers/${ server . id } /sse` ,
6551+ headers : {
6552+ Authorization : "Bearer your-token-here" ,
6553+ } ,
6554+ } ,
6555+ } ,
6556+ } ;
6557+
6558+ case "http" :
6559+ return {
6560+ mcpServers : {
6561+ [ cleanServerName ] : {
6562+ type : "http" ,
6563+ url : `${ baseUrl } /servers/${ server . id } ` ,
6564+ headers : {
6565+ Authorization : "Bearer your-token-here" ,
6566+ } ,
6567+ } ,
6568+ } ,
6569+ } ;
6570+
6571+ default :
6572+ throw new Error ( `Unknown config type: ${ configType } ` ) ;
6573+ }
6574+ }
6575+
6576+ /**
6577+ * Show the config display modal with generated configuration
6578+ * @param {Object } server - Server object
6579+ * @param {string } configType - Configuration type
6580+ * @param {Object } config - Generated configuration
6581+ */
6582+ function showConfigDisplayModal ( server , configType , config ) {
6583+ const descriptions = {
6584+ stdio : "Configuration for Claude Desktop, CLI tools, and stdio-based MCP clients" ,
6585+ sse : "Configuration for LangChain, LlamaIndex, and other SSE-based frameworks" ,
6586+ http : "Configuration for REST clients and HTTP-based MCP integrations" ,
6587+ } ;
6588+
6589+ const usageInstructions = {
6590+ stdio : "Save as .mcp.json in your user directory or use in Claude Desktop settings" ,
6591+ sse : "Use with MCP client libraries that support Server-Sent Events transport" ,
6592+ http : "Use with HTTP clients or REST API wrappers for MCP protocol" ,
6593+ } ;
6594+
6595+ // Update modal content
6596+ const descriptionEl = safeGetElement ( "config-description" ) ;
6597+ const usageEl = safeGetElement ( "config-usage" ) ;
6598+ const contentEl = safeGetElement ( "config-content" ) ;
6599+
6600+ if ( descriptionEl ) {
6601+ descriptionEl . textContent = `${ descriptions [ configType ] } for server "${ server . name } "` ;
6602+ }
6603+
6604+ if ( usageEl ) {
6605+ usageEl . textContent = usageInstructions [ configType ] ;
6606+ }
6607+
6608+ if ( contentEl ) {
6609+ contentEl . value = JSON . stringify ( config , null , 2 ) ;
6610+ }
6611+
6612+ // Update title and open the modal
6613+ const titleEl = safeGetElement ( "config-display-title" ) ;
6614+ if ( titleEl ) {
6615+ titleEl . textContent = `${ configType . toUpperCase ( ) } Configuration for ${ server . name } ` ;
6616+ }
6617+ openModal ( "config-display-modal" ) ;
6618+ }
6619+
6620+ /**
6621+ * Copy configuration to clipboard
6622+ */
6623+ async function copyConfigToClipboard ( ) {
6624+ try {
6625+ const contentEl = safeGetElement ( "config-content" ) ;
6626+ if ( ! contentEl ) {
6627+ throw new Error ( "Config content not found" ) ;
6628+ }
6629+
6630+ await navigator . clipboard . writeText ( contentEl . value ) ;
6631+ showSuccessMessage ( "Configuration copied to clipboard!" ) ;
6632+ } catch ( error ) {
6633+ console . error ( "Error copying to clipboard:" , error ) ;
6634+
6635+ // Fallback: select the text for manual copying
6636+ const contentEl = safeGetElement ( "config-content" ) ;
6637+ if ( contentEl ) {
6638+ contentEl . select ( ) ;
6639+ contentEl . setSelectionRange ( 0 , 99999 ) ; // For mobile devices
6640+ showErrorMessage ( "Please copy the selected text manually (Ctrl+C)" ) ;
6641+ } else {
6642+ showErrorMessage ( "Failed to copy configuration" ) ;
6643+ }
6644+ }
6645+ }
6646+
6647+ /**
6648+ * Download configuration as JSON file
6649+ */
6650+ function downloadConfig ( ) {
6651+ if ( ! currentConfigData || ! currentConfigType || ! currentServerName ) {
6652+ showErrorMessage ( "No configuration data available" ) ;
6653+ return ;
6654+ }
6655+
6656+ try {
6657+ const content = JSON . stringify ( currentConfigData , null , 2 ) ;
6658+ const blob = new Blob ( [ content ] , { type : "application/json" } ) ;
6659+ const url = window . URL . createObjectURL ( blob ) ;
6660+
6661+ const a = document . createElement ( "a" ) ;
6662+ a . href = url ;
6663+ a . download = `${ currentServerName } -${ currentConfigType } -config.json` ;
6664+ document . body . appendChild ( a ) ;
6665+ a . click ( ) ;
6666+ document . body . removeChild ( a ) ;
6667+ window . URL . revokeObjectURL ( url ) ;
6668+
6669+ showSuccessMessage ( `Configuration downloaded as ${ a . download } ` ) ;
6670+ } catch ( error ) {
6671+ console . error ( "Error downloading config:" , error ) ;
6672+ showErrorMessage ( "Failed to download configuration" ) ;
6673+ }
6674+ }
6675+
6676+ /**
6677+ * Go back to config selection modal
6678+ */
6679+ function goBackToSelection ( ) {
6680+ closeModal ( "config-display-modal" ) ;
6681+ openModal ( "config-selection-modal" ) ;
6682+ }
6683+
6684+ // Export functions to global scope immediately after definition
6685+ window . showConfigSelectionModal = showConfigSelectionModal ;
6686+ window . generateAndShowConfig = generateAndShowConfig ;
6687+ window . exportServerConfig = exportServerConfig ;
6688+ window . copyConfigToClipboard = copyConfigToClipboard ;
6689+ window . downloadConfig = downloadConfig ;
6690+ window . goBackToSelection = goBackToSelection ;
6691+
64006692// ===============================================
64016693// TAG FILTERING FUNCTIONALITY
64026694// ===============================================
0 commit comments