Skip to main content
Glama
MUSE-CODE-SPACE

Vibe Coding Documentation MCP (MUSE)

sessionHistory.ts8.35 kB
/** * 세션 히스토리 도구 * 바이브 코딩 세션을 저장, 조회, 검색하는 기능 * v2.6: 세션 히스토리 관리 */ import { saveSession, getSession, updateSession, deleteSession, listSessions, searchSessions, getStorageStats, SessionData, StoredSession } from '../core/sessionStorage.js'; export type SessionHistoryAction = 'save' | 'get' | 'update' | 'delete' | 'list' | 'search' | 'stats'; export interface SessionHistoryInput { action: SessionHistoryAction; // For save/update title?: string; summary?: string; tags?: string[]; codeContexts?: SessionData['codeContexts']; designDecisions?: SessionData['designDecisions']; metadata?: Record<string, unknown>; // For get/update/delete sessionId?: string; // For list limit?: number; offset?: number; filterTags?: string[]; sortBy?: 'createdAt' | 'updatedAt' | 'title'; sortOrder?: 'asc' | 'desc'; // For search keyword?: string; searchIn?: ('title' | 'summary' | 'tags')[]; } export interface SessionHistoryOutput { success: boolean; action: SessionHistoryAction; session?: SessionData; sessions?: StoredSession[]; total?: number; stats?: { totalSessions: number; totalCodeContexts: number; totalDesignDecisions: number; storageDir: string; oldestSession?: string; newestSession?: string; }; message?: string; error?: string; } export async function sessionHistoryTool(input: SessionHistoryInput): Promise<SessionHistoryOutput> { const { action } = input; try { switch (action) { case 'save': { if (!input.title || !input.summary) { return { success: false, action, error: 'title and summary are required for save action' }; } const session = await saveSession({ title: input.title, summary: input.summary, tags: input.tags || [], codeContexts: input.codeContexts || [], designDecisions: input.designDecisions || [], metadata: input.metadata }); return { success: true, action, session, message: `Session saved: ${session.id}` }; } case 'get': { if (!input.sessionId) { return { success: false, action, error: 'sessionId is required for get action' }; } const session = await getSession(input.sessionId); if (!session) { return { success: false, action, error: `Session not found: ${input.sessionId}` }; } return { success: true, action, session, message: `Session retrieved: ${session.title}` }; } case 'update': { if (!input.sessionId) { return { success: false, action, error: 'sessionId is required for update action' }; } const updates: Partial<SessionData> = {}; if (input.title !== undefined) updates.title = input.title; if (input.summary !== undefined) updates.summary = input.summary; if (input.tags !== undefined) updates.tags = input.tags; if (input.codeContexts !== undefined) updates.codeContexts = input.codeContexts; if (input.designDecisions !== undefined) updates.designDecisions = input.designDecisions; if (input.metadata !== undefined) updates.metadata = input.metadata; const session = await updateSession(input.sessionId, updates); return { success: true, action, session, message: `Session updated: ${session.id}` }; } case 'delete': { if (!input.sessionId) { return { success: false, action, error: 'sessionId is required for delete action' }; } const deleted = await deleteSession(input.sessionId); if (!deleted) { return { success: false, action, error: `Session not found: ${input.sessionId}` }; } return { success: true, action, message: `Session deleted: ${input.sessionId}` }; } case 'list': { const { sessions, total } = await listSessions({ limit: input.limit, offset: input.offset, tags: input.filterTags, sortBy: input.sortBy, sortOrder: input.sortOrder }); return { success: true, action, sessions, total, message: `Found ${total} session(s)` }; } case 'search': { if (!input.keyword) { return { success: false, action, error: 'keyword is required for search action' }; } const sessions = await searchSessions(input.keyword, { limit: input.limit, searchIn: input.searchIn }); return { success: true, action, sessions, total: sessions.length, message: `Found ${sessions.length} session(s) matching "${input.keyword}"` }; } case 'stats': { const stats = await getStorageStats(); return { success: true, action, stats, message: `Storage contains ${stats.totalSessions} session(s)` }; } default: return { success: false, action, error: `Unknown action: ${action}` }; } } catch (error) { return { success: false, action, error: error instanceof Error ? error.message : String(error) }; } } export const sessionHistorySchema = { name: 'muse_session_history', description: 'Manages vibe coding session history. Save, retrieve, search, and manage past coding sessions with their code contexts and design decisions.', inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['save', 'get', 'update', 'delete', 'list', 'search', 'stats'], description: 'Action to perform: save (create new), get (retrieve by ID), update (modify existing), delete (remove), list (get all), search (find by keyword), stats (storage statistics)' }, sessionId: { type: 'string', description: 'Session ID (required for get, update, delete actions)' }, title: { type: 'string', description: 'Session title (required for save, optional for update)' }, summary: { type: 'string', description: 'Session summary (required for save, optional for update)' }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags for categorization' }, codeContexts: { type: 'array', description: 'Array of code context objects' }, designDecisions: { type: 'array', description: 'Array of design decision objects' }, metadata: { type: 'object', description: 'Additional metadata' }, limit: { type: 'number', description: 'Maximum results to return (for list/search, default: 50)' }, offset: { type: 'number', description: 'Number of results to skip (for list, default: 0)' }, filterTags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags (for list)' }, sortBy: { type: 'string', enum: ['createdAt', 'updatedAt', 'title'], description: 'Sort field (for list, default: updatedAt)' }, sortOrder: { type: 'string', enum: ['asc', 'desc'], description: 'Sort order (for list, default: desc)' }, keyword: { type: 'string', description: 'Search keyword (required for search action)' }, searchIn: { type: 'array', items: { type: 'string', enum: ['title', 'summary', 'tags'] }, description: 'Fields to search in (for search, default: all)' } }, required: ['action'] } };

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/MUSE-CODE-SPACE/vibe-coding-mcp'

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