@samanhappy/mcphub 0.12.17 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.fr.md +7 -5
  2. package/README.md +24 -4
  3. package/README.zh.md +25 -4
  4. package/bin/cli.js +64 -50
  5. package/dist/cli/call-arguments.js +81 -0
  6. package/dist/cli/call-arguments.js.map +1 -0
  7. package/dist/cli/commands/call.js +75 -0
  8. package/dist/cli/commands/call.js.map +1 -0
  9. package/dist/cli/commands/config.js +132 -0
  10. package/dist/cli/commands/config.js.map +1 -0
  11. package/dist/cli/commands/discover.js +127 -0
  12. package/dist/cli/commands/discover.js.map +1 -0
  13. package/dist/cli/commands/export.js +20 -0
  14. package/dist/cli/commands/export.js.map +1 -0
  15. package/dist/cli/commands/groups.js +107 -0
  16. package/dist/cli/commands/groups.js.map +1 -0
  17. package/dist/cli/commands/install.js +173 -0
  18. package/dist/cli/commands/install.js.map +1 -0
  19. package/dist/cli/commands/keys.js +91 -0
  20. package/dist/cli/commands/keys.js.map +1 -0
  21. package/dist/cli/commands/login.js +70 -0
  22. package/dist/cli/commands/login.js.map +1 -0
  23. package/dist/cli/commands/servers.js +142 -0
  24. package/dist/cli/commands/servers.js.map +1 -0
  25. package/dist/cli/commands/tools.js +162 -0
  26. package/dist/cli/commands/tools.js.map +1 -0
  27. package/dist/cli/context.js +44 -0
  28. package/dist/cli/context.js.map +1 -0
  29. package/dist/cli/errors.js +19 -0
  30. package/dist/cli/errors.js.map +1 -0
  31. package/dist/cli/help.js +157 -0
  32. package/dist/cli/help.js.map +1 -0
  33. package/dist/cli/http.js +93 -0
  34. package/dist/cli/http.js.map +1 -0
  35. package/dist/cli/main.js +81 -0
  36. package/dist/cli/main.js.map +1 -0
  37. package/dist/cli/output.js +47 -0
  38. package/dist/cli/output.js.map +1 -0
  39. package/dist/cli/parse-args.js +103 -0
  40. package/dist/cli/parse-args.js.map +1 -0
  41. package/dist/cli/profile.js +109 -0
  42. package/dist/cli/profile.js.map +1 -0
  43. package/dist/cli/prompts.js +56 -0
  44. package/dist/cli/prompts.js.map +1 -0
  45. package/dist/controllers/oauthServerController.js +37 -1
  46. package/dist/controllers/oauthServerController.js.map +1 -1
  47. package/dist/dao/ServerDaoDbImpl.js +3 -0
  48. package/dist/dao/ServerDaoDbImpl.js.map +1 -1
  49. package/dist/db/connection.js +48 -4
  50. package/dist/db/connection.js.map +1 -1
  51. package/dist/db/entities/Server.js +4 -0
  52. package/dist/db/entities/Server.js.map +1 -1
  53. package/dist/db/entities/VectorEmbedding.js +2 -5
  54. package/dist/db/entities/VectorEmbedding.js.map +1 -1
  55. package/dist/db/repositories/VectorEmbeddingRepository.js +100 -34
  56. package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
  57. package/dist/services/dataService.js +10 -1
  58. package/dist/services/dataService.js.map +1 -1
  59. package/dist/services/mcpService.js +47 -10
  60. package/dist/services/mcpService.js.map +1 -1
  61. package/dist/services/sseService.js +5 -3
  62. package/dist/services/sseService.js.map +1 -1
  63. package/dist/services/vectorSearchService.js +16 -3
  64. package/dist/services/vectorSearchService.js.map +1 -1
  65. package/dist/utils/migration.js +1 -0
  66. package/dist/utils/migration.js.map +1 -1
  67. package/dist/utils/serverConfigPersistence.js +5 -0
  68. package/dist/utils/serverConfigPersistence.js.map +1 -1
  69. package/frontend/dist/assets/ActivityPage-DwzGiMh_.js +2 -0
  70. package/frontend/dist/assets/ActivityPage-DwzGiMh_.js.map +1 -0
  71. package/frontend/dist/assets/ConfirmDialog-CxlizGia.js +2 -0
  72. package/frontend/dist/assets/ConfirmDialog-CxlizGia.js.map +1 -0
  73. package/frontend/dist/assets/Dashboard-BUCJcvk-.js +2 -0
  74. package/frontend/dist/assets/Dashboard-BUCJcvk-.js.map +1 -0
  75. package/frontend/dist/assets/DeleteDialog-DRbWonMu.js +2 -0
  76. package/frontend/dist/assets/DeleteDialog-DRbWonMu.js.map +1 -0
  77. package/frontend/dist/assets/EndpointCopy-D5NjDdYi.js +2 -0
  78. package/frontend/dist/assets/EndpointCopy-D5NjDdYi.js.map +1 -0
  79. package/frontend/dist/assets/GroupsPage-DfLlww4U.js +33 -0
  80. package/frontend/dist/assets/GroupsPage-DfLlww4U.js.map +1 -0
  81. package/frontend/dist/assets/LoginPage-DCjqYw_8.js +2 -0
  82. package/frontend/dist/assets/LoginPage-DCjqYw_8.js.map +1 -0
  83. package/frontend/dist/assets/LogsPage-CTa8kuDf.js +2 -0
  84. package/frontend/dist/assets/LogsPage-CTa8kuDf.js.map +1 -0
  85. package/frontend/dist/assets/MarketPage-C2Rh4WJB.js +3 -0
  86. package/frontend/dist/assets/MarketPage-C2Rh4WJB.js.map +1 -0
  87. package/frontend/dist/assets/{Pagination-y-gVO8ms.js → Pagination-BFi-X7qY.js} +2 -2
  88. package/frontend/dist/assets/{Pagination-y-gVO8ms.js.map → Pagination-BFi-X7qY.js.map} +1 -1
  89. package/frontend/dist/assets/PromptsPage-Dh3qjX3x.js +2 -0
  90. package/frontend/dist/assets/PromptsPage-Dh3qjX3x.js.map +1 -0
  91. package/frontend/dist/assets/ResourcesPage-Bc5ZpCIh.js +2 -0
  92. package/frontend/dist/assets/ResourcesPage-Bc5ZpCIh.js.map +1 -0
  93. package/frontend/dist/assets/ServersPage-hgCbCglG.js +37 -0
  94. package/frontend/dist/assets/ServersPage-hgCbCglG.js.map +1 -0
  95. package/frontend/dist/assets/SettingsPage-BzNX8mXv.js +12 -0
  96. package/frontend/dist/assets/SettingsPage-BzNX8mXv.js.map +1 -0
  97. package/frontend/dist/assets/StatusDot-CQzailBQ.js +2 -0
  98. package/frontend/dist/assets/StatusDot-CQzailBQ.js.map +1 -0
  99. package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js → ToggleGroup-CNBBvo3C.js} +2 -2
  100. package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js.map → ToggleGroup-CNBBvo3C.js.map} +1 -1
  101. package/frontend/dist/assets/UsersPage-C33b7LCM.js +2 -0
  102. package/frontend/dist/assets/UsersPage-C33b7LCM.js.map +1 -0
  103. package/frontend/dist/assets/{framework-vendor-_OBebcuv.js → framework-vendor-BUhDPOUZ.js} +2 -2
  104. package/frontend/dist/assets/{framework-vendor-_OBebcuv.js.map → framework-vendor-BUhDPOUZ.js.map} +1 -1
  105. package/frontend/dist/assets/{i18n-vendor-MQ921plD.js → i18n-vendor-Kbr87Ofu.js} +2 -2
  106. package/frontend/dist/assets/{i18n-vendor-MQ921plD.js.map → i18n-vendor-Kbr87Ofu.js.map} +1 -1
  107. package/frontend/dist/assets/icons-vendor-CKgJB3SC.js +292 -0
  108. package/frontend/dist/assets/icons-vendor-CKgJB3SC.js.map +1 -0
  109. package/frontend/dist/assets/index-BGiKkKzj.js +3 -0
  110. package/frontend/dist/assets/index-BGiKkKzj.js.map +1 -0
  111. package/frontend/dist/assets/index-D0OIBhmN.css +1 -0
  112. package/frontend/dist/assets/{resourceService-BfCTSBsr.js → resourceService-C6umWRgq.js} +2 -2
  113. package/frontend/dist/assets/{resourceService-BfCTSBsr.js.map → resourceService-C6umWRgq.js.map} +1 -1
  114. package/frontend/dist/assets/useServerData-P5In98R4.js +2 -0
  115. package/frontend/dist/assets/{useServerData-QZqQTYcv.js.map → useServerData-P5In98R4.js.map} +1 -1
  116. package/frontend/dist/assets/useSettingsData-Cz7vKGLE.js +2 -0
  117. package/frontend/dist/assets/{useSettingsData-D3VROqS7.js.map → useSettingsData-Cz7vKGLE.js.map} +1 -1
  118. package/frontend/dist/assets/variableDetection-DsYuiOB_.js +16 -0
  119. package/frontend/dist/assets/variableDetection-DsYuiOB_.js.map +1 -0
  120. package/frontend/dist/index.html +5 -5
  121. package/package.json +2 -1
  122. package/frontend/dist/assets/ActivityPage-ClgKeihP.js +0 -2
  123. package/frontend/dist/assets/ActivityPage-ClgKeihP.js.map +0 -1
  124. package/frontend/dist/assets/Badge-Ck2fhRdl.js +0 -2
  125. package/frontend/dist/assets/Badge-Ck2fhRdl.js.map +0 -1
  126. package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js +0 -2
  127. package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js.map +0 -1
  128. package/frontend/dist/assets/Dashboard-BIXrLobn.js +0 -2
  129. package/frontend/dist/assets/Dashboard-BIXrLobn.js.map +0 -1
  130. package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js +0 -2
  131. package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js.map +0 -1
  132. package/frontend/dist/assets/GroupsPage-BjrvyHwu.js +0 -33
  133. package/frontend/dist/assets/GroupsPage-BjrvyHwu.js.map +0 -1
  134. package/frontend/dist/assets/LoginPage-BBHt_TfF.js +0 -2
  135. package/frontend/dist/assets/LoginPage-BBHt_TfF.js.map +0 -1
  136. package/frontend/dist/assets/LogsPage-D8Znq5NB.js +0 -2
  137. package/frontend/dist/assets/LogsPage-D8Znq5NB.js.map +0 -1
  138. package/frontend/dist/assets/MarketPage-haRuzjCw.js +0 -3
  139. package/frontend/dist/assets/MarketPage-haRuzjCw.js.map +0 -1
  140. package/frontend/dist/assets/PromptsPage-ByHWPyGe.js +0 -2
  141. package/frontend/dist/assets/PromptsPage-ByHWPyGe.js.map +0 -1
  142. package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js +0 -2
  143. package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js.map +0 -1
  144. package/frontend/dist/assets/ServersPage-CtS1I4yS.js +0 -37
  145. package/frontend/dist/assets/ServersPage-CtS1I4yS.js.map +0 -1
  146. package/frontend/dist/assets/SettingsPage-DxVigf7p.js +0 -12
  147. package/frontend/dist/assets/SettingsPage-DxVigf7p.js.map +0 -1
  148. package/frontend/dist/assets/UsersPage-Bipw33cS.js +0 -2
  149. package/frontend/dist/assets/UsersPage-Bipw33cS.js.map +0 -1
  150. package/frontend/dist/assets/icons-vendor-B67NtVuR.js +0 -172
  151. package/frontend/dist/assets/icons-vendor-B67NtVuR.js.map +0 -1
  152. package/frontend/dist/assets/index-CmnA4an8.js +0 -5
  153. package/frontend/dist/assets/index-CmnA4an8.js.map +0 -1
  154. package/frontend/dist/assets/index-DfFHVARX.css +0 -1
  155. package/frontend/dist/assets/useGroupData-DLhbP6zd.js +0 -2
  156. package/frontend/dist/assets/useGroupData-DLhbP6zd.js.map +0 -1
  157. package/frontend/dist/assets/useServerData-QZqQTYcv.js +0 -2
  158. package/frontend/dist/assets/useSettingsData-D3VROqS7.js +0 -2
  159. package/frontend/dist/assets/variableDetection-C3Xi21av.js +0 -16
  160. package/frontend/dist/assets/variableDetection-C3Xi21av.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarketPage-C2Rh4WJB.js","sources":["../../src/hooks/useMarketData.ts","../../src/hooks/useCloudData.ts","../../src/hooks/useRegistryData.ts","../../src/components/MarketServerCard.tsx","../../src/components/MarketServerDetail.tsx","../../src/components/CloudServerCard.tsx","../../src/components/MCPRouterApiKeyError.tsx","../../src/components/CloudServerDetail.tsx","../../src/components/RegistryServerCard.tsx","../../src/components/RegistryServerDetail.tsx","../../src/components/ui/CursorPagination.tsx","../../src/pages/MarketPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { MarketServer, ApiResponse, ServerConfig } from '@/types';\nimport { apiGet, apiPost } from '../utils/fetchInterceptor';\n\nexport const useMarketData = () => {\n const { t } = useTranslation();\n const [servers, setServers] = useState<MarketServer[]>([]);\n const [allServers, setAllServers] = useState<MarketServer[]>([]);\n const [categories, setCategories] = useState<string[]>([]);\n const [tags, setTags] = useState<string[]>([]);\n const [selectedCategory, setSelectedCategory] = useState<string>('');\n const [selectedTag, setSelectedTag] = useState<string>('');\n const [searchQuery, setSearchQuery] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [currentServer, setCurrentServer] = useState<MarketServer | null>(null);\n const [installedServers, setInstalledServers] = useState<string[]>([]);\n\n // Pagination states\n const [currentPage, setCurrentPage] = useState(1);\n const [serversPerPage, setServersPerPage] = useState(9);\n const [totalPages, setTotalPages] = useState(1);\n\n // Fetch all market servers\n const fetchMarketServers = useCallback(async () => {\n try {\n setLoading(true);\n const data: ApiResponse<MarketServer[]> = await apiGet('/market/servers');\n\n if (data && data.success && Array.isArray(data.data)) {\n setAllServers(data.data);\n // Apply pagination to the fetched data\n applyPagination(data.data, currentPage);\n } else {\n console.error('Invalid market servers data format', { data });\n setError(t('market.fetchError'));\n }\n } catch (err) {\n console.error('Error fetching market servers', { err });\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n }, [t]);\n\n // Apply pagination to data\n const applyPagination = useCallback(\n (data: MarketServer[], page: number, itemsPerPage = serversPerPage) => {\n const totalItems = data.length;\n const calculatedTotalPages = Math.ceil(totalItems / itemsPerPage);\n setTotalPages(calculatedTotalPages);\n\n // Ensure current page is valid\n const validPage = Math.max(1, Math.min(page, calculatedTotalPages));\n if (validPage !== page) {\n setCurrentPage(validPage);\n }\n\n const startIndex = (validPage - 1) * itemsPerPage;\n const paginatedServers = data.slice(startIndex, startIndex + itemsPerPage);\n setServers(paginatedServers);\n },\n [serversPerPage],\n );\n\n // Change page\n const changePage = useCallback(\n (page: number) => {\n setCurrentPage(page);\n applyPagination(allServers, page, serversPerPage);\n },\n [allServers, applyPagination, serversPerPage],\n );\n\n // Fetch all categories\n const fetchCategories = useCallback(async () => {\n try {\n const data: ApiResponse<string[]> = await apiGet('/market/categories');\n\n if (data && data.success && Array.isArray(data.data)) {\n setCategories(data.data);\n } else {\n console.error('Invalid categories data format', { data });\n }\n } catch (err) {\n console.error('Error fetching categories', { err });\n }\n }, []);\n\n // Fetch all tags\n const fetchTags = useCallback(async () => {\n try {\n const data: ApiResponse<string[]> = await apiGet('/market/tags');\n\n if (data && data.success && Array.isArray(data.data)) {\n setTags(data.data);\n } else {\n console.error('Invalid tags data format', { data });\n }\n } catch (err) {\n console.error('Error fetching tags', { err });\n }\n }, []);\n\n // Fetch server by name\n const fetchServerByName = useCallback(\n async (name: string) => {\n try {\n setLoading(true);\n const data: ApiResponse<MarketServer> = await apiGet(`/market/servers/${name}`);\n\n if (data && data.success && data.data) {\n setCurrentServer(data.data);\n return data.data;\n } else {\n console.error('Invalid market server data format', { name, data });\n setError(t('market.serverNotFound'));\n return null;\n }\n } catch (err) {\n console.error('Error fetching market server', { name, err });\n setError(err instanceof Error ? err.message : String(err));\n return null;\n } finally {\n setLoading(false);\n }\n },\n [t],\n );\n\n // Search servers by query\n const searchServers = useCallback(\n async (query: string) => {\n try {\n setLoading(true);\n setSearchQuery(query);\n\n if (!query.trim()) {\n // Fetch fresh data from server instead of just applying pagination\n fetchMarketServers();\n return;\n }\n\n const data: ApiResponse<MarketServer[]> = await apiGet(\n `/market/servers/search?query=${encodeURIComponent(query)}`,\n );\n\n if (data && data.success && Array.isArray(data.data)) {\n setAllServers(data.data);\n setCurrentPage(1);\n applyPagination(data.data, 1);\n } else {\n console.error('Invalid market search results format', { query, data });\n setError(t('market.searchError'));\n }\n } catch (err) {\n console.error('Error searching market servers', { query, err });\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n },\n [t, allServers, applyPagination, fetchMarketServers],\n );\n\n // Filter servers by category\n const filterByCategory = useCallback(\n async (category: string) => {\n try {\n setLoading(true);\n setSelectedCategory(category);\n setSelectedTag(''); // Reset tag filter when filtering by category\n\n if (!category) {\n fetchMarketServers();\n return;\n }\n\n const data: ApiResponse<MarketServer[]> = await apiGet(\n `/market/categories/${encodeURIComponent(category)}`,\n );\n\n if (data && data.success && Array.isArray(data.data)) {\n setAllServers(data.data);\n setCurrentPage(1);\n applyPagination(data.data, 1);\n } else {\n console.error('Invalid market category filter results format', { category, data });\n setError(t('market.filterError'));\n }\n } catch (err) {\n console.error('Error filtering market servers by category', { category, err });\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n },\n [t, fetchMarketServers, applyPagination],\n );\n\n // Filter servers by tag\n const filterByTag = useCallback(\n async (tag: string) => {\n try {\n setLoading(true);\n setSelectedTag(tag);\n setSelectedCategory(''); // Reset category filter when filtering by tag\n\n if (!tag) {\n fetchMarketServers();\n return;\n }\n\n const data: ApiResponse<MarketServer[]> = await apiGet(\n `/market/tags/${encodeURIComponent(tag)}`,\n );\n\n if (data && data.success && Array.isArray(data.data)) {\n setAllServers(data.data);\n setCurrentPage(1);\n applyPagination(data.data, 1);\n } else {\n console.error('Invalid market tag filter results format', { tag, data });\n setError(t('market.tagFilterError'));\n }\n } catch (err) {\n console.error('Error filtering market servers by tag', { tag, err });\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n },\n [t, fetchMarketServers, applyPagination],\n );\n\n // Fetch installed servers\n const fetchInstalledServers = useCallback(async () => {\n try {\n const data = await apiGet<{ success: boolean; data: any[] }>('/servers');\n\n if (data && data.success && Array.isArray(data.data)) {\n // Extract server names\n const installedServerNames = data.data.map((server: any) => server.name);\n setInstalledServers(installedServerNames);\n }\n } catch (err) {\n console.error('Error fetching installed servers', { err });\n }\n }, []);\n\n // Check if a server is already installed\n const isServerInstalled = useCallback(\n (serverName: string) => {\n return installedServers.includes(serverName);\n },\n [installedServers],\n );\n\n // Install server to the local environment\n const installServer = useCallback(\n async (server: MarketServer, customConfig: ServerConfig) => {\n try {\n const installType = server.installations?.npm\n ? 'npm'\n : Object.keys(server.installations || {}).length > 0\n ? Object.keys(server.installations)[0]\n : null;\n\n if (!installType || !server.installations?.[installType]) {\n setError(t('market.noInstallationMethod'));\n return false;\n }\n\n const installation = server.installations[installType];\n\n // Prepare server configuration, merging with customConfig\n const serverConfig = {\n name: server.name,\n config:\n customConfig.type === 'stdio'\n ? {\n command: customConfig.command || installation.command || '',\n args: customConfig.args || installation.args || [],\n env: { ...installation.env, ...customConfig.env },\n }\n : customConfig,\n };\n\n // Call the createServer API\n const result = await apiPost<{ success: boolean; message?: string }>(\n '/servers',\n serverConfig,\n );\n\n if (!result.success) {\n throw new Error(result.message || 'Failed to install server');\n }\n\n // Update installed servers list after successful installation\n await fetchInstalledServers();\n return true;\n } catch (err) {\n console.error('Error installing market server', { serverName: server.name, err });\n setError(err instanceof Error ? err.message : String(err));\n return false;\n }\n },\n [t, fetchInstalledServers],\n );\n\n // Change servers per page\n const changeServersPerPage = useCallback(\n (perPage: number) => {\n setServersPerPage(perPage);\n setCurrentPage(1);\n applyPagination(allServers, 1, perPage);\n },\n [allServers, applyPagination],\n );\n\n // Load initial data\n useEffect(() => {\n fetchMarketServers();\n fetchCategories();\n fetchTags();\n fetchInstalledServers();\n }, [fetchMarketServers, fetchCategories, fetchTags, fetchInstalledServers]);\n\n return {\n servers,\n allServers,\n categories,\n tags,\n selectedCategory,\n selectedTag,\n searchQuery,\n loading,\n error,\n setError,\n currentServer,\n fetchMarketServers,\n fetchServerByName,\n searchServers,\n filterByCategory,\n filterByTag,\n installServer,\n // Pagination properties and methods\n currentPage,\n totalPages,\n serversPerPage,\n changePage,\n changeServersPerPage,\n // Installed servers methods\n isServerInstalled,\n };\n};\n","import { useState, useEffect, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CloudServer, ApiResponse, CloudServerTool } from '@/types';\nimport { apiGet, apiPost } from '../utils/fetchInterceptor';\n\nexport const useCloudData = () => {\n const { t } = useTranslation();\n const [servers, setServers] = useState<CloudServer[]>([]);\n const [allServers, setAllServers] = useState<CloudServer[]>([]);\n const [categories, setCategories] = useState<string[]>([]);\n const [tags, setTags] = useState<string[]>([]);\n const [selectedCategory, setSelectedCategory] = useState<string>('');\n const [selectedTag, setSelectedTag] = useState<string>('');\n const [searchQuery, setSearchQuery] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [currentServer, setCurrentServer] = useState<CloudServer | null>(null);\n\n // Pagination states\n const [currentPage, setCurrentPage] = useState(1);\n const [serversPerPage, setServersPerPage] = useState(9);\n const [totalPages, setTotalPages] = useState(1);\n\n // Fetch all cloud market servers\n const fetchCloudServers = useCallback(async () => {\n try {\n setLoading(true);\n const data: ApiResponse<CloudServer[]> = await apiGet('/cloud/servers');\n\n if (data && data.success && Array.isArray(data.data)) {\n setAllServers(data.data);\n // Apply pagination to the fetched data\n applyPagination(data.data, currentPage);\n } else {\n console.error('Invalid cloud market servers data format', { data });\n setError(t('cloud.fetchError'));\n }\n } catch (err) {\n console.error('Error fetching cloud market servers', { err });\n const errorMessage = err instanceof Error ? err.message : String(err);\n // Keep the original error message for API key errors\n if (\n errorMessage === 'MCPROUTER_API_KEY_NOT_CONFIGURED' ||\n errorMessage.toLowerCase().includes('mcprouter api key not configured')\n ) {\n setError(errorMessage);\n } else {\n setError(errorMessage);\n }\n } finally {\n setLoading(false);\n }\n }, [t]);\n\n // Apply pagination to data\n const applyPagination = useCallback(\n (data: CloudServer[], page: number, itemsPerPage = serversPerPage) => {\n const totalItems = data.length;\n const calculatedTotalPages = Math.ceil(totalItems / itemsPerPage);\n setTotalPages(calculatedTotalPages);\n\n // Ensure current page is valid\n const validPage = Math.max(1, Math.min(page, calculatedTotalPages));\n if (validPage !== page) {\n setCurrentPage(validPage);\n }\n\n const startIndex = (validPage - 1) * itemsPerPage;\n const paginatedServers = data.slice(startIndex, startIndex + itemsPerPage);\n setServers(paginatedServers);\n },\n [serversPerPage],\n );\n\n // Change page\n const changePage = useCallback(\n (page: number) => {\n setCurrentPage(page);\n applyPagination(allServers, page, serversPerPage);\n },\n [allServers, applyPagination, serversPerPage],\n );\n\n // Fetch all categories\n const fetchCategories = useCallback(async () => {\n try {\n const data: ApiResponse<string[]> = await apiGet('/cloud/categories');\n\n if (data && data.success && Array.isArray(data.data)) {\n setCategories(data.data);\n } else {\n console.error('Invalid cloud market categories data format', { data });\n }\n } catch (err) {\n console.error('Error fetching cloud market categories', { err });\n }\n }, []);\n\n // Fetch all tags\n const fetchTags = useCallback(async () => {\n try {\n const data: ApiResponse<string[]> = await apiGet('/cloud/tags');\n\n if (data && data.success && Array.isArray(data.data)) {\n setTags(data.data);\n } else {\n console.error('Invalid cloud market tags data format', { data });\n }\n } catch (err) {\n console.error('Error fetching cloud market tags', { err });\n }\n }, []);\n\n // Fetch server by name\n const fetchServerByName = useCallback(\n async (name: string) => {\n try {\n setLoading(true);\n const data: ApiResponse<CloudServer> = await apiGet(`/cloud/servers/${name}`);\n\n if (data && data.success && data.data) {\n setCurrentServer(data.data);\n return data.data;\n } else {\n console.error('Invalid cloud server data format', { name, data });\n setError(t('cloud.serverNotFound'));\n return null;\n }\n } catch (err) {\n console.error('Error fetching cloud server', { name, err });\n const errorMessage = err instanceof Error ? err.message : String(err);\n // Keep the original error message for API key errors\n if (\n errorMessage === 'MCPROUTER_API_KEY_NOT_CONFIGURED' ||\n errorMessage.toLowerCase().includes('mcprouter api key not configured')\n ) {\n setError(errorMessage);\n } else {\n setError(errorMessage);\n }\n return null;\n } finally {\n setLoading(false);\n }\n },\n [t],\n );\n\n // Search servers by query\n const searchServers = useCallback(\n async (query: string) => {\n try {\n setLoading(true);\n setSearchQuery(query);\n\n if (!query.trim()) {\n // Fetch fresh data from server instead of just applying pagination\n fetchCloudServers();\n return;\n }\n\n const data: ApiResponse<CloudServer[]> = await apiGet(\n `/cloud/servers/search?query=${encodeURIComponent(query)}`,\n );\n\n if (data && data.success && Array.isArray(data.data)) {\n setAllServers(data.data);\n setCurrentPage(1);\n applyPagination(data.data, 1);\n } else {\n console.error('Invalid cloud search results format', { query, data });\n setError(t('cloud.searchError'));\n }\n } catch (err) {\n console.error('Error searching cloud servers', { query, err });\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n },\n [t, allServers, applyPagination, fetchCloudServers],\n );\n\n // Filter servers by category\n const filterByCategory = useCallback(\n async (category: string) => {\n try {\n setLoading(true);\n setSelectedCategory(category);\n setSelectedTag(''); // Reset tag filter when filtering by category\n\n if (!category) {\n fetchCloudServers();\n return;\n }\n\n const data: ApiResponse<CloudServer[]> = await apiGet(\n `/cloud/categories/${encodeURIComponent(category)}`,\n );\n\n if (data && data.success && Array.isArray(data.data)) {\n setAllServers(data.data);\n setCurrentPage(1);\n applyPagination(data.data, 1);\n } else {\n console.error('Invalid cloud category filter results format', { category, data });\n setError(t('cloud.filterError'));\n }\n } catch (err) {\n console.error('Error filtering cloud servers by category', { category, err });\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n },\n [t, fetchCloudServers, applyPagination],\n );\n\n // Filter servers by tag\n const filterByTag = useCallback(\n async (tag: string) => {\n try {\n setLoading(true);\n setSelectedTag(tag);\n setSelectedCategory(''); // Reset category filter when filtering by tag\n\n if (!tag) {\n fetchCloudServers();\n return;\n }\n\n const data: ApiResponse<CloudServer[]> = await apiGet(\n `/cloud/tags/${encodeURIComponent(tag)}`,\n );\n\n if (data && data.success && Array.isArray(data.data)) {\n setAllServers(data.data);\n setCurrentPage(1);\n applyPagination(data.data, 1);\n } else {\n console.error('Invalid cloud tag filter results format', { tag, data });\n setError(t('cloud.tagFilterError'));\n }\n } catch (err) {\n console.error('Error filtering cloud servers by tag', { tag, err });\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n },\n [t, fetchCloudServers, applyPagination],\n );\n\n // Fetch tools for a specific server\n const fetchServerTools = useCallback(async (serverName: string) => {\n try {\n const data: ApiResponse<CloudServerTool[]> = await apiGet(\n `/cloud/servers/${serverName}/tools`,\n );\n\n if (!data.success) {\n console.error('Failed to fetch cloud server tools', { serverName, data });\n throw new Error(data.message || 'Failed to fetch cloud server tools');\n }\n\n if (data && data.success && Array.isArray(data.data)) {\n return data.data;\n } else {\n console.error('Invalid cloud server tools data format', { serverName, data });\n return [];\n }\n } catch (err) {\n console.error('Error fetching tools for cloud server', { serverName, err });\n const errorMessage = err instanceof Error ? err.message : String(err);\n // Re-throw API key errors so they can be handled by the component\n if (\n errorMessage === 'MCPROUTER_API_KEY_NOT_CONFIGURED' ||\n errorMessage.toLowerCase().includes('mcprouter api key not configured')\n ) {\n throw err;\n }\n return [];\n }\n }, []);\n\n // Call a tool on a cloud server\n const callServerTool = useCallback(\n async (serverName: string, toolName: string, args: Record<string, any>) => {\n try {\n // URL-encode server and tool names to handle slashes (e.g., \"com.atlassian/atlassian-mcp-server\")\n const data = await apiPost(\n `/cloud/servers/${encodeURIComponent(serverName)}/tools/${encodeURIComponent(toolName)}/call`,\n {\n arguments: args,\n },\n );\n\n if (data && data.success) {\n return data.data;\n } else {\n throw new Error(data.message || 'Failed to call tool');\n }\n } catch (err) {\n console.error('Error calling tool on cloud server', { serverName, toolName, err });\n throw err;\n }\n },\n [],\n );\n\n // Change servers per page\n const changeServersPerPage = useCallback(\n (perPage: number) => {\n setServersPerPage(perPage);\n setCurrentPage(1);\n applyPagination(allServers, 1, perPage);\n },\n [allServers, applyPagination],\n );\n\n // Load initial data\n useEffect(() => {\n fetchCloudServers();\n fetchCategories();\n fetchTags();\n }, [fetchCloudServers, fetchCategories, fetchTags]);\n\n return {\n servers,\n allServers,\n categories,\n tags,\n selectedCategory,\n selectedTag,\n searchQuery,\n loading,\n error,\n setError,\n currentServer,\n fetchCloudServers: fetchCloudServers,\n fetchServerByName,\n searchServers,\n filterByCategory,\n filterByTag,\n fetchServerTools,\n callServerTool,\n // Pagination properties and methods\n currentPage,\n totalPages,\n serversPerPage,\n changePage,\n changeServersPerPage,\n };\n};\n","import { useState, useEffect, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n RegistryServerEntry,\n RegistryServersResponse,\n RegistryServerVersionResponse,\n RegistryServerVersionsResponse,\n} from '@/types';\nimport { apiGet } from '../utils/fetchInterceptor';\n\nexport const useRegistryData = () => {\n const { t } = useTranslation();\n const [servers, setServers] = useState<RegistryServerEntry[]>([]);\n const [allServers, setAllServers] = useState<RegistryServerEntry[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [searchQuery, setSearchQuery] = useState<string>('');\n\n // Cursor-based pagination states\n const [currentPage, setCurrentPage] = useState(1);\n const [serversPerPage, setServersPerPage] = useState(9);\n const [nextCursor, setNextCursor] = useState<string | null>(null);\n const [hasNextPage, setHasNextPage] = useState(false);\n const [cursorHistory, setCursorHistory] = useState<string[]>([]);\n const [totalPages] = useState(1); // Legacy support, not used in cursor pagination\n\n // Fetch registry servers with cursor-based pagination\n const fetchRegistryServers = useCallback(\n async (cursor?: string, search?: string) => {\n try {\n setLoading(true);\n setError(null);\n\n // Build query parameters\n const params = new URLSearchParams();\n params.append('limit', serversPerPage.toString());\n if (cursor) {\n params.append('cursor', cursor);\n }\n const queryToUse = search !== undefined ? search : searchQuery;\n if (queryToUse.trim()) {\n params.append('search', queryToUse.trim());\n }\n\n const response = await apiGet(`/registry/servers?${params.toString()}`);\n\n if (response && response.success && response.data) {\n const data: RegistryServersResponse = response.data;\n if (data.servers && Array.isArray(data.servers)) {\n setServers(data.servers);\n // Update pagination state\n const hasMore = data.metadata.count === serversPerPage && !!data.metadata.nextCursor;\n setHasNextPage(hasMore);\n setNextCursor(data.metadata.nextCursor || null);\n\n // For display purposes, keep track of all loaded servers\n if (!cursor) {\n // First page\n setAllServers(data.servers);\n } else {\n // Subsequent pages - append to all servers\n setAllServers((prev) => [...prev, ...data.servers]);\n }\n } else {\n console.error('Invalid registry servers data format', { data });\n setError(t('registry.fetchError'));\n }\n } else {\n setError(t('registry.fetchError'));\n }\n } catch (err) {\n console.error('Error fetching registry servers', { cursor, search, err });\n const errorMessage = err instanceof Error ? err.message : String(err);\n setError(errorMessage);\n } finally {\n setLoading(false);\n }\n },\n [t, serversPerPage],\n );\n\n // Navigate to next page\n const goToNextPage = useCallback(async () => {\n if (!hasNextPage || !nextCursor) return;\n\n // Save current cursor to history for back navigation\n const currentCursor = cursorHistory[cursorHistory.length - 1] || '';\n setCursorHistory((prev) => [...prev, currentCursor]);\n\n setCurrentPage((prev) => prev + 1);\n await fetchRegistryServers(nextCursor, searchQuery);\n }, [hasNextPage, nextCursor, cursorHistory, searchQuery, fetchRegistryServers]);\n\n // Navigate to previous page\n const goToPreviousPage = useCallback(async () => {\n if (currentPage <= 1) return;\n\n // Get the previous cursor from history\n const newHistory = [...cursorHistory];\n newHistory.pop(); // Remove current position\n const previousCursor = newHistory[newHistory.length - 1];\n\n setCursorHistory(newHistory);\n setCurrentPage((prev) => prev - 1);\n\n // Fetch with previous cursor (undefined for first page)\n await fetchRegistryServers(previousCursor || undefined, searchQuery);\n }, [currentPage, cursorHistory, searchQuery, fetchRegistryServers]);\n\n // Change page (legacy support for page number navigation)\n const changePage = useCallback(\n async (page: number) => {\n if (page === currentPage) return;\n\n if (page > currentPage && hasNextPage) {\n await goToNextPage();\n } else if (page < currentPage && currentPage > 1) {\n await goToPreviousPage();\n }\n },\n [currentPage, hasNextPage, goToNextPage, goToPreviousPage],\n );\n\n // Change items per page\n const changeServersPerPage = useCallback(\n async (newServersPerPage: number) => {\n setServersPerPage(newServersPerPage);\n setCurrentPage(1);\n setCursorHistory([]);\n setAllServers([]);\n await fetchRegistryServers(undefined, searchQuery);\n },\n [searchQuery, fetchRegistryServers],\n );\n\n // Fetch server by name\n const fetchServerByName = useCallback(\n async (serverName: string) => {\n try {\n setLoading(true);\n setError(null);\n\n // URL encode the server name\n const encodedName = encodeURIComponent(serverName);\n const response = await apiGet(`/registry/servers/versions?serverName=${encodedName}`);\n\n if (response && response.success && response.data) {\n const data: RegistryServerVersionsResponse = response.data;\n if (data.servers && Array.isArray(data.servers) && data.servers.length > 0) {\n // Return the first server entry (should be the latest or specified version)\n return data.servers[0];\n } else {\n console.error('Invalid registry server data format', { serverName, data });\n setError(t('registry.serverNotFound'));\n return null;\n }\n } else {\n setError(t('registry.serverNotFound'));\n return null;\n }\n } catch (err) {\n console.error('Error fetching registry server', { serverName, err });\n const errorMessage = err instanceof Error ? err.message : String(err);\n setError(errorMessage);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [t],\n );\n\n // Fetch all versions of a server\n const fetchServerVersions = useCallback(async (serverName: string) => {\n try {\n setError(null);\n\n // URL encode the server name\n const encodedName = encodeURIComponent(serverName);\n const response = await apiGet(`/registry/servers/versions?serverName=${encodedName}`);\n\n if (response && response.success && response.data) {\n const data: RegistryServerVersionsResponse = response.data;\n if (data.servers && Array.isArray(data.servers)) {\n return data.servers;\n } else {\n console.error('Invalid registry server versions data format', { serverName, data });\n return [];\n }\n } else {\n return [];\n }\n } catch (err) {\n console.error('Error fetching versions for registry server', { serverName, err });\n const errorMessage = err instanceof Error ? err.message : String(err);\n setError(errorMessage);\n return [];\n }\n }, []);\n\n // Fetch specific version of a server\n const fetchServerVersion = useCallback(async (serverName: string, version: string) => {\n try {\n setError(null);\n\n // URL encode the server name and version\n const encodedName = encodeURIComponent(serverName);\n const encodedVersion = encodeURIComponent(version);\n const response = await apiGet(`/registry/servers/version?serverName=${encodedName}&version=${encodedVersion}`);\n\n if (response && response.success && response.data) {\n const data: RegistryServerVersionResponse = response.data;\n if (data && data.server) {\n return data;\n } else {\n console.error('Invalid registry server version data format', { serverName, version, data });\n return null;\n }\n } else {\n return null;\n }\n } catch (err) {\n console.error('Error fetching specific registry server version', { serverName, version, err });\n const errorMessage = err instanceof Error ? err.message : String(err);\n setError(errorMessage);\n return null;\n }\n }, []);\n\n // Search servers by query (client-side filtering on loaded data)\n const searchServers = useCallback(\n async (query: string) => {\n console.log('Searching registry servers', { query });\n setSearchQuery(query);\n setCurrentPage(1);\n setCursorHistory([]);\n setAllServers([]);\n\n await fetchRegistryServers(undefined, query);\n },\n [fetchRegistryServers],\n );\n\n // Clear search\n const clearSearch = useCallback(async () => {\n setSearchQuery('');\n setCurrentPage(1);\n setCursorHistory([]);\n setAllServers([]);\n await fetchRegistryServers(undefined, '');\n }, [fetchRegistryServers]);\n\n // Initial fetch\n useEffect(() => {\n fetchRegistryServers(undefined, searchQuery);\n // Only run on mount\n }, []);\n\n return {\n servers,\n allServers,\n loading,\n error,\n setError,\n searchQuery,\n searchServers,\n clearSearch,\n fetchServerByName,\n fetchServerVersions,\n fetchServerVersion,\n // Cursor-based pagination\n currentPage,\n totalPages,\n hasNextPage,\n hasPreviousPage: currentPage > 1,\n changePage,\n goToNextPage,\n goToPreviousPage,\n serversPerPage,\n changeServersPerPage,\n };\n};\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Check, Zap } from 'lucide-react';\nimport { MarketServer } from '@/types';\n\ninterface MarketServerCardProps {\n server: MarketServer;\n onClick: (server: MarketServer) => void;\n}\n\nconst getInitials = (name: string) =>\n name\n .split(' ')\n .map((w) => w.charAt(0))\n .join('')\n .toUpperCase()\n .slice(0, 2);\n\nconst MarketServerCard: React.FC<MarketServerCardProps> = ({ server, onClick }) => {\n const { t } = useTranslation();\n const tags = (server.tags || []).slice(0, 3);\n const category = server.categories?.[0];\n\n return (\n <div\n className=\"hub-card flex flex-col cursor-pointer transition-colors h-full overflow-hidden\"\n onClick={() => onClick(server)}\n onMouseEnter={(e) => (e.currentTarget.style.borderColor = 'var(--hub-ink-2)')}\n onMouseLeave={(e) => (e.currentTarget.style.borderColor = 'var(--hub-line)')}\n >\n <div className=\"p-3.5 flex-1 flex flex-col gap-2.5\">\n <div className=\"flex items-center gap-2\">\n <div\n className=\"hub-mono\"\n style={{\n width: 28,\n height: 28,\n borderRadius: 7,\n background: 'var(--hub-ink)',\n color: 'var(--hub-bg)',\n display: 'grid',\n placeItems: 'center',\n fontWeight: 600,\n fontSize: 13,\n flexShrink: 0,\n }}\n >\n {getInitials(server.display_name || server.name)[0] || '?'}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-1.5\">\n <span\n className=\"truncate\"\n style={{ fontSize: 14, fontWeight: 500, letterSpacing: '-0.01em' }}\n >\n {server.display_name}\n </span>\n {server.is_official && (\n <span\n className=\"inline-flex items-center gap-0.5\"\n style={{\n fontSize: 10,\n color: 'var(--hub-accent)',\n background: 'var(--hub-accent-soft)',\n padding: '0 5px',\n height: 16,\n borderRadius: 3,\n fontWeight: 500,\n }}\n >\n <Check size={9} strokeWidth={2.5} />\n {t('market.official')}\n </span>\n )}\n </div>\n <div\n className=\"hub-mono truncate\"\n style={{ fontSize: 11, color: 'var(--hub-ink-3)' }}\n >\n @{server.author?.name || t('market.unknown')}\n </div>\n </div>\n </div>\n\n <div\n className=\"flex-1 line-clamp-2\"\n style={{ fontSize: 12.5, color: 'var(--hub-ink-2)', lineHeight: 1.5 }}\n >\n {server.description}\n </div>\n\n {tags.length > 0 && (\n <div className=\"flex gap-1 flex-wrap\">\n {tags.map((tag) => (\n <span\n key={tag}\n className=\"hub-tag\"\n style={{\n background: 'oklch(0.96 0.04 145)',\n color: 'oklch(0.4 0.1 145)',\n border: 0,\n }}\n >\n #{tag}\n </span>\n ))}\n </div>\n )}\n </div>\n\n <div\n className=\"flex items-center justify-between px-3.5 py-2\"\n style={{\n borderTop: '1px solid var(--hub-line-2)',\n background: 'var(--hub-bg-2)',\n }}\n >\n <div\n className=\"hub-mono flex items-center gap-3\"\n style={{ fontSize: 11.5, color: 'var(--hub-ink-3)' }}\n >\n <span className=\"inline-flex items-center gap-1\">\n <Zap size={11} />\n {server.tools?.length ?? 0} {t('server.tools').toLowerCase()}\n </span>\n {category && <span className=\"truncate\">{category}</span>}\n </div>\n </div>\n </div>\n );\n};\n\nexport default MarketServerCard;\n","import React, { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { MarketServer, MarketServerInstallation } from '@/types';\nimport ServerForm from './ServerForm';\nimport { detectVariables } from '../utils/variableDetection';\n\nimport { ServerConfig } from '@/types';\n\ninterface MarketServerDetailProps {\n server: MarketServer;\n onBack: () => void;\n onInstall: (server: MarketServer, config: ServerConfig) => void;\n installing?: boolean;\n isInstalled?: boolean;\n}\n\nconst MarketServerDetail: React.FC<MarketServerDetailProps> = ({\n server,\n onBack,\n onInstall,\n installing = false,\n isInstalled = false,\n}) => {\n const { t } = useTranslation();\n const [modalVisible, setModalVisible] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [confirmationVisible, setConfirmationVisible] = useState(false);\n const [pendingPayload, setPendingPayload] = useState<any>(null);\n const [detectedVariables, setDetectedVariables] = useState<string[]>([]);\n\n // Helper function to determine button state\n const getButtonProps = () => {\n if (isInstalled) {\n return {\n className: 'bg-green-600 cursor-default px-4 py-2 rounded text-sm font-medium text-white',\n disabled: true,\n text: t('market.installed'),\n };\n } else if (installing) {\n return {\n className:\n 'bg-gray-400 cursor-not-allowed px-4 py-2 rounded text-sm font-medium text-white',\n disabled: true,\n text: t('market.installing'),\n };\n } else {\n return {\n className:\n 'hub-btn primary',\n disabled: false,\n text: t('market.install'),\n };\n }\n };\n\n const toggleModal = () => {\n setModalVisible(!modalVisible);\n setError(null); // Clear any previous errors when toggling modal\n setConfirmationVisible(false);\n setPendingPayload(null);\n };\n\n const handleConfirmInstall = async () => {\n if (pendingPayload) {\n await proceedWithInstall(pendingPayload);\n setConfirmationVisible(false);\n setPendingPayload(null);\n }\n };\n\n const proceedWithInstall = async (payload: any) => {\n try {\n setError(null);\n onInstall(server, payload.config);\n setModalVisible(false);\n } catch (err) {\n console.error('Error installing server:', err);\n setError(t('errors.serverInstall'));\n }\n };\n\n const handleInstall = () => {\n if (!isInstalled) {\n toggleModal();\n }\n };\n\n // Get the preferred installation configuration based on priority:\n // npm > uvx > default\n const getPreferredInstallation = (): MarketServerInstallation | undefined => {\n if (!server.installations) {\n return undefined;\n }\n\n if (server.installations.npm) {\n return server.installations.npm;\n } else if (server.installations.uvx) {\n return server.installations.uvx;\n } else if (server.installations.default) {\n return server.installations.default;\n }\n\n // If none of the preferred types are available, get the first available installation type\n const installTypes = Object.keys(server.installations);\n if (installTypes.length > 0) {\n return server.installations[installTypes[0]];\n }\n\n return undefined;\n };\n\n const handleSubmit = async (payload: any) => {\n try {\n // Check for variables in the payload\n const variables = detectVariables(payload);\n\n if (variables.length > 0) {\n // Show confirmation dialog\n setDetectedVariables(variables);\n setPendingPayload(payload);\n setConfirmationVisible(true);\n } else {\n // Install directly if no variables found\n await proceedWithInstall(payload);\n }\n } catch (err) {\n console.error('Error processing server installation:', err);\n setError(t('errors.serverInstall'));\n }\n };\n\n const buttonProps = getButtonProps();\n const preferredInstallation = getPreferredInstallation();\n\n return (\n <div className=\"bg-white dark:bg-gray-800 rounded-lg shadow-md p-6\">\n <div className=\"mb-4\">\n <button onClick={onBack} className=\"text-gray-600 hover:text-gray-900 flex items-center\">\n <svg\n className=\"h-5 w-5 mr-1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n {t('market.backToList')}\n </button>\n </div>\n\n <div className=\"flex justify-between items-start mb-4\">\n <div>\n <h2 className=\"text-2xl font-bold text-gray-900 flex items-center flex-wrap\">\n {server.display_name}\n <span className=\"text-sm font-normal text-gray-500 ml-2\">({server.name})</span>\n <span className=\"text-sm font-normal text-gray-600 ml-4\">\n {t('market.author')}: {server.author?.name || t('market.unknown')} •{' '}\n {t('market.license')}: {server.license} •\n <a\n href={server.repository.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-blue-500 hover:underline ml-1\"\n >\n {t('market.repository')}\n </a>\n </span>\n </h2>\n </div>\n\n <div className=\"flex items-center\">\n {server.is_official && (\n <span className=\"bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300 text-sm font-normal px-4 py-2 rounded mr-2 flex items-center label-primary\">\n {t('market.official')}\n </span>\n )}\n <button\n onClick={handleInstall}\n disabled={buttonProps.disabled}\n className={buttonProps.className}\n >\n {buttonProps.text}\n </button>\n </div>\n </div>\n\n <p className=\"text-gray-700 mb-6\">{server.description}</p>\n\n <div className=\"mb-6\">\n <h3 className=\"text-lg font-semibold mb-3\">\n {t('market.categories')} & {t('market.tags')}\n </h3>\n <div className=\"flex flex-wrap gap-2\">\n {server.categories?.map((category, index) => (\n <span key={`cat-${index}`} className=\"bg-gray-100 dark:bg-gray-800 text-gray-800 px-3 py-1 rounded\">\n {category}\n </span>\n ))}\n {server.tags &&\n server.tags.map((tag, index) => (\n <span\n key={`tag-${index}`}\n className=\"bg-gray-100 dark:bg-gray-800 text-green-700 px-2 py-1 rounded text-sm\"\n >\n #{tag}\n </span>\n ))}\n </div>\n </div>\n\n {server.arguments && Object.keys(server.arguments).length > 0 && (\n <div className=\"mb-6\">\n <h3 className=\"text-lg font-semibold mb-3\">{t('market.arguments')}</h3>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 dark:divide-gray-700\">\n <thead className=\"bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700\">\n <tr>\n <th className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap\">\n {t('market.argumentName')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap\">\n {t('market.description')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap\">\n {t('market.required')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap\">\n {t('market.example')}\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700\">\n {Object.entries(server.arguments).map(([name, arg], index) => (\n <tr key={index}>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900\">\n {name}\n </td>\n <td className=\"px-6 py-4 text-sm text-gray-500\">{arg.description}</td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">\n {arg.required ? (\n <span className=\"text-green-600\">✓</span>\n ) : (\n <span className=\"text-gray-600\">✗</span>\n )}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">\n <code className=\"bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded\">{arg.example}</code>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n\n <div className=\"mb-6\">\n <h3 className=\"text-lg font-semibold mb-3\">{t('market.tools')}</h3>\n <div className=\"space-y-4\">\n {server.tools?.map((tool, index) => (\n <div key={index} className=\"border border-gray-200 dark:border-gray-700 rounded p-4\">\n <h4 className=\"font-medium mb-2\">\n {tool.name}\n <button\n type=\"button\"\n onClick={() => {\n // Toggle visibility of schema (simplified for this implementation)\n const element = document.getElementById(`schema-${index}`);\n if (element) {\n element.classList.toggle('hidden');\n }\n }}\n className=\"text-sm text-blue-500 font-normal hover:underline focus:outline-none ml-2\"\n >\n {t('market.viewSchema')}\n </button>\n </h4>\n <p className=\"text-gray-600 mb-2\">{tool.description}</p>\n <div className=\"mt-2\">\n <pre\n id={`schema-${index}`}\n className=\"hidden bg-gray-50 dark:bg-gray-800 p-3 rounded text-sm overflow-auto mt-2\"\n >\n {JSON.stringify(tool.inputSchema, null, 2)}\n </pre>\n </div>\n </div>\n ))}\n </div>\n </div>\n\n {server.examples && server.examples.length > 0 && (\n <div className=\"mb-6\">\n <h3 className=\"text-lg font-semibold mb-3\">{t('market.examples')}</h3>\n <div className=\"space-y-4\">\n {server.examples.map((example, index) => (\n <div key={index} className=\"border border-gray-200 dark:border-gray-700 rounded p-4\">\n <h4 className=\"font-medium mb-2\">{example.title}</h4>\n <p className=\"text-gray-600 mb-2\">{example.description}</p>\n <pre className=\"bg-gray-50 dark:bg-gray-800 p-3 rounded text-sm overflow-auto\">{example.prompt}</pre>\n </div>\n ))}\n </div>\n </div>\n )}\n\n <div className=\"mt-6 flex justify-end\">\n <button\n onClick={handleInstall}\n disabled={buttonProps.disabled}\n className={buttonProps.className}\n >\n {buttonProps.text}\n </button>\n </div>\n\n {modalVisible && (\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4\">\n <ServerForm\n onSubmit={handleSubmit}\n onCancel={toggleModal}\n modalTitle={t('market.installServer', { name: server.display_name })}\n formError={error}\n initialData={{\n name: server.name,\n status: 'disconnected',\n config: preferredInstallation\n ? {\n command: preferredInstallation.command || '',\n args: preferredInstallation.args || [],\n env: preferredInstallation.env || {},\n }\n : undefined,\n }}\n />\n </div>\n )}\n\n {confirmationVisible && (\n <div className=\"fixed inset-0 bg-black/50 z-[60] flex items-center justify-center p-4\">\n <div className=\"hub-card p-6 w-full max-w-md\">\n <h3 className=\"text-lg font-semibold text-gray-900 mb-4\">\n {t('server.confirmVariables')}\n </h3>\n <p className=\"text-gray-600 mb-4\">{t('server.variablesDetected')}</p>\n <div className=\"bg-yellow-50 border border-yellow-200 rounded p-3 mb-4\">\n <div className=\"flex items-start\">\n <div className=\"flex-shrink-0\">\n <svg className=\"h-5 w-5 text-yellow-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path\n fillRule=\"evenodd\"\n d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </div>\n <div className=\"ml-3\">\n <h4 className=\"text-sm font-medium text-yellow-800\">\n {t('server.detectedVariables')}:\n </h4>\n <ul className=\"mt-1 text-sm text-yellow-700\">\n {detectedVariables.map((variable, index) => (\n <li key={index} className=\"font-mono\">\n ${`{${variable}}`}\n </li>\n ))}\n </ul>\n </div>\n </div>\n </div>\n <p className=\"text-gray-600 text-sm mb-6\">{t('market.confirmVariablesMessage')}</p>\n <div className=\"flex justify-end space-x-3\">\n <button\n onClick={() => {\n setConfirmationVisible(false);\n setPendingPayload(null);\n }}\n className=\"hub-btn\"\n >\n {t('common.cancel')}\n </button>\n <button\n onClick={handleConfirmInstall}\n className=\"hub-btn primary\"\n >\n {t('market.confirmAndInstall')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default MarketServerDetail;\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Zap } from 'lucide-react';\nimport { CloudServer } from '@/types';\n\ninterface CloudServerCardProps {\n server: CloudServer;\n onClick: (server: CloudServer) => void;\n}\n\nconst formatDate = (dateString: string) => {\n try {\n const date = new Date(dateString);\n const y = date.getFullYear();\n const m = (date.getMonth() + 1).toString().padStart(2, '0');\n const d = date.getDate().toString().padStart(2, '0');\n return `${y}/${m}/${d}`;\n } catch {\n return '';\n }\n};\n\nconst CloudServerCard: React.FC<CloudServerCardProps> = ({ server, onClick }) => {\n const { t } = useTranslation();\n\n const getDescription = () => {\n if (server.description && server.description.length <= 150) return server.description;\n if (server.content) {\n const lines = server.content.split('\\n').filter((line) => line.trim());\n for (const line of lines) {\n if (line.length > 50 && line.length <= 150) return line;\n }\n }\n return server.description\n ? server.description.slice(0, 150) + '...'\n : t('cloud.noDescription');\n };\n\n return (\n <div\n className=\"hub-card flex flex-col cursor-pointer transition-colors h-full overflow-hidden\"\n onClick={() => onClick(server)}\n onMouseEnter={(e) => (e.currentTarget.style.borderColor = 'var(--hub-ink-2)')}\n onMouseLeave={(e) => (e.currentTarget.style.borderColor = 'var(--hub-line)')}\n >\n <div className=\"p-3.5 flex-1 flex flex-col gap-2.5\">\n <div className=\"flex items-start gap-2\">\n <div\n className=\"hub-mono flex-shrink-0\"\n style={{\n width: 28,\n height: 28,\n borderRadius: 7,\n background: 'var(--hub-ink)',\n color: 'var(--hub-bg)',\n display: 'grid',\n placeItems: 'center',\n fontWeight: 600,\n fontSize: 13,\n }}\n >\n {(server.title || server.name).charAt(0).toUpperCase()}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-1.5\">\n <span\n className=\"truncate\"\n style={{ fontSize: 14, fontWeight: 500, letterSpacing: '-0.01em' }}\n >\n {server.title || server.name}\n </span>\n <span\n className=\"hub-tag accent flex-shrink-0\"\n style={{ fontSize: 10 }}\n >\n MCP\n </span>\n </div>\n <div\n className=\"hub-mono truncate\"\n style={{ fontSize: 11, color: 'var(--hub-ink-3)' }}\n >\n @{server.author_name}\n </div>\n </div>\n </div>\n\n <div\n className=\"flex-1 line-clamp-2\"\n style={{ fontSize: 12.5, color: 'var(--hub-ink-2)', lineHeight: 1.5 }}\n >\n {getDescription()}\n </div>\n </div>\n\n <div\n className=\"flex items-center justify-between px-3.5 py-2\"\n style={{\n borderTop: '1px solid var(--hub-line-2)',\n background: 'var(--hub-bg-2)',\n }}\n >\n <div\n className=\"hub-mono flex items-center gap-3\"\n style={{ fontSize: 11.5, color: 'var(--hub-ink-3)' }}\n >\n {server.tools && server.tools.length > 0 && (\n <span className=\"inline-flex items-center gap-1\">\n <Zap size={11} />\n {server.tools.length} {t('server.tools').toLowerCase()}\n </span>\n )}\n {server.updated_at && <span>{formatDate(server.updated_at)}</span>}\n </div>\n <span\n className=\"hub-mono\"\n style={{ fontSize: 11, color: 'var(--hub-accent)' }}\n >\n {t('cloud.viewDetails')} →\n </span>\n </div>\n </div>\n );\n};\n\nexport default CloudServerCard;\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate } from 'react-router-dom';\n\nconst MCPRouterApiKeyError: React.FC = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n\n const handleConfigureSettings = () => {\n navigate('/settings');\n };\n\n const handleGetApiKey = () => {\n window.open('https://mcprouter.co', '_blank', 'noopener,noreferrer');\n };\n\n return (\n <div className=\"bg-amber-50 border border-amber-200 dark:bg-amber-900/20 dark:border-amber-900/50 rounded-lg p-6 mb-6\">\n <div className=\"flex items-start\">\n <div className=\"flex-shrink-0\">\n <svg\n className=\"h-5 w-5 text-amber-400 dark:text-amber-500\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </div>\n <div className=\"ml-3 flex-1\">\n <h3 className=\"text-sm font-medium text-amber-800 dark:text-amber-400\">\n {t('cloud.apiKeyNotConfigured')}\n </h3>\n <div className=\"mt-2 text-sm text-amber-700 dark:text-amber-300\">\n <p>{t('cloud.apiKeyNotConfiguredDescription')}</p>\n </div>\n <div className=\"mt-4 flex flex-wrap gap-2\">\n <button\n onClick={handleGetApiKey}\n className=\"hub-btn primary inline-flex items-center\"\n >\n <svg\n className=\"w-4 h-4 mr-1.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"\n />\n </svg>\n {t('cloud.getApiKey')}\n </button>\n <button\n onClick={handleConfigureSettings}\n className=\"inline-flex items-center px-3 py-2 text-sm font-medium text-amber-800 dark:text-amber-400 bg-amber-100 border border-amber-300 dark:bg-amber-900/40 dark:border-amber-700 dark:text-amber-300 rounded-md hover:bg-amber-200 dark:hover:bg-amber-900/60 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-amber-500 dark:focus:ring-amber-400 transition-colors duration-200\"\n >\n <svg\n className=\"w-4 h-4 mr-1.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\"\n />\n </svg>\n {t('cloud.configureInSettings')}\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default MCPRouterApiKeyError;\n","import React, { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CloudServer, CloudServerTool, ServerConfig } from '@/types';\nimport { apiGet } from '@/utils/fetchInterceptor';\nimport { useSettingsData } from '@/hooks/useSettingsData';\nimport MCPRouterApiKeyError from './MCPRouterApiKeyError';\nimport ServerForm from './ServerForm';\n\ninterface CloudServerDetailProps {\n serverName: string;\n onBack: () => void;\n onCallTool?: (serverName: string, toolName: string, args: Record<string, any>) => Promise<any>;\n fetchServerTools?: (serverName: string) => Promise<CloudServerTool[]>;\n onInstall?: (server: CloudServer, config: ServerConfig) => void;\n installing?: boolean;\n isInstalled?: boolean;\n}\n\nconst CloudServerDetail: React.FC<CloudServerDetailProps> = ({\n serverName,\n onBack,\n onCallTool,\n fetchServerTools,\n onInstall,\n installing = false,\n isInstalled = false\n}) => {\n const { t } = useTranslation();\n const { mcpRouterConfig } = useSettingsData();\n const [server, setServer] = useState<CloudServer | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [tools, setTools] = useState<CloudServerTool[]>([]);\n const [loadingTools, setLoadingTools] = useState(false);\n const [toolsApiKeyError, setToolsApiKeyError] = useState(false);\n const [toolCallLoading, setToolCallLoading] = useState<string | null>(null);\n const [toolCallResults, setToolCallResults] = useState<Record<string, any>>({});\n const [toolArgs, setToolArgs] = useState<Record<string, Record<string, any>>>({});\n const [expandedSchemas, setExpandedSchemas] = useState<Record<string, boolean>>({});\n const [modalVisible, setModalVisible] = useState(false);\n const [installError, setInstallError] = useState<string | null>(null);\n\n // Helper function to check if error is MCPRouter API key not configured\n const isMCPRouterApiKeyError = (errorMessage: string) => {\n console.error('Checking for MCPRouter API key error:', errorMessage);\n return errorMessage === 'MCPROUTER_API_KEY_NOT_CONFIGURED' ||\n errorMessage.toLowerCase().includes('mcprouter api key not configured');\n };\n\n // Helper function to determine button state for install\n const getInstallButtonProps = () => {\n if (isInstalled) {\n return {\n className: \"hub-btn cursor-default\",\n disabled: true,\n text: t('market.installed')\n };\n } else if (installing) {\n return {\n className: \"hub-btn cursor-not-allowed opacity-50\",\n disabled: true,\n text: t('market.installing')\n };\n } else {\n return {\n className: \"hub-btn primary\",\n disabled: false,\n text: t('market.install')\n };\n }\n };\n\n // Handle install button click\n const handleInstall = () => {\n if (!isInstalled && onInstall) {\n setModalVisible(true);\n setInstallError(null);\n }\n };\n\n // Handle modal close\n const handleModalClose = () => {\n setModalVisible(false);\n setInstallError(null);\n };\n\n // Handle install form submission\n const handleInstallSubmit = async (payload: any) => {\n try {\n if (!server || !onInstall) return;\n\n setInstallError(null);\n onInstall(server, payload.config);\n setModalVisible(false);\n } catch (err) {\n console.error('Error installing server:', err);\n setInstallError(t('errors.serverInstall'));\n }\n };\n\n // Load server details\n useEffect(() => {\n const loadServerDetails = async () => {\n try {\n setLoading(true);\n setError(null);\n const response = await apiGet(`/cloud/servers/${serverName}`);\n\n if (response && response.success && response.data) {\n setServer(response.data);\n setTools(response.data.tools || []);\n } else {\n setError(t('cloud.serverNotFound'));\n }\n } catch (err) {\n console.error('Failed to load server details:', err);\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setLoading(false);\n }\n };\n\n loadServerDetails();\n }, [serverName, t]);\n\n // Load tools if not already loaded\n useEffect(() => {\n const loadTools = async () => {\n if (server && (!server.tools || server.tools.length === 0) && fetchServerTools) {\n setLoadingTools(true);\n setToolsApiKeyError(false);\n try {\n const fetchedTools = await fetchServerTools(server.name);\n setTools(fetchedTools);\n } catch (error) {\n console.error('Failed to load tools:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (isMCPRouterApiKeyError(errorMessage)) {\n setToolsApiKeyError(true);\n }\n } finally {\n setLoadingTools(false);\n }\n }\n };\n\n loadTools();\n }, [server?.name, server?.tools, fetchServerTools]);\n\n // Format creation date\n const formatDate = (dateStr: string) => {\n try {\n const date = new Date(dateStr);\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n const seconds = String(date.getSeconds()).padStart(2, '0');\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n } catch {\n return dateStr;\n }\n };\n\n // Handle tool argument changes\n const handleArgChange = (toolName: string, argName: string, value: any) => {\n setToolArgs(prev => ({\n ...prev,\n [toolName]: {\n ...prev[toolName],\n [argName]: value\n }\n }));\n };\n\n // Handle tool call\n const handleCallTool = async (toolName: string) => {\n if (!onCallTool || !server) return;\n\n setToolCallLoading(toolName);\n try {\n const args = toolArgs[toolName] || {};\n const result = await onCallTool(server.server_key, toolName, args);\n setToolCallResults(prev => ({\n ...prev,\n [toolName]: result\n }));\n } catch (error) {\n console.error('Tool call failed:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n setToolCallResults(prev => ({\n ...prev,\n [toolName]: { error: errorMessage }\n }));\n } finally {\n setToolCallLoading(null);\n }\n };\n\n // Toggle schema visibility\n const toggleSchema = (toolName: string) => {\n setExpandedSchemas(prev => ({\n ...prev,\n [toolName]: !prev[toolName]\n }));\n };\n\n // Render tool input field based on schema\n const renderToolInput = (tool: CloudServerTool, propName: string, propSchema: any) => {\n const currentValue = toolArgs[tool.name]?.[propName] || '';\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {\n let value: any = e.target.value;\n\n // Convert value based on schema type\n if (propSchema.type === 'number' || propSchema.type === 'integer') {\n value = value === '' ? undefined : Number(value);\n } else if (propSchema.type === 'boolean') {\n value = e.target.value === 'true';\n }\n\n handleArgChange(tool.name, propName, value);\n };\n\n if (propSchema.type === 'boolean') {\n return (\n <select\n value={currentValue === true ? 'true' : currentValue === false ? 'false' : ''}\n onChange={handleChange}\n className=\"w-full border rounded-md px-3 py-2 border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 form-input\"\n >\n <option value=\"\"></option>\n <option value=\"true\">{t('common.true')}</option>\n <option value=\"false\">{t('common.false')}</option>\n </select>\n );\n } else if (propSchema.type === 'number' || propSchema.type === 'integer') {\n return (\n <input\n type=\"number\"\n step={propSchema.type === 'integer' ? '1' : 'any'}\n value={currentValue || ''}\n onChange={handleChange}\n className=\"w-full border rounded-md px-3 py-2 border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 form-input\"\n />\n );\n } else {\n return (\n <input\n type=\"text\"\n value={currentValue || ''}\n onChange={handleChange}\n className=\"w-full border rounded-md px-3 py-2 border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 form-input\"\n />\n );\n }\n };\n\n return (\n <div className=\"bg-white dark:bg-gray-800 rounded-lg shadow-md p-6\">\n <div className=\"mb-6\">\n <button\n onClick={onBack}\n className=\"inline-flex items-center text-gray-600 hover:text-gray-900 transition-colors group\"\n >\n <svg className=\"h-5 w-5 mr-2 transform group-hover:-translate-x-1 transition-transform\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fillRule=\"evenodd\" d=\"M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z\" clipRule=\"evenodd\" />\n </svg>\n {t('cloud.backToList')}\n </button>\n </div>\n\n {loading ? (\n <div className=\"bg-white dark:bg-gray-800 rounded-xl shadow-sm p-12\">\n <div className=\"flex flex-col items-center\">\n <svg className=\"animate-spin h-12 w-12 text-blue-500 mb-4\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <p className=\"text-gray-600 text-lg\">{t('app.loading')}</p>\n </div>\n </div>\n ) : error && !isMCPRouterApiKeyError(error) ? (\n <div className=\"bg-white dark:bg-gray-800 rounded-xl shadow-sm p-6\">\n <div className=\"bg-red-50 border border-red-200 dark:bg-red-900/20 dark:border-red-900/50 rounded-lg p-4\">\n <div className=\"flex items-center\">\n <svg className=\"h-5 w-5 text-red-400 dark:text-red-500 mr-3\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clipRule=\"evenodd\" />\n </svg>\n <p className=\"text-red-700 dark:text-red-400\">{error}</p>\n </div>\n </div>\n </div>\n ) : !server ? (\n <div className=\"bg-white dark:bg-gray-800 rounded-xl shadow-sm p-12\">\n <div className=\"text-center\">\n <svg className=\"h-12 w-12 text-gray-400 mx-auto mb-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1} d=\"M9.172 16.172a4 4 0 015.656 0M9 12h6m-6-4h6m2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n <p className=\"text-gray-600 text-lg\">{t('cloud.serverNotFound')}</p>\n </div>\n </div>\n ) : (\n <div className=\"space-y-6\">\n {/* Server Header Card */}\n <div className=\"bg-white dark:bg-gray-800 rounded-xl shadow-sm overflow-hidden\">\n <div className=\"bg-gradient-to-r from-gray-100 to-gray-200 dark:from-gray-800 dark:to-gray-700 px-6 py-4\">\n <div className=\"flex justify-between items-end\">\n <div className=\"flex-1\">\n <h1 className=\"text-2xl font-bold text-gray-800 mb-2\">\n {server.title || server.name}\n </h1>\n <div className=\"flex flex-wrap items-center gap-4 text-gray-600\">\n <span className=\"text-sm bg-white/60 dark:bg-gray-800/60 text-gray-700 px-3 py-1 rounded-full\">\n {server.name}\n </span>\n <div className=\"flex items-center\">\n <svg className=\"h-4 w-4 mr-1\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z\" clipRule=\"evenodd\" />\n </svg>\n {t('cloud.by')} {server.author_name}\n </div>\n </div>\n </div>\n\n <div className=\"text-right flex flex-col items-end gap-3\">\n <div className=\"text-xs text-gray-500\">\n {t('cloud.updated')}: {formatDate(server.updated_at)}\n </div>\n {onInstall && !isMCPRouterApiKeyError(error || '') && !toolsApiKeyError && (\n <button\n onClick={handleInstall}\n disabled={getInstallButtonProps().disabled}\n className={getInstallButtonProps().className}\n >\n {getInstallButtonProps().text}\n </button>\n )}\n </div>\n </div>\n </div>\n </div>\n\n {/* Description Card */}\n <div className=\"bg-white dark:bg-gray-800 rounded-xl shadow-sm p-6\">\n <h2 className=\"text-xl font-semibold text-gray-900 mb-4 flex items-center\">\n <svg className=\"h-5 w-5 text-gray-500 mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n {t('cloud.description')}\n </h2>\n <p className=\"text-gray-700 leading-relaxed\">{server.description}</p>\n </div>\n\n {/* Content Card */}\n {server.content && (\n <div className=\"bg-white dark:bg-gray-800 rounded-xl shadow-sm p-6\">\n <h2 className=\"text-xl font-semibold text-gray-900 mb-4 flex items-center\">\n <svg className=\"h-5 w-5 text-gray-500 mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 12h6m-6 4h6m2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n {t('cloud.details')}\n </h2>\n <div className=\"bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4 overflow-auto\">\n <pre className=\"text-sm text-gray-800 whitespace-pre-wrap\">{server.content}</pre>\n </div>\n </div>\n )}\n\n {/* Tools Card */}\n <div className=\"bg-white dark:bg-gray-800 rounded-xl shadow-sm p-6\">\n <h2 className=\"text-xl font-semibold text-gray-900 mb-4 flex items-center\">\n <svg className=\"h-5 w-5 text-gray-500 mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z\" />\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 12a3 3 0 11-6 0 3 3 0 016 0z\" />\n </svg>\n {t('cloud.tools')}\n {tools.length > 0 && (\n <span className=\"ml-2 bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300 text-sm font-medium px-2.5 py-0.5 rounded-full\">\n {tools.length}\n </span>\n )}\n </h2>\n\n {/* Check for API key error */}\n {toolsApiKeyError && (\n <MCPRouterApiKeyError />\n )}\n\n {loadingTools ? (\n <div className=\"flex items-center justify-center py-12\">\n <svg className=\"animate-spin h-8 w-8 text-blue-500 mr-3\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span className=\"text-gray-600\">{t('cloud.loadingTools')}</span>\n </div>\n ) : tools.length === 0 && !toolsApiKeyError ? (\n <div className=\"text-center py-12\">\n <svg className=\"h-12 w-12 text-gray-400 mx-auto mb-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1} d=\"M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4\" />\n </svg>\n <p className=\"text-gray-600\">{t('cloud.noTools')}</p>\n </div>\n ) : tools.length > 0 ? (\n <div className=\"space-y-4\">\n {tools.map((tool, index) => (\n <div key={index} className=\"border border-gray-200 dark:border-gray-700 rounded-lg p-6 hover:border-gray-300 transition-colors\">\n <div className=\"flex justify-between items-start mb-4\">\n <div className=\"flex-1\">\n <h3 className=\"text-lg font-medium text-gray-900 mb-2 flex items-center\">\n <span className=\"bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300 text-xs font-medium px-2 py-1 rounded mr-3\">\n TOOL\n </span>\n {tool.name}\n </h3>\n <p className=\"text-gray-600 leading-relaxed whitespace-pre-wrap\">{tool.description}</p>\n </div>\n {onCallTool && (\n <button\n onClick={() => handleCallTool(tool.name)}\n disabled={toolCallLoading === tool.name}\n className=\"hub-btn primary ml-4 flex items-center min-w-[100px] justify-center\"\n >\n {toolCallLoading === tool.name ? (\n <>\n <svg className=\"animate-spin h-4 w-4 mr-2\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n {t('cloud.calling')}\n </>\n ) : (\n <>\n <svg className=\"h-4 w-4 mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M14.828 14.828a4 4 0 01-5.656 0M9 10h6m2 8l4-4H7l4 4z\" />\n </svg>\n {t('cloud.callTool')}\n </>\n )}\n </button>\n )}\n </div>\n\n {/* Tool inputs */}\n {tool.inputSchema && tool.inputSchema.properties && Object.keys(tool.inputSchema.properties).length > 0 && (\n <div className=\"border-t border-gray-100 dark:border-gray-700 pt-4\">\n <div className=\"flex items-center gap-3 mb-4\">\n <h4 className=\"text-sm font-medium text-gray-700\">{t('cloud.parameters')}</h4>\n <button\n onClick={() => toggleSchema(tool.name)}\n className=\"text-sm text-blue-600 hover:text-blue-800 focus:outline-none flex items-center gap-1 transition-colors\"\n >\n {t('cloud.viewSchema')}\n <svg\n className={`h-3 w-3 transition-transform duration-200 ${expandedSchemas[tool.name] ? 'rotate-90' : 'rotate-0'}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path fillRule=\"evenodd\" d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\" clipRule=\"evenodd\" />\n </svg>\n </button>\n </div>\n\n {/* Schema content */}\n {expandedSchemas[tool.name] && (\n <div className=\"mb-4\">\n <div className=\"bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-3 overflow-auto\">\n <pre className=\"text-sm text-gray-800\">\n {JSON.stringify(tool.inputSchema, null, 2)}\n </pre>\n </div>\n </div>\n )}\n\n <div className=\"space-y-4\">\n {Object.entries(tool.inputSchema.properties).map(([propName, propSchema]: [string, any]) => (\n <div key={propName} className=\"space-y-2\">\n <label className=\"block text-sm font-medium text-gray-700\">\n {propName}\n {tool.inputSchema.required?.includes(propName) && (\n <span className=\"text-red-500 ml-1\">*</span>\n )}\n </label>\n {propSchema.description && (\n <p className=\"text-xs text-gray-500\">{propSchema.description}</p>\n )}\n {renderToolInput(tool, propName, propSchema)}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Tool call result */}\n {toolCallResults[tool.name] && (\n <div className=\"border-t border-gray-100 dark:border-gray-700 pt-4 mt-4\">\n {toolCallResults[tool.name].error ? (\n <>\n {isMCPRouterApiKeyError(toolCallResults[tool.name].error) ? (\n <MCPRouterApiKeyError />\n ) : (\n <>\n <h4 className=\"text-sm font-medium text-red-600 mb-3 flex items-center\">\n <svg className=\"h-4 w-4 text-red-500 mr-2\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clipRule=\"evenodd\" />\n </svg>\n {t('cloud.error')}\n </h4>\n <div className=\"bg-red-50 border border-red-200 dark:bg-red-900/20 dark:border-red-900/50 rounded-lg p-4\">\n <pre className=\"text-sm text-red-800 dark:text-red-300 whitespace-pre-wrap overflow-auto\">\n {toolCallResults[tool.name].error}\n </pre>\n </div>\n </>\n )}\n </>\n ) : (\n <>\n <h4 className=\"text-sm font-medium text-gray-700 mb-3 flex items-center\">\n <svg className=\"h-4 w-4 text-green-500 mr-2\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clipRule=\"evenodd\" />\n </svg>\n {t('cloud.result')}\n </h4>\n <div className=\"bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4\">\n <pre className=\"text-sm text-gray-800 whitespace-pre-wrap overflow-auto\">\n {JSON.stringify(toolCallResults[tool.name], null, 2)}\n </pre>\n </div>\n </>\n )}\n </div>\n )}\n </div>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n )}\n\n {/* Install Modal */}\n {modalVisible && server && (\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4\">\n <ServerForm\n onSubmit={handleInstallSubmit}\n onCancel={handleModalClose}\n modalTitle={t('cloud.installServer', { name: server.title || server.name })}\n formError={installError}\n initialData={{\n name: server.name,\n status: 'disconnected',\n config: {\n type: 'streamable-http',\n url: server.server_url,\n headers: {\n 'Authorization': `Bearer ${mcpRouterConfig.apiKey || '<MCPROUTER_API_KEY>'}`,\n 'HTTP-Referer': mcpRouterConfig.referer || '<YOUR_APP_URL>',\n 'X-Title': mcpRouterConfig.title || '<YOUR_APP_NAME>'\n }\n }\n }}\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default CloudServerDetail;\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Package, Globe, Check } from 'lucide-react';\nimport { RegistryServerEntry } from '@/types';\n\ninterface RegistryServerCardProps {\n serverEntry: RegistryServerEntry;\n onClick: (serverEntry: RegistryServerEntry) => void;\n}\n\nconst formatDate = (dateString?: string) => {\n if (!dateString) return '';\n try {\n const date = new Date(dateString);\n const y = date.getFullYear();\n const m = (date.getMonth() + 1).toString().padStart(2, '0');\n const d = date.getDate().toString().padStart(2, '0');\n return `${y}/${m}/${d}`;\n } catch {\n return '';\n }\n};\n\nconst RegistryServerCard: React.FC<RegistryServerCardProps> = ({ serverEntry, onClick }) => {\n const { t } = useTranslation();\n const { server, _meta } = serverEntry;\n const officialMeta = _meta?.['io.modelcontextprotocol.registry/official'];\n const isLatest = officialMeta?.isLatest;\n const publishedAt = officialMeta?.publishedAt;\n const updatedAt = officialMeta?.updatedAt;\n const packageCount = server.packages?.length || 0;\n const remoteCount = server.remotes?.length || 0;\n const description = server.description\n ? server.description.length <= 150\n ? server.description\n : server.description.slice(0, 150) + '...'\n : t('registry.noDescription');\n\n const icon = (() => {\n if (server.icons && server.icons.length > 0) {\n const light = server.icons.find((i) => !i.theme || i.theme === 'light');\n return light || server.icons[0];\n }\n return null;\n })();\n\n return (\n <div\n className=\"hub-card flex flex-col cursor-pointer transition-colors h-full overflow-hidden\"\n onClick={() => onClick(serverEntry)}\n onMouseEnter={(e) => (e.currentTarget.style.borderColor = 'var(--hub-ink-2)')}\n onMouseLeave={(e) => (e.currentTarget.style.borderColor = 'var(--hub-line)')}\n >\n <div className=\"p-3.5 flex-1 flex flex-col gap-2.5\">\n <div className=\"flex items-start gap-2\">\n {icon ? (\n <img\n src={icon.src}\n alt={server.title || server.name}\n className=\"rounded-md object-cover flex-shrink-0\"\n style={{ width: 28, height: 28 }}\n onError={(e) => {\n (e.currentTarget as HTMLImageElement).style.display = 'none';\n }}\n />\n ) : (\n <div\n className=\"hub-mono flex-shrink-0\"\n style={{\n width: 28,\n height: 28,\n borderRadius: 7,\n background: 'var(--hub-ink)',\n color: 'var(--hub-bg)',\n display: 'grid',\n placeItems: 'center',\n fontWeight: 600,\n fontSize: 13,\n }}\n >\n {server.name.charAt(0).toUpperCase()}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-1.5\">\n <span\n className=\"truncate\"\n style={{ fontSize: 14, fontWeight: 500, letterSpacing: '-0.01em' }}\n >\n {server.title || server.name}\n </span>\n {isLatest && (\n <span\n className=\"inline-flex items-center gap-0.5 flex-shrink-0\"\n style={{\n fontSize: 10,\n color: 'oklch(0.4 0.13 145)',\n background: 'oklch(0.95 0.05 145)',\n padding: '0 5px',\n height: 16,\n borderRadius: 3,\n fontWeight: 500,\n }}\n >\n <Check size={9} strokeWidth={2.5} />\n {t('registry.latest')}\n </span>\n )}\n </div>\n <div\n className=\"hub-mono truncate\"\n style={{ fontSize: 11, color: 'var(--hub-ink-3)' }}\n >\n {server.name} · v{server.version}\n </div>\n </div>\n </div>\n\n <div\n className=\"flex-1 line-clamp-2\"\n style={{ fontSize: 12.5, color: 'var(--hub-ink-2)', lineHeight: 1.5 }}\n >\n {description}\n </div>\n </div>\n\n <div\n className=\"flex items-center justify-between px-3.5 py-2\"\n style={{ borderTop: '1px solid var(--hub-line-2)', background: 'var(--hub-bg-2)' }}\n >\n <div\n className=\"hub-mono flex items-center gap-3\"\n style={{ fontSize: 11.5, color: 'var(--hub-ink-3)' }}\n >\n {packageCount > 0 && (\n <span className=\"inline-flex items-center gap-1\">\n <Package size={11} />\n {packageCount}\n </span>\n )}\n {remoteCount > 0 && (\n <span className=\"inline-flex items-center gap-1\">\n <Globe size={11} />\n {remoteCount}\n </span>\n )}\n {(publishedAt || updatedAt) && <span>{formatDate(updatedAt || publishedAt)}</span>}\n </div>\n <span className=\"hub-mono\" style={{ fontSize: 11, color: 'var(--hub-accent)' }}>\n {t('registry.viewDetails')} →\n </span>\n </div>\n </div>\n );\n};\n\nexport default RegistryServerCard;\n","import { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n RegistryServerEntry,\n RegistryPackage,\n RegistryRemote,\n RegistryServerData,\n ServerConfig,\n} from '@/types';\nimport ServerForm from './ServerForm';\n\ninterface RegistryServerDetailProps {\n serverEntry: RegistryServerEntry;\n onBack: () => void;\n onInstall?: (server: RegistryServerData, config: ServerConfig) => void;\n installing?: boolean;\n isInstalled?: boolean;\n fetchVersions?: (serverName: string) => Promise<RegistryServerEntry[]>;\n}\n\nconst RegistryServerDetail: React.FC<RegistryServerDetailProps> = ({\n serverEntry,\n onBack,\n onInstall,\n installing = false,\n isInstalled = false,\n fetchVersions,\n}) => {\n const { t } = useTranslation();\n const { server, _meta } = serverEntry;\n\n const [_selectedVersion, _setSelectedVersion] = useState<string>(server.version);\n const [_availableVersions, setAvailableVersions] = useState<RegistryServerEntry[]>([]);\n const [_loadingVersions, setLoadingVersions] = useState(false);\n const [modalVisible, setModalVisible] = useState(false);\n const [selectedInstallType, setSelectedInstallType] = useState<'package' | 'remote' | null>(null);\n const [selectedOption, setSelectedOption] = useState<RegistryPackage | RegistryRemote | null>(\n null,\n );\n const [installError, setInstallError] = useState<string | null>(null);\n const [expandedSections, setExpandedSections] = useState<Record<string, boolean>>({\n packages: true,\n remotes: true,\n repository: true,\n });\n\n const officialMeta = _meta?.['io.modelcontextprotocol.registry/official'];\n\n // Load available versions\n useEffect(() => {\n const loadVersions = async () => {\n if (fetchVersions) {\n setLoadingVersions(true);\n try {\n const versions = await fetchVersions(server.name);\n setAvailableVersions(versions);\n } catch (error) {\n console.error('Failed to load versions:', error);\n } finally {\n setLoadingVersions(false);\n }\n }\n };\n\n loadVersions();\n }, [server.name, fetchVersions]);\n\n // Get icon to display\n const getIcon = () => {\n if (server.icons && server.icons.length > 0) {\n const lightIcon = server.icons.find((icon) => !icon.theme || icon.theme === 'light');\n return lightIcon || server.icons[0];\n }\n return null;\n };\n\n const icon = getIcon();\n\n // Format date\n const formatDate = (dateString?: string) => {\n if (!dateString) return '';\n try {\n const date = new Date(dateString);\n return date.toLocaleDateString();\n } catch {\n return '';\n }\n };\n\n // Toggle section expansion\n const toggleSection = (section: string) => {\n setExpandedSections((prev) => ({ ...prev, [section]: !prev[section] }));\n };\n\n // Handle install button click\n const handleInstallClick = (\n type: 'package' | 'remote',\n option: RegistryPackage | RegistryRemote,\n ) => {\n setSelectedInstallType(type);\n setSelectedOption(option);\n setInstallError(null);\n setModalVisible(true);\n };\n\n // Handle modal close\n const handleModalClose = () => {\n setModalVisible(false);\n setInstallError(null);\n };\n\n // Handle install submission\n const handleInstallSubmit = async (payload: any) => {\n try {\n if (!onInstall || !selectedOption || !selectedInstallType) return;\n\n setInstallError(null);\n\n // Extract the ServerConfig from the payload\n const config: ServerConfig = payload.config;\n\n // Call onInstall with server data and config\n onInstall(server, config);\n setModalVisible(false);\n } catch (err) {\n console.error('Error installing server:', err);\n setInstallError(t('errors.serverInstall'));\n }\n };\n\n // Build initial data for ServerForm\n const getInitialFormData = () => {\n if (!selectedOption || !selectedInstallType) return null;\n console.log('Building initial form data for:', selectedOption);\n\n if (selectedInstallType === 'package' && 'identifier' in selectedOption) {\n const pkg = selectedOption as RegistryPackage;\n\n // Build environment variables from package definition\n const env: Record<string, string> = {};\n if (pkg.environmentVariables) {\n pkg.environmentVariables.forEach((envVar) => {\n env[envVar.name] = envVar.default || '';\n });\n }\n\n const command = getCommand(pkg.registryType);\n return {\n name: server.name,\n status: 'disconnected' as const,\n config: {\n type: 'stdio' as const,\n command: command,\n args: getArgs(command, pkg),\n env: Object.keys(env).length > 0 ? env : undefined,\n },\n };\n } else if (selectedInstallType === 'remote' && 'url' in selectedOption) {\n const remote = selectedOption as RegistryRemote;\n\n // Build headers from remote definition\n const headers: Record<string, string> = {};\n if (remote.headers) {\n remote.headers.forEach((header) => {\n headers[header.name] = header.default || header.value || '';\n });\n }\n\n // Determine transport type - default to streamable-http for remotes\n const transportType = remote.type === 'sse' ? ('sse' as const) : ('streamable-http' as const);\n\n return {\n name: server.name,\n status: 'disconnected' as const,\n config: {\n type: transportType,\n url: remote.url,\n headers: Object.keys(headers).length > 0 ? headers : undefined,\n },\n };\n }\n\n return null;\n };\n\n // Render package option\n const renderPackage = (pkg: RegistryPackage, index: number) => {\n return (\n <div\n key={index}\n className=\"border border-gray-200 dark:border-gray-700 rounded-lg p-4 mb-3 hover:border-blue-400 transition-colors\"\n >\n <div className=\"flex items-start justify-between mb-3\">\n <div className=\"flex-1\">\n <h4 className=\"font-medium text-gray-900\">{pkg.identifier}</h4>\n {pkg.version && <p className=\"text-sm text-gray-500\">Version: {pkg.version}</p>}\n {pkg.runtimeHint && <p className=\"text-sm text-gray-600 mt-1\">{pkg.runtimeHint}</p>}\n </div>\n <button\n onClick={() => handleInstallClick('package', pkg)}\n disabled={isInstalled || installing}\n className={`px-4 py-2 rounded text-sm font-medium transition-colors ${\n isInstalled\n ? 'hub-btn cursor-default'\n : installing\n ? 'hub-btn cursor-not-allowed opacity-50'\n : 'hub-btn primary'\n }`}\n >\n {isInstalled\n ? t('registry.installed')\n : installing\n ? t('registry.installing')\n : t('registry.install')}\n </button>\n </div>\n\n {/* Package details */}\n {pkg.registryType && (\n <div className=\"text-sm text-gray-600 mb-2\">\n <span className=\"font-medium\">Registry:</span> {pkg.registryType}\n </div>\n )}\n\n {/* Transport type */}\n {pkg.transport && (\n <div className=\"text-sm text-gray-600 mb-2\">\n <span className=\"font-medium\">Transport:</span> {pkg.transport.type}\n {pkg.transport.url && <span className=\"ml-2 text-gray-500\">({pkg.transport.url})</span>}\n </div>\n )}\n\n {/* Environment Variables */}\n {pkg.environmentVariables && pkg.environmentVariables.length > 0 && (\n <div className=\"mt-3 border-t border-gray-200 dark:border-gray-700 pt-3\">\n <h5 className=\"text-sm font-medium text-gray-700 mb-2\">\n {t('registry.environmentVariables')}:\n </h5>\n <div className=\"space-y-2\">\n {pkg.environmentVariables.map((envVar, envIndex) => (\n <div key={envIndex} className=\"text-sm\">\n <div className=\"flex items-start\">\n <span className=\"font-mono text-gray-900 font-medium\">{envVar.name}</span>\n {envVar.isRequired && (\n <span className=\"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800\">\n {t('common.required')}\n </span>\n )}\n {envVar.isSecret && (\n <span className=\"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800\">\n {t('common.secret')}\n </span>\n )}\n </div>\n {envVar.description && <p className=\"text-gray-600 mt-1\">{envVar.description}</p>}\n {envVar.default && (\n <p className=\"text-gray-500 mt-1\">\n <span className=\"font-medium\">{t('common.default')}:</span>{' '}\n <span className=\"font-mono\">{envVar.default}</span>\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Package Arguments */}\n {pkg.packageArguments && pkg.packageArguments.length > 0 && (\n <div className=\"mt-3 border-t border-gray-200 dark:border-gray-700 pt-3\">\n <h5 className=\"text-sm font-medium text-gray-700 mb-2\">\n {t('registry.packageArguments')}:\n </h5>\n <div className=\"space-y-2\">\n {pkg.packageArguments.map((arg, argIndex) => (\n <div key={argIndex} className=\"text-sm\">\n <div className=\"flex items-start\">\n <span className=\"font-mono text-gray-900 font-medium\">{arg.name}</span>\n {arg.isRequired && (\n <span className=\"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800\">\n {t('common.required')}\n </span>\n )}\n {arg.isSecret && (\n <span className=\"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800\">\n {t('common.secret')}\n </span>\n )}\n {arg.isRepeated && (\n <span className=\"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-300\">\n {t('common.repeated')}\n </span>\n )}\n </div>\n {arg.description && <p className=\"text-gray-600 mt-1\">{arg.description}</p>}\n {arg.type && (\n <p className=\"text-gray-500 mt-1\">\n <span className=\"font-medium\">{t('common.type')}:</span>{' '}\n <span className=\"font-mono\">{arg.type}</span>\n </p>\n )}\n {arg.default && (\n <p className=\"text-gray-500 mt-1\">\n <span className=\"font-medium\">{t('common.default')}:</span>{' '}\n <span className=\"font-mono\">{arg.default}</span>\n </p>\n )}\n {arg.value && (\n <p className=\"text-gray-500 mt-1\">\n <span className=\"font-medium\">{t('common.value')}:</span>{' '}\n <span className=\"font-mono\">{arg.value}</span>\n </p>\n )}\n {arg.valueHint && (\n <p className=\"text-gray-500 mt-1\">\n <span className=\"font-medium\">{t('common.valueHint')}:</span>{' '}\n <span className=\"font-mono\">{arg.valueHint}</span>\n </p>\n )}\n {arg.choices && arg.choices.length > 0 && (\n <p className=\"text-gray-500 mt-1\">\n <span className=\"font-medium\">{t('common.choices')}:</span>{' '}\n <span className=\"font-mono\">{arg.choices.join(', ')}</span>\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n };\n\n // Render remote option\n const renderRemote = (remote: RegistryRemote, index: number) => {\n return (\n <div\n key={index}\n className=\"border border-gray-200 dark:border-gray-700 rounded-lg p-4 mb-3 hover:border-blue-400 transition-colors\"\n >\n <div className=\"flex items-start justify-between mb-3\">\n <div className=\"flex-1\">\n <h4 className=\"font-medium text-gray-900\">{remote.type}</h4>\n <p className=\"text-sm text-gray-600 mt-1 break-all\">{remote.url}</p>\n </div>\n <button\n onClick={() => handleInstallClick('remote', remote)}\n disabled={isInstalled || installing}\n className={`px-4 py-2 rounded text-sm font-medium transition-colors ${\n isInstalled\n ? 'hub-btn cursor-default'\n : installing\n ? 'hub-btn cursor-not-allowed opacity-50'\n : 'hub-btn primary'\n }`}\n >\n {isInstalled\n ? t('registry.installed')\n : installing\n ? t('registry.installing')\n : t('registry.install')}\n </button>\n </div>\n\n {/* Headers */}\n {remote.headers && remote.headers.length > 0 && (\n <div className=\"mt-3 border-t border-gray-200 dark:border-gray-700 pt-3\">\n <h5 className=\"text-sm font-medium text-gray-700 mb-2\">{t('registry.headers')}:</h5>\n <div className=\"space-y-2\">\n {remote.headers.map((header, headerIndex) => (\n <div key={headerIndex} className=\"text-sm\">\n <div className=\"flex items-start\">\n <span className=\"font-mono text-gray-900 font-medium\">{header.name}</span>\n {header.isRequired && (\n <span className=\"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800\">\n {t('common.required')}\n </span>\n )}\n {header.isSecret && (\n <span className=\"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800\">\n {t('common.secret')}\n </span>\n )}\n </div>\n {header.description && <p className=\"text-gray-600 mt-1\">{header.description}</p>}\n {header.value && (\n <p className=\"text-gray-500 mt-1\">\n <span className=\"font-medium\">{t('common.value')}:</span>{' '}\n <span className=\"font-mono\">{header.value}</span>\n </p>\n )}\n {header.default && (\n <p className=\"text-gray-500 mt-1\">\n <span className=\"font-medium\">{t('common.default')}:</span>{' '}\n <span className=\"font-mono\">{header.default}</span>\n </p>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n );\n };\n\n return (\n <div className=\"bg-white dark:bg-gray-800 shadow rounded-lg p-6\">\n {/* Header */}\n <div className=\"mb-6\">\n <button\n onClick={onBack}\n className=\"flex items-center text-blue-600 hover:text-blue-800 mb-4 transition-colors\"\n >\n <svg className=\"w-5 h-5 mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n {t('registry.backToList')}\n </button>\n\n <div className=\"flex items-start space-x-4\">\n {/* Icon */}\n {icon ? (\n <img\n src={icon.src}\n alt={server.title}\n className=\"w-20 h-20 rounded-lg object-cover flex-shrink-0\"\n onError={(e) => {\n e.currentTarget.style.display = 'none';\n }}\n />\n ) : (\n <div className=\"w-20 h-20 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center text-white text-3xl font-semibold flex-shrink-0\">\n M\n </div>\n )}\n\n {/* Title and metadata */}\n <div className=\"flex-1\">\n <h1 className=\"text-3xl font-bold text-gray-900 mb-2\">{server.name}</h1>\n\n <div className=\"flex flex-wrap gap-2 mb-3\">\n {officialMeta?.isLatest && (\n <span className=\"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-green-100 text-green-800\">\n {t('registry.latest')}\n </span>\n )}\n <span className=\"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300\">\n v{server.version}\n </span>\n {officialMeta?.status && (\n <span className=\"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-gray-100 dark:bg-gray-800 text-gray-800\">\n {officialMeta.status}\n </span>\n )}\n {/* Dates */}\n <span className=\"flex flex-wrap items-center gap-4 text-sm text-gray-600\">\n {officialMeta?.publishedAt && (\n <div>\n <span className=\"font-medium\">{t('registry.published')}:</span>{' '}\n {formatDate(officialMeta.publishedAt)}\n </div>\n )}\n {officialMeta?.updatedAt && (\n <div>\n <span className=\"font-medium\">{t('registry.updated')}:</span>{' '}\n {formatDate(officialMeta.updatedAt)}\n </div>\n )}\n </span>\n </div>\n </div>\n </div>\n </div>\n\n {/* Description */}\n <div className=\"mb-6\">\n <h2 className=\"text-xl font-semibold text-gray-900 mb-3\">{t('registry.description')}</h2>\n <p className=\"text-gray-700 leading-relaxed whitespace-pre-wrap\">{server.description}</p>\n </div>\n\n {/* Website */}\n {server.websiteUrl && (\n <div className=\"mb-6\">\n <h2 className=\"text-xl font-semibold text-gray-900 mb-3\">{t('registry.website')}</h2>\n <a\n href={server.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-blue-600 hover:text-blue-800 hover:underline\"\n >\n {server.websiteUrl}\n </a>\n </div>\n )}\n\n {/* Packages */}\n {server.packages && server.packages.length > 0 && (\n <div className=\"mb-6\">\n <button\n onClick={() => toggleSection('packages')}\n className=\"flex items-center justify-between w-full text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors\"\n >\n <span>\n {t('registry.packages')} ({server.packages.length})\n </span>\n <svg\n className={`w-5 h-5 transform transition-transform ${expandedSections.packages ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </button>\n {expandedSections.packages && (\n <div className=\"space-y-3\">{server.packages.map(renderPackage)}</div>\n )}\n </div>\n )}\n\n {/* Remotes */}\n {server.remotes && server.remotes.length > 0 && (\n <div className=\"mb-6\">\n <button\n onClick={() => toggleSection('remotes')}\n className=\"flex items-center justify-between w-full text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors\"\n >\n <span>\n {t('registry.remotes')} ({server.remotes.length})\n </span>\n <svg\n className={`w-5 h-5 transform transition-transform ${expandedSections.remotes ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </button>\n {expandedSections.remotes && (\n <div className=\"space-y-3\">{server.remotes.map(renderRemote)}</div>\n )}\n </div>\n )}\n\n {/* Repository */}\n {server.repository && (\n <div className=\"mb-6\">\n <button\n onClick={() => toggleSection('repository')}\n className=\"flex items-center justify-between w-full text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors\"\n >\n <span>{t('registry.repository')}</span>\n <svg\n className={`w-5 h-5 transform transition-transform ${expandedSections.repository ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </button>\n {expandedSections.repository && (\n <div className=\"border border-gray-200 dark:border-gray-700 rounded-lg p-4\">\n {server.repository.url && (\n <div className=\"mb-2\">\n <span className=\"font-medium text-gray-700\">URL:</span>{' '}\n <a\n href={server.repository.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-blue-600 hover:text-blue-800 hover:underline break-all\"\n >\n {server.repository.url}\n </a>\n </div>\n )}\n {server.repository.source && (\n <div className=\"mb-2\">\n <span className=\"font-medium text-gray-700\">Source:</span>{' '}\n {server.repository.source}\n </div>\n )}\n {server.repository.subfolder && (\n <div className=\"mb-2\">\n <span className=\"font-medium text-gray-700\">Subfolder:</span>{' '}\n {server.repository.subfolder}\n </div>\n )}\n {server.repository.id && (\n <div>\n <span className=\"font-medium text-gray-700\">ID:</span> {server.repository.id}\n </div>\n )}\n </div>\n )}\n </div>\n )}\n\n {/* Install Modal */}\n {modalVisible && selectedOption && selectedInstallType && (\n <div className=\"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4\">\n <ServerForm\n onSubmit={handleInstallSubmit}\n onCancel={handleModalClose}\n modalTitle={t('registry.installServer', { name: server.title || server.name })}\n formError={installError}\n initialData={getInitialFormData()}\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default RegistryServerDetail;\n// Helper function to determine command based on registry type\nfunction getCommand(registryType: string): string {\n // Map registry types to appropriate commands\n switch (registryType.toLowerCase()) {\n case 'pypi':\n case 'python':\n return 'uvx';\n case 'npm':\n case 'node':\n return 'npx';\n case 'oci':\n case 'docker':\n return 'docker';\n default:\n return '';\n }\n}\n\n// Helper function to get appropriate args based on command type and package identifier\nfunction getArgs(command: string, pkg: RegistryPackage): string[] {\n const identifier = [pkg.identifier + (pkg.version ? `@${pkg.version}` : '')];\n\n // Build package arguments if available\n const packageArgs: string[] = [];\n if (pkg.packageArguments && pkg.packageArguments.length > 0) {\n pkg.packageArguments.forEach((arg) => {\n // Add required arguments or arguments with default values\n if (arg.isRequired || arg.default || arg.value) {\n const argName = `--${arg.name}`;\n // Priority: value > default > placeholder\n const argValue = arg.value || arg.default || `\\${${arg.name.toUpperCase()}}`;\n packageArgs.push(argName, argValue);\n }\n });\n }\n\n // Map commands to appropriate argument patterns\n switch (command.toLowerCase()) {\n case 'uvx':\n // For Python packages: uvx package-name --arg1 value1 --arg2 value2\n return [...identifier, ...packageArgs];\n case 'npx':\n // For Node.js packages: npx package-name --arg1 value1 --arg2 value2\n return [...identifier, ...packageArgs];\n case 'docker': {\n // add envs from environment variables if available\n const envs: string[] = [];\n if (pkg.environmentVariables) {\n pkg.environmentVariables.forEach((env) => {\n envs.push('-e', `${env.name}`);\n });\n }\n // For Docker images: docker run -i package-name --arg1 value1 --arg2 value2\n return ['run', '-i', '--rm', ...envs, ...identifier, ...packageArgs];\n }\n default:\n // If no specific pattern is defined, return identifier with package args\n return [...identifier, ...packageArgs];\n }\n}\n","import React from 'react';\n\ninterface CursorPaginationProps {\n currentPage: number;\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n onNextPage: () => void;\n onPreviousPage: () => void;\n}\n\nconst CursorPagination: React.FC<CursorPaginationProps> = ({\n currentPage,\n hasNextPage,\n hasPreviousPage,\n onNextPage,\n onPreviousPage,\n}) => {\n return (\n <div className=\"flex items-center justify-center space-x-2 my-6\">\n {/* Previous button */}\n <button\n onClick={onPreviousPage}\n disabled={!hasPreviousPage}\n className={`px-4 py-2 rounded transition-all duration-200 ${\n hasPreviousPage\n ? 'bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary'\n : 'bg-gray-100 text-gray-400 cursor-not-allowed'\n }`}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-5 w-5 inline-block mr-1\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n Prev\n </button>\n\n {/* Current page indicator */}\n <span className=\"px-4 py-2 bg-blue-500 text-white rounded btn-primary\">\n Page {currentPage}\n </span>\n\n {/* Next button */}\n <button\n onClick={onNextPage}\n disabled={!hasNextPage}\n className={`px-4 py-2 rounded transition-all duration-200 ${\n hasNextPage\n ? 'bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary'\n : 'bg-gray-100 text-gray-400 cursor-not-allowed'\n }`}\n >\n Next\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-5 w-5 inline-block ml-1\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n );\n};\n\nexport default CursorPagination;\n","import React, { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate, useParams, useSearchParams } from 'react-router-dom';\nimport { Search, AlertCircle, X, ChevronDown } from 'lucide-react';\nimport {\n MarketServer,\n CloudServer,\n ServerConfig,\n RegistryServerEntry,\n RegistryServerData,\n} from '@/types';\nimport { useMarketData } from '@/hooks/useMarketData';\nimport { useCloudData } from '@/hooks/useCloudData';\nimport { useRegistryData } from '@/hooks/useRegistryData';\nimport { useToast } from '@/contexts/ToastContext';\nimport { apiPost } from '@/utils/fetchInterceptor';\nimport MarketServerCard from '@/components/MarketServerCard';\nimport MarketServerDetail from '@/components/MarketServerDetail';\nimport CloudServerCard from '@/components/CloudServerCard';\nimport CloudServerDetail from '@/components/CloudServerDetail';\nimport RegistryServerCard from '@/components/RegistryServerCard';\nimport RegistryServerDetail from '@/components/RegistryServerDetail';\nimport MCPRouterApiKeyError from '@/components/MCPRouterApiKeyError';\nimport Pagination from '@/components/ui/Pagination';\nimport CursorPagination from '@/components/ui/CursorPagination';\n\nconst MarketPage: React.FC = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const { serverName } = useParams<{ serverName?: string }>();\n const { showToast } = useToast();\n\n const [searchParams, setSearchParams] = useSearchParams();\n const currentTab = searchParams.get('tab') || 'cloud';\n\n const {\n servers: localServers,\n allServers: allLocalServers,\n categories: localCategories,\n loading: localLoading,\n error: localError,\n setError: setLocalError,\n searchServers: searchLocalServers,\n filterByCategory: filterLocalByCategory,\n filterByTag: filterLocalByTag,\n selectedCategory: selectedLocalCategory,\n selectedTag: selectedLocalTag,\n installServer: installLocalServer,\n fetchServerByName: fetchLocalServerByName,\n isServerInstalled,\n currentPage: localCurrentPage,\n totalPages: localTotalPages,\n changePage: changeLocalPage,\n serversPerPage: localServersPerPage,\n changeServersPerPage: changeLocalServersPerPage,\n } = useMarketData();\n\n const {\n servers: cloudServers,\n allServers: allCloudServers,\n loading: cloudLoading,\n error: cloudError,\n setError: setCloudError,\n fetchServerTools,\n callServerTool,\n currentPage: cloudCurrentPage,\n totalPages: cloudTotalPages,\n changePage: changeCloudPage,\n serversPerPage: cloudServersPerPage,\n changeServersPerPage: changeCloudServersPerPage,\n } = useCloudData();\n\n const {\n servers: registryServers,\n allServers: allRegistryServers,\n loading: registryLoading,\n error: registryError,\n setError: setRegistryError,\n searchServers: searchRegistryServers,\n clearSearch: clearRegistrySearch,\n fetchServerByName: fetchRegistryServerByName,\n fetchServerVersions: fetchRegistryServerVersions,\n currentPage: registryCurrentPage,\n totalPages: registryTotalPages,\n hasNextPage: registryHasNextPage,\n hasPreviousPage: registryHasPreviousPage,\n changePage: changeRegistryPage,\n goToNextPage: goToRegistryNextPage,\n goToPreviousPage: goToRegistryPreviousPage,\n serversPerPage: registryServersPerPage,\n changeServersPerPage: changeRegistryServersPerPage,\n } = useRegistryData();\n\n const [selectedServer, setSelectedServer] = useState<MarketServer | null>(null);\n const [selectedCloudServer, setSelectedCloudServer] = useState<CloudServer | null>(null);\n const [selectedRegistryServer, setSelectedRegistryServer] = useState<RegistryServerEntry | null>(\n null,\n );\n const [searchQuery, setSearchQuery] = useState('');\n const [registrySearchQuery, setRegistrySearchQuery] = useState('');\n const [installing, setInstalling] = useState(false);\n const [installedCloudServers, setInstalledCloudServers] = useState<Set<string>>(new Set());\n const [installedRegistryServers, setInstalledRegistryServers] = useState<Set<string>>(new Set());\n\n useEffect(() => {\n const loadServerDetails = async () => {\n if (serverName) {\n if (currentTab === 'cloud') {\n const server = cloudServers.find((s) => s.name === serverName);\n if (server) setSelectedCloudServer(server);\n else navigate('/market?tab=cloud');\n } else if (currentTab === 'registry') {\n const serverEntry = await fetchRegistryServerByName(serverName);\n if (serverEntry) setSelectedRegistryServer(serverEntry);\n else navigate('/market?tab=registry');\n } else {\n const server = await fetchLocalServerByName(serverName);\n if (server) setSelectedServer(server);\n else navigate('/market?tab=local');\n }\n } else {\n setSelectedServer(null);\n setSelectedCloudServer(null);\n setSelectedRegistryServer(null);\n }\n };\n loadServerDetails();\n }, [\n serverName,\n currentTab,\n cloudServers,\n fetchLocalServerByName,\n fetchRegistryServerByName,\n navigate,\n ]);\n\n const switchTab = (tab: 'local' | 'cloud' | 'registry') => {\n const newParams = new URLSearchParams(searchParams);\n newParams.set('tab', tab);\n setSearchParams(newParams);\n if (serverName) navigate('/market?' + newParams.toString());\n };\n\n const handleSearch = (e: React.FormEvent) => {\n e.preventDefault();\n if (currentTab === 'local') searchLocalServers(searchQuery);\n else if (currentTab === 'registry') searchRegistryServers(registrySearchQuery);\n };\n\n const handleCategoryClick = (category: string) => {\n if (currentTab === 'local') filterLocalByCategory(category);\n };\n\n const handleClearFilters = () => {\n if (currentTab === 'local') {\n setSearchQuery('');\n filterLocalByCategory('');\n filterLocalByTag('');\n } else if (currentTab === 'registry') {\n setRegistrySearchQuery('');\n clearRegistrySearch();\n }\n };\n\n const handleServerClick = (server: MarketServer | CloudServer | RegistryServerEntry) => {\n if (currentTab === 'cloud') {\n const cloudServer = server as CloudServer;\n navigate(`/market/${cloudServer.name}?tab=cloud`);\n } else if (currentTab === 'registry') {\n const registryServer = server as RegistryServerEntry;\n const name = registryServer.server?.name;\n if (name) navigate(`/market/${encodeURIComponent(name)}?tab=registry`);\n } else {\n const marketServer = server as MarketServer;\n navigate(`/market/${marketServer.name}?tab=local`);\n }\n };\n\n const handleBackToList = () => navigate(`/market?tab=${currentTab}`);\n\n const handleLocalInstall = async (server: MarketServer, config: ServerConfig) => {\n try {\n setInstalling(true);\n const success = await installLocalServer(server, config);\n if (success) {\n showToast(t('market.installSuccess', { serverName: server.display_name }), 'success');\n }\n } finally {\n setInstalling(false);\n }\n };\n\n const handleCloudInstall = async (server: CloudServer, config: ServerConfig) => {\n try {\n setInstalling(true);\n const payload = { name: server.name, config };\n const result = await apiPost('/servers', payload);\n if (!result.success) {\n showToast(result?.message || t('server.addError'), 'error');\n return;\n }\n setInstalledCloudServers((prev) => new Set(prev).add(server.name));\n showToast(t('cloud.installSuccess', { name: server.title || server.name }), 'success');\n } catch (error) {\n showToast(\n t('cloud.installError', { error: error instanceof Error ? error.message : String(error) }),\n 'error',\n );\n } finally {\n setInstalling(false);\n }\n };\n\n const handleRegistryInstall = async (server: RegistryServerData, config: ServerConfig) => {\n try {\n setInstalling(true);\n const payload = { name: server.name, config };\n const result = await apiPost('/servers', payload);\n if (!result.success) {\n showToast(result?.message || t('server.addError'), 'error');\n return;\n }\n setInstalledRegistryServers((prev) => new Set(prev).add(server.name));\n showToast(t('registry.installSuccess', { name: server.title || server.name }), 'success');\n } catch (error) {\n showToast(\n t('registry.installError', { error: error instanceof Error ? error.message : String(error) }),\n 'error',\n );\n } finally {\n setInstalling(false);\n }\n };\n\n const handleCallTool = async (\n name: string,\n toolName: string,\n args: Record<string, any>,\n ) => {\n try {\n const result = await callServerTool(name, toolName, args);\n showToast(t('cloud.toolCallSuccess', { toolName }), 'success');\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (!isMCPRouterApiKeyError(errorMessage)) {\n showToast(t('cloud.toolCallError', { toolName, error: errorMessage }), 'error');\n }\n throw error;\n }\n };\n\n const isMCPRouterApiKeyError = (errorMessage: string) =>\n errorMessage === 'MCPROUTER_API_KEY_NOT_CONFIGURED' ||\n errorMessage.toLowerCase().includes('mcprouter api key not configured');\n\n const handlePageChange = (page: number) => {\n if (currentTab === 'local') changeLocalPage(page);\n else if (currentTab === 'registry') changeRegistryPage(page);\n else changeCloudPage(page);\n window.scrollTo({ top: 0, behavior: 'smooth' });\n };\n\n const handleChangeItemsPerPage = (e: React.ChangeEvent<HTMLSelectElement>) => {\n const v = parseInt(e.target.value, 10);\n if (currentTab === 'local') changeLocalServersPerPage(v);\n else if (currentTab === 'registry') changeRegistryServersPerPage(v);\n else changeCloudServersPerPage(v);\n };\n\n if (selectedServer) {\n return (\n <MarketServerDetail\n server={selectedServer}\n onBack={handleBackToList}\n onInstall={handleLocalInstall}\n installing={installing}\n isInstalled={isServerInstalled(selectedServer.name)}\n />\n );\n }\n\n if (selectedCloudServer) {\n return (\n <CloudServerDetail\n serverName={selectedCloudServer.name}\n onBack={handleBackToList}\n onCallTool={handleCallTool}\n fetchServerTools={fetchServerTools}\n onInstall={handleCloudInstall}\n installing={installing}\n isInstalled={installedCloudServers.has(selectedCloudServer.name)}\n />\n );\n }\n\n if (selectedRegistryServer) {\n return (\n <RegistryServerDetail\n serverEntry={selectedRegistryServer}\n onBack={handleBackToList}\n onInstall={handleRegistryInstall}\n installing={installing}\n isInstalled={installedRegistryServers.has(selectedRegistryServer.server.name)}\n fetchVersions={fetchRegistryServerVersions}\n />\n );\n }\n\n const isLocalTab = currentTab === 'local';\n const isRegistryTab = currentTab === 'registry';\n const servers = isLocalTab ? localServers : isRegistryTab ? registryServers : cloudServers;\n const allServers = isLocalTab\n ? allLocalServers\n : isRegistryTab\n ? allRegistryServers\n : allCloudServers;\n const categories = isLocalTab ? localCategories : [];\n const loading = isLocalTab ? localLoading : isRegistryTab ? registryLoading : cloudLoading;\n const error = isLocalTab ? localError : isRegistryTab ? registryError : cloudError;\n const setError = isLocalTab ? setLocalError : isRegistryTab ? setRegistryError : setCloudError;\n const selectedCategory = isLocalTab ? selectedLocalCategory : '';\n const selectedTag = isLocalTab ? selectedLocalTag : '';\n const currentPage = isLocalTab\n ? localCurrentPage\n : isRegistryTab\n ? registryCurrentPage\n : cloudCurrentPage;\n const totalPages = isLocalTab\n ? localTotalPages\n : isRegistryTab\n ? registryTotalPages\n : cloudTotalPages;\n const serversPerPage = isLocalTab\n ? localServersPerPage\n : isRegistryTab\n ? registryServersPerPage\n : cloudServersPerPage;\n\n const tabs: { id: 'cloud' | 'local' | 'registry'; label: string; sourceLabel: string; sourceUrl: string }[] = [\n { id: 'cloud', label: t('cloud.title'), sourceLabel: 'MCPRouter', sourceUrl: 'https://mcprouter.co' },\n { id: 'local', label: t('market.title'), sourceLabel: 'MCPM', sourceUrl: 'https://mcpm.sh' },\n {\n id: 'registry',\n label: t('registry.title'),\n sourceLabel: t('registry.official'),\n sourceUrl: 'https://registry.modelcontextprotocol.io',\n },\n ];\n\n return (\n <div>\n {/* Header */}\n <div className=\"flex items-end justify-between gap-4 mb-6\">\n <div>\n <h1 className=\"hub-h1\">{t('nav.market')}</h1>\n <p className=\"hub-sub\">\n {tabs.map((tab) => tab.label).join(' · ')}\n </p>\n </div>\n </div>\n\n {/* Tabs */}\n <div className=\"mb-5\">\n <div style={{ borderBottom: '1px solid var(--hub-line)' }}>\n <nav className=\"flex -mb-px gap-1.5\">\n {tabs.map((tab) => {\n const active = currentTab === tab.id;\n return (\n <button\n key={tab.id}\n onClick={() => switchTab(tab.id)}\n className=\"py-2 px-3 transition-colors text-[14px]\"\n style={{\n borderBottom: '2px solid ' + (active ? 'var(--hub-ink)' : 'transparent'),\n color: active ? 'var(--hub-ink)' : 'var(--hub-ink-3)',\n fontWeight: active ? 500 : 400,\n }}\n >\n {tab.label}\n <a\n href={tab.sourceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hub-mono ml-1.5\"\n style={{ fontSize: 11, color: 'var(--hub-ink-3)' }}\n onClick={(e) => e.stopPropagation()}\n >\n ({tab.sourceLabel})\n </a>\n </button>\n );\n })}\n </nav>\n </div>\n </div>\n\n {error && (\n <>\n {!isLocalTab && isMCPRouterApiKeyError(error) ? (\n <MCPRouterApiKeyError />\n ) : (\n <div\n className=\"hub-card flex items-center justify-between gap-3 mb-4\"\n style={{\n padding: '10px 14px',\n borderColor: 'oklch(0.85 0.1 25)',\n background: 'oklch(0.97 0.03 25)',\n color: 'oklch(0.4 0.18 25)',\n }}\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <AlertCircle size={14} className=\"flex-shrink-0\" />\n <span className=\"truncate text-[13px]\">{error}</span>\n </div>\n <button className=\"hub-icon-btn sm\" onClick={() => setError(null)}>\n <X size={13} />\n </button>\n </div>\n )}\n </>\n )}\n\n {/* Search bar */}\n {(isLocalTab || isRegistryTab) && (\n <form onSubmit={handleSearch} className=\"hub-card flex items-center gap-2 px-3 mb-5\" style={{ padding: 6 }}>\n <Search size={16} style={{ color: 'var(--hub-ink-3)', margin: '0 6px 0 6px' }} />\n <input\n type=\"text\"\n value={isRegistryTab ? registrySearchQuery : searchQuery}\n onChange={(e) => {\n if (isRegistryTab) setRegistrySearchQuery(e.target.value);\n else setSearchQuery(e.target.value);\n }}\n placeholder={\n isRegistryTab ? t('registry.searchPlaceholder') : t('market.searchPlaceholder')\n }\n className=\"flex-1 bg-transparent outline-none\"\n style={{ height: 32, fontSize: 14, color: 'var(--hub-ink)' }}\n />\n <button type=\"submit\" className=\"hub-btn\">\n {t('common.search')}\n </button>\n {((isLocalTab && (searchQuery || selectedCategory || selectedTag)) ||\n (isRegistryTab && registrySearchQuery)) && (\n <button type=\"button\" onClick={handleClearFilters} className=\"hub-btn ghost\">\n {t('common.clear')}\n </button>\n )}\n </form>\n )}\n\n <div className={isLocalTab ? 'grid gap-5' : ''} style={isLocalTab ? { gridTemplateColumns: '180px 1fr' } : undefined}>\n {/* Categories sidebar (local only) */}\n {isLocalTab && (\n <div>\n <h3 className=\"hub-sect mb-2\">{t('market.categories')}</h3>\n <div className=\"flex flex-col gap-0.5\">\n <button\n onClick={() => filterLocalByCategory('')}\n className=\"flex items-center justify-between transition-colors text-[13px]\"\n style={{\n padding: '6px 10px',\n borderRadius: 6,\n background: !selectedCategory ? 'var(--hub-surface)' : 'transparent',\n color: !selectedCategory ? 'var(--hub-ink)' : 'var(--hub-ink-2)',\n border: '1px solid ' + (!selectedCategory ? 'var(--hub-line)' : 'transparent'),\n }}\n >\n <span>{t('common.all')}</span>\n <span className=\"hub-mono\" style={{ fontSize: 11, color: 'var(--hub-ink-3)' }}>\n {allLocalServers.length}\n </span>\n </button>\n {categories.map((cat) => (\n <button\n key={cat}\n onClick={() => handleCategoryClick(cat)}\n className=\"flex items-center justify-between transition-colors text-[13px]\"\n style={{\n padding: '6px 10px',\n borderRadius: 6,\n background: selectedCategory === cat ? 'var(--hub-surface)' : 'transparent',\n color: selectedCategory === cat ? 'var(--hub-ink)' : 'var(--hub-ink-2)',\n border:\n '1px solid ' + (selectedCategory === cat ? 'var(--hub-line)' : 'transparent'),\n }}\n >\n <span className=\"truncate\">{cat}</span>\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Grid */}\n <div>\n {loading ? (\n <div className=\"hub-card p-6 text-center\" style={{ color: 'var(--hub-ink-3)' }}>\n {t('app.loading')}\n </div>\n ) : servers.length === 0 ? (\n <div className=\"hub-card p-10 text-center\" style={{ color: 'var(--hub-ink-3)' }}>\n {isLocalTab\n ? t('market.noServers')\n : isRegistryTab\n ? t('registry.noServers')\n : t('cloud.noServers')}\n </div>\n ) : (\n <>\n <div className=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3\">\n {servers.map((server, index) =>\n isLocalTab ? (\n <MarketServerCard\n key={index}\n server={server as MarketServer}\n onClick={handleServerClick}\n />\n ) : isRegistryTab ? (\n <RegistryServerCard\n key={index}\n serverEntry={server as RegistryServerEntry}\n onClick={handleServerClick}\n />\n ) : (\n <CloudServerCard\n key={index}\n server={server as CloudServer}\n onClick={handleServerClick}\n />\n ),\n )}\n </div>\n\n <div\n className=\"flex items-center mt-4 text-[12px]\"\n style={{ color: 'var(--hub-ink-3)' }}\n >\n <div className=\"flex-[2]\">\n {isLocalTab\n ? t('market.showing', {\n from: (currentPage - 1) * serversPerPage + 1,\n to: Math.min(currentPage * serversPerPage, allServers.length),\n total: allServers.length,\n })\n : isRegistryTab\n ? t('registry.showing', {\n from: (currentPage - 1) * serversPerPage + 1,\n to: (currentPage - 1) * serversPerPage + servers.length,\n total: allServers.length + (registryHasNextPage ? '+' : ''),\n })\n : t('cloud.showing', {\n from: (currentPage - 1) * serversPerPage + 1,\n to: Math.min(currentPage * serversPerPage, allServers.length),\n total: allServers.length,\n })}\n </div>\n <div className=\"flex-[4] flex justify-center\">\n {isRegistryTab ? (\n <CursorPagination\n currentPage={currentPage}\n hasNextPage={registryHasNextPage}\n hasPreviousPage={registryHasPreviousPage}\n onNextPage={goToRegistryNextPage}\n onPreviousPage={goToRegistryPreviousPage}\n />\n ) : (\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n onPageChange={handlePageChange}\n />\n )}\n </div>\n <div className=\"flex-[2] flex items-center justify-end gap-2\">\n <label htmlFor=\"perPage\">\n {isLocalTab\n ? t('market.perPage')\n : isRegistryTab\n ? t('registry.perPage')\n : t('cloud.perPage')}\n :\n </label>\n <div className=\"relative\">\n <select\n id=\"perPage\"\n value={serversPerPage}\n onChange={handleChangeItemsPerPage}\n className=\"hub-input pr-7\"\n style={{ height: 26, width: 70, padding: '0 6px', fontSize: 12 }}\n >\n <option value=\"6\">6</option>\n <option value=\"9\">9</option>\n <option value=\"12\">12</option>\n <option value=\"24\">24</option>\n </select>\n <ChevronDown\n size={11}\n className=\"absolute right-1.5 top-1/2 -translate-y-1/2 pointer-events-none\"\n style={{ color: 'var(--hub-ink-3)' }}\n />\n </div>\n </div>\n </div>\n </>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default MarketPage;\n"],"names":["useMarketData","t","useTranslation","servers","setServers","useState","allServers","setAllServers","categories","setCategories","tags","setTags","selectedCategory","setSelectedCategory","selectedTag","setSelectedTag","searchQuery","setSearchQuery","loading","setLoading","error","setError","currentServer","setCurrentServer","installedServers","setInstalledServers","currentPage","setCurrentPage","serversPerPage","setServersPerPage","totalPages","setTotalPages","fetchMarketServers","useCallback","data","apiGet","applyPagination","err","page","itemsPerPage","totalItems","calculatedTotalPages","validPage","startIndex","paginatedServers","changePage","fetchCategories","fetchTags","fetchServerByName","name","searchServers","query","filterByCategory","category","filterByTag","tag","fetchInstalledServers","installedServerNames","server","isServerInstalled","serverName","installServer","customConfig","installType","_a","_b","installation","serverConfig","result","apiPost","changeServersPerPage","perPage","useEffect","useCloudData","fetchCloudServers","errorMessage","fetchServerTools","callServerTool","toolName","args","useRegistryData","nextCursor","setNextCursor","hasNextPage","setHasNextPage","cursorHistory","setCursorHistory","fetchRegistryServers","cursor","search","params","queryToUse","response","hasMore","prev","goToNextPage","currentCursor","goToPreviousPage","newHistory","previousCursor","newServersPerPage","encodedName","fetchServerVersions","fetchServerVersion","version","encodedVersion","clearSearch","getInitials","w","MarketServerCard","onClick","jsxs","e","jsx","Check","Zap","_c","MarketServerDetail","onBack","onInstall","installing","isInstalled","modalVisible","setModalVisible","confirmationVisible","setConfirmationVisible","pendingPayload","setPendingPayload","detectedVariables","setDetectedVariables","getButtonProps","toggleModal","handleConfirmInstall","proceedWithInstall","payload","handleInstall","getPreferredInstallation","installTypes","handleSubmit","variables","detectVariables","buttonProps","preferredInstallation","index","arg","tool","element","example","ServerForm","variable","formatDate","dateString","date","y","m","d","CloudServerCard","getDescription","lines","line","MCPRouterApiKeyError","navigate","useNavigate","handleConfigureSettings","handleGetApiKey","CloudServerDetail","onCallTool","mcpRouterConfig","useSettingsData","setServer","tools","setTools","loadingTools","setLoadingTools","toolsApiKeyError","setToolsApiKeyError","toolCallLoading","setToolCallLoading","toolCallResults","setToolCallResults","toolArgs","setToolArgs","expandedSchemas","setExpandedSchemas","installError","setInstallError","isMCPRouterApiKeyError","getInstallButtonProps","handleModalClose","handleInstallSubmit","fetchedTools","dateStr","year","month","day","hours","minutes","seconds","handleArgChange","argName","value","handleCallTool","toggleSchema","renderToolInput","propName","propSchema","currentValue","handleChange","Fragment","RegistryServerCard","serverEntry","_meta","officialMeta","isLatest","publishedAt","updatedAt","packageCount","remoteCount","description","icon","i","Package","Globe","RegistryServerDetail","fetchVersions","_selectedVersion","_setSelectedVersion","_availableVersions","setAvailableVersions","_loadingVersions","setLoadingVersions","selectedInstallType","setSelectedInstallType","selectedOption","setSelectedOption","expandedSections","setExpandedSections","versions","toggleSection","section","handleInstallClick","type","option","config","getInitialFormData","pkg","env","envVar","command","getCommand","getArgs","remote","headers","header","transportType","renderPackage","envIndex","argIndex","renderRemote","headerIndex","registryType","identifier","packageArgs","argValue","envs","CursorPagination","hasPreviousPage","onNextPage","onPreviousPage","MarketPage","useParams","showToast","useToast","searchParams","setSearchParams","useSearchParams","currentTab","localServers","allLocalServers","localCategories","localLoading","localError","setLocalError","searchLocalServers","filterLocalByCategory","filterLocalByTag","selectedLocalCategory","selectedLocalTag","installLocalServer","fetchLocalServerByName","localCurrentPage","localTotalPages","changeLocalPage","localServersPerPage","changeLocalServersPerPage","cloudServers","allCloudServers","cloudLoading","cloudError","setCloudError","cloudCurrentPage","cloudTotalPages","changeCloudPage","cloudServersPerPage","changeCloudServersPerPage","registryServers","allRegistryServers","registryLoading","registryError","setRegistryError","searchRegistryServers","clearRegistrySearch","fetchRegistryServerByName","fetchRegistryServerVersions","registryCurrentPage","registryTotalPages","registryHasNextPage","registryHasPreviousPage","changeRegistryPage","goToRegistryNextPage","goToRegistryPreviousPage","registryServersPerPage","changeRegistryServersPerPage","selectedServer","setSelectedServer","selectedCloudServer","setSelectedCloudServer","selectedRegistryServer","setSelectedRegistryServer","registrySearchQuery","setRegistrySearchQuery","setInstalling","installedCloudServers","setInstalledCloudServers","installedRegistryServers","setInstalledRegistryServers","s","switchTab","tab","newParams","handleSearch","handleCategoryClick","handleClearFilters","handleServerClick","handleBackToList","handleLocalInstall","handleCloudInstall","handleRegistryInstall","handlePageChange","handleChangeItemsPerPage","v","isLocalTab","isRegistryTab","tabs","active","AlertCircle","X","Search","cat","Pagination","ChevronDown"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{j as t}from"./framework-vendor-_OBebcuv.js";import{u as l}from"./i18n-vendor-MQ921plD.js";const c=({currentPage:s,totalPages:r,onPageChange:e,disabled:a=!1})=>{const{t:x}=l(),y=()=>{const n=[];n.push(t.jsx("button",{onClick:()=>e(1),className:`px-3 py-1 mx-1 rounded ${s===1?"bg-blue-500 text-white btn-primary":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:"1"},"first"));const o=Math.max(2,s-Math.floor(5/2));o>2&&n.push(t.jsx("span",{className:"px-3 py-1",children:"..."},"ellipsis1"));for(let i=o;i<=Math.min(r-1,o+5-3);i++)n.push(t.jsx("button",{onClick:()=>e(i),className:`px-3 py-1 mx-1 rounded ${s===i?"bg-blue-500 text-white btn-primary":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:i},i));return o+5-3<r-1&&n.push(t.jsx("span",{className:"px-3 py-1",children:"..."},"ellipsis2")),r>1&&n.push(t.jsx("button",{onClick:()=>e(r),className:`px-3 py-1 mx-1 rounded ${s===r?"bg-blue-500 text-white btn-primary":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:r},"last")),n};return r<=1?null:t.jsxs("div",{className:"flex justify-center items-center my-6",children:[t.jsxs("button",{onClick:()=>e(Math.max(1,s-1)),disabled:a||s===1,className:`px-3 py-1 rounded mr-2 ${a||s===1?"bg-gray-100 text-gray-400 cursor-not-allowed":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:["« ",x("common.previous")]}),t.jsx("div",{className:"flex",children:y()}),t.jsxs("button",{onClick:()=>e(Math.min(r,s+1)),disabled:a||s===r,className:`px-3 py-1 rounded ml-2 ${a||s===r?"bg-gray-100 text-gray-400 cursor-not-allowed":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:[x("common.next")," »"]})]})};export{c as P};
2
- //# sourceMappingURL=Pagination-y-gVO8ms.js.map
1
+ import{j as t}from"./framework-vendor-BUhDPOUZ.js";import{u as l}from"./i18n-vendor-Kbr87Ofu.js";const c=({currentPage:s,totalPages:r,onPageChange:e,disabled:a=!1})=>{const{t:x}=l(),y=()=>{const n=[];n.push(t.jsx("button",{onClick:()=>e(1),className:`px-3 py-1 mx-1 rounded ${s===1?"bg-blue-500 text-white btn-primary":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:"1"},"first"));const o=Math.max(2,s-Math.floor(5/2));o>2&&n.push(t.jsx("span",{className:"px-3 py-1",children:"..."},"ellipsis1"));for(let i=o;i<=Math.min(r-1,o+5-3);i++)n.push(t.jsx("button",{onClick:()=>e(i),className:`px-3 py-1 mx-1 rounded ${s===i?"bg-blue-500 text-white btn-primary":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:i},i));return o+5-3<r-1&&n.push(t.jsx("span",{className:"px-3 py-1",children:"..."},"ellipsis2")),r>1&&n.push(t.jsx("button",{onClick:()=>e(r),className:`px-3 py-1 mx-1 rounded ${s===r?"bg-blue-500 text-white btn-primary":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:r},"last")),n};return r<=1?null:t.jsxs("div",{className:"flex justify-center items-center my-6",children:[t.jsxs("button",{onClick:()=>e(Math.max(1,s-1)),disabled:a||s===1,className:`px-3 py-1 rounded mr-2 ${a||s===1?"bg-gray-100 text-gray-400 cursor-not-allowed":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:["« ",x("common.previous")]}),t.jsx("div",{className:"flex",children:y()}),t.jsxs("button",{onClick:()=>e(Math.min(r,s+1)),disabled:a||s===r,className:`px-3 py-1 rounded ml-2 ${a||s===r?"bg-gray-100 text-gray-400 cursor-not-allowed":"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary"}`,children:[x("common.next")," »"]})]})};export{c as P};
2
+ //# sourceMappingURL=Pagination-BFi-X7qY.js.map