Skip to content

Commit 2a7f432

Browse files
author
Lasim
committed
feat(frontend): add API methods to fetch unique runtimes and languages
1 parent f270dc0 commit 2a7f432

File tree

2 files changed

+86
-19
lines changed

2 files changed

+86
-19
lines changed

services/frontend/src/services/mcpCatalogService.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,48 @@ export class McpCatalogService {
466466
static async updateStatus(serverId: string, status: 'active' | 'deprecated' | 'maintenance'): Promise<McpServer> {
467467
return this.updateGlobalServer(serverId, { status })
468468
}
469+
470+
/**
471+
* Get all unique runtime environments
472+
*/
473+
static async getRuntimes(): Promise<string[]> {
474+
const response = await fetch(`${this.baseUrl}/api/mcp/servers/runtimes`, {
475+
method: 'GET',
476+
credentials: 'include',
477+
headers: {
478+
'Content-Type': 'application/json',
479+
},
480+
})
481+
482+
if (!response.ok) {
483+
const errorData = await response.json().catch(() => ({}))
484+
throw new Error(errorData.message || `Failed to fetch runtimes: ${response.status}`)
485+
}
486+
487+
const data = await response.json()
488+
return data.data?.runtimes || []
489+
}
490+
491+
/**
492+
* Get all unique programming languages
493+
*/
494+
static async getLanguages(): Promise<string[]> {
495+
const response = await fetch(`${this.baseUrl}/api/mcp/servers/languages`, {
496+
method: 'GET',
497+
credentials: 'include',
498+
headers: {
499+
'Content-Type': 'application/json',
500+
},
501+
})
502+
503+
if (!response.ok) {
504+
const errorData = await response.json().catch(() => ({}))
505+
throw new Error(errorData.message || `Failed to fetch languages: ${response.status}`)
506+
}
507+
508+
const data = await response.json()
509+
return data.data?.languages || []
510+
}
469511
}
470512

471513
// Export McpCategoriesCache for backward compatibility

services/frontend/src/views/admin/mcp-server-catalog/index.vue

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { ref, onMounted, onUnmounted, watch } from 'vue'
2+
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
33
import { useI18n } from 'vue-i18n'
44
import { useRouter, useRoute } from 'vue-router'
55
import { toast } from 'vue-sonner'
@@ -58,6 +58,10 @@ const selectedRuntime = ref('all')
5858
const selectedFeatured = ref<'true' | 'false' | 'all'>('all')
5959
const selectedAutoInstall = ref<'true' | 'false' | 'all'>('all')
6060
61+
// Available runtimes (fetched from API)
62+
const availableRuntimes = ref<string[]>([])
63+
const availableLanguages = ref<string[]>([])
64+
6165
// Sync state
6266
const isSyncModalOpen = ref(false)
6367
const isSyncing = ref(false)
@@ -105,25 +109,22 @@ const statusOptions = [
105109
{ value: 'maintenance', label: t('mcpCatalog.filters.status.maintenance') }
106110
]
107111
108-
const languageOptions = [
112+
const languageOptions = computed(() => [
109113
{ value: 'all', label: t('mcpCatalog.filters.language.all') },
110-
{ value: 'TypeScript', label: 'TypeScript' },
111-
{ value: 'JavaScript', label: 'JavaScript' },
112-
{ value: 'Python', label: 'Python' },
113-
{ value: 'Go', label: 'Go' },
114-
{ value: 'Rust', label: 'Rust' },
115-
{ value: 'Java', label: 'Java' },
116-
{ value: 'C#', label: 'C#' },
117-
{ value: 'Ruby', label: 'Ruby' }
118-
]
119-
120-
const runtimeOptions = [
114+
...availableLanguages.value.map(language => ({
115+
value: language,
116+
label: language
117+
}))
118+
])
119+
120+
// Computed runtime options (dynamic from API)
121+
const runtimeOptions = computed(() => [
121122
{ value: 'all', label: t('mcpCatalog.filters.runtime.all') },
122-
{ value: 'node', label: 'Node.js' },
123-
{ value: 'python', label: 'Python' },
124-
{ value: 'docker', label: 'Docker' },
125-
{ value: 'binary', label: 'Binary' }
126-
]
123+
...availableRuntimes.value.map(runtime => ({
124+
value: runtime,
125+
label: runtime
126+
}))
127+
])
127128
128129
const featuredOptions = [
129130
{ value: 'all', label: t('mcpCatalog.filters.featured.all') },
@@ -437,9 +438,33 @@ const handleServerCreated = () => {
437438
toast.success(t('mcpCatalog.messages.createSuccess'))
438439
}
439440
441+
// Fetch available runtimes
442+
const fetchRuntimes = async () => {
443+
try {
444+
availableRuntimes.value = await McpCatalogService.getRuntimes()
445+
} catch (err) {
446+
console.error('Failed to fetch runtimes:', err)
447+
availableRuntimes.value = []
448+
}
449+
}
450+
451+
// Fetch available languages
452+
const fetchLanguages = async () => {
453+
try {
454+
availableLanguages.value = await McpCatalogService.getLanguages()
455+
} catch (err) {
456+
console.error('Failed to fetch languages:', err)
457+
availableLanguages.value = []
458+
}
459+
}
460+
440461
// Load data on component mount
441462
onMounted(async () => {
442-
await fetchServers()
463+
await Promise.all([
464+
fetchServers(),
465+
fetchRuntimes(),
466+
fetchLanguages()
467+
])
443468
444469
// Check for delete success message from query parameters
445470
const deletedServerName = route.query.deleted as string

0 commit comments

Comments
 (0)