How to build your own context graph for your go-to-market team
Updated
The short answer. A context graph for go-to-market is one store that holds every person, company, deal and conversation your team has, links them to each other, and keeps a source on every fact. To build one, write down the questions it has to answer, ingest email, meetings, calendar, Slack and your CRM, resolve every person and company to one ID, store it in Postgres or a graph database with embeddings next to the text, keep it current with event-driven syncs, and give your agents access over MCP. One person can get a working version in a few weeks. The hard part starts when a second person uses it: whose email each person and agent may see, keeping every sync current, and knowing whether the agents' output is any good.
If you're reading this, you have probably started already. There's a folder on your machine with markdown files, a few skills, a Claude Code session that knows your pipeline, maybe a cron job pulling call transcripts. It answers questions nobody on your team could answer before, and you were right to build it. This guide covers the rest: the parts a solo build skips, what each one takes, and where it makes sense to stand on something that already exists.
What a context graph is
People use "context graph" two ways. Foundation Capital's essay on the term describes decision traces: the record of why a decision was made, who approved it, and what they knew at the time. Engineers building agent memory use it for a graph of entities and relationships that an agent can walk to assemble context. In go-to-market the two meet, because the why behind a deal lives in its emails and calls. A graph that keeps those conversations whole, attached to the people, companies and deals they're about, holds both.
Three neighboring terms get mixed up with it:
- RAG (retrieval-augmented generation) finds chunks of text similar to a question and hands them to a model. A context graph also knows that the chunk came from the March 4 thread with Jane, that Jane is the VP Finance at Acme, that the thread is about the expansion deal, and who on your team may read it. Most context graphs use RAG inside them.
- A CRM stores fields that people type into a schema someone defined in advance. A context graph stores what happened and derives fields from it, so a field you invent today can be filled from last year's calls.
- A company brain is the broader idea: everything your company knows, available to people and agents. For a go-to-market team, the context graph is the customer half of it.
How to build one, step by step
1. Write the questions first
Write down 10 to 20 questions the graph has to answer, in the words your team uses. For example:
- Who at this account have we talked to, and who signs?
- What did we promise this customer on the last call, and did we send it?
- Which open deals have had no reply in two weeks?
- Why did we lose to that competitor last quarter, in the buyers' own words?
- What should I know before tomorrow's 10am?
Every source and every field you add should help answer one of these. If it doesn't, leave it out of version one.
2. Choose your sources, in order of signal
The deal lives in email and on calls. A CRM export with every dropdown filled holds very little of what happened, so start with conversations and attach the structured data to them.
| Source | What it holds | How you get it | Watch for |
|---|---|---|---|
| Email (Gmail, Outlook) | Pricing pushback, redlines, the champion going quiet, "let me loop in our CFO" | Gmail API (users.watch push through Cloud Pub/Sub, history.list for changes); Microsoft Graph for Outlook |
Every person's mailbox has different rules about what may be shared (see where it breaks) |
| Meeting transcripts (Gong, Granola, Zoom, a notetaker) | Objections, competitors named, commitments, who was in the room | Each vendor's API; most expose calls, participants and transcripts | Speaker labels and attendee emails vary by vendor |
| Calendar | Who met whom, and what's coming up | Google Calendar API or Microsoft Graph | Separate internal and external attendees early |
| Slack | Internal deal discussion, shared channels with customers | Events API for new messages, conversations.history for backfill |
The bot only sees channels it's a member of; private and shared channels need care |
| CRM (Salesforce, HubSpot) | Stages, amounts, owners, close dates | REST APIs, plus change events or webhooks | It holds what people typed, so treat it as one more source |
| Support and product usage (Zendesk, your warehouse) | Tickets, usage, health | APIs or warehouse tables | Joins to accounts by domain or account ID |
3. Decide schema-first or schema-later
Schema-first means you define objects and fields up front (deal stage, next step, competitor, MEDDPICC) and extract into them. Queries are cheap and predictable. Anything the buyer said at minute 38 that fits no field is gone, and a new field means re-running extraction over everything you've stored, if you kept it.
Schema-later means you store primary sources at full fidelity, whole threads and whole transcripts, linked to the people, companies and deals involved, and derive fields from them when you need them. It costs more storage and compute. It wins when your questions change, and in go-to-market they change every quarter.
What works in practice is a thin fixed core plus derived properties:
- Core objects: Person, Organization, Opportunity, and Interaction (an email thread, a meeting, a Slack message) with participants, time and source.
- Raw sources: the full text, kept, so you can re-derive anything later.
- Derived properties: fields a model fills from the sources, like pain points or the next step, each stored with its provenance.
Put provenance on every derived value from day one. Retrofitting it is close to impossible, because the information was thrown away at ingest.
-- one row per value, per version
create table property_value (
object_type text, -- person | organization | opportunity
object_id uuid,
property text, -- e.g. 'competitors'
value jsonb,
source_type text, -- email_thread | meeting | slack | crm | model
source_ids text[], -- the exact thread, message, or transcript span
derived_from uuid[], -- earlier property_value rows this was built from
visible_to text, -- who may read it (see "Where it breaks")
written_by text, -- person, sync job, or agent
valid_from timestamptz,
valid_to timestamptz
);
4. Resolve identity before anything else
The same person shows up as an email address in Gmail, a display name in Slack, a participant in Gong, and a contact in HubSpot. Until those are one ID, the graph is a pile of tables.
- People: key on the normalized email address. Keep an alias table, because one person can have several addresses. Map Slack users to email through the user profile. Match transcript participants by email where the vendor provides it, and by name plus meeting attendees where it doesn't.
- Organizations: key on the email domain. Exclude free-mail domains like gmail.com, handle companies with several domains, and decide how you treat subsidiaries.
- Opportunities: the hardest link. Match on organization, the people involved, and the time window, let a model propose the link with a confidence score, and route low-confidence links to a person.
- Keep a merge log. A wrong merge spreads one customer's history into another's. You need to be able to undo it.
5. Pick storage
| Option | Good for | Trade-off |
|---|---|---|
| Postgres with pgvector | The default. Relationships as tables and joins, vector search over the text, one database to run | Multi-hop questions mean recursive SQL |
| A graph database (Neo4j, Memgraph, FalkorDB, Amazon Neptune) | Multi-hop questions: "who do we know who used to work at this prospect?" | Another system to run; you still need text search beside it |
| A temporal knowledge graph framework (Graphiti, open source from Zep) | Facts that change over time; ingests episodes and keeps time-bounded facts | You still own ingestion, identity across sources, and permissions |
| Agent memory libraries (Mem0, Zep, LangGraph memory stores) | Memory for one agent or one user across sessions | Built around a user's memory, so a shared team record with per-person visibility is yours to add |
| Markdown in git | Where most folders start; Claude Code reads it well | Permissions stop at the repo: everyone with access sees every file |
| Enterprise search (Glean, Notion AI) | Searching documents and messages with each tool's own permissions | Organized around documents; the person, company and deal aren't the unit |
For a first version, Postgres with pgvector is enough for most teams.
6. Build retrieval for agents
An agent asking "what's going on with Acme?" should get the right context in one or two calls, with sources attached.
- Hybrid search: keyword and vector search over the text, then a walk outward from the matched person, company or deal.
- Precomputed account summaries, regenerated when new data lands, each sentence linked to its sources.
- Citations on everything: source ID and timestamp with every fact, so the agent can quote the call or the email and a person can check it.
- Tools shaped like jobs. A few broad tools like
get_account_context(domain),search_conversations(query, account)andget_timeline(entity, since)work better for agents than one tool per table.
7. Keep it fresh
- Push where the source supports it: Gmail
users.watchto Pub/Sub, the Slack Events API, Microsoft Graph change notifications, CRM change events. - Incremental cursors everywhere else, fetching only what changed since the last run.
- Idempotent upserts keyed on source IDs, so a replayed event does no harm.
- End-date facts when the source changes or deletes them, so stale facts don't sit next to current ones.
- Re-derive the summaries and properties that depend on anything that changed.
- A nightly reconciliation job that compares the graph to each source and fixes what the event stream missed.
- Track lag per source, and alert when one stops.
8. Give agents access over MCP
Wrap the store in an MCP server (the official TypeScript and Python SDKs both work) that exposes the tools from step 6. Connect it to Claude Code with claude mcp add, and to any other MCP client the same way. Three rules:
- Authenticate the person. The server should know who is asking, so it can apply that person's visibility.
- Start read-only. Add write tools one at a time, with approval on anything that touches a customer.
- Log every call: who asked, which tool, what came back.
9. Evaluate before you trust it
Write 20 to 50 questions from real accounts with known answers. Grade each answer on three things: is it correct, does it cite the right source, and did it leak anything the asker shouldn't see? For that last one, ask as a rep a question whose answer lives only in someone else's private thread. The right answer is that the agent can't see it. Re-run the set on every change and once a week.
A version you can build this week. Your CRM export, your Gong or Granola transcripts, and your own inbox, in Postgres with pgvector. One MCP server with three tools. Twenty test questions. It will work well, for you.
Where a homemade context graph breaks
The week-one version works because it has one reader. Nearly every hard part of a context graph appears when it gets a second one.
Email, and who can see whose mail
Your own inbox takes an afternoon. A team's email is a different problem, because every person's rules differ. A rep shares every customer thread but keeps HR, legal and personal mail private. A CEO shares almost nothing, and still expects the one thread that decided a deal to show up in the account's history. The CRO wants activity across every inbox. Those rules have to hold on every thread, for every person and every agent, and they have to be applied when the mail comes in, because a summary or embedding built from a private thread leaks it.
Google adds a gate. Reading Gmail takes a restricted scope. Once your app has users outside your own Workspace, it has to pass Google's verification, and because it keeps mail on your servers, a security assessment by a Google-approved third party, repeated at least once a year. Until it's verified, it's capped at 100 users. Inside your own Workspace, an internal app skips verification and the cap. The other common route, a service account with domain-wide delegation, can read every mailbox in the domain. Either way, every permission lives in your code.
Then there's removal. When a thread should never have been ingested, you have to delete it and every summary, embedding and derived field built from it. That takes the lineage from step 3, recorded from the first day.
The second user
The fix for email turns out to be the fix for everything else a second person touches. Most homemade graphs read through one API key per source, and almost every SaaS API key sees everything. Filtering results at read time works until someone forgets a filter. Who may read each thread, transcript and message has to be decided when it arrives and stored with it, and every agent has to run as the person it works for.
A second user usually also means someone who will never open a terminal. What took you weeks to shape for yourself needs a way to reach them in Slack or email, a way to see what their agents did, and a way to fix a skill when it misfires. That's a deployment product, built on top of the graph.
Keeping syncs fresh
Even with permissions right, the graph is only as good as its newest data. A redline that lands at 4pm on the last day of the quarter is useless to a nightly job. Each source fails in its own way: a Gmail watch expires after seven days unless you renew it, a Slack bot misses channels nobody added it to, a vendor changes an API, a token expires, and a cron job on someone's laptop stops when the laptop does. Every new source also needs a backfill, and backfills are where weekends go.
Identity across Slack, Gmail and Gong
Every source you add has to be matched against every source already in. People change jobs, use personal addresses, and appear in Gong under a nickname. A bad merge is worse than a missed one, because one customer's history starts showing up in another's briefing.
Schema drift
Even with every source matched, your business changes faster than your schema. New pricing, new stages, a new competitor. Each new field means re-deriving it across history. Skills drift the same way: a prompt tuned for last quarter's pipeline keeps running against this quarter's, and nothing tells you its output got worse.
Evaluating what agents produce
That's why evaluation can't be a one-time step. Once agents draft emails, update deals and brief reps, you need a record of what each one did, on what evidence, and how good it was. Without it you hear about a bad draft from the customer who received it.
None of this means you can't build it. Teams do. It means finishing costs more than starting: a permissions layer, an ingestion pipeline per source, identity resolution, lineage and purge, a deployment surface, and an eval harness, each maintained for as long as the business runs. And when one breaks, the cost isn't a missed sprint. It lands on your customers, in an email sent from stale data or a thread someone shouldn't have seen.
How Day AI handles those parts
Day AI provides the context graph and agent control plane to quickly and securely upgrade your company brain. You can run it as your CRM, with pipeline, contacts and companies kept current from your team's conversations, or on top of Salesforce or HubSpot. Either way you keep your folder, your skills and Claude Code. They connect to Day AI over MCP, to a graph built for the parts above.
| The hard part | Build it yourself | In Day AI |
|---|---|---|
| Team email with per-person rules | Sharing rules, thread ACLs at ingest, Google verification or domain-wide delegation | Each person connects their own Gmail and sets sharing rules |
| Visibility for every reader and agent | A visibility field on every record, enforced in every query | Each thread's visibility decided at ingestion; agents act as their person |
| Freshness | Webhooks, cursors, renewals, reconciliation, lag alerts | Continuous ingestion and a native recorder |
| Identity resolution | Match keys, alias tables, merge log, review queue | Every source resolves to the same people, companies and deals |
| Schema drift | Re-derive fields across history by hand | Custom properties filled from history by an agent |
| Provenance | A lineage table, recorded from the first day | Citations to the call or the message; a history of who changed each value and why |
| Evaluating agents | Golden sets, logs, graders | Skill run history and edit-by-feedback; the evaluation skill for your own build |
| Your other tools | An integration per tool, written and kept running by you | Connect any MCP server; agents read from it and write to it where it allows writes, so the Salesforce or HubSpot MCP gives two-way sync |
Email with each person's rules
Each person connects their own Gmail and Calendar, and nothing they have is shared until their sharing rules say so. One setting picks the default, share everything or nothing, and rules carve out exceptions by domain, by address, or by Gmail label. In share-everything mode, Day AI suggests domains to keep private, such as banks, e-signature services and recruiters. Day AI decides who can see each thread as a step in ingestion, before a message becomes anything a person or agent can read. When the same message sits in several teammates' inboxes, a private rule from any of them keeps it private, and one private message keeps its whole thread private.
Recorded meetings follow the same idea. One-on-ones and group meetings can have different defaults, and when attendees' settings conflict, the most private one wins.
Email in the graph comes from Google Workspace today. Outlook mail doesn't sync into it. Agents can reach Outlook, Outlook Calendar and Teams live, through connectors in beta.
Agents see what their person sees
An agent inherits the permissions of the person it works for, so every answer it gives and every action it takes stays inside what that person may see and do. In other systems, agents act under their person's own login.
Connect your MCPs, including Salesforce and HubSpot
Day AI supports connecting MCP servers, so your agents work with the tools you already use. Connect one and your agent can read from it. If the server supports writes, your agent can write to it when you ask, or a scheduled skill can do it on a cadence. Salesforce and HubSpot are the main example: connect their MCP and you get two-way sync, with agents reading from your CRM and writing back to it. A skill can update deal stages, notes and fields after every call, or pull CRM data into the graph on a schedule. Each person connects with their own login, through an OAuth app your company registers, so no shared admin key sits in the middle. If you want something custom, build it on the Day AI SDK.
Fresh by default
The notetaker writes the meeting into the graph when it ends. Email arrives continuously, and a new person's first email and calendar sync takes one to six hours. Gong and Granola connect with their full history, so a new workspace can start with years of calls already in it. Slack ingests from the moment the Day AI app joins a channel. Because the graph knows when something happens, skills can run on events, such as a recording being ready or an email landing, as well as on a schedule.
One graph, with history you can restructure later
Every source resolves into the same people, organizations and opportunities, and anyone your team emails becomes a contact automatically. Custom properties start from a definition an agent follows, filled from your team's conversations, from web research, or both, and backfilled across all the history already in the graph.
A composite of what we see in customer workspaces: a founder asks their agent to add a follow-up date to every deal, taken from dates buyers mentioned or set a few days after the last email. The agent proposes the property, tests it on three deals in different stages, then fills in the rest.
We learned why this matters on our own pipeline. We tracked competitors as free text, and when we looked at what the agent had captured across our deals, the most common competitor wasn't a company. It was teams deciding to build it themselves. A picklist would never have had that option. Some of those teams came back to us two or three months later.
Every fact traced to its source
Answers cite the call clip or the message they came from. Every value keeps its history: who changed it, a person or an agent, when, why, and what it was derived from.
Agents you can watch and fix
Every skill keeps a history of its runs. When one isn't doing what you want, you tell the agent, it shows you the skill definition, you change it, and every later run uses the change. To grade the build you already have, the company-brain-evaluation skill runs in your folder and scores it on safety, performance, capability and adoption.
It works with what you've built
The graph is exposed over MCP, with OAuth, at https://day.ai/api/mcp, and day.ai/mcp walks through setup for Claude, Claude Code and Cursor. Any other client that speaks MCP connects the same way. The MCP comes with every Day AI agent from the Turbo tier up, some tools are reserved for higher tiers, and there's no usage-based pricing. The Day AI SDK is an MIT-licensed TypeScript client for the same tools, for scripts, syncs and apps of your own. Our marketing team runs its work this way: a Claude Code repo with our skills in it, reading and writing the same graph the rest of the company uses.