Skip to main content
Glama
gemini2026

Documentation Search MCP Server

by gemini2026

scan_project_dependencies

Scan project dependencies in pyproject.toml or requirements.txt to identify security vulnerabilities and generate a comprehensive security report.

Instructions

Scans project dependencies from files like pyproject.toml or requirements.txt for vulnerabilities.

Args:
    project_path: The path to the project directory (defaults to current directory).

Returns:
    A comprehensive security report of all project dependencies.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_pathNo.

Implementation Reference

  • The main handler function for the 'scan_project_dependencies' tool, decorated with @mcp.tool() for registration. It orchestrates dependency parsing and vulnerability scanning.
    async def scan_project_dependencies(project_path: str = "."):
        """
        Scans project dependencies from files like pyproject.toml or requirements.txt for vulnerabilities.
    
        Args:
            project_path: The path to the project directory (defaults to current directory).
    
        Returns:
            A comprehensive security report of all project dependencies.
        """
        from .vulnerability_scanner import vulnerability_scanner
        from .project_scanner import find_and_parse_dependencies
    
        parsed_info = find_and_parse_dependencies(project_path)
    
        if not parsed_info:
            return {
                "error": "No dependency file found.",
                "message": "Supported files are pyproject.toml, requirements.txt, or package.json.",
            }
    
        filename, ecosystem, dependencies = parsed_info
    
        if not dependencies:
            return {
                "summary": {
                    "dependency_file": filename,
                    "ecosystem": ecosystem,
                    "total_dependencies": 0,
                    "vulnerable_count": 0,
                    "overall_project_risk": "None",
                    "message": "No dependencies found to scan.",
                },
                "vulnerable_packages": [],
            }
    
        total_deps = len(dependencies)
        logger.debug(
            "Found %s dependencies in %s. Scanning for vulnerabilities...",
            total_deps,
            filename,
        )
    
        scan_tasks = [
            vulnerability_scanner.scan_library(name, ecosystem)
            for name in dependencies.keys()
        ]
    
        results = await asyncio.gather(*scan_tasks, return_exceptions=True)
    
        vulnerable_deps = []
        for i, report_item in enumerate(results):
            dep_name = list(dependencies.keys())[i]
            if isinstance(report_item, Exception):
                # Could log this error
                continue
            else:
                report = report_item
                if report.vulnerabilities:  # type: ignore
                    vulnerable_deps.append(
                        {
                            "library": dep_name,
                            "version": dependencies[dep_name],
                            "vulnerability_count": report.total_vulnerabilities,  # type: ignore
                            "security_score": report.security_score,
                            "summary": (
                                report.recommendations[0]
                                if report.recommendations
                                else "Update to the latest version."
                            ),
                            "details": [
                                vuln.to_dict() for vuln in report.vulnerabilities[:3]
                            ],  # Top 3
                        }
                    )
    
        vulnerable_deps.sort(key=lambda x: x["security_score"])
    
        return {
            "summary": {
                "dependency_file": filename,
                "ecosystem": ecosystem,
                "total_dependencies": total_deps,
                "vulnerable_count": len(vulnerable_deps),
                "overall_project_risk": (
                    "High"
                    if any(d["security_score"] < 50 for d in vulnerable_deps)
                    else (
                        "Medium"
                        if any(d["security_score"] < 70 for d in vulnerable_deps)
                        else "Low"
                    )
                ),
            },
            "vulnerable_packages": vulnerable_deps,
        }
  • Helper function that locates and parses dependency files (pyproject.toml, requirements.txt, package.json) to extract package names and versions.
    def find_and_parse_dependencies(
        directory: str,
    ) -> Optional[Tuple[str, str, Dict[str, str]]]:
        """
        Finds and parses the most relevant dependency file in a directory.
    
        Returns:
            A tuple of (file_path, ecosystem, dependencies_dict) or None.
        """
        supported_files = {
            "pyproject.toml": ("PyPI", parse_pyproject_toml),
            "requirements.txt": ("PyPI", parse_requirements_txt),
            "package.json": ("npm", parse_package_json),
        }
    
        for filename, (ecosystem, parser_func) in supported_files.items():
            file_path = os.path.join(directory, filename)
            if os.path.exists(file_path):
                try:
                    with open(file_path, "r", encoding="utf-8") as f:
                        content = f.read()
                    dependencies = parser_func(content)
                    return filename, ecosystem, dependencies
                except Exception as e:
                    print(f"⚠️ Error parsing {filename}: {e}", file=sys.stderr)
                    # Continue to the next file type if parsing fails
                    continue
    
        return None
  • Core helper method in VulnerabilityScanner class that performs vulnerability scans on individual libraries using multiple sources (OSV, GitHub, Safety DB), called by the main handler for each dependency.
    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
Behavior3/5

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

With no annotations provided, the description carries full burden. It discloses the scanning behavior and output format ('comprehensive security report'), but lacks details on permissions needed, whether it modifies files, rate limits, or error handling. It adequately describes the core operation but misses important behavioral context for a security scanning tool.

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 efficiently structured with three focused sentences: purpose statement, parameter explanation, and return value description. Every sentence earns its place with no redundant information, and key information is front-loaded in the first sentence.

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?

For a security scanning tool with no annotations and no output schema, the description provides adequate basic information about what it does and what it returns. However, it lacks important context about the scanning methodology, report format details, error conditions, or integration with sibling tools, leaving gaps in understanding the tool's full behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage and only 1 parameter, the description adds significant value by explaining the parameter's purpose ('path to the project directory') and default behavior ('defaults to current directory'). This compensates well for the schema's lack of descriptions, though it doesn't elaborate on path format constraints.

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 specific action ('scans project dependencies') and resource ('from files like pyproject.toml or requirements.txt') with a distinct purpose ('for vulnerabilities'). It differentiates from siblings like 'scan_library_vulnerabilities' by focusing on project-level dependency scanning rather than library-specific analysis.

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

Usage Guidelines3/5

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

The description implies usage context by mentioning specific file types (pyproject.toml, requirements.txt), suggesting it's for Python projects. However, it doesn't explicitly state when to use this tool versus alternatives like 'snyk_scan_project' or 'scan_library_vulnerabilities', nor does it provide exclusion criteria or prerequisites.

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

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