Skip to main content
Glama

analyzeGraph

Analyzes graph data from Heptabase whiteboards, calculating centrality, clustering, and density metrics, and exports results to a specified path.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
exportPathNo
metricsNo
whiteboardIdNo

Implementation Reference

  • Core handler function executing the analyzeGraph tool logic, fetching graph data, computing metrics (centrality, clustering, density), generating analysis text, and optionally exporting to file.
    export async function analyzeGraph(
      dataService: HeptabaseDataService,
      params: z.infer<typeof analyzeGraphSchema>
    ) {
      let analysis: any = {
        timestamp: new Date().toISOString(),
        metrics: {}
      };
    
      if (params.whiteboardId) {
        // Analyze specific whiteboard
        const data = await dataService.getWhiteboard(params.whiteboardId, {
          includeCards: true,
          includeConnections: true
        });
    
        analysis.whiteboard = data.whiteboard.name;
        analysis.nodes = data.cards?.length || 0;
        analysis.edges = data.connections?.length || 0;
      } else {
        // Analyze entire knowledge graph
        const whiteboards = await dataService.getWhiteboards();
        const cards = await dataService.getCards();
        const connections = await dataService.getConnections();
    
        analysis.whiteboards = whiteboards.length;
        analysis.nodes = cards.length;
        analysis.edges = connections.length;
      }
    
      // Calculate metrics if requested
      if (params.metrics?.includes('centrality')) {
        analysis.metrics.centrality = await calculateCentrality(dataService, params.whiteboardId);
      }
    
      if (params.metrics?.includes('clustering')) {
        analysis.metrics.clustering = await calculateClustering(dataService, params.whiteboardId);
      }
    
      if (params.metrics?.includes('density')) {
        analysis.metrics.density = analysis.edges / (analysis.nodes * (analysis.nodes - 1));
      }
    
      // Format response
      let text = 'Knowledge Graph Analysis\n\n';
      
      if (params.whiteboardId) {
        text += `Whiteboard: ${analysis.whiteboard}\n`;
      } else {
        text += `Total whiteboards: ${analysis.whiteboards}\n`;
      }
      
      text += `Total nodes: ${analysis.nodes}\n`;
      text += `Total edges: ${analysis.edges}\n`;
    
      if (analysis.metrics.centrality) {
        text += '\nCentrality:\n';
        text += 'Most central nodes:\n';
        const sorted = Object.entries(analysis.metrics.centrality)
          .sort(([, a]: any, [, b]: any) => b - a)
          .slice(0, 5);
        
        for (const [nodeId, score] of sorted) {
          text += `- ${nodeId}: ${score}\n`;
        }
      }
    
      if (analysis.metrics.clustering) {
        text += `\nClustering coefficient: ${analysis.metrics.clustering}\n`;
      }
    
      if (analysis.metrics.density) {
        text += `\nGraph density: ${analysis.metrics.density.toFixed(3)}\n`;
      }
    
      // Export if requested
      if (params.exportPath) {
        await fs.mkdir(path.dirname(params.exportPath), { recursive: true });
        await fs.writeFile(params.exportPath, JSON.stringify(analysis, null, 2), 'utf8');
        text += `\nAnalysis saved to ${params.exportPath}`;
      }
    
      return {
        content: [{
          type: 'text',
          text
        }]
      };
    }
  • Zod schema defining input parameters for the analyzeGraph tool: optional whiteboardId, metrics array, and exportPath.
    export const analyzeGraphSchema = z.object({
      whiteboardId: z.string().optional(),
      metrics: z.array(z.enum(['centrality', 'clustering', 'density'])).optional(),
      exportPath: z.string().optional()
    });
  • src/server.ts:702-708 (registration)
    Registers the analyzeGraph tool in the tools object with schema and wrapped handler.
    this.tools.analyzeGraph = {
      inputSchema: analyzeGraphSchema,
      handler: async (params) => {
        await this.ensureDataServiceInitialized();
        return analyzeGraph(this.dataService, params);
      }
    };
  • src/server.ts:710-712 (registration)
    Registers the analyzeGraph tool with the MCP server using the schema and handler.
    this.server.tool('analyzeGraph', analyzeGraphSchema.shape, async (params: z.infer<typeof analyzeGraphSchema>) => {
      return this.tools.analyzeGraph.handler(params);
    });
  • Helper function to calculate degree centrality for nodes in the graph.
    async function calculateCentrality(dataService: HeptabaseDataService, whiteboardId?: string): Promise<Record<string, number>> {
      const connections = whiteboardId 
        ? (await dataService.getWhiteboard(whiteboardId, { includeConnections: true })).connections || []
        : await dataService.getConnections();
    
      const centrality: Record<string, number> = {};
    
      // Calculate degree centrality
      for (const connection of connections) {
        centrality[connection.beginId] = (centrality[connection.beginId] || 0) + 1;
        centrality[connection.endId] = (centrality[connection.endId] || 0) + 1;
      }
    
      return centrality;
    }
Install Server

Other Tools

Related 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/LarryStanley/heptabse-mcp'

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