Skip to main content
Glama
l4b4r4b4b4
by l4b4r4b4b4

search_crypto_coins

Search for cryptocurrencies by name, symbol, or keyword to get coin IDs and market cap ranking for use in portfolio creation.

Instructions

Search for cryptocurrencies on CoinGecko.

Find coins by name, symbol, or keyword. Useful for discovering coin IDs to use with create_portfolio.

Args: query: Search query (e.g., 'bitcoin', 'defi', 'layer 2').

Returns: Dictionary containing: - coins: List of matching coins (id, name, symbol, market_cap_rank) - count: Number of results - fetched_at: ISO timestamp

Example: # Search for DeFi coins result = search_crypto_coins(query="defi") for coin in result['coins']: print(f"{coin['name']} ({coin['symbol']}) - Rank: {coin['market_cap_rank']}")

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The @mcp.tool decorated function 'search_crypto_coins' that serves as the MCP tool handler. It accepts a query string, validates it, calls search_crypto(), and returns a dict with query, coins list, count, and fetched_at timestamp.
    @mcp.tool
    def search_crypto_coins(query: str) -> dict[str, Any]:
        """Search for cryptocurrencies on CoinGecko.
    
        Find coins by name, symbol, or keyword. Useful for discovering
        coin IDs to use with create_portfolio.
    
        Args:
            query: Search query (e.g., 'bitcoin', 'defi', 'layer 2').
    
        Returns:
            Dictionary containing:
            - coins: List of matching coins (id, name, symbol, market_cap_rank)
            - count: Number of results
            - fetched_at: ISO timestamp
    
        Example:
            ```
            # Search for DeFi coins
            result = search_crypto_coins(query="defi")
            for coin in result['coins']:
                print(f"{coin['name']} ({coin['symbol']}) - Rank: {coin['market_cap_rank']}")
            ```
        """
        if not query or len(query.strip()) == 0:
            return {"error": "Query cannot be empty"}
    
        try:
            coins = search_crypto(query.strip())
            return {
                "query": query,
                "coins": coins,
                "count": len(coins),
                "fetched_at": datetime.now().isoformat(),
            }
        except ValueError as error:
            return {
                "error": str(error),
                "suggestion": "CoinGecko API may be rate-limited. Try again later.",
            }
  • Helper function 'search_crypto' that performs the actual CoinGecko API call via _coingecko_request('search', ...) and returns a list of up to 20 matching coins with id, name, symbol, and market_cap_rank.
    def search_crypto(query: str) -> list[dict[str, Any]]:
        """Search for cryptocurrencies on CoinGecko.
    
        Args:
            query: Search query (e.g., 'bitcoin', 'defi').
    
        Returns:
            List of matching coins.
        """
        data = _coingecko_request("search", params={"query": query})
    
        return [
            {
                "id": coin["id"],
                "name": coin["name"],
                "symbol": coin["symbol"],
                "market_cap_rank": coin.get("market_cap_rank"),
            }
            for coin in data.get("coins", [])[:20]  # Limit to top 20
        ]
  • Core API helper '_coingecko_request' that calls CoinGecko API with rate limiting and error handling, used by search_crypto and all other CoinGecko functions.
    def _coingecko_request(
        endpoint: str,
        params: dict[str, Any] | None = None,
    ) -> dict[str, Any]:
        """Make a rate-limited request to CoinGecko API.
    
        Args:
            endpoint: API endpoint (without base URL).
            params: Query parameters.
    
        Returns:
            JSON response as dictionary.
    
        Raises:
            ValueError: If rate limited or request fails.
        """
        url = f"{COINGECKO_API_URL}/{endpoint}"
        try:
            response = requests.get(url, params=params, timeout=30)
            if response.status_code == 429:
                logger.warning("CoinGecko rate limit hit")
                raise ValueError(
                    "CoinGecko rate limit exceeded. Try again in a minute or use fewer symbols."
                )
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as error:
            logger.error(f"CoinGecko request failed: {error}")
            raise ValueError(f"Failed to fetch crypto data: {error}") from error
  • The 'register_data_tools' function that registers all data tools (including search_crypto_coins via @mcp.tool decorator) with the FastMCP server. The @mcp.tool decorator on the function at line 431 handles the actual registration.
    def register_data_tools(
        mcp: FastMCP, store: PortfolioStore, cache: RefCache | None = None
    ) -> None:
  • The tool's docstring acts as the schema/interface definition, describing the single 'query' input parameter (str), and the return dict structure containing 'coins', 'count', and 'fetched_at'.
    def search_crypto_coins(query: str) -> dict[str, Any]:
        """Search for cryptocurrencies on CoinGecko.
    
        Find coins by name, symbol, or keyword. Useful for discovering
        coin IDs to use with create_portfolio.
    
        Args:
            query: Search query (e.g., 'bitcoin', 'defi', 'layer 2').
    
        Returns:
            Dictionary containing:
            - coins: List of matching coins (id, name, symbol, market_cap_rank)
            - count: Number of results
            - fetched_at: ISO timestamp
    
        Example:
            ```
            # Search for DeFi coins
            result = search_crypto_coins(query="defi")
            for coin in result['coins']:
                print(f"{coin['name']} ({coin['symbol']}) - Rank: {coin['market_cap_rank']}")
            ```
        """
Behavior4/5

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

With no annotations provided, the description carries full responsibility. It details the return structure (coins list, count, fetched_at) and provides an example. It does not mention rate limits or authentication, but the tool appears simple and read-only, and the description sufficiently conveys its behavior.

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 concise but complete, with clear sections for purpose, parameters, returns, and an example. Every sentence adds value, and the important information is front-loaded.

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

Completeness5/5

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

Given the tool's simplicity (single parameter, no nested objects) and the fact that an output schema is described in the returns section, the description provides all necessary context for an agent to use the tool effectively, including input format and output structure.

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 only parameter, query, is well-explained with a description and concrete examples ('bitcoin', 'defi', 'layer 2'), adding significant value beyond the bare schema definition. Schema coverage is 0%, so the description compensates fully.

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

Purpose5/5

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

Clearly states the tool searches for cryptocurrencies by name, symbol, or keyword. It explicitly distinguishes itself by mentioning its utility for discovering coin IDs to use with create_portfolio, differentiating it from siblings like get_crypto_info or get_trending_coins.

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

Usage Guidelines4/5

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

The description gives a specific use case (finding coin IDs for create_portfolio) and implies appropriate scenarios via the example. However, it does not explicitly exclude cases where other tools might be better, such as using get_crypto_info for detailed coin data once the ID is known.

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/l4b4r4b4b4/portfolio-mcp'

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