add_entry
Add or update journal entries for the day by submitting content and optional tags. Appends to existing entries if already created, ensuring organized and continuous journaling.
Instructions
Add a new journal entry. If an entry for today already exists, it will append to the same file.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | The content of the journal entry | |
| tags | No | Optional tags for the entry (will also extract from content) |
Input Schema (JSON Schema)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"content": {
"description": "The content of the journal entry",
"type": "string"
},
"tags": {
"description": "Optional tags for the entry (will also extract from content)",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"content"
],
"type": "object"
}
Implementation Reference
- src/journal/manager.ts:233-311 (handler)Core handler function that executes the add_entry tool logic: generates timestamp, locks file, creates/appends entry to daily journal markdown file, extracts title/tags, handles backups, formats and writes the file.export async function addEntry( options: AddEntryOptions ): Promise<JournalEntry> { const t = now(); const date = t.format('YYYY-MM-DD'); const timestamp = t.format(); const filePath = getDateFilePath(date); // Acquire file lock await acquireLock(filePath); let backupPath: string | null = null; try { // Create entry const entry: JournalEntry = { id: `${date}-${timestamp}`, title: extractTitle(options.content), content: options.content, tags: options.tags || extractTags(options.content), created: timestamp, updated: timestamp, timestamp: t.format('HH:mm'), // HH:MM format }; // Read existing file or create new one const existingContent = await readFileIfExists(filePath); let journalFile: JournalFile; if (existingContent) { // Backup existing file backupPath = await backupFile(filePath); // Parse existing file journalFile = await parseJournalFile(filePath, existingContent); // Add new entry journalFile.entries.push(entry); journalFile.updated = timestamp; journalFile.entries_count = journalFile.entries.length; // Merge tags const allTags = new Set([...journalFile.tags, ...entry.tags]); journalFile.tags = Array.from(allTags).sort(); } else { // Create new file journalFile = { title: date, tags: entry.tags, created: timestamp, updated: timestamp, entries_count: 1, entries: [entry], filePath, date, }; } // Write file const content = formatJournalFile(journalFile); await writeFileWithDir(filePath, content); // Clean up backup file after successful write if (backupPath) { await deleteFile(backupPath); } return entry; } catch (error) { // If write failed and we have a backup, we can keep it for recovery // Log the backup path for manual recovery if needed if (backupPath) { console.error(`Write failed, backup file preserved at: ${backupPath}`); } throw error; } finally { releaseLock(filePath); } }
- src/mcp-server.ts:34-60 (registration)Registers the 'add_entry' MCP tool, defines input schema using Zod, and provides handler that calls the core addEntry function and formats response.'add_entry', 'Add a new journal entry. If an entry for today already exists, it will append to the same file.', { content: z.string().describe('The content of the journal entry'), tags: z .array(z.string()) .optional() .describe( 'Optional tags for the entry (will also extract from content)' ), }, async (args) => { const entry = await addEntry(args); return { content: [ { type: 'text', text: `✅ Journal entry added successfully!\n\n**Entry Details:**\n- ID: ${ entry.id }\n- Title: ${entry.title}\n- Tags: ${ entry.tags.join(', ') || 'None' }\n- Time: ${entry.timestamp}\n\n**Content:**\n${entry.content}`, }, ], }; } );
- src/journal/types.ts:50-53 (schema)TypeScript interface defining input options for addEntry function (content required, tags optional). Matches the Zod schema in registration.export interface AddEntryOptions { content: string; tags?: string[]; }