Skip to main content
Glama

MCP Project Context Server

project-store.ts3.63 kB
import fs from "fs-extra"; import path from "path"; import { v4 as uuidv4 } from "uuid"; import { ProjectContext, SessionContext, ProjectContextSchema, SessionContextSchema, } from "../types/project-types.js"; export class ProjectStore { private dataDir: string; private projectsDir: string; private sessionsDir: string; constructor(dataDir = "./data") { this.dataDir = dataDir; this.projectsDir = path.join(dataDir, "projects"); this.sessionsDir = path.join(dataDir, "sessions"); this.ensureDirectories(); } private async ensureDirectories(): Promise<void> { await fs.ensureDir(this.projectsDir); await fs.ensureDir(this.sessionsDir); } async createProject( projectData: Omit< ProjectContext, "id" | "createdAt" | "updatedAt" | "lastAccessedAt" > ): Promise<ProjectContext> { const now = new Date().toISOString(); const project: ProjectContext = { ...projectData, id: uuidv4(), createdAt: now, updatedAt: now, lastAccessedAt: now, }; const validated = ProjectContextSchema.parse(project); const filePath = path.join(this.projectsDir, `${project.id}.json`); await fs.writeJson(filePath, validated, { spaces: 2 }); return validated; } async getProject(projectId: string): Promise<ProjectContext | null> { const filePath = path.join(this.projectsDir, `${projectId}.json`); if (!(await fs.pathExists(filePath))) { return null; } const data = await fs.readJson(filePath); const project = ProjectContextSchema.parse(data); // Update last accessed time project.lastAccessedAt = new Date().toISOString(); await this.updateProject(project); return project; } async updateProject(project: ProjectContext): Promise<ProjectContext> { project.updatedAt = new Date().toISOString(); const validated = ProjectContextSchema.parse(project); const filePath = path.join(this.projectsDir, `${project.id}.json`); await fs.writeJson(filePath, validated, { spaces: 2 }); return validated; } async listProjects(): Promise<ProjectContext[]> { const files = await fs.readdir(this.projectsDir); const projects: ProjectContext[] = []; for (const file of files) { if (file.endsWith(".json")) { const data = await fs.readJson(path.join(this.projectsDir, file)); projects.push(ProjectContextSchema.parse(data)); } } return projects.sort( (a, b) => new Date(b.lastAccessedAt).getTime() - new Date(a.lastAccessedAt).getTime() ); } async createSession( sessionData: Omit<SessionContext, "sessionId"> ): Promise<SessionContext> { const session: SessionContext = { ...sessionData, sessionId: uuidv4(), }; const validated = SessionContextSchema.parse(session); const filePath = path.join(this.sessionsDir, `${session.sessionId}.json`); await fs.writeJson(filePath, validated, { spaces: 2 }); return validated; } async getProjectSessions(projectId: string): Promise<SessionContext[]> { const files = await fs.readdir(this.sessionsDir); const sessions: SessionContext[] = []; for (const file of files) { if (file.endsWith(".json")) { const data = await fs.readJson(path.join(this.sessionsDir, file)); const session = SessionContextSchema.parse(data); if (session.projectId === projectId) { sessions.push(session); } } } return sessions.sort( (a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime() ); } }

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/aaronfeingold/mcp-project-context'

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