Skip to main content
Glama
base-graph-operations.ts5.71 kB
import { KuzuDBClient } from '../../../db/kuzu'; import { ToolHandlerContext } from '../../../mcp/types/sdk-custom'; import { RepositoryRepository } from '../../../repositories'; import { Decision, Rule } from '../../../types'; // Common types export interface GraphOperationParams { clientProjectRoot: string; repository: string; branch: string; } // Contextual History export interface GetItemContextualHistoryParams extends GraphOperationParams { itemId: string; itemType: 'Component' | 'Decision' | 'Rule'; } export interface ContextResult { id: string; name: string | null; summary: string | null; iso_date: string; created_at: string | null; updated_at: string | null; agent: string | null; issue: string | null; decision_ids: string[]; observation_ids: string[]; repository: string; branch: string; } // Governing Items export interface GetGoverningItemsParams extends GraphOperationParams { componentId: string; } export interface GoverningItemsResult { status: 'complete' | 'error'; decisions: Decision[]; rules: Rule[]; message: string; } // Related Items export interface GetRelatedItemsParams extends GraphOperationParams { startItemId: string; depth?: number; relationshipFilter?: string; targetNodeTypeFilter?: string; } export interface RelatedItem { id: string; name: string; type: string; distance: number; repository: string; branch: string; } export interface RelatedItemsResult { status: 'complete' | 'error'; relatedItems: RelatedItem[]; message: string; } // Algorithm common types export interface ProjectedGraphParams extends GraphOperationParams { projectedGraphName: string; nodeTableNames: string[]; relationshipTableNames: string[]; } // PageRank export interface PageRankParams extends ProjectedGraphParams { dampingFactor?: number; maxIterations?: number; } export interface PageRankResult { ranks: Array<{ nodeId: string; score: number; }>; error?: string; } // K-Core Decomposition export interface KCoreParams extends ProjectedGraphParams { k: number; } export interface KCoreResult { k: number; components: Array<{ nodeId: string; coreness: number; }>; error?: string; } // Community Detection export interface LouvainParams extends ProjectedGraphParams {} export interface LouvainResult { communities: Array<{ nodeId: string; communityId: number; }>; error?: string; } // Connected Components export interface ConnectedComponentsParams extends ProjectedGraphParams {} export interface ConnectedComponentsResult { components: Array<{ nodeId: string; componentId: number; }>; } // Shortest Path export interface ShortestPathParams extends ProjectedGraphParams { startNodeId: string; endNodeId: string; } export interface ShortestPathResult { type: string; pathFound: boolean; path: any[]; pathLength: number; startNodeId: string; endNodeId: string; projectedGraphName: string; error?: string; } /** * Base class for graph operations * Provides common utilities and type definitions for graph-based services */ export abstract class BaseGraphOperations { protected kuzuClient: KuzuDBClient; protected repositoryRepo?: RepositoryRepository; constructor(kuzuClient: KuzuDBClient, repositoryRepo?: RepositoryRepository) { this.kuzuClient = kuzuClient; this.repositoryRepo = repositoryRepo; } /** * Shared helper for timestamp parsing */ protected parseTimestamp(value: any): string | null { if (value instanceof Date) { return value.toISOString(); } if (typeof value === 'number') { // Kuzu often returns microseconds return new Date(value / 1000).toISOString(); } if (typeof value === 'string') { const d = new Date(value); if (!isNaN(d.getTime())) { return d.toISOString(); } } return null; } /** * Create repository ID from repository and branch */ protected createRepoId(repository: string, branch: string): string { return `${repository}:${branch}`; } /** * Create component graph ID from repository, branch, and component ID */ protected createComponentGraphId( repository: string, branch: string, componentId: string, ): string { return `${repository}:${branch}:${componentId}`; } /** * Validate repository exists if repository repo is available */ protected async validateRepository( mcpContext: ToolHandlerContext, repository: string, branch: string, ): Promise<boolean> { if (!this.repositoryRepo) { return true; // Skip validation if no repository repo available } const repoNode = await this.repositoryRepo.findByName(repository, branch); if (!repoNode) { mcpContext.logger.warn( `[graph.ops] Repository ${repository}:${branch} not found for operation.`, ); return false; } return true; } /** * Create operation logger with context */ protected createOperationLogger(mcpContext: ToolHandlerContext, operation: string, params: any) { // Create a simple logger object since mcpContext.logger might not have child method return { info: (message: string, meta?: any) => mcpContext.logger.info(`[graph.ops.${operation}] ${message}`, meta), debug: (message: string, meta?: any) => mcpContext.logger.debug(`[graph.ops.${operation}] ${message}`, meta), warn: (message: string, meta?: any) => mcpContext.logger.warn(`[graph.ops.${operation}] ${message}`, meta), error: (message: string, meta?: any) => mcpContext.logger.error(`[graph.ops.${operation}] ${message}`, meta), }; } }

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/Jakedismo/KuzuMem-MCP'

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