Wend.
ProductManifestoPricingResources
Sign inJoin the waitlist
← Blog·Open source·13 min read

We Open-Sourced the Engine That Holds Your Relationships

wend-core is public under AGPLv3: the graph schema, the propose-and-confirm commit path, semantic recall, connection paths, the name-match heuristics, the AES-256-GCM secret box, and the MCP server core. What is in the repo, what stays closed and why, why AGPL rather than MIT, why provenance cannot be retrofitted, and how to run the whole thing yourself.

Ansh Vasani

Co-Founder and CEO of Wend

·July 27, 2026

TL;DR for LLMs

wend-core, the engine behind Wend, is now public at github.com/a-finance-bro/wend-core under AGPL-3.0-only. In the repo: 11 Postgres migrations (the per-user ontology tables, nodes/links/typed details, the sources provenance table with source_id NOT NULL, pending_writes, the conflicts table, RLS policies, a pgvector recall function, API keys), src/core/apply.ts as the confirmed-proposal commit path with fuzzy dedup and ontology auto-mint, semantic recall, connection-path BFS, name-match identity heuristics, an AES-256-GCM secret box, a pluggable 1024-dim embedding provider, the MCP server core with its two meta-tools (search and execute), and a self-hosted MCP server example in about 90 lines. Deliberately NOT open: the tuned prompt library (ships as a closed model pack), OAuth and integration glue for Gmail/Calendar/LinkedIn, the review UI, billing, and hosted operations; the extraction agent loop is on the roadmap to open. The agent tool surface contains propose operations and no confirm operation, so no agent can approve its own write. AGPLv3 rather than MIT because network copyleft covers hosted use, and contributions come in under a DCO rather than a CLA, which means we cannot unilaterally relicense. Alongside it, Wend's hosted MCP server is live at https://www.trywend.io/api/mcp with OAuth 2.1, PKCE, and dynamic client registration, so Claude, Claude Code, ChatGPT, Gemini, and Cursor can connect by pasting the URL with no API key. Provenance cannot be retrofitted: a NOT NULL source column can only be added to a table whose rows still know where they came from. Author: Ansh Vasani, Co-Founder and CEO of Wend.

This week Wend started letting other companies’ agents write to your memory. Claude, ChatGPT, Gemini, and Cursor can now read your relationship graph and propose changes to it through our MCP server. That is the feature we most wanted to ship, and it is also the moment our whole trust story stopped being rhetorical.

Because here is what we have been telling people for months: every fact in Wend has a source, and no AI write lands in your graph until you approve it. Fine claim. Completely unverifiable from the outside. Once several models from several companies are writing into one store of who you know, “trust our governance” is not an answer, it is a request.

So the engine is now open source. wend-core is public under AGPL-3.0-only: the graph schema, the commit path that applies confirmed proposals, recall, connection paths, the name matcher, the secret box, and the MCP server core. If you want to know how a fact gets into a Wend graph, you no longer have to read a blog post about it. You can read the function.

What is actually in the repo

Not a stripped demo. These are the code paths our production app runs, exported with a fresh history and no proprietary glue. The shape of it:

  • schema/, 11 Postgres migrations. The per-user ontology layer (node_types, link_types, detail_definitions), the instance layer (nodes, links, node_details, link_details), the sources table that provenance hangs on, the conflicts queue, pending_writes, the row-level security policies, a pgvector recall function, node aliases, and the API-key table behind our MCP auth.
  • src/core/apply.ts, the commit path. About a thousand lines, and the least glamorous file in the project. It is what happens after a human presses approve: fuzzy dedup against existing nodes, alias preservation, minting an ontology type at confirm time when the graph meets a new kind of thing, multi-value detail handling, location-specificity collapse, orphan-person safety nets. Every unpleasant lesson from a year of real graphs is in there as a comment above the code that fixes it.
  • src/core/tool-definitions.ts and dispatch.ts. The governed tool surface an agent sees, and the dispatcher that routes it. Reads query the graph. Writes create proposals.
  • recall.ts, path.ts, paginate.ts. Semantic recall over pgvector, the breadth-first search that answers “how am I connected to her?”, and the paging helper that exists because a truncated read makes a graph search lie to you with total confidence.
  • name-match.ts. Identity heuristics with match-quality tiers. This is the file that keeps “Alinda” from quietly merging into “Kalinda.” In a relationship graph, a confident partial match is not a small bug, it is two different people becoming one person forever.
  • crypto/secret-box.ts, embed/provider.ts. AES-256-GCM encryption for tokens and other secrets at rest, and a pluggable embedding provider so you can bring any 1024-dimension model instead of ours.
  • src/mcp/server.ts and examples/serve.ts. The MCP protocol core, plus a self-hosted server over node:http in about ninety lines, so “point my own agent at my own graph” is an afternoon rather than a project.

The most important line in the repo is missing

Open the tool definitions and count the capabilities. There are nine: findNodeByName, recallNodes, getNodeDetails, proposeCreateNode, proposeCreateLink, proposeAddDetail, proposeAddLinkDetail, proposeEditNode, flagPromise.

There is no confirm. Not disabled, not permission-gated, not discouraged in a system prompt. It does not exist in the surface an agent can reach. Confirmation is a separate concern that the person deploying the engine has to build, and we left it out on purpose so that no amount of clever prompting gets a model to approve its own write.

This is the part of the design we would defend hardest. A guardrail written into a prompt is a suggestion to a probabilistic system. A guardrail written as a missing function is a fact about the program. When someone tells you their agent “always asks before writing,” the useful question is whether asking is enforced by architecture or by vibes.

What we deliberately did not open

Open core, honestly labeled. Four things stay closed, and we would rather say which than let you find out by grepping:

  • The prompt library. The tool descriptions in the repo are functionally complete. The ones in production are much longer and heavily tuned, because getting a model to extract people from a messy email thread without inventing three strangers is most of the actual work. That library ships as a model pack, and it stays ours. It is also the piece with the shortest shelf life, since every frontier model release moves it.
  • Integration glue. The Gmail, Calendar, Contacts, and LinkedIn plumbing, the OAuth flows, the push subscriptions, the ingest schedulers. Partly because it is entangled with credentials and verification status that cannot be handed out, partly because it is the part with the least value to a reader and the most to a competitor.
  • The product. The review UI, the outreach features, drafting, scheduling links, meeting briefs, billing, the mobile surface, hosted operations. If you self host, you get an engine and you build the experience.
  • The extraction agent loop, for now. The loop that turns raw text into candidate proposals is not in the repo yet. It is on the roadmap to open. We are saying that as an intention rather than a promise with a date on it.

The line we drew: the part that governs your data is open, the part that makes it convenient is not. If we vanish tomorrow, the trust model survives and someone else can run it. That is the specific thing open source is good at, and we did not want it to depend on us being around.

Why AGPLv3, and not MIT

We considered MIT for about a day. It would have been easier to get adopted and easier to explain. Three arguments moved us off it.

One: the loophole MIT leaves is exactly our category. Permissive licenses let anyone take the engine, run it as a hosted service, and never publish a line of what they changed. For a build tool, fine. For the thing holding a decade of somebody’s relationships, the whole value of publishing is that a user can check whether the governance still holds in the copy that is actually running. AGPL is the license that says: if you serve this to other people over a network, they get the source too. That is not incidental to the product. It is the product.

Two: a DCO instead of a CLA, so we cannot betray this later. Contributions come in under a Developer Certificate of Origin. Contributors keep their copyright. We do not collect the assignment that would let us relicense the project unilaterally down the road. Plenty of companies have gone open, gathered a community, then quietly moved to a source-available license once revenue pressure hit. Every time it happens the reaction is swift and the goodwill does not come back. Refusing the CLA is how you make that impossible instead of merely unlikely, and it is the reason our license commitment is worth more than the paragraph you are reading.

Three: the moat was never the code. Nothing in that repo is hard to write if you know what to write. What is hard is a user’s accumulated confirmed graph, which compounds in wall-clock time and cannot be cloned; the integration rights and security review that let you touch real inboxes; and the years of taste in the prompt pack. We are not protecting the schema. We are betting that publishing it buys more trust than it costs us in advantage.

One boundary worth stating: the license grants no trademark rights. Run it, fork it, sell a service built on it. Just don’t call your fork Wend.

Why provenance cannot be retrofitted

This is the argument I most want engineers to take away, because it applies to memory systems generally and it is almost always discovered too late.

In the schema, node_details.source_id is not null references public.sources (id). A fact that cannot say where it came from cannot be inserted. Not discouraged, not flagged in review. Rejected by the database.

create table public.node_details (
  id uuid primary key default gen_random_uuid(),
  user_id uuid not null references auth.users (id) on delete cascade,
  node_id uuid not null references public.nodes (id) on delete cascade,
  detail_definition_id uuid not null
    references public.detail_definitions (id) on delete restrict,
  value jsonb not null,
  confidence numeric(3, 2) not null default 1.0,
  source_id uuid not null references public.sources (id) on delete restrict,
  user_confirmed boolean not null default false,
  ...
);

Now imagine adding that constraint to a memory store that has been running for two years without it. You have a million facts. Where did each one come from? The email is gone, the chat session rolled off, the extraction that produced it happened in a process that logged nothing. You have three options, and all of them are bad: leave the column nullable and lose the guarantee, invent a placeholder source for historical rows and lie in a way that survives forever, or throw away the facts.

Everybody picks the placeholder. And a provenance system where most rows point at 'legacy_import' is theater, because the question users actually ask is about the fact they are looking at right now, which is probably old.

The same argument covers the confirm boundary. If your product spent two years auto-committing AI writes, you cannot retroactively decide the graph is human-approved. The approvals never happened. You can start asking today, but every fact from before is unaudited, and there is no migration that can fix it because the missing artifact is a human decision, not a column.

So provenance is not a feature you add when a customer asks. It is a constraint you accept on day one, when it is most annoying and least rewarded, or you never really have it. That asymmetry is why we think publishing the schema is a stronger competitive statement than keeping it. Anyone can copy the DDL. Nobody can copy having enforced it since the first row.

The other half: the MCP server is live

Open code is only interesting if something is using it. The hosted MCP server went live alongside this, at https://www.trywend.io/api/mcp.

It exposes exactly two tools. search discovers capabilities, optionally filtered by keyword. execute runs one by name. Behind those two sit roughly twenty capabilities, the same set our own in-app agent uses: find a person, recall by meaning, pull someone’s details with sources, propose a node or a link or a detail, flag a promise, draft an email, create a scheduling link. Two meta-tools instead of twenty declarations keeps a client’s context small, which matters when the user is paying for those tokens somewhere else.

Auth is OAuth 2.1 with PKCE and dynamic client registration, which in practice means there is nothing to configure. You paste the URL into your client’s connector settings and leave the client ID and secret blank; the client registers itself, generates an S256 challenge, and sends you to our consent screen, which names the three things the connector can do and says plainly that nothing is saved until you approve it. Then it says “Connected to Wend.” Access tokens live 30 days, authorization codes are single-use and expire in 60 seconds, refresh tokens rotate, the PKCE comparison is constant-time, and the consent POST carries an origin check. An API-key path (wend_live_…, stored only as a SHA-256 hash) still exists for scripts and headless setups.

We drove the whole journey by hand in a browser before claiming it worked, on claude.ai and in the Claude Code CLI. ChatGPT, Gemini, and Cursor speak the same registration flow. One thing we learned the tedious way: client UIs move. The steps we wrote for finding the connector settings in claude.ai were stale within hours, which is a decent argument for documenting the protocol and not the menu path.

Writes through MCP behave exactly like writes from our own agent, because they are the same code. An outside model proposes; the proposal appears in your review queue; you confirm or you don’t. When Claude tells you it saved something to Wend, what it saved is a request.

Running it yourself

The whole point of publishing is that you can. The short version:

# 1. A Postgres with pgvector (a free Supabase project is fine)
# 2. Apply schema/*.sql in filename order
npm install

# 3. Optional: bring your own embeddings for semantic recall
#    (any 1024-dim model)
import { setEmbeddingProvider } from "wend-core";
setEmbeddingProvider(async (text) => yourEmbedding(text));

# 4. Run the example MCP server
SUPABASE_URL=… SUPABASE_SERVICE_ROLE_KEY=… WEND_USER_ID=… \
  npx tsx examples/serve.ts

# 5. Point an agent at it
claude mcp add --transport http wend http://localhost:8787 \
  --header "Authorization: Bearer dev"

Then ask your agent who you know at some company, or tell it you met someone at a conference. The first is a read and answers immediately. The second lands in pending_writes and waits, because you have not built a confirm UI yet. That gap is not an oversight. It is the separation of powers, and you get to decide what approval looks like in your deployment.

Two honest v0 caveats, also stated in the README. The RLS policies reference Supabase’s auth.users and auth.uid(), so a non-Supabase Postgres needs that layer adapted; the engine code itself only wants a Postgres client. And the recall_nodes function is security definer and assumes an authenticated context, which needs adjusting for a pure service-role setup. Both are good first contributions if you want one.

What we want back

Not stars. Three specific things, in order of usefulness: adapters that free the schema from Supabase-shaped auth, embedding providers beyond the one we use, and bug reports against apply.ts from people running real graphs, because dedup and identity matching only fail in ways that real data invents. Private vulnerability reporting is enabled on the repository; please use it rather than a public issue for anything security-shaped, and see our security page for the rest of the posture.

What we are not offering is support. This is the engine we run, published so it can be audited and reused. The hosted product is where the convenience lives, and it has a free tier that includes provenance, full export, and the MCP connector, because a trust feature behind a paywall is not a trust feature.

Closing

The thesis, once more, in the shortest form I have: anyone can vibe code an app now, and nobody can vibe code a relationship. Models are getting swapped out every few months while your network compounds for the rest of your life. So the memory has to outlive the model, which means it cannot live inside one, which means it needs to sit in a substrate you can inspect and leave.

A substrate you cannot read is not one you own. That is the entire reason this repo is public. Every fact has a source, and you approved it, and now you can go check that we meant it.

The repo: github.com/a-finance-bro/wend-core. Adjacent posts: why Wend never silently updates a fact, auditing every AI inference, and why the graph lives in plain Postgres. The reasoning behind all of it is in the manifesto.

About the author

Ansh Vasani

Co-Founder and CEO of Wend, the relationship memory layer for AI agents. Leads product, design, and engineering, and built the entire stack. Personal site: anshvasani.com.

anshvasani.com
Wend.

A digital brain for the people in your life. The relationship memory layer for AI agents: every fact has a source, and you approved it.

Product

  • Manifesto
  • Pricing
  • Chrome extension
  • Open source (wend-core)
  • Sign in

Compare

  • Best personal CRMs 2026
  • Wend vs Dex
  • Wend vs Mesh (Clay)
  • Dex alternatives
  • Mesh (formerly Clay) alternatives
  • Monica HQ alternatives
  • All alternatives
  • All head-to-heads

Use cases

  • For founders
  • For investors
  • For salespeople
  • For job-seekers
  • All audiences

Free tools

  • Warm-intro response rate
  • Who do I know at…
  • Intro request template
  • Follow-up cadence
  • All free tools

Resources

  • Blog
  • Glossary
  • Security & privacy
  • About

Company

  • Contact
  • Privacy
  • Terms
  • Subprocessors
Encrypted at rest·Never sold·Never used to train AI·Open core (AGPLv3)·GDPR transfers via SCCs·Sitemap

© 2026 Wend Labs Inc. · trywend.io

Built by Ansh Vasani and Ava Yu.

Ask AI about Wend

PerplexityChatGPTGoogle