edit_square igindin

How I Built Smart Search Across 3,500 Contacts in 2 Hours

Built semantic CRM search with Qdrant Cloud and Claude Code. Now instead of filters — I just ask in plain English.

Ilya Gindin
translate de  · es  · fr  · pt-br  · ru
read ilao dzindin version arrow_forward

I had accumulated ~3,500 contacts from various Telegram communities. Founders, creators, developers — all in one JSON. Finding anything specific was a nightmare.

Before this, I’d open the file, write jq queries, filter by fields. Want to find “founders in Berlin interested in AI”? Good luck with boolean logic.

Today I built a solution that lets me simply ask: “Find founders in Berlin working on AI.” And get a list back.

What I built

A local MCP server that:

  • Takes my CRM (a JSON file of contacts)
  • Turns each contact into a vector via embeddings
  • Stores everything in Qdrant Cloud
  • Lets me search via Claude Desktop in natural language

Now in Claude Desktop I just type:

“Find people similar to this contact”

“Who in my contacts works in marketing and lives in the US?”

“Creators with a large audience”

And I get relevant results. No jq, no filters, no pain.

Stack

  • Qdrant Cloud — free tier, 1GB storage
  • Embedding APItext-embedding-3-small for embeddings
  • MCP (Model Context Protocol) — integration with Claude Desktop
  • TypeScript — for the MCP server

Architecture

┌─────────────────────────────────────────────────────┐
│  Mac                                                │
│  ┌──────────────┐      ┌──────────────────────┐    │
│  │Claude Desktop│ ───▶ │  MCP server (node)   │    │
│  └──────────────┘      └──────────┬───────────┘    │
└───────────────────────────────────┼────────────────┘

                    ┌───────────────┴───────────────┐
                    │                               │
                    ▼                               ▼
        ┌───────────────────┐          ┌───────────────────┐
        │   Qdrant Cloud    │          │   Embedding API   │
        │   (vectors)       │          │   (embeddings)    │
        └───────────────────┘          └───────────────────┘

The MCP server runs locally, but the data lives in the cloud. That means:

  • Fast search (Qdrant is optimized for vectors)
  • Accessible from any device
  • Free at current data volumes

How I built it

1. Parsing contacts

Collected contacts from several Telegram communities via the MTProto API. Parsed around 8 communities of various types — from technical to creative. Got ~3,500 unique contacts.

2. Data enrichment

From raw username + first_name, I extracted:

  • Roles (founder, developer, creator)
  • Companies
  • Locations
  • Interest-based cohorts

After enrichment, ~1,500 contacts had enough data for quality search.

3. Qdrant Cloud

Created a cluster on cloud.qdrant.io — took 2 minutes. The free tier gives 1GB, which is enough for tens of thousands of contacts.

4. Indexing

Uploaded the enriched contacts to Qdrant — ~90 seconds for the full database. Cost of embeddings: less than a cent.

5. MCP server

Wrote an MCP server in TypeScript and connected it to Claude Desktop. The server takes a text query, generates an embedding, and searches for nearest neighbors in Qdrant.

Setup — standard claude_desktop_config.json configuration with three environment variables (API keys and cluster URL).

Restarted Claude Desktop — done.

Classic search finds exact word matches. Semantic search finds by meaning.

I type: “people who build products”

I find:

  • “founder of startup X”
  • “building my own project”
  • “indie hacker”
  • “launching my own service”

Even if the word “product” doesn’t appear anywhere — it finds by meaning. Embeddings encode semantics, not letters.

What’s next

Right now the data is static — after parsing I need to re-index. Planning:

  1. Automatic re-indexing when the CRM is updated
  2. Filters — combining semantics with exact conditions (e.g. by role and city)
  3. Outreach integration — find people similar to those who already replied

Summary

WhatHow much
Setup time~2 hours
Contacts in database~3,500
Contacts with data~1,500
Indexing cost< $0.01
Qdrant Cloudfree

Vibe coding in its purest form: instead of writing complex filters, I taught AI to understand my queries. Now the CRM is a conversation, not SQL.

← arrow keys or swipe →