Skip to main content
Glama
add.tsβ€’11.3 kB
/** * add-app: Register app by bundleId or packageName */ import { registerApp, findApp, loadRegisteredApps, saveRegisteredApps, type RegisteredApp, } from "@/packages/configs/secrets-config/registered-apps"; import { toRegisteredAppStoreInfo, toRegisteredGooglePlayInfo, } from "@/core/helpers/registration"; import { AppStoreService } from "@/core/services/app-store-service"; import { GooglePlayService } from "@/core/services/google-play-service"; const appStoreService = new AppStoreService(); const googlePlayService = new GooglePlayService(); interface AddAppOptions { /** App identifier (bundleId or packageName) */ identifier: string; /** Custom slug (if not specified, uses last part of identifier) */ slug?: string; /** Target store (default: both - check both stores) */ store?: "appStore" | "googlePlay" | "both"; } /** * Generate slug (last part of identifier) */ function generateSlug(identifier: string): string { const parts = identifier.split("."); return parts[parts.length - 1].toLowerCase(); } export async function handleAddApp(options: AddAppOptions) { const { identifier, slug: customSlug, store = "both" } = options; console.error(`[MCP] πŸ“± Adding app: ${identifier} (store: ${store})`); if (!identifier) { return { content: [ { type: "text" as const, text: `❌ identifier is required. Usage: \`\`\`json { "identifier": "com.example.app" } { "identifier": "com.example.app", "slug": "myapp" } { "identifier": "com.example.app", "store": "googlePlay" } \`\`\``, }, ], }; } // Check if already registered let existing; try { existing = findApp(identifier); } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [ { type: "text" as const, text: `❌ Failed to load registered apps: ${message}`, }, ], }; } if (existing) { // Update language info for existing apps let appsConfig; try { appsConfig = loadRegisteredApps(); } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [ { type: "text" as const, text: `❌ Failed to load registered apps: ${message}`, }, ], }; } const appIndex = appsConfig.apps.findIndex((a) => a.slug === existing.slug); if (appIndex >= 0) { let updated = false; const updateResults: string[] = []; // Update App Store language info if (store === "both" || store === "appStore") { if (existing.appStore) { const asResult = await appStoreService.fetchAppInfo(identifier); if (asResult.found && asResult.supportedLocales) { if (!appsConfig.apps[appIndex].appStore) { appsConfig.apps[appIndex].appStore = { bundleId: identifier, appId: asResult.appId, name: asResult.name, }; } appsConfig.apps[appIndex].appStore!.supportedLocales = asResult.supportedLocales; updated = true; updateResults.push( `🍎 App Store: Updated locales (${asResult.supportedLocales.length})` ); } } } // Update Google Play language info if (store === "both" || store === "googlePlay") { if (existing.googlePlay || store === "googlePlay") { const gpResult = await googlePlayService.fetchAppInfo(identifier); if (gpResult.found && gpResult.supportedLocales) { if (!appsConfig.apps[appIndex].googlePlay) { appsConfig.apps[appIndex].googlePlay = { packageName: identifier, name: gpResult.name, }; } appsConfig.apps[appIndex].googlePlay!.supportedLocales = gpResult.supportedLocales; if (gpResult.name) { appsConfig.apps[appIndex].googlePlay!.name = gpResult.name; } updated = true; updateResults.push( `πŸ€– Google Play: Updated locales (${gpResult.supportedLocales.length})` ); } } } if (updated) { saveRegisteredApps(appsConfig); const updatedApp = appsConfig.apps[appIndex]; const localeInfo: string[] = []; if ( updatedApp.appStore?.supportedLocales && updatedApp.appStore.supportedLocales.length > 0 ) { localeInfo.push( `β€’ App Store locales: ${updatedApp.appStore.supportedLocales.join(", ")}` ); } if ( updatedApp.googlePlay?.supportedLocales && updatedApp.googlePlay.supportedLocales.length > 0 ) { localeInfo.push( `β€’ Google Play locales: ${updatedApp.googlePlay.supportedLocales.join(", ")}` ); } return { content: [ { type: "text" as const, text: `βœ… App language info updated β€’ Slug: \`${updatedApp.slug}\` β€’ Name: ${updatedApp.name} β€’ App Store: ${updatedApp.appStore ? `βœ… ${updatedApp.appStore.bundleId}` : "❌"} β€’ Google Play: ${updatedApp.googlePlay ? `βœ… ${updatedApp.googlePlay.packageName}` : "❌"} ${updateResults.length > 0 ? `\n**Updates:**\n${updateResults.map((r) => ` β€’ ${r}`).join("\n")}` : ""} ${localeInfo.length > 0 ? `\n**Supported Languages:**\n${localeInfo.map((l) => ` ${l}`).join("\n")}` : ""}`, }, ], _meta: { app: updatedApp }, }; } } // If no updates were made, return existing info const localeInfo: string[] = []; if ( existing.appStore?.supportedLocales && existing.appStore.supportedLocales.length > 0 ) { localeInfo.push( `β€’ App Store locales: ${existing.appStore.supportedLocales.join(", ")}` ); } if ( existing.googlePlay?.supportedLocales && existing.googlePlay.supportedLocales.length > 0 ) { localeInfo.push( `β€’ Google Play locales: ${existing.googlePlay.supportedLocales.join(", ")}` ); } return { content: [ { type: "text" as const, text: `⏭️ App is already registered. β€’ Slug: \`${existing.slug}\` β€’ Name: ${existing.name} β€’ App Store: ${existing.appStore ? `βœ… ${existing.appStore.bundleId}` : "❌"} β€’ Google Play: ${existing.googlePlay ? `βœ… ${existing.googlePlay.packageName}` : "❌"} ${localeInfo.length > 0 ? `\n**Supported Languages:**\n${localeInfo.map((l) => ` ${l}`).join("\n")}` : ""}`, }, ], _meta: { app: existing }, }; } const slug = customSlug || generateSlug(identifier); // Check for slug duplicates const slugExists = findApp(slug); if (slugExists) { return { content: [ { type: "text" as const, text: `❌ slug "${slug}" is already in use. Please specify a different slug. \`\`\`json { "identifier": "${identifier}", "slug": "different-slug" } \`\`\``, }, ], }; } // Fetch app information by store (μ–Έμ–΄ 정보 포함) let appStoreInfo: RegisteredApp["appStore"] = undefined; let googlePlayInfo: RegisteredApp["googlePlay"] = undefined; let appName = identifier; const results: string[] = []; // Check App Store if (store === "both" || store === "appStore") { console.error(`[MCP] πŸ” Searching App Store for: ${identifier}`); const asResult = await appStoreService.fetchAppInfo(identifier); if (asResult.found) { appStoreInfo = toRegisteredAppStoreInfo({ bundleId: identifier, appInfo: asResult, }); appName = asResult.name || appName; const localeInfo = asResult.supportedLocales && asResult.supportedLocales.length > 0 ? ` (${asResult.supportedLocales.length} locales)` : ""; results.push(`🍎 App Store: βœ… Found (${asResult.name})${localeInfo}`); } else { results.push(`🍎 App Store: ❌ Not found`); } } // Check Google Play if (store === "both" || store === "googlePlay") { console.error(`[MCP] πŸ” Searching Google Play for: ${identifier}`); const gpResult = await googlePlayService.fetchAppInfo(identifier); if (gpResult.found) { googlePlayInfo = toRegisteredGooglePlayInfo({ packageName: identifier, appInfo: gpResult, }); appName = gpResult.name || appName; const localeInfo = gpResult.supportedLocales && gpResult.supportedLocales.length > 0 ? ` (${gpResult.supportedLocales.length} locales)` : ""; results.push(`πŸ€– Google Play: βœ… Found (${gpResult.name})${localeInfo}`); } else { results.push(`πŸ€– Google Play: ❌ Not found`); } } // Must be found in at least one store if (!appStoreInfo && !googlePlayInfo) { return { content: [ { type: "text" as const, text: `❌ App not found. **Search Results:** ${results.map((r) => ` β€’ ${r}`).join("\n")} **Things to Check:** β€’ Verify identifier is correct: \`${identifier}\` β€’ Verify app is registered in the store β€’ Verify authentication settings are correct (use auth-check tool)`, }, ], }; } // Register app try { console.error(`[MCP] πŸ’Ύ Registering app with slug: ${slug}`); const newApp = registerApp({ slug, name: appName, appStore: appStoreInfo, googlePlay: googlePlayInfo, }); console.error(`[MCP] βœ… App registered successfully`); const storeIcons = [ appStoreInfo ? "🍎" : null, googlePlayInfo ? "πŸ€–" : null, ] .filter(Boolean) .join("+"); const localeInfo: string[] = []; if ( appStoreInfo?.supportedLocales && appStoreInfo.supportedLocales.length > 0 ) { localeInfo.push( `β€’ App Store locales: ${appStoreInfo.supportedLocales.join(", ")}` ); } if ( googlePlayInfo?.supportedLocales && googlePlayInfo.supportedLocales.length > 0 ) { localeInfo.push( `β€’ Google Play locales: ${googlePlayInfo.supportedLocales.join(", ")}` ); } return { content: [ { type: "text" as const, text: `βœ… App registration complete (${storeIcons}) **Registration Info:** β€’ Slug: \`${newApp.slug}\` β€’ Name: ${newApp.name} ${appStoreInfo ? `β€’ App Store: ${appStoreInfo.bundleId} (ID: ${appStoreInfo.appId})` : ""} ${googlePlayInfo ? `β€’ Google Play: ${googlePlayInfo.packageName}` : ""} ${localeInfo.length > 0 ? `\n**Supported Languages:**\n${localeInfo.map((l) => ` ${l}`).join("\n")}` : ""} **Search Results:** ${results.map((r) => ` β€’ ${r}`).join("\n")} You can now reference this app in other tools using the \`app: "${slug}"\` parameter.`, }, ], _meta: { app: newApp }, }; } catch (error) { const msg = error instanceof Error ? error.message : String(error); return { content: [ { type: "text" as const, text: `❌ App registration failed: ${msg}`, }, ], }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/quartz-labs-dev/pabal-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server