Skip to main content
Glama

get_tree_validation_report

Validate tree structure to identify antipatterns and calculate quality score for research organization hierarchies.

Instructions

Get validation report for all splits in a tree. Identifies antipatterns and provides an overall quality score. Use this after building a tree to check for common failure modes.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
treeIdYesID of the tree to validate

Implementation Reference

  • Core handler function that executes the tool logic: generates a comprehensive validation report for all splits in a given tree by calling validateSplitQuality on each split tile and aggregating scores and issues.
    getTreeValidationReport(treeId: string): {
      treeId: string;
      splitReports: SplitQualityReport[];
      overallScore: number;
      summary: string;
    } {
      const tree = this.trees.get(treeId);
      if (!tree) {
        throw new Error(`Tree ${treeId} not found`);
      }
    
      const allTiles = this.getTilesInTree(tree.rootTileId);
      const tilesWithSplits = allTiles.filter((t) => t.childrenIds.length > 0);
    
      const splitReports = tilesWithSplits.map((tile) => this.validateSplitQuality(tile.id));
    
      const overallScore =
        splitReports.length > 0
          ? Math.round(splitReports.reduce((sum, r) => sum + r.score, 0) / splitReports.length)
          : 100;
    
      const totalIssues = splitReports.reduce((sum, r) => sum + r.issues.length, 0);
      const totalErrors = splitReports.reduce(
        (sum, r) => sum + r.issues.filter((i) => i.severity === "error").length,
        0
      );
    
      let summary = `Tree has ${splitReports.length} splits with ${totalIssues} total issues (${totalErrors} errors). Overall score: ${overallScore}/100.`;
    
      if (overallScore >= 80) {
        summary += " Tree structure is good quality.";
      } else if (overallScore >= 60) {
        summary += " Some improvements recommended.";
      } else {
        summary += " Significant issues detected - review recommendations.";
      }
    
      return {
        treeId,
        splitReports,
        overallScore,
        summary,
      };
    }
  • Input schema definition for the tool, specifying the required 'treeId' parameter.
      name: "get_tree_validation_report",
      description: "Get validation report for all splits in a tree. Identifies antipatterns and provides an overall quality score. Use this after building a tree to check for common failure modes.",
      inputSchema: {
        type: "object",
        properties: {
          treeId: {
            type: "string",
            description: "ID of the tree to validate",
          },
        },
        required: ["treeId"],
      },
    },
  • src/index.ts:654-664 (registration)
    Tool handler registration in the MCP CallToolRequestSchema switch statement, delegating execution to treeManager.getTreeValidationReport.
    case "get_tree_validation_report": {
      const result = treeManager.getTreeValidationReport(args.treeId as string);
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(result, null, 2),
          },
        ],
      };
    }
  • Key helper method called by the handler to validate individual split quality, detecting antipatterns such as vague language, catch-all buckets, mixed dimensions, retroactive splitting, and incomplete coverage.
    validateSplitQuality(tileId: string): SplitQualityReport {
      const tile = this.tiles.get(tileId);
      if (!tile) {
        throw new Error(`Tile ${tileId} not found`);
      }
    
      const issues: ValidationIssue[] = [];
      const recommendations: string[] = [];
    
      // Get children for analysis
      const children = tile.childrenIds.map((id) => this.tiles.get(id)).filter((t) => t !== undefined) as Tile[];
    
      if (children.length === 0) {
        return {
          tileId: tile.id,
          tileTitle: tile.title,
          issues: [],
          score: 100,
          recommendations: ["Tile has no children - nothing to validate"],
        };
      }
    
      // 1. Check for vague language
      const vagueIssues = this.detectVagueLanguage(tile, children);
      issues.push(...vagueIssues);
    
      // 2. Check for catch-all buckets
      const catchAllIssues = this.detectCatchAllBuckets(tile, children);
      issues.push(...catchAllIssues);
    
      // 3. Check for mixed dimensions
      const mixedDimIssues = this.detectMixedDimensions(tile, children);
      issues.push(...mixedDimIssues);
    
      // 4. Check for retroactive splitting
      const retroactiveIssues = this.detectRetroactiveSplitting(tile, children);
      issues.push(...retroactiveIssues);
    
      // 5. Check for incomplete coverage
      if (!tile.isMECE) {
        issues.push({
          type: "incomplete_coverage",
          severity: "warning",
          message: "Split has not been validated for MECE completeness",
          tileId: tile.id,
          suggestion: "Use mark_mece to validate that the split is Mutually Exclusive and Collectively Exhaustive",
        });
      }
    
      // Generate recommendations
      if (issues.length === 0) {
        recommendations.push("Split appears well-structured");
        if (tile.isMECE) {
          recommendations.push("MECE validation completed");
        }
      } else {
        const errorCount = issues.filter((i) => i.severity === "error").length;
        const warningCount = issues.filter((i) => i.severity === "warning").length;
    
        if (errorCount > 0) {
          recommendations.push(`Address ${errorCount} critical issue(s) before proceeding`);
        }
        if (warningCount > 0) {
          recommendations.push(`Review ${warningCount} warning(s) to improve split quality`);
        }
    
        // Specific recommendations
        if (issues.some((i) => i.type === "vague_language")) {
          recommendations.push("Replace vague terms with measurable physical properties or precise definitions");
        }
        if (issues.some((i) => i.type === "catch_all_bucket")) {
          recommendations.push("Replace catch-all categories with specific, splittable subsets");
        }
        if (issues.some((i) => i.type === "mixed_dimensions")) {
          recommendations.push("Use a single consistent dimension/attribute for this split level");
        }
        if (issues.some((i) => i.type === "retroactive_splitting")) {
          recommendations.push("Consider physics/math-based splits instead of known solution types");
        }
      }
    
      // Calculate score (100 - 20 per error - 10 per warning)
      const errorPenalty = issues.filter((i) => i.severity === "error").length * 20;
      const warningPenalty = issues.filter((i) => i.severity === "warning").length * 10;
      const score = Math.max(0, 100 - errorPenalty - warningPenalty);
    
      return {
        tileId: tile.id,
        tileTitle: tile.title,
        issues,
        score,
        recommendations,
      };
    }

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/k-chrispens/tiling-trees-mcp'

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