The Closing Window
Finding Meaning in Your Notes with CK Search image
Photo by Greg Rakozy on Unsplash

Finding Meaning in Your Notes with CK Search

AI Insights

TL;DR

CK Search adds local semantic search to any directory, with a built-in MCP server for AI agent integration. Semantic search overcomes the limits of keyword search by finding notes based on meaning, not string matching. This post walks through the dead simple installation, configuration, and explains how semantic search finds what keyword search can't. It's not magic, and I'll be honest about where it falls short.

When Search Can't See What You Mean

In the first post, I described the moment when good organization still isn't enough. You can tag perfectly and still not find what you need, because you're searching for a concept and your note used different words. That's the ceiling of keyword search.

I have around 1,900 markdown files across three Obsidian vaults. If you're not an Obsidian user, you can just think of this as 1,900 text files in three different folders. They're tagged, linked, and structured with frontmatter, or more simply put, page properties. The organization is solid. But when I search for "authentication," I don't find my note about "session token management." When I search for "AI assistant," I miss the note about "Claude Desktop." The information is there. The search just can't see it.

Obsidian's built-in search, and most plugins that extend it, work on the same principle: match the characters you typed against the characters in your files. Some add functions to improve the keyword matches, but they're still searching for text only, not meaning.

Semantic search works differently. Instead of matching strings, it converts both your query and your notes into numerical representations and measures how close they are in meaning. "Authentication" and "session token management" end up near each other in this numerical space, because they're about the same concept. The search understands what you mean, not just what you typed.


There are several tools that can add semantic search to Obsidian. I evaluated a few before settling on CK Search. CK Search isn't Obsidian-specific. It searches through any directory with text files.

The two things that mattered most to me: CK Search works without Obsidian running, and it has a built-in MCP server. The first means I can search from the command line, from scripts, from anywhere. The second means Claude Code can use it directly as a tool without additional dependencies, configuration or setup. It's also built in Rust, a language known for its speed.

One thing to know upfront: CK Search has no GUI. There's no Obsidian plugin with a search bar. It's a command-line tool, and that's by design β€” it's built to be used by AI agents and scripts, not clicked through manually. If you're looking for a point-and-click semantic search experience inside Obsidian, Smart Connections or Copilot might be a better fit. If you're building a system where an AI agent queries your notes programmatically, CK Search is the better tool.

Tool Comparison

CK Search Smart Connections Copilot for Obsidian
Search type Semantic + hybrid Semantic Semantic
MCP support Built-in server Plugin None
Multi-vault Any directory Per-vault Per-vault
Requires Obsidian No Yes Yes
Local-first Yes Yes Varies

Installation

CK Search is installed via Cargo, the Rust package manager. If you don't have Rust, you'll need it first.

# Install Rust (if you don't have it)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env

# Install CK Search
cargo install ck-search

# Verify
ck --version

That's it. No Node.js runtime, no Python environment, no Docker container. One command, one tool.


Before configuring anything else, test it from the command line:

# Semantic search β€” finds by meaning
ck --sem "ideas for improving workflow" /path/to/your/vault

The first time you run this, CK Search will build an index. It reads every markdown file in the directory and stores the numerical representation of them in a .ck/ folder. Every search after that is near-instantaneous β€” it only re-indexes files that have changed. There's no background process, no daemon, no watcher. CK Search only runs when you search. Zero resource overhead the rest of the time.

Try a few queries and compare them to what Obsidian's built-in search returns. This is where you'll feel the difference. Search for a concept you know is in your notes but using different words than you wrote. Semantic search will find it. Keyword search won't.

CK Search also supports keyword search and hybrid mode (semantic + keyword combined), but I primarily use it for semantic search. My stack already has keyword tools covered: grep, Obsidian's built-in search, the Omnisearch plugin. CK Search's unique value is it understands meanings. Nothing else in my stack does that.


Connecting It to an AI Agent

If you're using Claude Code or any other AI agent, CK Search becomes dramatically more useful as an MCP server. MCP (Model Context Protocol) is an open standard for connecting AI tools to external data sources and capabilities. Claude Code supports it natively.

The simplest approach to setting this up is a .mcp.json file:

{
  "mcpServers": {
    "ck-search": {
      "command": "/Users/yourname/.cargo/bin/ck",
      "args": ["--serve"]
    }
  }
}

Find your actual path with which ck and replace the command accordingly.

Once connected, Claude Code gets access to tools including:

  • semantic_search β€” the main one. Conceptual, meaning-based search.
  • hybrid_search β€” semantic + keyword combined.

In practice, when I ask Claude Code a question about my notes, it calls semantic_search with a natural language query, gets back ranked results with file paths and snippets, then reads the top matches to synthesize an answer.


What to Index (and What Not To)

CK Search indexes everything in the directory you point it at, minus whatever you exclude. You want to skip anything that isn't meaningful text content. The key principle: only index files that contain knowledge you'd want to search by meaning. App configuration and media files aren't that. They're noise that dilutes the index.

To exclude files, create a .ckignore file in the root of the directory you want to search.

CK Search indexes text-based files like markdown, code and plain text. If you have PDFs, images with text, or Office documents, you'll need a different tool for those. I use the Omnisearch Obsidian plugin, which handles PDFs via text extraction and images via OCR. But that's a different post.


When Semantic Search Sucks

I want to be honest about this, because too many posts about AI tooling oversell the magic.

Semantic search is bad at:

  • Exact strings. Searching for an error message, a function name, a specific tag? Use grep or Obsidian's built-in search. Semantic search will give you conceptually related results, which is not what you want when you need the exact file that contains ERROR_CODE_4032.
  • Short, common queries. Searching for "meeting" will return everything vaguely related to meetings. Not helpful.
  • Disambiguation. "Apple" the company and "apple" the fruit are the same numerical representation. Context helps, but it's not perfect.
  • Frontmatter (page properties) queries. Searching for notes with a specific tag or date? That's structured data. Use grep with a regex, not semantic search.
  • Recently added content. If you just created a note, it won't be in the index until the next search triggers a re-index of changed files. This is usually fine, but worth knowing.

The honest take: semantic search is one tool, not the only tool. It fills a specific gap that keyword search can't. But keyword search fills gaps that semantic search can't. The best setup uses both.


The Bigger Picture

CK Search is one piece of a larger search system I've built for my knowledge base.

The full stack, briefly:

  • CK Search: Semantic search over markdown files (what this post covers)
  • Grep: Exact text and regex matching (built-in, zero setup)
  • Omnisearch: Keyword search across all file types including PDFs and images with OCR
  • Sift: A custom RAG and temporal knowledge graph system for an external but related knowledge base (separate from Obsidian)

When my AI agent handles a search query, it runs all of these in parallel and synthesizes the combined results. But that's a later post. For now, CK Search on its own is a significant upgrade over keyword-only search.


What's Next

The next post covers how I built an external knowledge base using Sift, an open-source system that combines vector search, RAG, and a temporal knowledge graph to go beyond what any single vault search tool can do. Your knowledge doesn't all live in markdown files. Research papers, web articles, YouTube videos, podcasts, reference documents β€” the stuff you've collected from outside your vault β€” needs a home too. And once it has one, you can start asking questions across all of it and getting answers with sources.


This post is part of the AI-Powered Knowledge Management Series. Previous: From Folders to Knowledge Base. Next: Beyond Obsidian β€” Building an External Knowledge Base with Sift.

Powered by Buttondown.