Objective
An effective SDR agent does four jobs: score which leads are worth working, match each lead to the most relevant proof (a case study or feature), map the buying committee so it reaches the right person, and draft outreach that actually sounds personalized. That's usually a CRM + a scoring service + a vector store + a graph + an LLM gateway. Here you'll build the whole outbound agent on one database, composing this cluster's building blocks. The same brain drives any framework or a voice agent — see Use it from your agent at the end.
Step 1: Create the lead store with scoring features
Each lead carries the firmographic + engagement features the model scores on.
CREATE TABLE IF NOT EXISTS recipe_sdr_leads (
lead_id INTEGER PRIMARY KEY,
company TEXT,
contact TEXT,
employees INTEGER,
pageviews INTEGER, -- site engagement
demo_requested INTEGER, -- 1 if they asked for a demo
industry_fit DOUBLE, -- 0..1 ICP fit
pain_note TEXT -- free-text note from research
);
INSERT INTO recipe_sdr_leads
(lead_id, company, contact, employees, pageviews, demo_requested, industry_fit, pain_note) VALUES
(1,'Nimbus Retail','Sara Lin',420, 38,1,0.90,'Struggling to unify product search across 5 stores.'),
(2,'Tiny Studio','Joe Park',6, 3,0,0.30,'Just browsing, hobby project.'),
(3,'Atlas Logistics','Mara Cole',1300, 52,1,0.85,'Needs real-time tracking and faster analytics.'),
(4,'Quiet Cafe','Ben Adler',4, 1,0,0.20,'Looked at pricing once.'),
(5,'Helio Health','Dr. Vasquez',780, 41,1,0.88,'Wants semantic search over clinical documents.');
Step 2: Train a lead-scoring model (AutoML)
Learn from past leads which features predicted a closed-won deal.
CREATE TABLE IF NOT EXISTS recipe_sdr_history (
hist_id INTEGER PRIMARY KEY,
employees INTEGER,
pageviews INTEGER,
demo_requested INTEGER,
industry_fit DOUBLE,
converted INTEGER -- label: 1 = became an opportunity
);
INSERT INTO recipe_sdr_history
(hist_id, employees, pageviews, demo_requested, industry_fit, converted) VALUES
(1,500,40,1,0.90,1),(2,8,2,0,0.25,0),(3,1200,55,1,0.88,1),(4,5,1,0,0.20,0),
(5,700,44,1,0.85,1),(6,10,3,0,0.30,0),(7,900,48,1,0.92,1),(8,6,2,0,0.22,0),
(9,640,39,1,0.80,1),(10,9,4,0,0.28,0),(11,1100,51,1,0.86,1),(12,7,1,0,0.18,0),
(13,820,46,1,0.89,1),(14,4,2,0,0.21,0),(15,760,43,1,0.84,1),(16,11,3,0,0.33,0),
(17,980,49,1,0.91,1),(18,5,1,0,0.19,0),(19,710,42,1,0.83,1),(20,8,2,0,0.26,0);
CREATE EXPERIMENT sdr_score_exp AS
SELECT employees, pageviews, demo_requested, industry_fit, converted AS target
FROM recipe_sdr_history
WITH (
task_type = 'binary_classification',
target_column = 'target',
optimization_metric = 'auc',
algorithms = ['logistic_regression', 'random_forest', 'gradient_boosting'],
validation_strategy = 'stratified_kfold',
n_folds = 3,
max_trials = 15
);
DEPLOY MODEL sdr_score FROM EXPERIMENT sdr_score_exp;
Step 3: Create the proof library (case studies / features) for matching
Embed your proof points so the agent can match a lead's pain to the most relevant one.
CREATE TABLE IF NOT EXISTS recipe_sdr_proof (
proof_id INTEGER PRIMARY KEY,
title TEXT,
content TEXT,
embedding VECTOR(384)
);
INSERT INTO recipe_sdr_proof (proof_id, title, content) VALUES
(1,'Unified search case study','How Nimbus-like retailers unified product search across stores and lifted conversion 18%.'),
(2,'Real-time analytics case study','How a logistics firm cut tracking latency and ran analytics 10x faster.'),
(3,'Clinical document search','How a health system added semantic search over clinical notes, HIPAA-safe.'),
(4,'Cost savings whitepaper','How teams replaced a 5-service stack with one engine and halved infra cost.');
UPDATE recipe_sdr_proof SET embedding = EMBED(content);
Step 4: Score the leads and rank by likelihood to convert
Use the model to focus the agent on the leads worth working first.
SELECT company, contact,
AUTOML.PREDICT('sdr_score', employees, pageviews, demo_requested, industry_fit) AS lead_score
FROM recipe_sdr_leads
ORDER BY lead_score DESC;
Step 5: Match a top lead to the best proof point
Find the case study whose content best matches the lead's stated pain — by meaning.
SELECT title, content,
COSINE_SIMILARITY(embedding,
EMBED((SELECT pain_note FROM recipe_sdr_leads WHERE lead_id = 1))) AS relevance
FROM recipe_sdr_proof
ORDER BY relevance DESC
LIMIT 1;
Step 6: Map the buying committee (graph)
Model who reports to whom so the agent reaches the economic buyer, not just the first contact.
MERGE (l:Lead {name: 'Sara Lin', title: 'Head of Digital'})
MERGE (vp:Person {name: 'Tom Reyes', title: 'VP Engineering'})
MERGE (cfo:Person {name: 'Ada Quinn', title: 'CFO'})
MERGE (co:Company {name: 'Nimbus Retail'})
MERGE (l)-[:WORKS_AT]->(co)
MERGE (vp)-[:WORKS_AT]->(co)
MERGE (cfo)-[:WORKS_AT]->(co)
MERGE (l)-[:REPORTS_TO]->(vp)
MERGE (vp)-[:REPORTS_TO]->(cfo);
Step 7: Find the economic buyer two hops up
Walk the reporting chain to identify who signs off on budget.
MATCH (l:Lead {name: 'Sara Lin'})-[:REPORTS_TO]->(:Person)-[:REPORTS_TO]->(buyer:Person)
RETURN buyer.name AS economic_buyer, buyer.title AS title;
Step 8: Draft personalized outreach (GENERATE)
Stitch the lead's pain and the matched proof into a tailored opener — not a generic blast. First materialize the matched proof (projecting the similarity we order by), then assemble the lead + proof into one context row, then generate from that row.
CREATE TABLE IF NOT EXISTS recipe_sdr_match (proof_id INTEGER PRIMARY KEY, content TEXT, relevance DOUBLE);
INSERT INTO recipe_sdr_match (proof_id, content, relevance)
SELECT proof_id, content,
COSINE_SIMILARITY(embedding, EMBED((SELECT pain_note FROM recipe_sdr_leads WHERE lead_id = 1))) AS relevance
FROM recipe_sdr_proof
ORDER BY relevance DESC
LIMIT 1;
CREATE TABLE IF NOT EXISTS recipe_sdr_ctx (id INTEGER PRIMARY KEY, contact TEXT, company TEXT, pain TEXT, proof TEXT);
INSERT INTO recipe_sdr_ctx (id, contact, company, pain, proof)
SELECT 1,
(SELECT contact FROM recipe_sdr_leads WHERE lead_id = 1),
(SELECT company FROM recipe_sdr_leads WHERE lead_id = 1),
(SELECT pain_note FROM recipe_sdr_leads WHERE lead_id = 1),
(SELECT content FROM recipe_sdr_match LIMIT 1);
SELECT GENERATE(
'Write a 3-sentence cold email opener to ' || contact || ' at ' || company ||
'. Their pain: ' || pain ||
'. Reference this proof: ' || proof ||
'. Be specific, no fluff.') AS outreach
FROM recipe_sdr_ctx;
Cleanup (Optional)
DROP TABLE IF EXISTS recipe_sdr_leads;
DROP TABLE IF EXISTS recipe_sdr_history;
DROP TABLE IF EXISTS recipe_sdr_proof;
DROP TABLE IF EXISTS recipe_sdr_match;
DROP TABLE IF EXISTS recipe_sdr_ctx;
MATCH (n:Lead) DETACH DELETE n;
MATCH (n:Person) DETACH DELETE n;
MATCH (n:Company) DETACH DELETE n;
Expected Outcomes
- Step 4 ranks Nimbus, Atlas, and Helio at the top and the tiny hobby accounts at the bottom — the agent works the right leads.
- Step 5 matches Nimbus's "unify product search" pain to the unified-search case study.
- Step 7 identifies the CFO as the economic buyer two hops up the reporting chain.
- Step 8 drafts a specific opener referencing the lead's exact pain and the matched proof — personalization at scale.
You've built a complete AI SDR — lead scoring, proof matching, committee mapping, and personalized drafting — on one database.
Use it from your agent (framework-agnostic — this is the whole point)
The SDR brain is just leads + a model + a proof index + a graph + GENERATE, so any agent shell drives it with no framework lock-in:
- REST / SDK —
POST /v1/query/execute(any language), or@synapcores/sdkclient.executeQuery(...). Your agent scores leads (Step 4), matches proof (Step 5), finds the buyer (Step 7), and drafts outreach (Step 8) — then hands the draft to a human or sends it. - MCP (native, on by default) — point any MCP client (Claude Code, Cursor, a custom loop, a voice runtime) at
ws://<your-instance>/mcp?token=<jwt>(JWT from onePOST /v1/auth/login→access_token). Thequerytool scores/matches/drafts; theexecutetool runs Cypher for the committee graph and logs activity — the whole outbound loop as tool calls. - Any framework — OpenClaw, a LangGraph sales workflow, a custom loop, or a voice SDR that dials and personalizes live all call the same brain. The database is the brain; the framework is swappable.
Key Concepts Learned
- An SDR agent composes lead-scoring ML, semantic proof matching, a buying-committee graph, and
GENERATEdrafting. - The graph turns "who do I email?" into a reporting-chain walk to the economic buyer.
- Matching the lead's pain to a proof point by meaning is what makes the draft feel personalized.
- Because it's plain data ops (AutoML + SQL + Cypher + GENERATE / REST / MCP), the SDR agent works from any framework — the agent-agnostic backend pattern this cluster builds on.