Skip to main content
Glama
gemini2026

Documentation Search MCP Server

by gemini2026

suggest_secure_libraries

Find secure programming libraries by searching partial names and viewing security scores to make informed development decisions.

Instructions

Enhanced library suggestions that include security scores for informed decisions.

Args:
    partial_name: Partial library name to search for
    include_security_score: Whether to include security scores (slower but more informative)

Returns:
    Library suggestions with optional security information

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
partial_nameYes
include_security_scoreNo

Implementation Reference

  • The primary handler function for the 'suggest_secure_libraries' MCP tool. It fetches basic library suggestions and enriches the top 5 with security scores obtained from security_integration.get_security_summary, sorts by score, and returns enhanced suggestions.
    @mcp.tool()
    async def suggest_secure_libraries(
        partial_name: str, include_security_score: bool = True
    ):
        """
        Enhanced library suggestions that include security scores for informed decisions.
    
        Args:
            partial_name: Partial library name to search for
            include_security_score: Whether to include security scores (slower but more informative)
    
        Returns:
            Library suggestions with optional security information
        """
        await enforce_rate_limit("suggest_secure_libraries")
    
        # Get basic suggestions first
        basic_suggestions = await suggest_libraries(partial_name)
    
        if not include_security_score or not basic_suggestions:
            return {
                "suggestions": basic_suggestions,
                "partial_name": partial_name,
                "security_info_included": False,
            }
    
        # Add security information for top 5 suggestions
        from .vulnerability_scanner import security_integration
    
        enhanced_suggestions = []
        top_suggestions = basic_suggestions[:5]  # Limit to avoid too many API calls
    
        # Get security scores in parallel
        security_tasks = [
            security_integration.get_security_summary(lib, "PyPI")
            for lib in top_suggestions
        ]
    
        try:
            security_results = await asyncio.gather(*security_tasks, return_exceptions=True)
    
            for lib, sec_res_item in zip(top_suggestions, security_results):
                suggestion = {"library": lib}
    
                if isinstance(sec_res_item, Exception):
                    suggestion.update(
                        {
                            "security_score": None,
                            "security_status": "unknown",
                            "security_badge": "❓",
                        }
                    )
                else:
                    security_result = sec_res_item
                    score = security_result.get("security_score", 50)
                    suggestion.update(
                        {
                            "security_score": score,
                            "security_status": security_result.get("status", "unknown"),  # type: ignore
                            "security_badge": (
                                "🛡️"
                                if score >= 90
                                else "✅"
                                if score >= 70
                                else "⚠️"
                                if score >= 50
                                else "🚨"
                            ),
                            "vulnerabilities": security_result.get(
                                "total_vulnerabilities", 0
                            ),  # type: ignore
                        }
                    )
    
                enhanced_suggestions.append(suggestion)
    
            # Add remaining suggestions without security info
            for lib in basic_suggestions[5:]:
                enhanced_suggestions.append(
                    {
                        "library": lib,
                        "security_score": None,
                        "security_status": "not_scanned",
                        "note": "Use scan_library_vulnerabilities for security details",
                    }
                )
    
            # Sort by security score for enhanced suggestions
            enhanced_suggestions.sort(
                key=lambda x: x.get("security_score") or 0, reverse=True
            )
    
            return {
                "suggestions": enhanced_suggestions,
                "partial_name": partial_name,
                "security_info_included": True,
                "total_suggestions": len(enhanced_suggestions),
                "note": "Libraries with security scores are sorted by security rating",
            }
    
        except Exception as e:
            return {
                "suggestions": [{"library": lib} for lib in basic_suggestions],
                "partial_name": partial_name,
                "security_info_included": False,
                "error": f"Security enhancement failed: {str(e)}",
            }
  • The 'suggest_libraries' helper tool called by suggest_secure_libraries to get initial library name matches from the configured docs_urls dictionary.
    @mcp.tool()
    async def suggest_libraries(partial_name: str):
        """
        Suggest libraries based on partial input for auto-completion.
    
        Args:
            partial_name: Partial library name to search for (e.g. "lang" -> ["langchain"])
    
        Returns:
            List of matching library names
        """
        if not partial_name:
            return list(sorted(docs_urls.keys()))
    
        partial_lower = partial_name.lower()
        suggestions = []
    
        # Exact matches first
        for lib in docs_urls.keys():
            if lib.lower() == partial_lower:
                suggestions.append(lib)
    
        # Starts with matches
        for lib in docs_urls.keys():
            if lib.lower().startswith(partial_lower) and lib not in suggestions:
                suggestions.append(lib)
    
        # Contains matches
        for lib in docs_urls.keys():
            if partial_lower in lib.lower() and lib not in suggestions:
                suggestions.append(lib)
    
        return sorted(suggestions[:10])  # Limit to top 10 suggestions
  • The SecurityIntegration.get_security_summary method used by suggest_secure_libraries to obtain security scores and summaries for suggested libraries by scanning OSV, GitHub advisories, and Safety DB.
    async def get_security_summary(
        self, library_name: str, ecosystem: str = "PyPI"
    ) -> Dict[str, Any]:
        """Get concise security summary"""
        try:
            report = await self.scanner.scan_library(library_name, ecosystem)
            return {
                "library": library_name,
                "security_score": report.security_score,
                "total_vulnerabilities": report.total_vulnerabilities,
                "critical_vulnerabilities": report.critical_count,
                "status": "secure" if report.security_score >= 70 else "at_risk",
                "primary_recommendation": (
                    report.recommendations[0]
                    if report.recommendations
                    else "No specific recommendations"
                ),
            }
        except Exception as e:
            return {
                "library": library_name,
                "security_score": 50.0,
                "error": str(e),
                "status": "unknown",
            }
  • Core VulnerabilityScanner.scan_library method that performs parallel scans across OSV, GitHub advisories, and Safety DB (for PyPI), generates SecurityReport, and caches results. Called by get_security_summary.
    async def scan_library(
        self, library_name: str, ecosystem: str = "PyPI"
    ) -> SecurityReport:
        """
        Comprehensive vulnerability scan for a library
    
        Args:
            library_name: Name of the library (e.g., "fastapi", "react")
            ecosystem: Package ecosystem ("PyPI", "npm", "Maven", etc.)
    
        Returns:
            SecurityReport with vulnerability details
        """
        cache_key = f"{library_name}_{ecosystem}"
    
        # Check cache first
        if self._is_cached(cache_key):
            return self.cache[cache_key]["data"]
    
        vulnerabilities = []
    
        # Scan multiple sources in parallel
        scan_tasks = [
            self._scan_osv(library_name, ecosystem),
            self._scan_github_advisories(library_name, ecosystem),
            (
                self._scan_safety_db(library_name)
                if ecosystem.lower() == "pypi"
                else self._empty_scan()
            ),
        ]
    
        try:
            results = await asyncio.gather(*scan_tasks, return_exceptions=True)
    
            for result in results:
                if isinstance(result, list):
                    vulnerabilities.extend(result)
                elif isinstance(result, Exception):
                    print(f"Scan error: {result}", file=sys.stderr)
    
        except Exception as e:
            print(f"Vulnerability scan failed for {library_name}: {e}", file=sys.stderr)
    
        # Generate security report
        report = self._generate_security_report(
            library_name, ecosystem, vulnerabilities
        )
    
        # Cache the result
        self._cache_result(cache_key, report)
    
        return report

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/gemini2026/documentation-search-mcp'

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