The Intelligence Layer
One knowledge graph. Per-client namespaces. MCP accessible from anywhere — local Claude Code sessions and cloud Trigger.dev agents alike.
Architecture
Click any node to see what it does and how it connects.
How it works at runtime
What happens when a cloud agent boots up with a client_id.
Client view
What clients see — their graph, gated, interactive.
Their pipeline as a living graph
Clients log in via Supabase Auth. Every query server-side injects their client_id — they cannot escape their namespace. No other client's data is ever visible.
-
✓Click contact nodes → see company, campaign history, reply sentiment
-
✓Click campaigns → see which contacts touched, conversion paths
-
✓Filter by time range, ICP match, pipeline stage
-
✓Full subgraph export on request — portable, ownership clear
-
✓Nobody else gives them this. Most agencies send a Notion doc.
Interactive — Cytoscape.js in production
Integration planning
Click each area to expand. Add your planning notes in the text field.
Campaign sends, reply rates, bounce data flows into the graph. Agents querying "what worked for this client" pull from real campaign history — not guesses.
- Campaign → graph on send
- Reply events write back to Contact nodes
- Positive replies → ICP signal update
Clay CLI runs enrichment waterfalls from the command line — no manual table work. Dashboard buttons can trigger CLI calls via Vercel serverless functions: button click → API route → clay enrich --table client-acme → result streams back. Full CLI/API actions from any UI are completely possible.
- Clay CLI fires enrichment jobs from dashboard buttons
- Enriched contact/company data → graph node attributes
- Waterfall results feed ICP scoring in graph
- Vercel fn = bridge between UI button and CLI binary
Every cloud agent workflow gets MCP access at boot. Pre-established Cypher queries inject per-client context into the system prompt before any task execution.
- MCP URL passed in Claude API call
- client_id scopes all graph queries
- Agent writes learned facts back post-run
lg-restate batch workflows call the graph before executing prompts. Client context snippet injected into prompt templates at runtime — prompts stay generic, context stays dynamic.
- Graph query runs as prompt pre-step
- Context snippet merged into RowRequest
- Results optionally write new nodes back
Profile views, connection accepts, post engagement — these are intent signals. If they flow into the graph, agents can time outreach based on real buying signals.
- Profile view → intent signal on Contact node
- Connection accept → relationship edge
- Trigger.dev workflow watches for signal
Every inbox reply, thread, and lead interaction stored as a Contact node event in the graph. Agent handling a reply already knows full conversation history, prior sentiment, and what was promised — before reading a single email.
- Per-lead reply history → Contact node events
- Sentiment + intent tags written to graph on classify
- Agent pulling context gets full thread summary before responding
- Cross-client patterns surface without leaking data
Graph stores the full conversion chain: Contact → Reply → Interested → Booked → Closed. Every node timestamped. Query: "what % of positive replies converted to bookings for campaign X" is a single Cypher traversal.
- Funnel stages as edges: REPLIED → INTERESTED → BOOKED
- Booking rate per campaign = graph query, not spreadsheet
- Client dashboard shows their funnel live
- Cross-campaign comparisons expose what's actually working
- Cal.com / Calendly webhook → BOOKED edge written on confirm
Clients log in, see their own graph. Supabase Auth gates it. Railway hosts the Next.js app and any CLI workers. Cloudflare sits in front for DNS, edge caching, and DDoS protection. Server-side query injection ensures client_id filter on every Cypher call — clients cannot escape their namespace.
- Railway — Next.js app + CLI worker services
- Cloudflare — DNS, edge cache, tunnel if needed
- Supabase Auth — JWT gates all API routes
- API routes inject client_id into every Cypher query
- Cytoscape.js renders their subgraph interactively
- Export button → APOC dump of their data only