How I Built Smart Search Across 3,500 Contacts in 2 Hours
Three thousand five hundred names in a file. Before: boolean logic, jq, trial and error. After: a sentence.
classic search: semantic search:
────────────── ───────────────
city == "Berlin" "founders in Berlin
AND role == "founder" working on AI"
AND tags includes "AI"
↓ ↓
what you wrote what you meant
The filter knows only what you typed. The vector knows what you meant.
The word “product” does not appear in the result. The meaning of “product” does.
query: "people who build products"
found:
──────
"founder of startup X"
"building my own project"
"indie hacker"
"launching my own service"
Letters point to other letters. Embeddings point to meaning.
what it cost to build:
setup time ── 2 hours
indexing time ── 90 seconds
embedding cost ── < $0.01
Qdrant Cloud ── free tier
The infrastructure is not the hard part. The hard part was the raw data — three years of contacts in a flat file, no structure, no roles, no cities.
Enrichment turned noise into signal. Indexing turned signal into searchable.
Mac
┌──────────────┐ ┌──────────────────┐
│Claude Desktop│ ───▶ │ MCP server │
└──────────────┘ └────────┬─────────┘
│
┌────────────┴────────────┐
▼ ▼
┌──────────────────┐ ┌────────────────────┐
│ Qdrant Cloud │ │ Embedding API │
└──────────────────┘ └────────────────────┘
The server runs where you are. The data lives where it is safe. The query travels between them in milliseconds.
The CRM was a file I queried. Now it is a conversation I have.
The database did not change. The interface to it did.
That is the only change that matters to the person asking the question.
— Ilao Dzindin