Skip to main content
Glama
bch1212

agentfetch-mcp

search_and_fetch

Search the web and fetch top results in one call. Provide a query, set the number of results (1-10), and a token limit per result to combine search and fetch into a single round-trip.

Instructions

Web search + fetch top results in one call.

WHEN TO USE:

  • You have a research question, not specific URLs. E.g. "what's the latest on X", "find docs for Y library", "recent news about Z".

  • You'd otherwise have to call a search tool, parse results, then call fetch — this collapses that into one round-trip.

Args: query: Search query (2–500 chars). num_results: Top N to fetch (1–10, default 3). max_tokens_each: Per-result cap (default 2000).

Returns: {"query": str, "count": int, "results": [<fetch_url shape>, ...]}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
num_resultsNo
max_tokens_eachNo

Implementation Reference

  • Core handler for the search_and_fetch tool. Uses Jina's search endpoint to find URLs, then runs each through the AgentFetch fetch_many pipeline. Returns combined results with query, count, and results array.
    def search_and_fetch(
        query: str,
        num_results: int = 3,
        max_tokens_each: int = 2000,
    ) -> dict:
        """Search the web and return clean content from the top results.
    
        Wraps Jina's search endpoint to find URLs, then runs each through the
        AgentFetch pipeline. Returns one combined response.
    
        Args:
            query: Search query string.
            num_results: Number of top results to fetch (default 3, max 10).
            max_tokens_each: Token budget per result.
        """
        num_results = max(1, min(num_results, 10))
        urls = jina_fetcher.search(query, num_results=num_results)
        if not urls:
            return {
                "query": query,
                "count": 0,
                "results": [],
                "error": "search returned no results",
            }
        results = fetch_many(urls, max_tokens_each=max_tokens_each)
        return {"query": query, "count": len(results), "results": results}
  • Input schema defined via function signature (query: str, num_results: int = 3, max_tokens_each: int = 2000). Output schema is the returned dict with keys: query, count, results, and optionally error.
    def search_and_fetch(
        query: str,
        num_results: int = 3,
        max_tokens_each: int = 2000,
    ) -> dict:
        """Search the web and return clean content from the top results.
    
        Wraps Jina's search endpoint to find URLs, then runs each through the
        AgentFetch pipeline. Returns one combined response.
    
        Args:
            query: Search query string.
            num_results: Number of top results to fetch (default 3, max 10).
            max_tokens_each: Token budget per result.
        """
        num_results = max(1, min(num_results, 10))
        urls = jina_fetcher.search(query, num_results=num_results)
        if not urls:
            return {
                "query": query,
                "count": 0,
                "results": [],
                "error": "search returned no results",
            }
        results = fetch_many(urls, max_tokens_each=max_tokens_each)
        return {"query": query, "count": len(results), "results": results}
  • Registration of the search_and_fetch tool via the @mcp.tool() decorator. The server function delegates to the imported _search_and_fetch from agentfetch.mcp.tools.search_fetch.
    @mcp.tool()
    def search_and_fetch(
        query: str, num_results: int = 3, max_tokens_each: int = 2000
    ) -> dict:
        """Web search + fetch top results in one call.
    
        WHEN TO USE:
        - You have a research question, not specific URLs. E.g. "what's the
          latest on X", "find docs for Y library", "recent news about Z".
        - You'd otherwise have to call a search tool, parse results, then call
          fetch — this collapses that into one round-trip.
    
        Args:
            query: Search query (2–500 chars).
            num_results: Top N to fetch (1–10, default 3).
            max_tokens_each: Per-result cap (default 2000).
    
        Returns:
            {"query": str, "count": int, "results": [<fetch_url shape>, ...]}
        """
        return _search_and_fetch(
            query=query,
            num_results=num_results,
            max_tokens_each=max_tokens_each,
        )
  • Import of the search_and_fetch handler (aliased as _search_and_fetch) from the tools module into the server.
    from agentfetch.mcp.tools.search_fetch import (
        search_and_fetch as _search_and_fetch,
    )
  • Jina search helper — uses Jina's /search/ endpoint to convert a query into a list of URLs. Used by search_and_fetch to discover URLs before fetching them.
    def search(query: str, num_results: int = 3, timeout: int = 30) -> list[str]:
        """Use Jina's `/search/` endpoint to get top-N URLs for a query.
    
        The fetch pipeline is responsible for actually fetching the bodies — this
        function only returns URLs.
        """
        headers = {"Accept": "application/json"}
        api_key = get_settings().jina_api_key
        if api_key:
            headers["Authorization"] = f"Bearer {api_key}"
        try:
            resp = httpx.get(
                f"https://s.jina.ai/{query}",
                headers=headers,
                timeout=timeout,
            )
        except httpx.HTTPError:
            return []
        if resp.status_code != 200:
            return []
        try:
            data = resp.json()
        except ValueError:
            return []
        results = data.get("data") if isinstance(data, dict) else data
        if not isinstance(results, list):
            return []
        urls: list[str] = []
        for item in results[:num_results]:
            if isinstance(item, dict) and "url" in item:
                urls.append(item["url"])
        return urls
Behavior4/5

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

With no annotations, the description effectively discloses the combined search-and-fetch behavior and the return format. However, it lacks details on error handling or failure scenarios for individual result fetches.

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 well-structured with a header and 'WHEN TO USE' section, making it easy to parse. It is concise yet informative, though the parameter descriptions could be integrated more succinctly.

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?

The description adequately covers the tool's purpose, usage, parameters, and return format. Given no output schema, the return shape is documented. Missing details on partial failures or edge cases, but overall sufficient for this combined tool.

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?

Despite zero schema coverage, the description fully compensates by specifying constraints (query 2-500 chars, num_results 1-10, max_tokens_each default 2000) and explaining each parameter's role, adding substantial meaning beyond the schema.

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?

The description clearly states 'Web search + fetch top results in one call,' which precisely defines the tool's combined action. It distinguishes itself from siblings like fetch_url and fetch_multiple by highlighting the aggregation of search and fetch into one step.

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 includes a 'WHEN TO USE' section that explicitly recommends the tool for research questions rather than specific URLs. It contrasts with the alternative of using separate search and fetch tools, providing clear guidance on when to prefer this tool.

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/bch1212/agentfetch-mcp'

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