Skip to main content
Glama
rule.ops.ts5.03 kB
import { KuzuDBClient } from '../../db/kuzu'; import { ToolHandlerContext } from '../../mcp/types/sdk-custom'; import { RepositoryRepository, RuleRepository } from '../../repositories'; import { Rule, RuleInput } from '../../types'; // Simple context type to avoid SDK import issues type McpContext = { logger: any; }; // Helper function to parse timestamps from BaseEntity (Date | undefined) to string | null // This can be shared or made a utility if used in multiple ops files. function parseBaseEntityTimestamp(timestamp: Date | undefined): string | null { if (timestamp instanceof Date) { return timestamp.toISOString(); } return null; } /** * Creates or updates a rule in a repository. * * @param mcpContext - The MCP server request context. * @param repositoryName - The name of the repository. * @param branch - The branch of the repository. * @param ruleData - Data for the rule to be upserted. * @param repositoryRepo - Instance of RepositoryRepository. * @param ruleRepo - Instance of RuleRepository. * @returns A Promise resolving to the upserted Rule object or null if repository not found. */ export async function upsertRuleOp( mcpContext: ToolHandlerContext, repositoryName: string, branch: string, ruleData: RuleInput, repositoryRepo: RepositoryRepository, ruleRepo: RuleRepository, ): Promise<Rule | null> { const logger = mcpContext.logger; const repository = await repositoryRepo.findByName(repositoryName, branch); if (!repository || !repository.id) { logger.warn(`[rule.ops.upsertRuleOp] Repository not found: ${repositoryName}/${branch}`); return null; } const ruleToUpsert: Rule = { id: ruleData.id, repository: repository.id, branch: branch, name: ruleData.name, created: ruleData.created, triggers: ruleData.triggers || null, content: ruleData.content || null, status: ruleData.status || 'active', created_at: new Date(), updated_at: new Date(), }; logger.debug( `[rule.ops.upsertRuleOp] Calling ruleRepo.upsertRule for ${ruleToUpsert.id} in repo ${repository.id}`, { ruleToUpsert }, ); const upsertedRule = await ruleRepo.upsertRule(ruleToUpsert); if (!upsertedRule) { logger.warn( `[rule.ops.upsertRuleOp] ruleRepo.upsertRule returned null for ${ruleData.id} in ${repositoryName}:${branch}`, ); return null; } logger.info( `[rule.ops.upsertRuleOp] Rule ${upsertedRule.id} upserted successfully in ${repositoryName}:${branch}.`, ); return normalizeRule(upsertedRule, repositoryName, branch); } /** * Retrieves all active rules for a repository and branch. * * @param mcpContext - The MCP server request context. * @param repositoryName - The name of the repository. * @param branch - The branch of the repository. * @param repositoryRepo - Instance of RepositoryRepository. * @param ruleRepo - Instance of RuleRepository. * @returns A Promise resolving to an array of active Rule objects. */ export async function getActiveRulesOp( mcpContext: ToolHandlerContext, repositoryName: string, branch: string, repositoryRepo: RepositoryRepository, ruleRepo: RuleRepository, ): Promise<Rule[]> { const logger = mcpContext.logger; logger.debug(`[rule.ops.getActiveRulesOp] For ${repositoryName}:${branch}`); const repository = await repositoryRepo.findByName(repositoryName, branch); if (!repository || !repository.id) { logger.warn(`[rule.ops.getActiveRulesOp] Repository not found: ${repositoryName}/${branch}`); return []; } const activeRules = await ruleRepo.getActiveRules(repository.id, branch); logger.debug( `[rule.ops.getActiveRulesOp] Found ${activeRules.length} active rules for ${repositoryName}:${branch}.`, ); return activeRules.map((rule: Rule) => normalizeRule(rule, repositoryName, branch)); } /** * Helper function to ensure rule has repository and branch fields populated */ function normalizeRule(rule: Rule, repositoryName: string, branch: string): Rule { return { ...rule, repository: repositoryName, branch: branch, }; } export async function deleteRuleOp( mcpContext: ToolHandlerContext, kuzuClient: KuzuDBClient, repositoryRepo: RepositoryRepository, repositoryName: string, branch: string, ruleId: string, ): Promise<boolean> { const logger = mcpContext.logger; const repository = await repositoryRepo.findByName(repositoryName, branch); if (!repository || !repository.id) { logger.warn(`[rule.ops.deleteRuleOp] Repository ${repositoryName}:${branch} not found.`); return false; } const graphUniqueId = `${repositoryName}:${branch}:${ruleId}`; const deleteQuery = ` MATCH (r:Rule {graph_unique_id: $graphUniqueId}) DETACH DELETE r RETURN 1 as deletedCount `; const result = await kuzuClient.executeQuery(deleteQuery, { graphUniqueId }); const deletedCount = result[0]?.deletedCount || 0; logger.info(`[rule.ops.deleteRuleOp] Deleted ${deletedCount} rule(s) with ID ${ruleId}`); return deletedCount > 0; }

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