Skip to main content
Glama
ascentkorea

Hubble MCP Server

by ascentkorea

get_graph_info

Retrieve keyword relationship data from Hubble's cluster finder, including related terms, connections, and search patterns for analysis.

Instructions

키워드 관계 정보(리스닝마인드의 클러스터 파인더의 결과 조회, 키워드 관계 정보 조회)
모든 키워드는 소문자로 변환하여 요청
args:
    req_param: ClusterParameters, 키워드 관계 정보 조회 요청 파라미터
returns:
    dict[ClusterResponse, Any] | None: 키워드 관계 정보 조회 결과
ClusterResponse 는 아래와 같은 정보를 포함합니다:  

nodes: 조회한 키워드의 앞과 뒤로 2혹은 2hop 거리 안에서 검색된 모든 키워드(노드) 리스트
nodes_count: 키워드(노드) 수
rels: 관계 리스트
rels_count: 관계 수
closeness: 관계에서 키워드가 출현한 위치.
distance: 모든 관계에서 키워드가 출현한 위치.
type: PEOPLE_ALSO_SEARCH_FOR | RELATED_SEARCHES | REFINEMENTS | PEOPLE_ALSO_ASK_FOR  

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
req_paramYes

Implementation Reference

  • The handler function for the 'get_graph_info' tool. It is registered via @mcp.tool(), uses async_retry decorator, takes ClusterParameters as input, sends a POST request to the /cluster endpoint of the Hubble API, and returns the raw response text.
    @mcp.tool()
    @async_retry(exceptions=(Exception), tries=2, delay=0.3)
    async def get_graph_info(
            req_param: ClusterParameters) -> dict[ClusterResponse, Any] | None:
        '''
        키워드 관계 정보(리스닝마인드의 클러스터 파인더의 결과 조회, 키워드 관계 정보 조회)
        모든 키워드는 소문자로 변환하여 요청
        args:
            req_param: ClusterParameters, 키워드 관계 정보 조회 요청 파라미터
        returns:
            dict[ClusterResponse, Any] | None: 키워드 관계 정보 조회 결과
        ClusterResponse 는 아래와 같은 정보를 포함합니다:  
        
        nodes: 조회한 키워드의 앞과 뒤로 2혹은 2hop 거리 안에서 검색된 모든 키워드(노드) 리스트
        nodes_count: 키워드(노드) 수
        rels: 관계 리스트
        rels_count: 관계 수
        closeness: 관계에서 키워드가 출현한 위치.
        distance: 모든 관계에서 키워드가 출현한 위치.
        type: PEOPLE_ALSO_SEARCH_FOR | RELATED_SEARCHES | REFINEMENTS | PEOPLE_ALSO_ASK_FOR  
        '''
        async with httpx.AsyncClient() as client:
            headers = {"X-API-Key": HUBBLE_API_KEY}
            response = await client.post(
                f"{HUBBLE_API_URL}/cluster",
                headers=headers,
                json=req_param.model_dump(),
                timeout=30.0)
            response.raise_for_status()
            return response.text
  • Input schema for the get_graph_info tool, defined as Pydantic BaseModel ClusterParameters with fields for keyword, gl (geolocation), limit, hop, and orientation.
    class ClusterParameters(BaseModel):
        keyword: str = Field(
            min_length=1,
            title="keyword(str)",
            description="요청 키워드",
        )
        gl: Literal['kr', 'jp'] = Field(
            default='kr',
            title="Geolocation",
            description="국가 코드",
        )
        limit: int = Field(default=1000, ge=1, le=10000, title='limit(int)', description='관계수 limit 욥션')
        hop: int = Field(
            default=2,
            ge=1,
            le=3,
            title="hop(int)",
            description="hop 수",
        )
        orientation: Literal['UNDIRECTED', 'NATURAL', 'REVERSE'] = Field(
            default='UNDIRECTED',
            title="direction",
            description="관계 방향",
        )
        _request_at: str
        _api_key: str
        def __init__(self, **data):
            super().__init__(**data)
            self._request_at = datetime.now(UTC).isoformat(timespec='milliseconds') + 'Z' # yapf:disable
  • Output schema models for the get_graph_info tool: ClusterRels (relations), ClusterData (nodes and rels), and ClusterResponse (full response structure inheriting from BaseResponse).
    class ClusterRels(BaseModel):
        closeness: int = Field(description="""
    해당 type 에서 키워드가 출현한 위치
        """)
        distance: int = Field(description="""
    전체 type 에서 키워드가 출현한 위치
        """)
        source: str
        target: str
        type: str = Field(description="""
    관계 type
    * PEOPLE_ALSO_SEARCH_FOR
    * RELATED_SEARCHES
    * REFINEMENTS
    * PEOPLE_ALSO_ASK_FOR  
        """)
    class ClusterData(BaseModel):
        nodes: List[str] = Field(description="키워드(노드) 리스트")
        nodes_count: int = Field(description="키워드(노드) 수")
        rels: List[ClusterRels]
        rels_count: int = Field(description="관계 수")
    class ClusterResponse(BaseResponse):
        request_detail: ClusterParameters = Field(description="요청 받았던 파라미터")
        cost: int = Field(default=0)
        remain_credits: int = Field(default=-1)  # serviceAPI
        data: Optional[ClusterData] = Field(default=None)
Behavior3/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 does reveal some behavioral aspects: it mentions that keywords are converted to lowercase, describes the return structure (nodes, relationships, counts, metrics), and indicates the tool queries a specific system ('Listening Mind's Cluster Finder'). However, it lacks important behavioral context such as rate limits, authentication requirements, error conditions, or whether this is a read-only operation versus a mutation.

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

Conciseness3/5

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

The description is reasonably structured with sections for purpose, args, returns, and response details. However, it includes some redundancy (repeating 'keyword relationship information 조회' in Korean and English) and could be more front-loaded. The technical details about lowercase conversion and response structure are valuable but could be organized more efficiently.

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

Completeness4/5

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

Given the complexity of the tool (relationship graph analysis with multiple parameters) and the absence of both annotations and output schema, the description does a good job of explaining what the tool does, what parameters it expects, and what it returns. It provides the response structure details that would normally be in an output schema. The main gaps are lack of behavioral constraints and usage context compared to sibling tools.

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

Parameters5/5

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

The description provides excellent parameter semantics despite 0% schema description coverage. It explains that 'req_param' contains 'ClusterParameters' for keyword relationship information queries, and then details what ClusterResponse includes (nodes, relationships, counts, closeness, distance, type). This fully compensates for the lack of schema descriptions by explaining both the input structure and the return value structure in meaningful terms.

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

Purpose3/5

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

The description states the tool retrieves keyword relationship information from 'Listening Mind's Cluster Finder', which provides a general purpose. However, it's somewhat vague about what this relationship information entails beyond mentioning nodes and relationships, and it doesn't clearly differentiate from sibling tools like 'get_keyword_info' or 'get_search_path' that might also retrieve keyword-related data.

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. It mentions that all keywords should be converted to lowercase, which is a technical requirement rather than usage context. There's no indication of when this tool is appropriate compared to sibling tools like 'get_keyword_info' or when to use it for relationship analysis versus other crawling 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/ascentkorea/hubble_mcp'

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