The open-source meta-model for operating a company. → companygraph.io
A company's knowledge is scattered across wikis, decks, tickets and chat threads — each with its own structure, its own half-truth, and nothing that can check any of it. CompanyGraph is the structure that knowledge takes instead: one Markdown file per entity, in folders named for their type, with schemas saying what each type carries. People can read it, and agents can rely on it.
It is not invented. It is the generalization of a model that already works in two places that never knew about each other — a multi-person company, and a company of one. Both arrived at the same shape.
| Repository | What it is |
|---|---|
| meta-model | The vocabulary: core types and the packs a kind of company adds, one schema per type, the conventions that make a graph of Markdown files checkable, a worked example, and the companygraph command that makes an instance, keeps it current and installs the Obsidian plugin, from a menu or by name |
| mental-model | CompanyGraph described in its own vocabulary — the second instance, and the first whose subject is a project rather than a person |
| mcp-server | A read-only MCP server over any instance: an agent asks which types a company declares, what one entity says and what evidence a claim rests on, and it draws a part of the model as a diagram; every answer is what the model says at one commit |
| mcp-companygraph-io | The MCP server running on CompanyGraph's own model, at mcp.companygraph.io, the address to give a client; every answer is what that model says at one pinned commit |
| obsidian-plugin | An Obsidian plugin for any instance: the meta-model's checks while a file is edited, and completion for what its schemas declare; the meta-model's command installs it |
| chat-server | A chat over any instance's MCP host: a visitor asks in their own words on a site, the service asks the host's tools and Claude writes the answer from what they said, naming the entity each claim rests on, answering a grouping as a table and a structure as the picture the host drew; it holds no model and pins no commit |
| companygraph.github.io | The site at companygraph.io — landing page with the vision and values, the model, its processes, principles and surfaces, the CLI, the talks, billing, privacy, and a chat that answers from the model |
New here? The short introduction is the fastest way in: why a company's knowledge lives everywhere and nowhere, what two companies that never met both arrived at, and what is written today. DE · EN. The other talks go further: one on core and the packs, one on each pack, and one each on the Obsidian plugin, on how far a model reaches and on what stays when the model changes.
One repository defines the vocabulary; everything else takes it. An instance is a folder of Markdown that vendors core/ at a release and records which one, so a graph written last year still says what it meant. A site pins the repository it renders by commit, so a page and the model it was built from move together on purpose.
flowchart TB
subgraph cg["companygraph"]
MM["<b>meta-model</b><br/>the vocabulary: core types,<br/>packs, one schema each,<br/>the conventions,<br/>and the companygraph command"]
SITE["<b>companygraph.io</b><br/>landing with the vision,<br/>the CLI, model pages, the talks"]
MCP["<b>mcp-server</b><br/>read-only MCP<br/>over any instance,<br/>and its diagrams"]
CGMM["<b>mental-model</b><br/>CompanyGraph, described<br/>in its own vocabulary"]
PLUGIN["<b>obsidian-plugin</b><br/>the checks, while<br/>a file is edited"]
MCPCG["<b>mcp.companygraph.io</b><br/>and chat.companygraph.io,<br/>on the second instance"]
CHAT["<b>chat-server</b><br/>a chat over any<br/>instance's MCP host,<br/>in tables and pictures"]
end
subgraph gg["guestgraph"]
GGMM["<b>mental-model</b><br/>GuestGraph, described<br/>in this vocabulary"]
GGIO["<b>guestgraph.io</b><br/>landing, model pages<br/>and the problems"]
MCPGG["<b>mcp.guestgraph.io</b><br/>and chat.guestgraph.io,<br/>on the third instance"]
end
subgraph rb["robertblust"]
MENTAL["<b>mental-model</b><br/>the reference instance:<br/>one company, described"]
BLUST["<b>blust.ch</b><br/>profile, model pages<br/>and the blog"]
MCPD["<b>mcp.blust.ch</b><br/>and chat.blust.ch,<br/>on the reference instance"]
DESIGN["<b>design</b><br/>tokens, page chrome<br/>and the page checks"]
end
MM -- "core vendored at a release" --> MENTAL & GGMM
MM -- "core and every pack, at a release" --> CGMM
MM -- "the parser and checks, by tag · bundled" --> PLUGIN
MM -. "the command installs its newest release" .-> PLUGIN
MM -- "the instance parser, by tag" --> MCP & SITE & BLUST & GGIO
MM -- "pinned by commit · builds the model pages" --> SITE
CGMM -- "pinned by commit · builds the model pages" --> SITE
MENTAL -- "pinned by commit · builds the model pages" --> BLUST
GGMM -- "pinned by commit · builds the model pages" --> GGIO
MCP -- "pinned by tag" --> SITE & BLUST & GGIO
MCP -- "pinned by tag" --> MCPD & MCPCG & MCPGG
CHAT -- "pinned by tag · deployed beside each server" --> MCPD & MCPCG & MCPGG
MENTAL -- "pinned by commit · parsed into a snapshot" --> MCPD
CGMM -- "pinned by commit · parsed into a snapshot" --> MCPCG
GGMM -- "pinned by commit · parsed into a snapshot" --> MCPGG
DESIGN -- "pinned by tag" --> SITE & BLUST & GGIO & MCPD & MCPCG & MCPGG
BLUST -. "the chat button asks" .-> MCPD
SITE -. "the chat button asks" .-> MCPCG
GGIO -. "the chat button asks" .-> MCPGG
The dotted lines are the ones that are not pins. The command fetches the plugin's newest release when it runs, because the plugin already pins the meta-model and a pin back would make each release wait on the other, and a site's chat button sends a visitor's question to the chat beside its server. The meta-model is the only vocabulary anything else depends on, and it depends on nothing; design gives the sites and the deployments their look and their page checks, and holds no vocabulary. That is what lets an instance live in a repository of its own, under its own license, on a machine that never runs any of this.
- One Markdown file per entity — frontmatter for the fields, a Markdown body for the prose. A document holding many entities as headings has no name to reference any of them by
- An entity is a file when it owns nothing, and a folder when it owns collections of its own — one mechanism, not two
- The canonical name of an entity is its H1 — not a
namefield, not the filename, and no fallback chain between them - Every reference is by canonical name, never by path — moving a file breaks nothing, and renaming an entity breaks loudly rather than quietly
- Schemas are Markdown, read by agents and by the checker alike — not a stage on the way to JSON Schema, and no second format kept for the checker
- Apache 2.0 — the meta-model is open source and stays that way
Core defines a type without obliging you to populate it: a company that does not group what its people have achieved writes no achievement-kind, and the type stays in core either way. A pack is for vocabulary a kind of company would not have at all — what a pack is →
-
✅ The person cluster —
profile,experience,skill,proficiency-levelandvalue, the conventions that make them checkable, and a worked example. One person described completely, rather than every type partially. -
✅ The reference instance — a real company described in this vocabulary:
robertblust/mental-model, a company of one, laid out by hand before the tooling existed. What it taught is §7 of its spec. -
✅ The rest of core — after the person cluster came
identityandvision, which let an instance name the company it describes and say where it is going;source,identifierandlocalization;experience-kindandachievement-kind;surface; direction'sstrategic-objective,strategyandkpi;seat, the responsibility a process names in each phase; operation'sprocess,phaseandtrack;productwith itsproduct-kind,feature,domainandconcept;questionandquestion-kind;brand;decisionwith itsdecision-kindanddecision-status;rule,riskandcontrol, with a KPI naming the controls it assesses; anddata-processor,processing-activityandstored-item, for what a privacy page and a record of processing have to say. A gate stays a section of its phase, saying where failure leads, rather than a type of its own, andgroupwent to the organization pack rather than into core. The talk One core, and the words your company adds shows what every company shares and where a pack begins. -
✅ Packs — vocabulary only some kinds of company need at all, vendored beside core. An instance takes a pack with
init --pack <name>, and the second instance takes every one. Each pack's README says what its types carry and what they draw on, and each pack has a talk of its own:- software, for a company that builds software, in domain-driven design's terms:
bounded-context,aggregate,concept-design,domain-eventandfeature-design— README · talk - organization, for a company of more than one person:
group,group-kindandjob— README · talk - landscape, for a company that runs systems, aligned to ArchiMate® 4:
system,system-kind,service,data-objectandenvironment— README · talk - requirements, for a company that says what its products must do before it builds
them:
use-caseandrequirement— README · talk
- software, for a company that builds software, in domain-driven design's terms:
-
✅ Tooling — the
companygraphcommand, shipped inside the meta-model rather than in a repository of its own, and run from a release tag asnpx github:companygraph/meta-model#<tag>. Run with nothing after it at a terminal, it opens a menu over what it does and stays open until Quit, so making a model, checking it and putting the editor in front of it is one run; companygraph.io/cli plays it. Each entry is also a command by name, for a script or a CI step:initwrites an instance that passes the checks on its first day,upgrademoves its vendored core, its skills, its manifest and its workflow's tag together,checkruns the mechanical checks, andobsidianinstalls the Obsidian plugin's newest release in a vault or updates it there.judgeasks a decision model whether each page keeps its schema's writing rules, advisory, and only once the owner has agreed to what it sends.formholds a repository's Markdown to one form,adoptgives a site or a service that holds no model the same form check, workflow and seat hook, andpinsreports which of a repository's pins are behind.commitsrefuses a commit whose seat its phase does not list, andseatsreads the history back by seat.idprints a fresh id, andidsgives every page one that stays with it. A repository chooses the gate that checks every change before it lands: the GitHub workflow, git hooks for a repository that never reaches GitHub, or none.initalso installs agent skills for Claude: validating an instance against its schemas' writing rules, exporting it for an agent and for Gemini Notebook, producing a surface the model records, asking a decision model the writing rules once the owner consents, building a profile from a folder of a person's documents, building an instance from a company's web address, and recording the consent a source's content is used under. -
✅ The checker — the checks that are about an instance rather than about the meta-model ship as
companygraph-meta-model/checks, and an instance runs them through a reusable workflow at the release its manifest names. They read the schemas from the core your instance vendored, never from the core in the package, so the Markdown schemas are their source of truth — safe because the meta-model's own suite holds every schema to its fixed shape. What they cannot read, a schema's writing rules,judgeasks of a decision model, advisory and failing no check. The tooling'scheckruns these same checks. -
✅ The MCP server —
companygraph/mcp-server, the way an agent reaches a model without being handed the files. It asks which types a company declares, what one entity says and what evidence a claim rests on, read-only, and every answer is what the model says at one commit. It parses a snapshot with the meta-model's own parser, so a new type in core arrives without a change to the server and it knows no instance's names or facts. It also draws: the concepts, a process, one entity's neighborhood or the schemas themselves, as a Mermaid diagram whose links a client can follow, and in an instance that takes the landscape pack, one system in its landscape and what it holds. The reference instance runs it at mcp.blust.ch, published to the MCP Registry asch.blust/mental-model, and the second instance runs it at mcp.companygraph.io, published asio.companygraph/mental-model, and GuestGraph's instance runs it at mcp.guestgraph.io, published asio.guestgraph/mental-model. -
✅ The Obsidian plugin —
companygraph/obsidian-plugin, the checks an instance runs, shown while a file is edited, with completion for what the schemas declare and a rename that follows an entity's name everywhere it is used. It bundles the meta-model's own checker, so a new rule in core reaches the editor without code of its own, and it refuses a vault whose core is newer than the checker it carries rather than check it against rules it does not know. It is not in Obsidian's community directory; the meta-model's command installs it. -
✅ The second instance —
companygraph/mental-model, CompanyGraph described in the vocabulary it publishes. The reference instance showed the vocabulary holds a real company; it could not show that it holds one that is not a person. This one describes a project, and the people and agents in it are the seats that do its work. It takes every pack: how its software is designed, in the software pack's bounded contexts; the systems it runs on and what they hold; the one group its people and agents sit in, with who directs whom; and what its product is held to, as use cases and requirements. Its privacy page is built from its processors and stored items, and what the AI Act asks of a company that lets an agent answer for it is answered from its rules, risks and controls. -
✅ The chat —
companygraph/chat-server, a chat over any instance's MCP host, so a visitor who will not connect an agent can still ask the model a question in their own words. It is a client of the server above and holds no model of its own: it asks the host's tools and has Claude write the answer from what they said, naming the entity each claim rests on and linking it. Each instance with a server runs it beside the server, at chat.blust.ch, chat.companygraph.io and chat.guestgraph.io, reached from the button at the foot of every prose page of blust.ch, companygraph.io and guestgraph.io. What it may spend is written down in the deployment, and every refusal is made before the model is asked. It answers a grouping as a table and a structure as the picture the server drew, in the visitor's language, and offers the next questions from what the answer was about. -
✅ The third instance —
guestgraph/mental-model, GuestGraph described in this vocabulary. The two instances before it describe a company of one and the project behind the vocabulary, and what each ships is about modeling; this one describes a company whose product is about something else, guest identity in hospitality, and it runs the server and the chat beside it at mcp.guestgraph.io.
What the companies adopting the model ask for decides which packs come next. Nothing beyond that is promised, and a request starts as an issue on the meta-model.
companygraph.io is the home page. The meta-model and its tooling are open source and stay that way; if anything ever costs money it is consulting time, and nothing is sold today — how it would be billed →
Built spec-first in the open. Early days — star meta-model to follow along.