Skip to main content
Glama
MiguelAlvRed

Store Scraper MCP

by MiguelAlvRed

similar

Find apps similar to a specified iOS or Android application by providing its iTunes trackId or Bundle ID, with country-specific results available.

Instructions

Get apps similar to the specified app

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNoiTunes trackId of the app
appIdNoBundle ID of the app
countryNoTwo-letter country code (default: us)us

Implementation Reference

  • The main handler function for the 'similar' tool. Fetches the app page HTML using buildSimilarUrl and parses similar apps using parseSimilarFromHTML.
    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,
        };
      }
    }
  • Input schema definition for the 'similar' tool in the ListTools response.
      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',
          },
        },
      },
    },
  • Registration of the 'similar' handler in the CallToolRequestSchema switch statement.
    case 'similar':
      return await handleSimilar(args);
  • Helper function to parse similar apps from App Store HTML page.
    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;
    }
  • Helper function to build the URL for the App Store app page where similar apps are listed.
    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}`;
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the action ('Get apps similar') but fails to describe key traits like whether this is a read-only operation, potential rate limits, authentication needs, or the format of returned data. This leaves significant gaps for a tool that likely queries external data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that directly states the tool's purpose without any fluff or redundancy. It is front-loaded and appropriately sized, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of querying similar apps and the lack of annotations and output schema, the description is incomplete. It doesn't explain what 'similar' means (e.g., by genre, ratings, or features), how results are returned, or any limitations, making it inadequate for an agent to use effectively without additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds no parameter-specific information beyond what the input schema provides, which has 100% coverage with clear descriptions for 'id', 'appId', and 'country'. Since the schema does the heavy lifting, the baseline score of 3 is appropriate, as the description doesn't compensate or add extra meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Get') and resource ('apps similar to the specified app'), making it immediately understandable. However, it doesn't explicitly differentiate from sibling tools like 'gp_similar' or 'search', which could provide overlapping functionality, preventing a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives such as 'gp_similar', 'search', or 'suggest' from the sibling list. It lacks context on prerequisites, exclusions, or specific scenarios where this tool is preferred, leaving the agent to infer usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/MiguelAlvRed/mobile-store-scraper-mcp'

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