Skip to main content
Glama

get_stylus_context

Retrieve Stylus documentation and code examples from the knowledge base to support development with version-aware search capabilities.

Instructions

Retrieve relevant Stylus documentation and code examples from the knowledge base. Use this to find examples, patterns, and documentation for Stylus development. Supports version-aware search to prioritize results matching your SDK version.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query (concept, function name, or code pattern). Include specific technical terms for best results.
n_resultsNoNumber of results to return (1-20, default: 5)
content_typeNoFilter by content type (default: all)all
rerankNoWhether to apply advanced reranking with BM25 and metadata boosting (default: true, recommended)
target_versionNoTarget stylus-sdk version to prioritize results for. Results matching this version are boosted.

Implementation Reference

  • The logic that processes and ranks search results (with optional reranking) into the final context object for the get_stylus_context tool.
    def _process_results(
        self,
        raw_results: dict,
        n_results: int,
        query: str,
        rerank: bool,
    ) -> list[dict]:
        """
        Process raw ChromaDB results into context objects.
    
        Args:
            raw_results: Raw query results from ChromaDB.
            n_results: Number of results to return.
            query: Original query (for reranking).
            rerank: Whether to apply reranking.
    
        Returns:
            List of context dictionaries.
        """
        # Check if results are empty
        if not raw_results:
            return []
    
        # ChromaDB returns results as: {"ids": [[id1, id2, ...]], ...}
        # Check if we have any results
        if not raw_results.get("ids") or len(raw_results["ids"]) == 0:
            return []
    
        # Check if the first (and only) result list is empty
        if len(raw_results["ids"][0]) == 0:
            return []
    
        ids = raw_results["ids"][0]  # noqa: F841
        documents = raw_results["documents"][0]
        metadatas = raw_results["metadatas"][0]
        distances = raw_results["distances"][0]  # noqa: F841
    
        # Check if hybrid search scores are available
        hybrid_scores = raw_results.get("scores", [[]])[0] if "scores" in raw_results else None
    
        # Apply reranking if enabled (cross-encoder + MMR)
        if rerank and self.reranker and len(documents) > 0:
            reranked = self.reranker.rerank(
                query=query,
                documents=documents,
                embeddings=None,  # Computed once if needed, then reused in MMR
                query_embedding=None,  # Computed once if needed, then reused in MMR
                top_k=n_results,
            )
    
            # Build contexts from reranked results
            contexts = []
            for item in reranked:
                # Get original index from reranked result
                orig_idx = item.get("original_index", item.get("index", 0))
    
                # Ensure index is within bounds
                if orig_idx >= len(documents):
                    continue
    
                metadata = metadatas[orig_idx] if orig_idx < len(metadatas) else {}
    
                # Prefer the hybrid combined score (cross-encoder + MMR) when available.
                ce_score = item.get("cross_encoder_score", item.get("relevance_score", 0.5))
                # NVIDIA reranker returns unbounded logits; map to [0, 1] with sigmoid.
                relevance = 1.0 / (1.0 + math.exp(-float(ce_score)))
    
                contexts.append(
                    self._build_context(
                        content=documents[orig_idx],
                        metadata=metadata,
                        distance=distances[orig_idx] if orig_idx < len(distances) else 1.0,
                        relevance_score=relevance,
                    )
                )
    
            return contexts
    
        # Without reranking, process in score/distance order
        contexts = []
        for i in range(min(n_results, len(documents))):
            metadata = metadatas[i] if i < len(metadatas) else {}
    
            # Use hybrid scores if available, otherwise convert distance to relevance
            if hybrid_scores and i < len(hybrid_scores):
                # Hybrid scores are already normalized and higher is better
                relevance = hybrid_scores[i]
            else:
                # Convert distance to relevance score (cosine distance)
                # Distance of 0 = perfect match = 1.0 relevance
                # Distance of 2 = opposite = 0.0 relevance
                relevance = max(0.0, 1.0 - (distances[i] / 2.0))
    
            contexts.append(
                self._build_context(
                    content=documents[i],
                    metadata=metadata,
                    distance=distances[i],
                    relevance_score=relevance,
                )
            )
    
        return contexts
  • The main 'execute' method of the GetStylusContextTool class which performs the hybrid search and retrieval.
    def execute(
        self,
        query: str,
        n_results: int = 5,
        content_type: str = "all",
        rerank: bool = True,
        category_boosts: Optional[dict[str, float]] = None,
        target_version: Optional[str] = None,
        **kwargs,
    ) -> dict:
        """
        Retrieve relevant context from the knowledge base.
    
        Args:
            query: Search query string.
            n_results: Number of results to return (1-20).
            content_type: Filter by type: "all", "docs", or "code".
            rerank: Whether to rerank results.
            category_boosts: Optional dict mapping category names to boost multipliers.
                           If None, uses default Stylus boosts. Pass {} to disable boosting.
                           Example: {"stylus": 1.3, "arbitrum_sdk": 1.5}
            target_version: Target stylus-sdk version to prioritize results for.
                          Results matching this version are boosted, deprecated versions penalized.
    
        Returns:
            Dict with contexts, total_results, and query.
        """
        # Validate input
        if not query or not query.strip():
            return {"error": "Query is required and cannot be empty"}
    
        query = query.strip()
        n_results = max(1, min(20, n_results))
    
        try:
            # Check if collection has data
            collection_count = self.vectordb.collection.count()
            collection_name = self.vectordb.collection_name
            persist_dir = str(self.vectordb.persist_directory)
            persist_dir_abs = str(self.vectordb.persist_directory.resolve())
    
            # Check if persist directory exists
            persist_dir_exists = self.vectordb.persist_directory.exists()
            cwd = str(Path.cwd())
    
            if collection_count == 0:
                return {
                    "error": (
                        "Collection is empty. Please ingest data first using the ingestion script."
                    ),
                    "contexts": [],
                    "total_results": 0,
                    "query": query,
                    "collection_count": 0,
                    "collection_name": collection_name,
                    "persist_directory": persist_dir,
                    "persist_directory_absolute": persist_dir_abs,
                    "persist_directory_exists": persist_dir_exists,
                    "current_working_directory": cwd,
                    "diagnostic": (
                        "If you just ingested data, you may"
                        " need to restart the MCP server to"
                        " pick up the new collection."
                    ),
                }
        except Exception as e:
            return {"error": f"Retrieval failed: {str(e)}"}
    
        # Build metadata filter
        where_filter = None
        if content_type == "docs":
            where_filter = {"type": {"$eq": "documentation"}}
        elif content_type == "code":
            where_filter = {"type": {"$eq": "code"}}
    
        # Configure category boosts
        category_boosts = self._get_category_boosts(category_boosts)
    
        try:
            # Fetch more results for reranking
            fetch_count = n_results * 3 if rerank and self.use_reranking else n_results
    
            # Query vector database with enhanced hybrid search
            if self.use_reranking and rerank:
                # Use hybrid search with BM25 + metadata boosting + version scoring
                raw_results = self.vectordb.hybrid_search(
                    query_text=query,
                    n_results=fetch_count,
                    where=where_filter,
                    alpha=0.5,  # Balanced vector + BM25
                    category_boosts=category_boosts,
                    use_bm25=True,
                    target_version=target_version,
                )
            else:
                # Use standard vector search
                raw_results = self.vectordb.query(
                    query_text=query,
                    n_results=fetch_count,
                    where=where_filter,
                )
    
            # Process results
            contexts = self._process_results(raw_results, n_results, query, rerank)
    
            return {
                "contexts": contexts,
                "total_results": len(contexts),
                "query": query,
            }
    
        except Exception as e:
            return {"error": f"Retrieval failed: {str(e)}"}
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 adds useful context about version-aware search and prioritization of results, but does not cover aspects like rate limits, authentication needs, error handling, or the format of returned results. This leaves gaps for an agent to understand operational constraints.

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 front-loaded with the core purpose in the first sentence, followed by additional context in a second sentence. Every sentence adds value without redundancy, making it efficient and well-structured for quick understanding.

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

Completeness3/5

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

Given the tool's complexity (5 parameters, no annotations, no output schema), the description is adequate but incomplete. It covers the purpose and some behavioral context, but lacks details on output format, error cases, or performance characteristics, which could hinder an agent's ability to use it effectively without trial and error.

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?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description implies search functionality and version prioritization, but does not add specific meaning beyond what the schema provides, such as explaining how 'target_version' interacts with 'query' or detailing the 'rerank' algorithm. Baseline 3 is appropriate given high schema coverage.

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 the verb ('Retrieve') and resource ('Stylus documentation and code examples from the knowledge base'), specifying it's for finding examples, patterns, and documentation for Stylus development. It distinguishes from sibling tools like 'ask_stylus' or 'generate_stylus_code' by focusing on retrieval rather than generation or questioning.

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 for when to use this tool ('to find examples, patterns, and documentation for Stylus development') and mentions version-aware search. However, it does not explicitly state when not to use it or name specific alternatives among sibling tools, such as 'ask_stylus' for queries or 'generate_stylus_code' for code generation.

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/Quantum3-Labs/ARBuilder'

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