Skip to main content
Glama

analyzeGraph

Analyze network graphs within Heptabase by computing metrics like centrality, clustering, and density, and export results to a specified path. Ideal for data-driven insights from whiteboard structures.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
exportPathNo
metricsNo
whiteboardIdNo

Implementation Reference

  • Main handler function that analyzes the knowledge graph or specific whiteboard, computing metrics like node/edge counts, centrality, clustering coefficient, and density. Formats results as text and optionally exports to JSON.
    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 input schema defining optional parameters: whiteboardId, metrics array (centrality/clustering/density), 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-712 (registration)
    Registers the analyzeGraph tool both internally (this.tools.analyzeGraph) and with the MCP server (this.server.tool), wrapping the handler with data service initialization.
    this.tools.analyzeGraph = { inputSchema: analyzeGraphSchema, handler: async (params) => { await this.ensureDataServiceInitialized(); return analyzeGraph(this.dataService, params); } }; 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; }
  • Helper function to calculate the average clustering coefficient for the graph.
    async function calculateClustering(dataService: HeptabaseDataService, whiteboardId?: string): Promise<number> { const connections = whiteboardId ? (await dataService.getWhiteboard(whiteboardId, { includeConnections: true })).connections || [] : await dataService.getConnections(); // Simple clustering coefficient calculation // In a real implementation, this would be more sophisticated if (connections.length === 0) return 0; // Build adjacency list const adjacency: Record<string, Set<string>> = {}; for (const connection of connections) { if (!adjacency[connection.beginId]) adjacency[connection.beginId] = new Set(); if (!adjacency[connection.endId]) adjacency[connection.endId] = new Set(); adjacency[connection.beginId].add(connection.endId); adjacency[connection.endId].add(connection.beginId); } // Calculate local clustering coefficient for each node let totalClustering = 0; let nodeCount = 0; for (const [node, neighbors] of Object.entries(adjacency)) { if (neighbors.size < 2) continue; let triangles = 0; const neighborArray = Array.from(neighbors); for (let i = 0; i < neighborArray.length; i++) { for (let j = i + 1; j < neighborArray.length; j++) { if (adjacency[neighborArray[i]]?.has(neighborArray[j])) { triangles++; } } } const possibleTriangles = (neighbors.size * (neighbors.size - 1)) / 2; totalClustering += triangles / possibleTriangles; nodeCount++; } return nodeCount > 0 ? totalClustering / nodeCount : 0; }

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/heptabase-mcp'

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