Skip to main content
Glama

hypertool-mcp

FileServerConfigGroupRepository.tsโ€ข4.9 kB
/** * File-based implementation of ServerConfigGroup repository * Stores groups in a simple JSON file */ import { promises as fs } from "fs"; import * as path from "path"; import { v4 as uuidv4 } from "uuid"; import { ServerConfigGroup, IServerConfigGroupRepository, ServerConfigRecord, IServerConfigRecordRepository, } from "../interfaces.js"; import { createChildLogger } from "../../utils/logging.js"; import { getHomeDir } from "../../utils/paths.js"; const logger = createChildLogger({ module: "FileServerConfigGroupRepository", }); interface GroupsFileContent { version: string; groups: ServerConfigGroup[]; } /** * File-based server configuration group repository */ export class FileServerConfigGroupRepository implements IServerConfigGroupRepository { private groupsFilePath: string; private serverRepository: IServerConfigRecordRepository; constructor( serverRepository: IServerConfigRecordRepository, basePath?: string ) { const baseDir = basePath || path.join(getHomeDir(), ".toolprint/hypertool-mcp"); this.groupsFilePath = path.join(baseDir, "groups.json"); this.serverRepository = serverRepository; } /** * Initialize the repository (ensure file exists) */ async init(): Promise<void> { const dir = path.dirname(this.groupsFilePath); await fs.mkdir(dir, { recursive: true }); // Create file if it doesn't exist try { await fs.access(this.groupsFilePath); } catch { await this.saveGroups([]); } } /** * Load groups from file */ private async loadGroups(): Promise<ServerConfigGroup[]> { try { const content = await fs.readFile(this.groupsFilePath, "utf-8"); const data: GroupsFileContent = JSON.parse(content); return data.groups || []; } catch (error) { if ((error as any).code === "ENOENT") { return []; } logger.error("Failed to load groups:", error); throw error; } } /** * Save groups to file */ private async saveGroups(groups: ServerConfigGroup[]): Promise<void> { const content: GroupsFileContent = { version: "1.0.0", groups, }; await fs.writeFile( this.groupsFilePath, JSON.stringify(content, null, 2), "utf-8" ); } /** * Add a new group */ async add(group: Omit<ServerConfigGroup, "id">): Promise<ServerConfigGroup> { const groups = await this.loadGroups(); // Check if name already exists if (groups.some((g) => g.name === group.name)) { throw new Error(`Group with name "${group.name}" already exists`); } // Create new group with ID const newGroup: ServerConfigGroup = { ...group, id: uuidv4(), }; // Add to groups and save groups.push(newGroup); await this.saveGroups(groups); return newGroup; } /** * Update an existing group */ async update(group: ServerConfigGroup): Promise<ServerConfigGroup | null> { const groups = await this.loadGroups(); const index = groups.findIndex((g) => g.id === group.id); if (index === -1) { return null; } // Check for name conflicts (excluding current group) const nameConflict = groups.some( (g) => g.name === group.name && g.id !== group.id ); if (nameConflict) { throw new Error(`Group with name "${group.name}" already exists`); } // Update and save groups[index] = group; await this.saveGroups(groups); return group; } /** * Delete a group */ async delete(id: string): Promise<boolean> { const groups = await this.loadGroups(); const initialLength = groups.length; const filteredGroups = groups.filter((g) => g.id !== id); if (filteredGroups.length === initialLength) { return false; // Group not found } await this.saveGroups(filteredGroups); return true; } /** * Find a group by ID */ async findById(id: string): Promise<ServerConfigGroup | null> { const groups = await this.loadGroups(); return groups.find((g) => g.id === id) || null; } /** * Find a group by name */ async findByName(name: string): Promise<ServerConfigGroup | null> { const groups = await this.loadGroups(); return groups.find((g) => g.name === name) || null; } /** * Find all groups */ async findAll(): Promise<ServerConfigGroup[]> { return this.loadGroups(); } /** * Find all servers in a group */ async findServersInGroup(groupId: string): Promise<ServerConfigRecord[]> { const group = await this.findById(groupId); if (!group) { return []; } // Fetch all servers const allServers = await this.serverRepository.findAll(); // Filter servers that are in the group const groupServers = allServers.filter((server) => group.serverIds.includes(server.id) ); return groupServers; } }

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/toolprint/hypertool-mcp'

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