/**
* Self MCP Server - Tools
* Ferramentas disponíveis para a IA manipular o Self
*/
import defaultDb from '../db/index.js'
import { createMarkdownGenerator } from '../lib/markdown.js'
import { writeFileSync } from 'fs'
import { join, dirname } from 'path'
import { fileURLToPath } from 'url'
const __dirname = dirname(fileURLToPath(import.meta.url))
/**
* Definição de todas as tools do MCP
*/
export const toolDefinitions = [
{
name: 'set_foundation',
description: 'Define um valor, anti-valor ou identidade futura. Use para estabelecer os fundamentos do Self.',
inputSchema: {
type: 'object',
properties: {
type: {
type: 'string',
enum: ['value', 'anti_value', 'identity'],
description: 'Tipo do fundamento: value (valor), anti_value (anti-valor) ou identity (identidade futura)',
},
content: {
type: 'string',
description: 'O conteúdo do fundamento. Para valores, uma palavra ou frase curta. Para identidade, uma frase descritiva.',
},
},
required: ['type', 'content'],
},
},
{
name: 'add_intention',
description: 'Adiciona uma intenção (o que move o usuário). Pode ser um problema, curiosidade, identidade desejada ou experiência.',
inputSchema: {
type: 'object',
properties: {
type: {
type: 'string',
enum: ['problem', 'curiosity', 'identity', 'experience'],
description: 'Tipo da intenção: problem (problema do mundo), curiosity (o que fascina), identity (quem quer ser), experience (o que quer viver)',
},
content: {
type: 'string',
description: 'Descrição da intenção',
},
isPrimary: {
type: 'boolean',
description: 'Se esta é a intenção principal (padrão: false)',
default: false,
},
},
required: ['type', 'content'],
},
},
{
name: 'add_mission',
description: 'Adiciona uma missão de longo prazo, conectada a uma intenção.',
inputSchema: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'Código da missão (ex: M1, M2)',
},
content: {
type: 'string',
description: 'Descrição da missão. Deve começar com um verbo de ação (Construir, Ensinar, Proteger, Criar...)',
},
intentionId: {
type: 'number',
description: 'ID da intenção relacionada (opcional)',
},
},
required: ['code', 'content'],
},
},
{
name: 'add_goal',
description: 'Adiciona uma meta anual, conectada a uma missão.',
inputSchema: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'Código da meta (ex: G1, G2)',
},
content: {
type: 'string',
description: 'Descrição da meta - deve ser específica e alcançável em 12 meses',
},
year: {
type: 'number',
description: 'Ano da meta (ex: 2025)',
},
metric: {
type: 'string',
description: 'Como medir se a meta foi alcançada',
},
missionId: {
type: 'number',
description: 'ID da missão relacionada (opcional)',
},
},
required: ['code', 'content', 'year'],
},
},
{
name: 'add_project',
description: 'Adiciona um projeto ativo, conectado a uma meta.',
inputSchema: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'Código do projeto (ex: PJ1, PJ2)',
},
content: {
type: 'string',
description: 'Descrição do projeto - o que você está fazendo esta semana/mês',
},
goalId: {
type: 'number',
description: 'ID da meta relacionada (opcional)',
},
},
required: ['code', 'content'],
},
},
{
name: 'add_obstacle',
description: 'Registra um obstáculo e uma estratégia para superá-lo.',
inputSchema: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'Código do obstáculo (ex: O1, O2)',
},
obstacle: {
type: 'string',
description: 'Descrição do obstáculo - seja honesto, pode ser interno ou externo',
},
strategy: {
type: 'string',
description: 'Estratégia para contornar o obstáculo',
},
},
required: ['code', 'obstacle'],
},
},
{
name: 'add_daily',
description: 'Registra uma entrada no registro diário (vitória, aprendizado ou desvio).',
inputSchema: {
type: 'object',
properties: {
date: {
type: 'string',
description: 'Data no formato YYYY-MM-DD',
},
type: {
type: 'string',
enum: ['victory', 'learning', 'deviation'],
description: 'Tipo da entrada: victory (vitória), learning (aprendizado), deviation (desvio)',
},
content: {
type: 'string',
description: 'Descrição concisa do que aconteceu',
},
missionId: {
type: 'number',
description: 'ID da missão impactada (opcional)',
},
},
required: ['date', 'type', 'content'],
},
},
{
name: 'export_markdown',
description: 'Gera o arquivo self.md a partir do banco de dados.',
inputSchema: {
type: 'object',
properties: {
outputPath: {
type: 'string',
description: 'Caminho onde salvar o arquivo (opcional, padrão: ../self.md)',
},
},
},
},
{
name: 'clear_all',
description: 'CUIDADO: Limpa todos os dados do Self. Requer confirmação.',
inputSchema: {
type: 'object',
properties: {
confirm: {
type: 'string',
description: 'Digite "CONFIRM" para confirmar a exclusão de todos os dados',
},
},
required: ['confirm'],
},
},
]
/**
* Cria função executeTool com instância de db injetada
* @param {Object} db - Instância do banco de dados (funções)
* @returns {Function} Função executeTool
*/
export function createToolExecutor(db) {
const generateMarkdown = createMarkdownGenerator(db)
return async function executeTool(name, args) {
switch (name) {
case 'set_foundation': {
const result = db.addFoundation(args.type, args.content)
db.touchLastUpdated()
return {
content: [
{
type: 'text',
text: `✅ Fundamento adicionado: ${args.type} = "${args.content}"`,
},
],
}
}
case 'add_intention': {
const result = db.addIntention(args.type, args.content, args.isPrimary || false)
db.touchLastUpdated()
const primary = args.isPrimary ? ' (primária)' : ''
return {
content: [
{
type: 'text',
text: `✅ Intenção adicionada${primary}: ${args.type} = "${args.content}"`,
},
],
}
}
case 'add_mission': {
const result = db.addMission(args.code, args.intentionId || null, args.content)
db.touchLastUpdated()
return {
content: [
{
type: 'text',
text: `✅ Missão ${args.code} adicionada: "${args.content}"`,
},
],
}
}
case 'add_goal': {
const result = db.addGoal(args.code, args.missionId || null, args.year, args.content, args.metric || null)
db.touchLastUpdated()
return {
content: [
{
type: 'text',
text: `✅ Meta ${args.code} (${args.year}) adicionada: "${args.content}"`,
},
],
}
}
case 'add_project': {
const result = db.addProject(args.code, args.goalId || null, args.content)
db.touchLastUpdated()
return {
content: [
{
type: 'text',
text: `✅ Projeto ${args.code} adicionado: "${args.content}"`,
},
],
}
}
case 'add_obstacle': {
const result = db.addObstacle(args.code, args.obstacle, args.strategy || null)
db.touchLastUpdated()
return {
content: [
{
type: 'text',
text: `✅ Obstáculo ${args.code} registrado: "${args.obstacle}"`,
},
],
}
}
case 'add_daily': {
const result = db.addDaily(args.date, args.type, args.content, args.missionId || null)
db.touchLastUpdated()
const typeLabels = {
victory: 'Vitória',
learning: 'Aprendizado',
deviation: 'Desvio',
}
return {
content: [
{
type: 'text',
text: `✅ [${typeLabels[args.type]}] registrado para ${args.date}: "${args.content}"`,
},
],
}
}
case 'export_markdown': {
const markdown = generateMarkdown()
const outputPath = args.outputPath || join(__dirname, '..', '..', 'self.md')
writeFileSync(outputPath, markdown, 'utf-8')
return {
content: [
{
type: 'text',
text: `✅ Arquivo self.md exportado para: ${outputPath}\n\n---\n\n${markdown}`,
},
],
}
}
case 'clear_all': {
if (args.confirm !== 'CONFIRM') {
return {
content: [
{
type: 'text',
text: '❌ Para limpar todos os dados, você precisa passar confirm: "CONFIRM"',
},
],
isError: true,
}
}
db.clearAll()
return {
content: [
{
type: 'text',
text: '✅ Todos os dados foram apagados. O Self está vazio.',
},
],
}
}
default:
return {
content: [
{
type: 'text',
text: `❌ Tool desconhecida: ${name}`,
},
],
isError: true,
}
}
}
}
// Backward compatibility: export executeTool using default db
export const executeTool = createToolExecutor(defaultDb)
export default { toolDefinitions, executeTool, createToolExecutor }