Skip to content

inchan/zettel-memory

Repository files navigation

Zettel Memory

v0.0.1 - Local-first persistent memory MCP server

License: MIT Node.js TypeScript

둜컬 νΌμ‹œμŠ€ν„΄νŠΈ λ©”λͺ¨λ¦¬λ₯Ό MCP μ„œλ²„λ‘œ λ…ΈμΆœν•˜μ—¬, Claude λ“± MCP ν˜Έν™˜ AI μ—μ΄μ „νŠΈκ°€ λ‹Ήμ‹ μ˜ 지식 베이슀λ₯Ό ν™œμš©ν•  수 있게 ν•©λ‹ˆλ‹€.

✨ Features

  • πŸ“ Markdown + YAML Front Matter - ν‘œμ€€ 포맷으둜 λ…ΈνŠΈ μ €μž₯
  • πŸ—‚οΈ PARA Organization - Projects/Areas/Resources/Archives λΆ„λ₯˜
  • πŸ”— Zettelkasten Linking - UID 기반 λ…ΈνŠΈ μ—°κ²° 및 백링크
  • πŸ” SQLite FTS5 Search - λΉ λ₯Έ μ „λ¬Έ 검색 (P95 < 1ms)
  • πŸ€– AI-Powered Organization - Ollama ν†΅ν•©μœΌλ‘œ μžλ™ λ…ΈνŠΈ 정리
  • 🏠 Local-first - λͺ¨λ“  데이터λ₯Ό λ‘œμ»¬μ— μ•ˆμ „ν•˜κ²Œ 보관
  • πŸ” Privacy - λ„€νŠΈμ›Œν¬ μ†‘μΆœ μ—†μŒ, μ›μžμ  μ“°κΈ°

πŸš€ Quick Start

Installation

npm install -g @inchankang/zettel-memory

Or use with npx:

npx @inchankang/zettel-memory --vault ~/my-vault

Claude Desktop Setup

Add to your Claude Desktop config (~/.config/claude/claude_desktop_config.json):

{
  "mcpServers": {
    "memory": {
      "command": "npx",
      "args": [
        "@inchankang/zettel-memory",
        "--vault",
        "/Users/yourname/Documents/memory-vault"
      ]
    }
  }
}

Create a Test Note

# Create vault directory
mkdir -p ~/my-vault

# Create a sample note
cat > ~/my-vault/my-first-note-20250101T120000Z.md << 'EOF'
---
id: "20250101T120000Z"
title: "My First Note"
category: "Resources"
tags: ["getting-started"]
created: "2025-01-01T12:00:00Z"
updated: "2025-01-01T12:00:00Z"
links: []
---

# My First Note

This is my first note in Zettel Memory!

## What I can do

- Store knowledge in Markdown
- Link notes together
- Search through my notes
- Let Claude access my knowledge base
EOF

πŸ“š Available Tools (v0.0.1)

Zettel Memory provides 14 MCP tools for complete note management:

Core CRUD Tools

create_note

Create a new Markdown note with Front Matter.

Input:

{
  "title": "My Note",
  "content": "Note content...",
  "category": "Resources",
  "tags": ["tag1", "tag2"],
  "project": "optional-project-name"
}

Output: Note ID (UID), file path, and metadata


read_note

Read a note by its unique ID.

Input:

{
  "uid": "20250101T120000Z",
  "includeMetadata": false,
  "includeLinks": false
}

Options:

  • includeMetadata: Add file size, word count, character count
  • includeLinks: Add backlink analysis and broken link detection

Output: Full note content with metadata


list_notes

List notes with filtering, sorting, and pagination.

Input:

{
  "category": "Projects",
  "tags": ["important"],
  "project": "my-project",
  "limit": 100,
  "offset": 0,
  "sortBy": "updated",
  "sortOrder": "desc"
}

Filters (all optional):

  • category: Filter by PARA category (Projects/Areas/Resources/Archives)
  • tags: Filter by tags (OR logic - matches any tag)
  • project: Filter by project name

Sorting:

  • sortBy: created, updated, or title
  • sortOrder: asc or desc

Pagination:

  • limit: Max results (default 100, max 1000)
  • offset: Skip first N results

Output: List of notes with metadata, total count, and pagination info


search_memory

Full-text search powered by SQLite FTS5.

Input:

{
  "query": "zettelkasten method",
  "limit": 10,
  "category": "Resources",
  "tags": ["productivity"]
}

Features:

  • FTS5 full-text search with ranking
  • Category and tag filtering
  • Performance metrics (search time, result count)
  • Snippet generation with query highlighting

Output: Ranked search results with snippets, scores, and metadata


update_note

Update an existing note's title, content, metadata, or links.

Input:

{
  "uid": "20250101T120000Z",
  "title": "Updated Title",
  "content": "New content...",
  "category": "Projects",
  "tags": ["updated", "important"],
  "project": "new-project",
  "links": ["other-note-uid"]
}

Features:

  • Partial updates (only provide fields you want to change)
  • Auto-updates updated timestamp
  • Syncs with search index automatically
  • At least one field required (besides uid)

Output: Updated note metadata and list of modified fields


delete_note

Delete a note permanently (requires explicit confirmation).

Input:

{
  "uid": "20250101T120000Z",
  "confirm": true
}

Safety:

  • confirm: true required to prevent accidental deletion
  • Returns note info before deletion
  • Removes from search index automatically
  • ⚠️ Cannot be undone

Output: Deleted note information with confirmation


Analytics & Organization Tools

  • get_vault_stats - Get statistics about your vault (note count, categories, tags)
  • get_backlinks - Find all notes linking to a specific note
  • get_metrics - Get performance metrics (JSON or Prometheus format)
  • find_orphan_notes - Find notes without any incoming or outgoing links
  • find_stale_notes - Find notes that haven't been updated recently
  • get_organization_health - Get overall health score and recommendations
  • archive_notes - Batch archive old or unused notes
  • suggest_links - Get AI-powered link suggestions based on content similarity

πŸ—‚οΈ Note Structure

Each note follows this structure:

---
id: "20250101T120000000000Z"  # Auto-generated UID (timestamp-based)
title: "Note Title"
category: "Resources"          # PARA: Projects|Areas|Resources|Archives
tags: ["tag1", "tag2"]        # Optional tags
project: "project-name"       # Optional project association
created: "2025-01-01T12:00:00Z"
updated: "2025-01-01T12:00:00Z"
links: ["other-note-uid"]     # Links to other notes
---

# Note Title

Your note content in Markdown...

## You can use

- Lists
- **Bold** and *italic*
- [Links](https://example.com)
- [[other-note-uid]] (Zettelkasten-style links)

File naming: {sanitized-title}-{uid}.md

  • Example: my-project-notes-20250101T120000Z.md

πŸ› οΈ Development

Prerequisites

  • Node.js 18+
  • npm 8+

Setup

# Clone the repository
git clone https://github.com/inchankang/zettel-memory.git
cd zettel-memory

# Install dependencies
npm install

# Build all packages
npm run build

# Run tests
npm test

# Type check
npm run typecheck

# Lint
npm run lint

Project Structure

zettel-memory/
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ mcp-server/      # MCP server & CLI
β”‚   β”œβ”€β”€ storage-md/      # Markdown storage & Front Matter
β”‚   β”œβ”€β”€ index-search/    # FTS5 search & link graph
β”‚   β”œβ”€β”€ assoc-engine/    # Context-aware ranking (planned for v0.1.0+)
β”‚   └── common/          # Shared utilities & types
└── docs/                # Documentation & specs

Running Locally

Direct Execution (Recommended):

# βœ… Root-level options (Claude Desktop compatible)
node packages/mcp-server/dist/cli.js --vault /tmp/test-vault --index /tmp/test-index.db

# Or with npm
npm start -- --vault /tmp/test-vault --index /tmp/test-index.db

# Using npx (if published)
npx @inchankang/zettel-memory --vault ~/my-vault --index ~/.memory-index.db

Subcommand (Backward Compatible):

# ⚠️ Still works but not recommended
node packages/mcp-server/dist/cli.js server --vault /tmp/test-vault

Healthcheck:

node packages/mcp-server/dist/cli.js healthcheck --vault /tmp/test-vault --index /tmp/test-index.db

Available Options:

--vault <path>      # Vault directory path (default: ./vault)
--index <path>      # Index database path (default: ./.memory-index.db)
--mode <mode>       # Mode: dev | prod (default: dev)
--timeout <ms>      # Tool execution timeout (default: 5000ms)
--retries <count>   # Tool execution retry count (default: 2)
--verbose           # Enable verbose logging
--help              # Show help
--version           # Show version

πŸ“– Documentation

πŸ—ΊοΈ Roadmap

v0.0.1 (Current) βœ…

  • Complete CRUD operations (create/read/update/delete/list/search)
  • Markdown + Front Matter storage
  • PARA categorization
  • FTS5 full-text search with ranking
  • Link analysis & backlinks
  • CLI interface
  • MCP server integration
  • Test coverage: 498 tests passing

v0.1.0 (Next)

  • Comprehensive unit tests (50%+ coverage)
  • Performance benchmarks & KPI validation
  • Zettelkasten link auto-suggestions
  • File watcher for real-time sync
  • Production error handling & logging

v1.0.0 (Future)

  • Vector embedding search
  • Olima Context-Aware Ranking Engine ⚠️ Planned Feature
    • Semantic similarity-based note recommendations
    • Session context-aware re-ranking
    • Automatic link suggestions based on content analysis
  • Advanced link graph queries
  • Docker image
  • Production-ready CI/CD

Note on Olima: The "Olima" context-aware ranking engine is a planned feature for future releases. Currently, the project uses Ollama (local LLM platform) for AI-powered note organization via the organize_notes tool.

🀝 Contributing

Contributions are welcome! Please follow the guidelines below.

Development Workflow

  1. Follow DEVELOPMENT_GUIDELINES.md
  2. Write tests for new features
  3. Ensure npm run build succeeds
  4. Use Conventional Commits for commit messages
  5. Submit a pull request

πŸ“„ License

MIT License - see LICENSE file for details.

πŸ™ Acknowledgments

πŸ“ž Support


Status: 🚧 Alpha - Under active development

Note: This is an alpha release. APIs may change. Feedback and contributions are greatly appreciated!

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •