Skip to main content
Glama

coingeckotokeninfoagent_get_top_token_holders

Retrieve the top 50 token holder addresses for a specific token on a designated blockchain network, enabling insights into token distribution and wallet activity.

Instructions

Get top 50 token holder addresses for a token on a specific network.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
addressYesToken contract address
networkYesNetwork ID (e.g., base)

Implementation Reference

  • MCP handler that executes any registered tool, including 'coingeckotokeninfoagent_get_top_token_holders', by proxying arguments to the remote Mesh agent API.
    @app.call_tool()
    async def call_tool(name: str, arguments: dict) -> List[types.TextContent]:
        """Call the specified tool with the given arguments."""
        try:
            if name not in self.tool_registry:
                raise ValueError(f"Unknown tool: {name}")
    
            tool_info = self.tool_registry[name]
            result = await self.execute_tool(
                agent_id=tool_info["agent_id"],
                tool_name=tool_info["tool_name"],
                tool_arguments=arguments,
            )
    
            # Convert result to TextContent
            return [types.TextContent(type="text", text=str(result))]
        except Exception as e:
            logger.error(f"Error calling tool {name}: {e}")
            raise ValueError(f"Failed to call tool {name}: {str(e)}") from e
  • Dynamically registers the tool by constructing its MCP name as '{agent_id.lower()}_ {tool_name}' (e.g., 'coingeckotokeninfoagent_get_top_token_holders' for CoinGeckoTokenInfoAgent's get_top_token_holders tool) and storing agent/tool metadata including input schema.
    for tool in agent_data.get("tools", []):
        if tool.get("type") == "function":
            function_data = tool.get("function", {})
            tool_name = function_data.get("name")
    
            if not tool_name:
                continue
    
            # Create a unique tool ID
            tool_id = f"{agent_id.lower()}_{tool_name}"
    
            # Get parameters or create default schema
            parameters = function_data.get("parameters", {})
            if not parameters:
                parameters = {
                    "type": "object",
                    "properties": {},
                    "required": [],
                }
    
            # Store tool info
            tool_registry[tool_id] = {
                "agent_id": agent_id,
                "tool_name": tool_name,
                "description": function_data.get("description", ""),
                "parameters": parameters,
            }
  • MCP registration endpoint that lists all dynamically registered tools, including the target tool with its schema.
    @app.list_tools()
    async def list_tools() -> List[types.Tool]:
        """List all available tools."""
        return [
            types.Tool(
                name=tool_id,
                description=tool_info["description"],
                inputSchema=tool_info["parameters"],
            )
            for tool_id, tool_info in self.tool_registry.items()
        ]
  • CoinGeckoTokenInfoAgent is included in default supported agents, enabling registration of its tools like get_top_token_holders.
    DEFAULT_AGENTS = [
        "CoinGeckoTokenInfoAgent",
        "DexScreenerTokenInfoAgent",
        "ElfaTwitterIntelligenceAgent",
        "ExaSearchAgent",
        "TwitterInfoAgent",
        "AIXBTProjectInfoAgent",
        "EtherscanAgent",
        "EvmTokenInfoAgent",
        "FundingRateAgent",
        "UnifaiTokenAnalysisAgent",
        "YahooFinanceAgent",
        "ZerionWalletAnalysisAgent"
  • Helper function called by the main handler to perform the actual API call to the remote agent for tool execution.
    async def execute_tool(
        self, agent_id: str, tool_name: str, tool_arguments: Dict[str, Any]
    ) -> Dict[str, Any]:
        """Execute a tool on a mesh agent.
    
        Args:
            agent_id: ID of the agent to execute the tool on
            tool_name: Name of the tool to execute
            tool_arguments: Arguments to pass to the tool
    
        Returns:
            Tool execution result
    
        Raises:
            ToolExecutionError: If there's an error executing the tool
        """
        request_data = {
            "agent_id": agent_id,
            "input": {"tool": tool_name, "tool_arguments": tool_arguments},
        }
    
        # Add API key if available
        if Config.HEURIST_API_KEY:
            request_data["api_key"] = Config.HEURIST_API_KEY
    
        try:
            result = await call_mesh_api(
                "mesh_request", method="POST", json=request_data
            )
            return result.get("data", result)  # Prefer the 'data' field if it exists
        except MeshApiError as e:
            # Re-raise API errors with clearer context
            raise ToolExecutionError(str(e)) from e
        except Exception as e:
            logger.error(f"Error calling {agent_id} tool {tool_name}: {e}")
            raise ToolExecutionError(
                f"Failed to call {agent_id} tool {tool_name}: {str(e)}"
            ) from e
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 but omits critical details like rate limits, authentication needs, response format (e.g., list structure, pagination), or error handling. This leaves significant gaps in understanding how the tool behaves beyond the basic operation.

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 front-loads the core purpose without unnecessary words. It directly communicates what the tool does, making it easy to parse and understand quickly, with no wasted information.

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 fetching token holder data, no annotations, and no output schema, the description is incomplete. It lacks details on return values (e.g., format of holder addresses, any additional data like balances), error cases, or operational constraints, which are essential for effective tool use in this 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 input schema has 100% description coverage, clearly documenting both parameters ('address' as token contract address and 'network' as network ID). The description does not add any semantic details beyond this, such as examples or constraints, so it meets the baseline for adequate but not enhanced parameter understanding.

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 verb ('Get') and resource ('top 50 token holder addresses for a token on a specific network'), making the purpose specific and understandable. However, it does not explicitly differentiate from sibling tools like 'coingeckotokeninfoagent_get_token_info', which might also provide token-related data, leaving room for ambiguity in distinguishing use cases.

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 other token info tools in the sibling list. It lacks context on prerequisites, exclusions, or comparisons, leaving the agent to infer usage based solely on the purpose statement without explicit direction.

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

Related 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/heurist-network/heurist-mesh-mcp-server'

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