Skip to main content
Glama

dependency_health

Check dependency health across npm, Rust, Python, and Go by analyzing version freshness, deprecation, and CVEs.

Instructions

Dependency health — version freshness, deprecation, CVEs across npm/Rust/Python/Go

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Main handler function `executeDependencyHealth` — assesses dependency health by checking version freshness, deprecation, and known CVEs via live intelligence. Accepts params (include_dev, ecosystem_filter, sort_by, limit), computes health score (0-100), and returns DependencyHealthResult with stats and sorted dependency list.
    export async function executeDependencyHealth(
      _db: FourDADatabase,
      params: DependencyHealthParams,
      liveIntel: LiveIntelligence | null,
    ): Promise<DependencyHealthResult> {
      const start = Date.now();
    
      if (!liveIntel || !liveIntel.isInitialized()) {
        return {
          scannedAt: new Date().toISOString(),
          projectPath: process.cwd(),
          ecosystemsScanned: [],
          totalDeps: 0,
          outdatedCount: 0,
          deprecatedCount: 0,
          vulnerableCount: 0,
          healthScore: 0,
          dependencies: [],
          vulnerabilitySummary: null,
          summary: "Live intelligence not initialized. No project manifests detected.",
          scanDurationMs: Date.now() - start,
          cached: false,
        };
      }
    
      // Get resolved deps
      const includeDev = params.include_dev ?? false;
      let deps = liveIntel.getResolvedDeps();
      if (!includeDev) {
        deps = deps.filter((d) => !d.isDev);
      }
      if (params.ecosystem_filter) {
        deps = deps.filter((d) => d.ecosystem === params.ecosystem_filter);
      }
    
      const ecosystems = [...new Set(deps.map((d) => d.ecosystem))];
    
      // Fetch registry health for all deps
      const registryData = await liveIntel.fetchRegistryHealth(deps);
    
      // Merge vulnerability data
      const vulnResult = liveIntel.getVulnerabilities();
      const vulnMap = new Map<string, number>();
      if (vulnResult) {
        for (const v of vulnResult.vulnerabilities) {
          vulnMap.set(v.package, (vulnMap.get(v.package) || 0) + 1);
        }
      }
    
      // Compute stats
      let outdated = 0;
      let deprecated = 0;
      let vulnerable = 0;
    
      for (const dep of registryData) {
        if (dep.versionsBehind && dep.versionsBehind.label !== "up-to-date") outdated++;
        if (dep.deprecated) deprecated++;
        if (vulnMap.has(dep.name)) vulnerable++;
      }
    
      // Sort
      const sortBy = params.sort_by ?? "risk";
      const sorted = [...registryData].sort((a, b) => {
        if (sortBy === "name") return a.name.localeCompare(b.name);
        if (sortBy === "outdated") {
          const aD = a.versionsBehind ? a.versionsBehind.major * 100 + a.versionsBehind.minor * 10 + a.versionsBehind.patch : 0;
          const bD = b.versionsBehind ? b.versionsBehind.major * 100 + b.versionsBehind.minor * 10 + b.versionsBehind.patch : 0;
          return bD - aD;
        }
        // risk: vulnerable > deprecated > major outdated > minor > patch > current
        const riskScore = (dep: RegistryPackageInfo) => {
          let score = 0;
          if (vulnMap.has(dep.name)) score += 1000;
          if (dep.deprecated) score += 500;
          if (dep.versionsBehind) {
            score += dep.versionsBehind.major * 100 + dep.versionsBehind.minor * 10 + dep.versionsBehind.patch;
          }
          return score;
        };
        return riskScore(b) - riskScore(a);
      });
    
      const limit = params.limit ?? 50;
      const limited = sorted.slice(0, limit);
    
      // Health score: 100 = perfect, 0 = everything is on fire
      const total = registryData.length || 1;
      const vulnPenalty = Math.min(vulnerable * 15, 50);
      const deprecatedPenalty = Math.min(deprecated * 10, 30);
      const outdatedPenalty = Math.min(outdated * 2, 40);
      const healthScore = Math.max(0, 100 - vulnPenalty - deprecatedPenalty - outdatedPenalty);
    
      const vulnSummary = vulnResult ? {
        critical: vulnResult.bySeverity.critical,
        high: vulnResult.bySeverity.high,
        medium: vulnResult.bySeverity.medium,
        low: vulnResult.bySeverity.low,
      } : null;
    
      // Summary
      const parts: string[] = [];
      parts.push(`${total} dependenc${total !== 1 ? "ies" : "y"} scanned`);
      if (vulnerable > 0) parts.push(`${vulnerable} vulnerable`);
      if (deprecated > 0) parts.push(`${deprecated} deprecated`);
      if (outdated > 0) parts.push(`${outdated} outdated`);
      if (vulnerable === 0 && deprecated === 0 && outdated === 0) parts.push("all healthy");
    
      return {
        scannedAt: new Date().toISOString(),
        projectPath: process.cwd(),
        ecosystemsScanned: ecosystems,
        totalDeps: total,
        outdatedCount: outdated,
        deprecatedCount: deprecated,
        vulnerableCount: vulnerable,
        healthScore,
        dependencies: limited,
        vulnerabilitySummary: vulnSummary,
        summary: `Health: ${healthScore}/100. ${parts.join(", ")}.`,
        scanDurationMs: Date.now() - start,
        cached: false,
      };
    }
  • Input schema: `DependencyHealthParams` interface and `dependencyHealthTool` definition with inputSchema (include_dev boolean, ecosystem_filter enum, sort_by enum, limit number).
    export interface DependencyHealthParams {
      include_dev?: boolean;
      ecosystem_filter?: string;
      sort_by?: "risk" | "name" | "outdated";
      limit?: number;
    }
    
    export const dependencyHealthTool = {
      name: "dependency_health",
      description:
        "Assess health of project dependencies — version freshness, deprecation status, known CVEs. Auto-detects stack from lock files. Covers npm, Rust, Python, and Go.",
      inputSchema: {
        type: "object" as const,
        properties: {
          include_dev: {
            type: "boolean",
            description: "Include devDependencies. Default: false",
          },
          ecosystem_filter: {
            type: "string",
            enum: ["npm", "crates.io", "PyPI", "Go"],
            description: "Only show deps from this ecosystem. Default: all detected.",
          },
          sort_by: {
            type: "string",
            enum: ["risk", "name", "outdated"],
            description: "Sort order. 'risk' prioritizes vulnerable+deprecated+outdated. Default: risk",
          },
          limit: {
            type: "number",
            description: "Max dependencies to return. Default: 50",
          },
        },
      },
  • Output type: `DependencyHealthResult` interface containing scan metadata, health score, sorted dependencies array, vulnerability summary, and status info.
    export interface DependencyHealthResult {
      scannedAt: string;
      projectPath: string;
      ecosystemsScanned: string[];
      totalDeps: number;
      outdatedCount: number;
      deprecatedCount: number;
      vulnerableCount: number;
      healthScore: number;
      dependencies: RegistryPackageInfo[];
      vulnerabilitySummary: { critical: number; high: number; medium: number; low: number } | null;
      summary: string;
      scanDurationMs: number;
      cached: boolean;
    }
  • Dispatch registration mapping the tool name "dependency_health" to the executeDependencyHealth function (wrapped with getLiveIntelligence()).
    dependency_health: (db, params) => executeDependencyHealth(db, params, getLiveIntelligence()),
    upgrade_planner: (db, params) => executeUpgradePlanner(db, params, getLiveIntelligence()),
  • Schema registry entry for dependency_health with summary, schemaFile reference, category 'security', and tags.
    dependency_health: {
      summary: "Dependency health — version freshness, deprecation, CVEs across npm/Rust/Python/Go",
      schemaFile: "dependency-health.json",
      category: "security",
      tags: ["dependencies", "health", "outdated", "deprecated", "versions"],
      standalone: true,
    },
Behavior3/5

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

No annotations are provided; the description carries the full burden. It implies a read-only query of dependency health, but does not explicitly state it is non-destructive or read-only, nor does it disclose any side effects. Essential for agent safety, this is a minor gap.

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 a single line, front-loaded with the core function, and contains no redundant information. Every word adds value.

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 no parameters and no output schema, the description is sufficiently complete for a simple informational tool. It could be slightly more detailed on return format or depth, but it covers the essential purpose and scope.

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?

The input schema has zero parameters, so the description provides all meaning. It effectively defines the output scope: version freshness, deprecation, CVEs, and ecosystems covered. Baseline 4 is appropriate; no parameter info needed in description.

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 specifies what the tool does: provides dependency health information including version freshness, deprecation, and CVEs across multiple ecosystems (npm, Rust, Python, Go). It distinguishes itself from siblings like vulnerability_scan (narrower scope) and ecosystem_pulse (broader).

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 the tool is for assessing dependency health but does not explicitly state when to use it versus alternatives like vulnerability_scan for CVEs or upgrade_planner for upgrade paths. No explicit usage or exclusion guidelines provided.

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/runyourempire/4DA'

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