Technical Deep Dive

Local embeddings, vector retrieval, dual-plane architecture, and setup details for engineers.

Technical summary

AdKit is built on a few core components. Context embedding stays local; storage and retrieval use your own infrastructure.

Local embeddings (FastEmbed)

Context is embedded locally—no third-party API calls. FastEmbed runs in-process for low latency.

Vector retrieval (Qdrant)

Ads are stored as vectors in Qdrant. Semantic search returns candidates by similarity score.

Typed constraints

Topics, locale, verticals, exclusions, policy flags. Filters are applied after retrieval.

Dual-plane separation

Data Plane (runtime) = read-only matching. Control Plane (admin) = ingestion and provisioning. Data Plane allowlist prevents destructive/admin tools at runtime.

Dual-plane design

Two separate MCP server processes. Runtime never mutates data—that’s the security boundary.

Data Plane

Ad matching, read-only retrieval. Called by LLMs / Agents.

uv run ad-mcp-data
  • ads_match — semantic ad matching, returns candidates + match_id
  • ads_explain — audit trace for a prior match
  • ads_health — liveness/readiness
  • ads_capabilities — placements, constraints, schema

Control Plane

Provisioning, ingestion, admin. Called by Humans, CI/CD.

uv run ad-mcp-control
  • collection_ensure — create/align collection
  • ads_upsert_batch — batch ad ingestion
  • ads_delete — delete an ad
  • ads_bulk_disable — disable ads by filter

Data Plane allowlist: only ads_match, ads_explain, ads_health, ads_capabilities. No destructive ops at runtime.

Repository structure

Core modules and responsibilities.

src/ad_injector/
  models/ # Ad, Targeting, Policy; MCP request/response DTOs
  services/ # MatchService, PolicyEngine, TargetingEngine, IndexService
  adapters/ # QdrantVectorStore, FastEmbedProvider
  mcp/ # server, tools, auth, observability
  config/ # RuntimeSettings, env vars
  ops/ # smoke_check, migrations

Local setup & demo

Prerequisites: Python 3.10+, uv, Docker (for Qdrant).

Install uv

bash
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# Or with pip
pip install uv

Start Qdrant

bash
docker run -d --name qdrant -p 6333:6333 -p 6334:6334 qdrant/qdrant
docker ps --filter name=qdrant

Sync, create collection, seed ads

bash
uv sync
uv run ad-index create
uv run ad-index seed
uv run ad-index info      # Verify: Points count should be 5

Run the servers

bash
# Data Plane (LLM-facing, read-only)
uv run ad-mcp-data

# Control Plane (admin, separate terminal)
uv run ad-mcp-control