Skip to main content
Glama

Todo List MCP Server

by glaucia86
promptHandlers.ts9.65 kB
import { GetPromptRequest, GetPromptResult } from "@modelcontextprotocol/sdk/types.js"; import { TodoService } from "../services/todo.services.js"; import { createErrorResponse } from "../utils/validation.js"; class PromptHandlers { constructor(private todoService: TodoService) {} public handleListPrompts() { return { prompts: [ { name: "todo-summary", description: "Gera um resumo analítico dos todos com estatísticas avançadas", arguments: [ { name: "period", description: "Período para análise", required: false, }, { name: "includeCompleted", description: "Incluir todos completos na análise", required: false, }, ], }, { name: "todo-prioritization", description: "Sugere priorização inteligente dos todos baseada em múltiplos critérios", arguments: [ { name: "context", description: "Contexto adicional para priorização", required: false, }, { name: "focusArea", description: "Área de foco (trabalho, pessoal, estudos, etc.)", required: false, }, ], }, { name: "todo-insights", description: "Fornece insights detalhados sobre padrões de produtividade", arguments: [ { name: "analysisDepth", description: "Profundidade da análise (superficial, detalhada, completa)", required: false, }, ], }, ], }; } public async handleGetPrompt(request: GetPromptRequest): Promise<GetPromptResult> { const { name, arguments: args } = request.params; try { const todos = this.todoService.getAllTodos(); const stats = this.todoService.getStats(); switch (name) { case "todo-summary": const period = args?.period || "all"; const includeCompleted = args?.includeCompleted !== "false"; const filteredTodos = includeCompleted ? todos : todos.filter((todo) => !todo.completed); const priorityBreakdown = filteredTodos.reduce( (acc, todo) => { acc[todo.priority] = (acc[todo.priority] || 0) + 1; return acc; }, {} as Record<string, number> ); const tagFrequencySummary = filteredTodos .flatMap((todo) => todo.tags) .reduce((acc, tag) => { acc[tag] = (acc[tag] || 0) + 1; return acc; }, {} as Record<string, number>); const topTagsSummary = Object.entries(tagFrequencySummary) .sort(([, a], [, b]) => b - a) .slice(0, 5); return { messages: [ { role: "user", content: { type: "text", text: `Por favor, forneça um resumo analítico dos meus todos baseado nos dados abaixo: **Estatísticas Gerais:** - Total de todos: ${filteredTodos.length} - Todos completos: ${stats.completed} - Todos pendentes: ${stats.pending} - Taxa de conclusão: ${((stats.completed / stats.total) * 100).toFixed(1)}% **Distribuição por Prioridade:** ${Object.entries(priorityBreakdown) .map(([priority, count]) => `- ${priority}: ${count} todos`) .join("\n")} **Tags mais utilizadas:** ${topTagsSummary.map(([tag, count]) => `- ${tag}: ${count} usos`).join("\n") || "Nenhuma tag utilizada"} **Lista de Todos ${includeCompleted ? '(Completos e Pendentes)' : '(Apenas Pendentes)'}:** ${filteredTodos .map((todo, i) => `${i + 1}. [${todo.completed ? '✓' : ' '}] ${todo.title} (${todo.priority}) ${todo.tags.length > 0 ? `[${todo.tags.join(', ')}]` : ''}`) .join("\n")} Forneça insights sobre: 1. Padrões de produtividade 2. Sugestões de melhoria 3. Análise das prioridades 4. Recomendações baseadas nas tags 5. Tendências identificadas`, }, }, ], }; case "todo-prioritization": const context = args?.context || "geral"; const focusArea = args?.focusArea || "produtividade"; const pendingTodos = todos.filter((todo) => !todo.completed); return { messages: [ { role: "user", content: { type: "text", text: `Por favor, analise e sugira uma priorização inteligente para os seguintes todos pendentes: **Contexto:** ${context} **Área de Foco:** ${focusArea} **Todos Pendentes para Priorização:** ${pendingTodos .map((todo, i) => `${i + 1}. ${todo.title} - Prioridade atual: ${todo.priority} - Descrição: ${todo.description || 'Sem descrição'} - Tags: ${todo.tags.join(', ') || 'Nenhuma'} - Criado em: ${todo.createdAt.toLocaleString('pt-BR')}`) .join('\n\n')} **Estatísticas de Contexto:** - Total de todos pendentes: ${pendingTodos.length} - Distribuição por prioridade atual: - Alta: ${pendingTodos.filter(t => t.priority === 'high').length} - Média: ${pendingTodos.filter(t => t.priority === 'medium').length} - Baixa: ${pendingTodos.filter(t => t.priority === 'low').length} Forneça: 1. Uma lista priorizada dos todos (1-${pendingTodos.length}) 2. Justificativa para cada priorização 3. Sugestões de agrupamento ou sequenciamento 4. Recomendações de prazo 5. Identificação de dependências potenciais`, }, }, ], }; case "todo-insights": const analysisDepth = args?.analysisDepth || "detalhada"; const completedTodos = todos.filter((todo) => todo.completed); const avgCompletionTime = completedTodos.length > 0 ? completedTodos.reduce((acc, todo) => { const createdTime = new Date(todo.createdAt).getTime(); const completedTime = new Date(todo.completedAt || todo.createdAt).getTime(); return acc + (completedTime - createdTime); }, 0) / completedTodos.length / (1000 * 60 * 60 * 24) // em dias : 0; const priorityCompletionRates = ['high', 'medium', 'low'].map(priority => { const totalWithPriority = todos.filter(t => t.priority === priority).length; const completedWithPriority = todos.filter(t => t.priority === priority && t.completed).length; return { priority, total: totalWithPriority, completed: completedWithPriority, rate: totalWithPriority > 0 ? (completedWithPriority / totalWithPriority * 100).toFixed(1) : '0' }; }); const tagFrequencyInsights = todos .flatMap((todo) => todo.tags) .reduce((acc, tag) => { acc[tag] = (acc[tag] || 0) + 1; return acc; }, {} as Record<string, number>); const topTagsInsights = Object.entries(tagFrequencyInsights) .sort(([, a], [, b]) => b - a) .slice(0, 5); return { messages: [ { role: "user", content: { type: "text", text: `Forneça insights detalhados sobre meus padrões de produtividade baseado nos dados abaixo: **Nível de Análise:** ${analysisDepth} **Dados de Produtividade:** - Total de todos criados: ${todos.length} - Todos completos: ${completedTodos.length} - Todos pendentes: ${todos.length - completedTodos.length} - Taxa de conclusão geral: ${((completedTodos.length / todos.length) * 100).toFixed(1)}% - Tempo médio para conclusão: ${avgCompletionTime.toFixed(1)} dias **Taxa de Conclusão por Prioridade:** ${priorityCompletionRates.map(p => `- ${p.priority}: ${p.rate}% (${p.completed}/${p.total})`).join('\n')} **Distribuição Temporal dos Todos:** ${todos.slice(-10).map(todo => `- ${todo.title}: criado ${new Date(todo.createdAt).toLocaleDateString('pt-BR')} ${todo.completed ? '(✓ completo)' : '(pendente)'}`).join('\n')} **Tags e Categorização:** - Tags únicas utilizadas: ${Array.from(new Set(todos.flatMap(t => t.tags))).length} - Todos sem tags: ${todos.filter(t => t.tags.length === 0).length} - Tags mais produtivas: ${topTagsInsights.slice(0, 3).map(([tag, count]) => `${tag} (${count})`).join(', ') || 'N/A'} Por favor, analise e forneça: 1. **Padrões de Comportamento:** Tendências na criação e conclusão 2. **Eficiência por Categoria:** Qual tipo de tarefa você completa mais 3. **Pontos de Melhoria:** Onde focar para aumentar produtividade 4. **Recomendações Estratégicas:** Como otimizar seu sistema de todos 5. **Previsões:** Estimativas baseadas no histórico atual ${analysisDepth === 'completa' ? '\n**Análise Completa Solicitada:** Inclua correlações avançadas, sugestões de workflow e métricas preditivas.' : ''}`, }, }, ], }; default: throw new Error(`Prompt desconhecido: ${name}`); } } catch (error) { const errorResponse = createErrorResponse(error, `obter prompt ${name}`); return { messages: [ { role: "user", content: { type: "text", text: `❌ ${errorResponse.error}: ${errorResponse.details}`, }, }, ], }; } } } export { PromptHandlers };

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/glaucia86/todo-list-mcp-server'

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