Skip to main content
Glama
elad12390

Web Research Assistant

by elad12390

search_examples

Find code examples, tutorials, and technical articles to learn APIs, discover usage patterns, and solve programming problems.

Instructions

Search for code examples, tutorials, and technical articles.

Optimized for finding practical examples and learning resources. Can optionally filter by
time range for the most recent content. Perfect for learning new APIs, finding usage patterns,
or discovering how others solve specific technical problems.

Content Types:
- 'code': GitHub repos, code snippets, gists, Stack Overflow code examples
- 'articles': Blog posts, tutorials, documentation, technical articles
- 'both': Mix of code and written content (default)

Time Ranges:
- 'all': Search all available content (default, recommended for best results)
- 'year', 'month', 'week', 'day': Filter to recent content only

Examples:
- search_examples("FastAPI dependency injection examples", content_type="code")
- search_examples("React hooks tutorial", content_type="articles", time_range="year")
- search_examples("Rust lifetime examples", content_type="both")

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
reasoningYes
content_typeNoboth
time_rangeNoall
max_resultsNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Implementation of the 'search_examples' MCP tool handler. Searches for code examples, tutorials, and articles using an optimized SearXNG search with content-type specific query enhancements. Formats results with source indicators and diagnostics for limited diversity.
    @mcp.tool()
    async def search_examples(
        query: Annotated[
            str,
            "What you're looking for (e.g., 'Python async await examples', 'React hooks tutorial', 'Rust error handling patterns')",
        ],
        reasoning: Annotated[str, "Why you're searching for examples (required for analytics)"],
        content_type: Annotated[
            Literal["code", "articles", "both"],
            "Type of content to find: 'code' for code examples, 'articles' for tutorials/blogs, 'both' for mixed results",
        ] = "both",
        time_range: Annotated[
            Literal["day", "week", "month", "year", "all"],
            "How recent the content should be (use 'all' for best results, filter down if too many results)",
        ] = "all",
        max_results: Annotated[int, "How many results to return (1-10)"] = DEFAULT_MAX_RESULTS,
    ) -> str:
        """
        Search for code examples, tutorials, and technical articles.
    
        Optimized for finding practical examples and learning resources. Can optionally filter by
        time range for the most recent content. Perfect for learning new APIs, finding usage patterns,
        or discovering how others solve specific technical problems.
    
        Content Types:
        - 'code': GitHub repos, code snippets, gists, Stack Overflow code examples
        - 'articles': Blog posts, tutorials, documentation, technical articles
        - 'both': Mix of code and written content (default)
    
        Time Ranges:
        - 'all': Search all available content (default, recommended for best results)
        - 'year', 'month', 'week', 'day': Filter to recent content only
    
        Examples:
        - search_examples("FastAPI dependency injection examples", content_type="code")
        - search_examples("React hooks tutorial", content_type="articles", time_range="year")
        - search_examples("Rust lifetime examples", content_type="both")
        """
        start_time = time.time()
        success = False
        error_msg = None
        result = ""
    
        try:
            max_results = max(1, min(max_results, 10))
    
            # Build optimized search query based on content type
            enhanced_query = query
            if content_type == "code":
                # Prioritize code-heavy sources
                enhanced_query = f"{query} (site:github.com OR site:stackoverflow.com OR site:gist.github.com OR example OR snippet)"
            elif content_type == "articles":
                # Prioritize articles and tutorials
                enhanced_query = (
                    f"{query} (tutorial OR guide OR article OR blog OR how to OR documentation)"
                )
            else:  # both
                enhanced_query = f"{query} (example OR tutorial OR guide)"
    
            # Use 'it' category for better tech content
            hits = await searcher.search(
                enhanced_query,
                category="it",  # IT/tech category for better results
                max_results=max_results,
                time_range=time_range if time_range != "all" else None,
            )
    
            if not hits:
                result = (
                    f"No examples found for '{query}' in the {time_range if time_range != 'all' else 'all time'} range.\n\n"
                    "Try:\n"
                    "- Broader search terms\n"
                    "- Different time range\n"
                    "- Removing version numbers or very specific constraints\n\n"
                    "Note: Results depend on your SearXNG instance configuration. If you're only seeing MDN docs,\n"
                    "your SearXNG may need additional search engines enabled (GitHub, Stack Overflow, dev.to, etc.)."
                )
            else:
                # Format results with additional context
                lines = [
                    f"Code Examples & Articles for: {query}",
                    f"Time Range: {time_range.title() if time_range != 'all' else 'All time'} | Content Type: {content_type.title()}",
                    "─" * 50,
                    "",
                ]
    
                for idx, hit in enumerate(hits, 1):
                    # Add source indicator
                    source = ""
                    if "github.com" in hit.url:
                        source = "[GitHub] "
                    elif "stackoverflow.com" in hit.url:
                        source = "[Stack Overflow] "
                    elif "medium.com" in hit.url or "dev.to" in hit.url:
                        source = "[Article] "
    
                    snippet = f"\n   {hit.snippet}" if hit.snippet else ""
                    lines.append(f"{idx}. {source}{hit.title}")
                    lines.append(f"   {hit.url}{snippet}")
                    lines.append("")
    
                result_text = "\n".join(lines)
    
                # Add note if results seem limited (all from same domain)
                domains = set()
                for hit in hits:
                    if "://" in hit.url:
                        domain = hit.url.split("://")[1].split("/")[0]
                        domains.add(domain)
    
                if len(domains) == 1 and len(hits) > 2:
                    result_text += (
                        "\n\n──────────────────────────────────────────────────\n"
                        "ℹ️ Note: All results are from the same source. Your SearXNG instance may need\n"
                        "   additional search engines configured (GitHub, Stack Overflow, dev.to, Medium)\n"
                        "   to get diverse code examples and tutorials."
                    )
    
                result = clamp_text(result_text, MAX_RESPONSE_CHARS)
    
            success = True
        except Exception as exc:  # noqa: BLE001
            error_msg = str(exc)
            result = f"Search failed for '{query}': {exc}"
        finally:
            # Track usage
            response_time = (time.time() - start_time) * 1000
            tracker.track_usage(
                tool_name="search_examples",
                reasoning=reasoning,
                parameters={
                    "query": query,
                    "content_type": content_type,
                    "time_range": time_range,
                    "max_results": max_results,
                },
                response_time_ms=response_time,
                success=success,
                error_message=error_msg,
                response_size=len(result.encode("utf-8")),
            )
    
        return result
  • The @mcp.tool() decorator registers the search_examples function as an MCP tool.
    @mcp.tool()
    async def search_examples(
        query: Annotated[
            str,
            "What you're looking for (e.g., 'Python async await examples', 'React hooks tutorial', 'Rust error handling patterns')",
        ],
        reasoning: Annotated[str, "Why you're searching for examples (required for analytics)"],
        content_type: Annotated[
            Literal["code", "articles", "both"],
            "Type of content to find: 'code' for code examples, 'articles' for tutorials/blogs, 'both' for mixed results",
        ] = "both",
        time_range: Annotated[
            Literal["day", "week", "month", "year", "all"],
            "How recent the content should be (use 'all' for best results, filter down if too many results)",
        ] = "all",
        max_results: Annotated[int, "How many results to return (1-10)"] = DEFAULT_MAX_RESULTS,
    ) -> str:
        """
        Search for code examples, tutorials, and technical articles.
    
        Optimized for finding practical examples and learning resources. Can optionally filter by
        time range for the most recent content. Perfect for learning new APIs, finding usage patterns,
        or discovering how others solve specific technical problems.
    
        Content Types:
        - 'code': GitHub repos, code snippets, gists, Stack Overflow code examples
        - 'articles': Blog posts, tutorials, documentation, technical articles
        - 'both': Mix of code and written content (default)
    
        Time Ranges:
        - 'all': Search all available content (default, recommended for best results)
        - 'year', 'month', 'week', 'day': Filter to recent content only
    
        Examples:
        - search_examples("FastAPI dependency injection examples", content_type="code")
        - search_examples("React hooks tutorial", content_type="articles", time_range="year")
        - search_examples("Rust lifetime examples", content_type="both")
        """
        start_time = time.time()
        success = False
        error_msg = None
        result = ""
    
        try:
            max_results = max(1, min(max_results, 10))
    
            # Build optimized search query based on content type
            enhanced_query = query
            if content_type == "code":
                # Prioritize code-heavy sources
                enhanced_query = f"{query} (site:github.com OR site:stackoverflow.com OR site:gist.github.com OR example OR snippet)"
            elif content_type == "articles":
                # Prioritize articles and tutorials
                enhanced_query = (
                    f"{query} (tutorial OR guide OR article OR blog OR how to OR documentation)"
                )
            else:  # both
                enhanced_query = f"{query} (example OR tutorial OR guide)"
    
            # Use 'it' category for better tech content
            hits = await searcher.search(
                enhanced_query,
                category="it",  # IT/tech category for better results
                max_results=max_results,
                time_range=time_range if time_range != "all" else None,
            )
    
            if not hits:
                result = (
                    f"No examples found for '{query}' in the {time_range if time_range != 'all' else 'all time'} range.\n\n"
                    "Try:\n"
                    "- Broader search terms\n"
                    "- Different time range\n"
                    "- Removing version numbers or very specific constraints\n\n"
                    "Note: Results depend on your SearXNG instance configuration. If you're only seeing MDN docs,\n"
                    "your SearXNG may need additional search engines enabled (GitHub, Stack Overflow, dev.to, etc.)."
                )
            else:
                # Format results with additional context
                lines = [
                    f"Code Examples & Articles for: {query}",
                    f"Time Range: {time_range.title() if time_range != 'all' else 'All time'} | Content Type: {content_type.title()}",
                    "─" * 50,
                    "",
                ]
    
                for idx, hit in enumerate(hits, 1):
                    # Add source indicator
                    source = ""
                    if "github.com" in hit.url:
                        source = "[GitHub] "
                    elif "stackoverflow.com" in hit.url:
                        source = "[Stack Overflow] "
                    elif "medium.com" in hit.url or "dev.to" in hit.url:
                        source = "[Article] "
    
                    snippet = f"\n   {hit.snippet}" if hit.snippet else ""
                    lines.append(f"{idx}. {source}{hit.title}")
                    lines.append(f"   {hit.url}{snippet}")
                    lines.append("")
    
                result_text = "\n".join(lines)
    
                # Add note if results seem limited (all from same domain)
                domains = set()
                for hit in hits:
                    if "://" in hit.url:
                        domain = hit.url.split("://")[1].split("/")[0]
                        domains.add(domain)
    
                if len(domains) == 1 and len(hits) > 2:
                    result_text += (
                        "\n\n──────────────────────────────────────────────────\n"
                        "ℹ️ Note: All results are from the same source. Your SearXNG instance may need\n"
                        "   additional search engines configured (GitHub, Stack Overflow, dev.to, Medium)\n"
                        "   to get diverse code examples and tutorials."
                    )
    
                result = clamp_text(result_text, MAX_RESPONSE_CHARS)
    
            success = True
        except Exception as exc:  # noqa: BLE001
            error_msg = str(exc)
            result = f"Search failed for '{query}': {exc}"
        finally:
            # Track usage
            response_time = (time.time() - start_time) * 1000
            tracker.track_usage(
                tool_name="search_examples",
                reasoning=reasoning,
                parameters={
                    "query": query,
                    "content_type": content_type,
                    "time_range": time_range,
                    "max_results": max_results,
                },
                response_time_ms=response_time,
                success=success,
                error_message=error_msg,
                response_size=len(result.encode("utf-8")),
            )
    
        return result
  • Input schema defined via Annotated types for the tool parameters: query, reasoning, content_type, time_range, max_results.
    query: Annotated[
        str,
        "What you're looking for (e.g., 'Python async await examples', 'React hooks tutorial', 'Rust error handling patterns')",
    ],
    reasoning: Annotated[str, "Why you're searching for examples (required for analytics)"],
    content_type: Annotated[
        Literal["code", "articles", "both"],
        "Type of content to find: 'code' for code examples, 'articles' for tutorials/blogs, 'both' for mixed results",
    ] = "both",
    time_range: Annotated[
        Literal["day", "week", "month", "year", "all"],
        "How recent the content should be (use 'all' for best results, filter down if too many results)",
    ] = "all",
    max_results: Annotated[int, "How many results to return (1-10)"] = DEFAULT_MAX_RESULTS,
  • SearxSearcher.search method called by search_examples tool to perform the actual SearXNG search.
    async def search(
        self,
        query: str,
        *,
        category: str = DEFAULT_CATEGORY,
        max_results: int = DEFAULT_MAX_RESULTS,
        time_range: str | None = None,
    ) -> list[SearchHit]:
        """Return up to *max_results* hits for *query* within *category*.
    
        Args:
            query: Search query string
            category: SearXNG category (general, it, etc.)
            max_results: Maximum number of results to return
            time_range: Optional time filter (day, week, month, year)
        """
    
        limit = max(1, min(max_results, MAX_SEARCH_RESULTS))
        params = {
            "q": query,
            "categories": category,
            "format": "json",
            "pageno": 1,
        }
    
        # Add time range filter if specified
        if time_range:
            params["time_range"] = time_range
    
        async with httpx.AsyncClient(timeout=self.timeout, headers=self._headers) as client:
            response = await client.get(self.base_url, params=params)
            response.raise_for_status()
            payload = response.json()
    
        hits: list[SearchHit] = []
        for item in payload.get("results", [])[:limit]:
            title = (
                item.get("title") or item.get("pretty_url") or item.get("url") or "Untitled"
            ).strip()
            url = item.get("url") or ""
            snippet = (item.get("content") or item.get("snippet") or "").strip()
            snippet = clamp_text(snippet, MAX_SNIPPET_CHARS, suffix="…") if snippet else ""
            hits.append(SearchHit(title=title, url=url, snippet=snippet))
    
        return hits
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It discloses that the tool is 'optimized for finding practical examples and learning resources' and mentions time range filtering, which adds useful behavioral context. However, it doesn't cover critical aspects like rate limits, authentication needs, pagination behavior, or what happens with invalid queries. For a search tool with no annotations, this leaves gaps in transparency.

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 well-structured and appropriately sized. It starts with a clear purpose, provides usage context, lists content types and time ranges with explanations, and includes practical examples. Every sentence adds value without redundancy, and the information is front-loaded for quick understanding.

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 tool's moderate complexity (5 parameters, no annotations, but with an output schema), the description is largely complete. It covers purpose, usage, and parameter semantics thoroughly. However, it lacks details on behavioral aspects like error handling or performance, and since an output schema exists, it doesn't need to explain return values. For a search tool, this is good but not exhaustive.

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 schema description coverage is 0%, so the description must compensate fully. It does so effectively by explaining all parameters: 'query' is implied through examples, 'content_type' is detailed with options and meanings (code, articles, both), 'time_range' is explained with options and a recommendation, and 'max_results' is shown in examples. The 'reasoning' parameter is not mentioned, but the description adds significant value beyond the bare schema.

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 searches for 'code examples, tutorials, and technical articles' and is 'optimized for finding practical examples and learning resources.' It specifies the resource types (code, articles, both) and the verb 'search,' making the purpose evident. However, it doesn't explicitly differentiate from sibling tools like 'web_search' or 'package_search,' which might also involve searching for technical content.

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 provides clear context on when to use this tool: 'for learning new APIs, finding usage patterns, or discovering how others solve specific technical problems.' It includes examples that illustrate typical use cases. However, it lacks explicit guidance on when not to use it or alternatives among sibling tools (e.g., vs. 'web_search' for general searches or 'api_docs' for official documentation), which would be needed for a perfect score.

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/elad12390/web-research-assistant'

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