similar
Find alternative applications by providing an app's ID or bundle identifier. This tool retrieves similar apps from both iOS App Store and Google Play Store platforms.
Instructions
Get apps similar to the specified app
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | iTunes trackId of the app | |
| appId | No | Bundle ID of the app | |
| country | No | Two-letter country code (default: us) | us |
Implementation Reference
- src/server.js:348-388 (handler)The handler function for the 'similar' MCP tool. It builds the App Store app page URL, fetches the HTML, parses similar apps using parseSimilarFromHTML, and returns the results as JSON or error.async function handleSimilar(args) { try { const { id, appId, country = 'us' } = args; if (!id && !appId) { throw new Error('Either id or appId must be provided'); } // Try to get similar apps from the web page const url = buildSimilarUrl({ id, appId, country }); const html = await fetchText(url); const similarApps = parseSimilarFromHTML(html); // If HTML parsing didn't work, return empty array // In a production environment, you might want to implement more robust parsing return { content: [ { type: 'text', text: JSON.stringify({ similarApps, count: similarApps.length, note: similarApps.length === 0 ? 'Similar apps parsing from HTML is limited. Consider using search with related terms.' : null, }, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ error: error.message }, null, 2), }, ], isError: true, }; } }
- src/server.js:1107-1127 (registration)Registration of the 'similar' tool in the ListTools response, including name, description, and input schema definition.name: 'similar', description: 'Get apps similar to the specified app', inputSchema: { type: 'object', properties: { id: { type: 'number', description: 'iTunes trackId of the app', }, appId: { type: 'string', description: 'Bundle ID of the app', }, country: { type: 'string', description: 'Two-letter country code (default: us)', default: 'us', }, }, }, },
- src/server.js:1457-1458 (handler)Switch case in CallToolRequestSchema handler that routes calls to the 'similar' tool to handleSimilar function.case 'similar': return await handleSimilar(args);
- Helper function to parse similar apps from App Store HTML page using regex for JSON-LD and app links.export function parseSimilarFromHTML(html) { const similarApps = []; // App Store embeds similar apps in JSON-LD or in script tags // This is a simplified parser - in production you'd want more robust parsing try { // Try to find JSON-LD structured data const jsonLdMatches = html.matchAll(/<script[^>]*type=["']application\/ld\+json["'][^>]*>(.*?)<\/script>/gis); for (const match of jsonLdMatches) { try { const jsonLd = JSON.parse(match[1]); if (jsonLd['@graph']) { const apps = jsonLd['@graph'].filter(item => item['@type'] === 'SoftwareApplication'); apps.forEach(app => { if (app.url) { similarApps.push({ id: extractIdFromUrl(app.url) || null, appId: null, title: app.name || null, url: app.url || null, }); } }); } } catch (e) { // Skip invalid JSON } } // Try to extract app IDs from App Store links const appLinkMatches = html.matchAll(/apps\.apple\.com\/[^\/]+\/app\/id(\d+)/gi); const seenIds = new Set(); for (const match of appLinkMatches) { const appId = match[1]; if (!seenIds.has(appId)) { seenIds.add(appId); similarApps.push({ id: parseInt(appId, 10), appId: null, title: null, url: `https://apps.apple.com/app/id${appId}`, }); } } } catch (error) { // If parsing fails, return empty array // Error is silently handled } return similarApps; }
- src/endpoints/appStore.js:107-117 (helper)Helper function to build the App Store app page URL used for fetching similar apps HTML.export function buildSimilarUrl(params) { const { id, appId, country = 'us' } = params; if (!id && !appId) { throw new Error('Either id or appId must be provided'); } // Similar apps are found via the web page const appIdParam = id || appId; return `${APP_STORE_BASE}/${country}/app/id${appIdParam}`; }