{"id":48153882,"url":"https://github.com/jpalczewski/kajet","last_synced_at":"2026-04-04T17:14:15.738Z","repository":{"id":337303010,"uuid":"1152105620","full_name":"jpalczewski/kajet","owner":"jpalczewski","description":"Journaling-focused RAG MCP server for Obsidian. Local embeddings, Metal GPU, semantic search for your markdown notes. 📓","archived":false,"fork":false,"pushed_at":"2026-03-22T22:02:41.000Z","size":2648,"stargazers_count":0,"open_issues_count":19,"forks_count":0,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2026-03-23T15:45:13.218Z","etag":null,"topics":["embedding","journalling","markdown","obsidian","rag"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jpalczewski.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"agents.md","dco":null,"cla":null}},"created_at":"2026-02-07T11:23:56.000Z","updated_at":"2026-03-22T22:02:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jpalczewski/kajet","commit_stats":null,"previous_names":["jpalczewski/kajet"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/jpalczewski/kajet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpalczewski%2Fkajet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpalczewski%2Fkajet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpalczewski%2Fkajet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpalczewski%2Fkajet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jpalczewski","download_url":"https://codeload.github.com/jpalczewski/kajet/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpalczewski%2Fkajet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31407644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["embedding","journalling","markdown","obsidian","rag"],"created_at":"2026-04-04T17:14:15.512Z","updated_at":"2026-04-04T17:14:15.729Z","avatar_url":"https://github.com/jpalczewski.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📓 kajet\n\n[![codecov](https://codecov.io/gh/jpalczewski/kajet/branch/develop/graph/badge.svg?token=9VFDGOUUUF)](https://codecov.io/gh/jpalczewski/kajet)\n\nJournaling-focused RAG for Obsidian vaults, optimized for Apple Silicon GPU. Runs as an MCP server with a web dashboard ([Serena](https://github.com/oramasearch/serena)-inspired). Think [Rosebud AI](https://rosebud.app/) but for your local markdown notes.\n\n**[📋 Changelog](CHANGELOG.md)** | **[🛠️ Tools Reference](docs/TOOLS.md)** | **[🗺️ Roadmap](https://github.com/jpalczewski/kajet/issues)**\n\n## Why \"kajet\"?\n\n*Kajet* is an old/regional Polish word for a notebook (from French *cahier*). Once common, now mostly found in dialects or among older generations. The name came from a walk in the snow with the dog (the `/touch-grass` endpoint was temporarily unavailable due to weather conditions) — the phrase *\"sprawdzić w kajecie\"* (\"check it in the notebook\") struck me as an absurdly fitting thing to say to an LLM.\n\n## Why this exists\n\nI take a lot of notes in Obsidian and wanted a proper RAG pipeline that actually works for me — local, fast, and tailored to how I use my vault. [local-rag](https://github.com/jonfairbanks/local-rag) was an interesting starting point, but it runs JS-only CPU models. I wanted something optimized for macOS and Apple Silicon GPU, not a glorified `grep` burning through CPU cycles.\n\nAlso: the male urge to write a side-project in Rust was too strong. Nobody talks about the 30 GB `target/` folder, but here we are.\n\n## Features\n\n- 🔍 **Semantic search** over your entire vault via MCP `search` tool (hybrid vector + full-text)\n- 🧠 **Local embeddings** — AllMiniLM-L6-v2 via [candle](https://github.com/huggingface/candle), Metal GPU on Apple Silicon, with custom model support\n- ⚠️ **Embeddings migration path** — The built-in Candle backend works but is limited to a handful of models. For access to modern embedding models (nomic-embed, BGE-M3, E5-mistral, multilingual models, etc.), kajet now supports [Text Embeddings Inference (TEI)](https://github.com/huggingface/text-embeddings-inference) via the `kajet-remote` crate. TEI can run locally on the same machine or point to a remote endpoint as your needs scale. Candle backend remains available but is in maintenance mode.\n- 🌍 **Unicode normalization** — handles the two ways of writing `ę` in Unicode: NFC (`ę` as one character) vs NFD (`e` + combining ogonek). Searching for \"Gdańsk\" finds \"Gdańsk\" even when your filesystem and editor disagree on encoding\n- ⚡ **Incremental indexing** — only re-embeds changed files (content hashing)\n- 👀 **Live file watcher** — picks up vault changes automatically\n- 📝 **Note editing** — create, edit, append, and modify notes directly via MCP tools (`create_note`, `edit_note`)\n- 🌐 **Web dashboard** — search playground + live MCP event stream via WebSocket\n- ☁️ **Cloud storage support** — auto-detects cloud-synced vaults (iCloud, OneDrive, Dropbox, Google Drive) and stores LanceDB outside the sync folder. This is critical for performance: indexing 600 files on iCloud takes ~1 file/sec vs ~70s total (~8.5 files/sec) when stored locally on M4 Mac\n- 📦 **Single binary** — frontend embedded at compile time, zero runtime dependencies\n\n## System Requirements\n\n**Tested platforms:**\n- macOS (Apple Silicon) — primary target with Metal GPU acceleration\n- Linux (x86_64) — experimental CPU fallback\n\n**Runtime requirements (rough estimates):**\n- 16GB RAM (depends on vault size)\n- ~500MB disk space for embedding model\n- Additional space for LanceDB (varies by vault size)\n\n**Building from source:**\n- 15-40GB free disk space for Rust `target/` directory and dependencies\n- Expect 5-10 minute initial build (LanceDB pulls in large dependency trees)\n\n**Recommended:**\n- macOS 12+ (Monterey) or later for Metal GPU support\n- 8GB+ RAM for vaults with 1000+ files\n\n## Prerequisites\n\n### macOS\n```bash\nbrew install protobuf\n```\n\n### Ubuntu/Debian\n```bash\nsudo apt install protobuf-compiler libssl-dev build-essential pkg-config\n```\n\n\u003e ⚠️ **Note:** The above is AI hallucination. For a working Linux build, see the [CI workflow](https://github.com/jpalczewski/kajet/blob/develop/.github/workflows/ci.yml) — you'll need to translate dependencies to your favorite distro.\n\n## Installation\n\n### From source\n\n```bash\n# Clone and build (requires Deno for frontend build)\ngit clone https://github.com/yourusername/kajet.git\ncd kajet\ncd frontend \u0026\u0026 deno install \u0026\u0026 deno task build \u0026\u0026 cd ..\ncargo build --release\n\n# Binary will be at target/release/kajet\n```\n\n## ⚠️ Important Warning\n\n**kajet includes tools that can modify and delete your notes.** Destructive edits are backed up automatically, but **this is experimental software**. LLM agents can be unpredictable — data loss is a real risk if your agent decides to overwrite files because you didn't say \"good morning\" or \"thank you\" nicely enough.\n\n**This MCP is for playing around with data you have backed up.** Use git, Time Machine, or whatever backup solution you trust. Don't point it at your only copy of anything important.\n\nYou've been warned. 🙃\n\n## Usage\n\n### As MCP server (Claude Code / Claude Desktop)\n\nAdd to your `.claude/mcp.json` or Claude Desktop config:\n\n```json\n{\n  \"mcpServers\": {\n    \"kajet\": {\n      \"command\": \"/path/to/kajet\",\n      \"args\": [\"--vault\", \"/path/to/your/obsidian/vault\"]\n    }\n  }\n}\n```\n\nThe dashboard will be available at `http://localhost:3579` while the MCP server is running.\n\n**Example queries to try in Claude:**\n- \"What notes do I have about machine learning?\"\n- \"Find my thoughts on productivity systems\"\n- \"Show me notes mentioning both Rust and performance\"\n\n### With Goose\n\n[Goose](https://block.github.io/goose/) has a GUI where you can add MCP servers by clicking through the interface.\n\n**Protip:** Use the path to your built binary from `target/release/kajet` and pass `--vault /path/to/your/markdown/repo` as arguments.\n\n### Standalone (search playground only)\n\n```bash\nkajet --vault ~/Obsidian/Vault\n# Dashboard at http://localhost:3579\n```\n\n## Architecture\n\n```\nstdin/stdout ←→ [MCP stdio] ←→ Engine ←→ [Axum HTTP :3579] ←→ Browser\n                                  ↓\n                              LanceDB\n                          (.kajet/ in vault or ~/Library/Application Support/kajet/)\n```\n\n**Stack:**\n- **MCP**: Official `rmcp` SDK with `#[tool]` macros\n- **Embeddings**: [candle](https://github.com/huggingface/candle) (AllMiniLM-L6-v2, Metal GPU on macOS, CPU fallback on Linux)\n- **Vector DB**: [LanceDB](https://lancedb.com/) (embedded, Lance columnar format)\n- **Frontend**: Svelte + Vite, embedded in binary via `rust-embed`\n- **File watching**: [notify](https://github.com/notify-rs/notify) for live re-indexing\n- **HTTP**: [Axum](https://github.com/tokio-rs/axum) with WebSocket support\n\n**Workspace structure:**\n- `crates/core` — Domain model, `Engine`, trait definitions\n- `crates/parser` — Markdown parsing, chunking, wikilink extraction\n- `crates/backend` — Concrete implementations (embedder, vector store)\n- `crates/indexer` — Incremental indexing pipeline and file watcher\n- `crates/mcp` — MCP protocol handler\n- `crates/web` — Axum HTTP server and WebSocket broadcaster\n- `crates/writer` — Note creation and editing \n\n## MCP Tools\n\nkajet provides 12 MCP tools for semantic search, note management, and vault exploration.\n\nSee **[docs/TOOLS.md](docs/TOOLS.md)** for complete documentation with parameters and examples.\n\n## Development\n\n### Prerequisites for building\n\n- **Rust** (latest stable, edition 2024)\n- **Deno** (for frontend build) — [deno.land](https://deno.land)\n- **protobuf** (see [Prerequisites](#prerequisites))\n\n### Building from source\n\n```bash\n# 1. Build frontend first\ncd frontend\ndeno install\ndeno task build\ncd ..\n\n# 2. Build Rust workspace\ncargo build --release\n\n# Binary at target/release/kajet\n```\n\n### Running tests\n\n```bash\n# Run all tests with cargo-nextest (recommended)\ncargo nextest run --workspace\n\n# Run tests for a specific crate\ncargo nextest run -p kajet-parser\n\n# Run a single test by name\ncargo nextest run -E 'test(test_name)'\n\n# Fallback to standard cargo test if nextest not installed\ncargo test --workspace\n```\n\n### Code style\n\n```bash\n# Format check (runs on pre-commit hook)\ncargo fmt --check\n\n# Lint (runs on pre-commit hook)\ncargo clippy --workspace -- -D warnings\n\n# Typo check (runs on pre-commit hook)\ntypos\n```\n\nPre-commit hooks are managed via [Lefthook](https://github.com/evilmartians/lefthook). Install with:\n```bash\nlefthook install\n```\n\n### Running with MCP Inspector\n\n```bash\n# Use the included script\n./run-inspector.sh /path/to/vault\n\n# Or manually\nnpx @modelcontextprotocol/inspector cargo run -- --vault /path/to/vault\n```\n\n### Project conventions\n\n- **Commits**: Use [Conventional Commits](https://www.conventionalcommits.org/) (`feat:`, `fix:`, `refactor:`, `perf:`, `docs:`, `test:`, `chore:`, `ci:`)\n- **i18n**: User-facing strings go through `t!()` macro (rust-i18n). Locale files: `locales/{en,pl}.toml`\n- **Logging levels**:\n  - `INFO` = entry point (query, params, result count)\n  - `DEBUG` = timings and score stats\n  - `TRACE` = raw data (embeddings, scores)\n  - Use `#[tracing::instrument]` with `skip(self)` on search methods\n\n### Workspace architecture\n\nThe project uses a Cargo workspace with trait-based dependency injection:\n\n```\nkajet (root binary)\n├── kajet-core        # Domain model, Engine, trait definitions\n├── kajet-parser      # Markdown parsing, chunking, wikilinks\n├── kajet-backend     # Concrete implementations (embedder, vector store)\n├── kajet-indexer     # Incremental indexing pipeline + file watcher\n├── kajet-mcp         # MCP protocol handler\n├── kajet-web         # Axum HTTP server + WebSocket\n└── kajet-writer      # Note creation and editing (WIP)\n```\n\n## Roadmap\n\nSee [GitHub Issues](https://github.com/jpalczewski/kajet/issues) for planned features.\n\n## Acknowledgments\n\n- Inspired by [Serena](https://github.com/oramasearch/serena) for the MCP + dashboard approach\n- Built on [LanceDB](https://lancedb.com/), [candle](https://github.com/huggingface/candle), and the [MCP Rust SDK](https://github.com/modelcontextprotocol/rust-sdk)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpalczewski%2Fkajet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjpalczewski%2Fkajet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpalczewski%2Fkajet/lists"}