Skip to main content
Glama
re171113-byte

Startup Helper MCP

find_competitors

Identify nearby competitors and analyze market conditions, including franchise density and entry opportunities for specific business types and locations.

Instructions

주변 경쟁업체를 검색하고 분석합니다. 프랜차이즈 비율, 시장 진입 여지 등을 분석합니다.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
locationYes검색할 위치 (예: 강남역, 홍대입구)
business_typeYes검색할 업종 (예: 카페, 음식점)
radiusNo검색 반경 (m), 기본값: 300
limitNo결과 개수, 기본값: 10

Implementation Reference

  • Main handler function implementing the core logic for the 'find_competitors' tool: fetches competitors via Kakao API, computes franchise ratio, performs market gap analysis, and formats the response.
    export async function findCompetitors(
      location: string,
      businessType: string,
      radius: number = 300,
      limit: number = 10
    ): Promise<ApiResult<CompetitorAnalysis>> {
      try {
        // 경쟁업체 검색
        const competitors = await kakaoApi.findCompetitors(
          businessType,
          location,
          radius,
          limit
        );
    
        // 프랜차이즈 비율 계산
        const franchiseCount = competitors.filter((c) => isFranchise(c.name)).length;
        const franchiseRatio = competitors.length > 0
          ? Math.round((franchiseCount / competitors.length) * 100) / 100
          : 0;
    
        // 시장 갭 분석
        const marketGap = analyzeMarketGap(competitors, franchiseRatio, competitors.length);
    
        return {
          success: true,
          data: {
            query: businessType,
            location,
            radius,
            competitors,
            analysis: {
              totalCount: competitors.length,
              franchiseRatio,
              marketGap,
            },
          },
          meta: {
            source: DATA_SOURCES.kakaoLocal,
            timestamp: new Date().toISOString(),
          },
        };
      } catch (error) {
        console.error("경쟁업체 검색 실패:", error);
    
        return {
          success: false,
          error: {
            code: "COMPETITOR_SEARCH_FAILED",
            message: `경쟁업체 검색 중 오류가 발생했습니다: ${error instanceof Error ? error.message : "Unknown error"}`,
            suggestion: "위치명을 다시 확인하거나 잠시 후 시도해주세요.",
          },
        };
      }
    }
  • src/index.ts:42-58 (registration)
    MCP server registration of the 'find_competitors' tool, defining name, description, input schema, and thin wrapper handler that calls the main findCompetitors function.
    server.tool(
      "find_competitors",
      "주변 경쟁업체를 검색하고 분석합니다. 프랜차이즈 비율, 시장 진입 여지 등을 분석합니다.",
      {
        location: z.string().describe("검색할 위치 (예: 강남역, 홍대입구)"),
        business_type: z.string().describe("검색할 업종 (예: 카페, 음식점)"),
        radius: z.number().optional().default(300).describe("검색 반경 (m), 기본값: 300"),
        limit: z.number().optional().default(10).describe("결과 개수, 기본값: 10"),
      },
      async ({ location, business_type, radius, limit }) => {
        const result = await findCompetitors(location, business_type, radius, limit);
        return {
          content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
          isError: !result.success,
        };
      }
    );
  • Zod schema defining input parameters for the 'find_competitors' tool: location, business_type, radius, limit.
    {
      location: z.string().describe("검색할 위치 (예: 강남역, 홍대입구)"),
      business_type: z.string().describe("검색할 업종 (예: 카페, 음식점)"),
      radius: z.number().optional().default(300).describe("검색 반경 (m), 기본값: 300"),
      limit: z.number().optional().default(10).describe("결과 개수, 기본값: 10"),
    },
  • Kakao API client method that resolves location coordinates and searches for competitor places by keyword, transforming results into Competitor format.
    async findCompetitors(
      businessType: string,
      location: string,
      radius: number = 300,
      limit: number = 15
    ): Promise<Competitor[]> {
      // 먼저 위치 좌표 얻기
      const coords = await this.getCoordinates(location);
      if (!coords) {
        throw new Error(`위치를 찾을 수 없습니다: ${location}`);
      }
    
      // 업종으로 검색
      const places = await this.searchByKeyword(`${location} ${businessType}`, {
        x: String(coords.lng),
        y: String(coords.lat),
        radius,
        size: limit,
        sort: "distance",
      });
    
      return places.map((place) => ({
        id: place.id,
        name: place.place_name,
        category: place.category_name,
        address: place.road_address_name || place.address_name,
        distance: place.distance ? parseInt(place.distance, 10) : 0,
        phone: place.phone || undefined,
        placeUrl: place.place_url,
      }));
    }
  • Helper function that analyzes market gap based on competitor count and franchise ratio, providing strategic insights.
    function analyzeMarketGap(
      competitors: Competitor[],
      franchiseRatio: number,
      totalCount: number
    ): string {
      if (totalCount === 0) {
        return "해당 업종의 경쟁업체가 없습니다. 선점 기회가 있습니다.";
      }
    
      if (totalCount <= 3) {
        return "경쟁업체가 적어 진입하기 좋은 환경입니다.";
      }
    
      if (franchiseRatio >= 0.7) {
        return "프랜차이즈 비중이 높습니다. 개성있는 개인 매장으로 차별화 가능합니다.";
      }
    
      if (franchiseRatio <= 0.3) {
        return "개인 매장 비중이 높습니다. 브랜드 파워로 경쟁력 확보 가능합니다.";
      }
    
      if (totalCount >= 10) {
        return "경쟁이 치열합니다. 명확한 차별화 전략이 필요합니다.";
      }
    
      return "적절한 경쟁 환경입니다. 품질과 서비스로 승부하세요.";
    }
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. While it mentions analysis aspects (franchise ratio, market entry potential), it doesn't describe what the tool actually returns, whether it performs data aggregation, how analysis is conducted, or any limitations. For a tool with 4 parameters and no output schema, this leaves significant behavioral gaps.

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

Conciseness4/5

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

The description is concise with just two sentences that directly state the tool's purpose and analysis scope. There's no wasted text or redundancy. However, it could be more front-loaded by immediately stating it's for competitor analysis rather than starting with 'search and analyze surrounding competitors'.

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?

For a tool with 4 parameters, no annotations, and no output schema, the description is insufficient. It doesn't explain what the analysis output looks like, how the franchise ratio and market entry potential are calculated or presented, or any limitations of the analysis. The agent needs more context to understand what to expect from this tool's results.

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?

Schema description coverage is 100%, so all parameters are documented in the schema. The description doesn't add any parameter-specific information beyond what's already in the schema descriptions. It mentions analysis aspects but doesn't connect them to specific parameters. The baseline of 3 is appropriate when the schema does the heavy lifting.

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: 'search and analyze surrounding competitors' with specific analysis aspects mentioned (franchise ratio, market entry potential). It uses specific verbs ('search', 'analyze') and identifies the resource ('competitors'). However, it doesn't explicitly differentiate from sibling tools like 'analyze_commercial_area' or 'get_business_trends' which might have overlapping functionality.

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 the sibling tools. There's no mention of alternatives, prerequisites, or specific contexts where this tool is preferred over 'analyze_commercial_area' or 'get_business_trends'. The agent receives no help in selecting between these potentially related tools.

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/re171113-byte/startup-helper-mcp'

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