Domain Context Graph protocol for grounding AI in verified domain knowledge.
Project description
Domain Context Graph (DCG)
An open protocol for structuring domain knowledge so AI systems reason about your product — not just your code.
Why DCG?
AI coding assistants write confident code that violates business rules nobody documented. Security scanners flag vulnerabilities without knowing which domain owns the affected service. Incident responders trace call graphs without understanding blast radius across business capabilities.
- LLM training data is generic. Models know what "payments" means in general — not what your Payments domain is, who owns it, or what depends on it.
- Code graphs capture structure, not semantics. They see imports and call chains — not that two modules serve the same bounded context.
- Documentation decays instantly. Wikis are stale, unstructured, and not machine-queryable.
- Knowledge is tool-siloed. Your security scanner's vulnerability data can't connect to your code graph's ownership data because there's no shared schema.
DCG fills this gap: a standard, machine-readable protocol for domain knowledge that any AI system can consume — composable, adapter-driven, and federated across teams and repos.
Protocol specification: This repository contains both the protocol definition and the reference Python implementation. See Protocol Concepts below.
Table of Contents
- Install
- Quick Start
- Protocol Concepts
- CLI Reference
- Stack Composition
- Adapters
- YAML Seed Ingestion
- MCP Integration
- Graph Explorer UI
- Ontology Packs
- Static Export & Hosting
- Extending DCG
- Package Structure
- License
Install
pip install domain-context-graph
Optional extras:
pip install "domain-context-graph[ingest]" # YAML seed batch ingestion (adds requests)
pip install "domain-context-graph[dev]" # pytest + coverage for development
Verify the installation:
dcg --help
Quick Start
1. Create a project
dcg init my-domain --description "My product's domain knowledge"
cd my-domain
This creates a graph_card.json manifest and a graphs/default.json data file.
2. Add knowledge via MCP
Start the ingest server and connect from Claude Code, Cursor, or any MCP client:
dcg ingest-mcp --project .
Or add to your project's .mcp.json:
{
"mcpServers": {
"dcg-ingest": {
"command": "dcg-ingest-mcp",
"args": ["--project", "./my-domain"]
}
}
}
Then use natural language with your AI assistant to populate the graph:
"Create a domain called Payments. Add a Function entity called charge_card in the Payments domain."
3. Query the graph
dcg query ./my-domain --type Function
dcg query ./my-domain --domain Payments
4. Use it programmatically
from dcg.core import GraphStore, entity_uid, builders as kb
store = GraphStore()
# Define a domain
payments_uid = entity_uid(name="Payments")
store.add_entity(kb.entity(
uid=payments_uid,
label="Payments",
description="Payment processing domain",
attributes=[kb.attribute("instance of", kb.ref_value("dcg:meta:Domain"))],
))
# Place a code entity in that domain
fn_uid = entity_uid(name="charge_card", path="src/payments/charge.py")
store.add_entity(kb.entity(
uid=fn_uid,
label="charge_card",
attributes=[
kb.attribute("instance of", kb.ref_value("dcg:meta:Function")),
kb.attribute("part of", kb.ref_value(payments_uid)),
kb.attribute("file path", kb.string_value("src/payments/charge.py")),
],
))
# Query
functions = store.query(instance_of="dcg:meta:Function")
Protocol Concepts
Entities
Every piece of knowledge is an entity — a Wikibase-compatible JSON object with:
| Field | Description |
|---|---|
id |
Content-addressed UID (dcg:sha256:...) — deterministic from identity keys |
label |
Human-readable name |
description |
What this entity represents |
aliases |
Alternative names for discovery |
attributes |
Typed key-value pairs (references, strings, quantities) |
Content-Addressed Identity
Entity UIDs are SHA-256 hashes of their identity keys. The same entity always gets the same ID regardless of who creates it or when:
from dcg.core import entity_uid
uid = entity_uid(name="SQL Injection", type="Vulnerability")
# → dcg:sha256:a1b2c3... (deterministic)
Two-Axis Classification
Every entity is classified on two orthogonal axes:
- Type (
instance of): What it is structurally — Function, Class, Vulnerability, Domain - Domain (
part of): Where it belongs organizationally — Payments, Security, Infrastructure
This separation means you can query "all Functions in the Payments domain" or "all Vulnerabilities across all domains."
Relations
Typed, directed edges between entities:
charge_card --[calls]--> validate_input
SQLInjection --[mitigates]--> InputValidation
Relations are also content-addressed (UID = hash of source + target + property) and can carry qualifiers for metadata.
Retraction
Entities and relations can be soft-deleted (retracted) and later permanently purged. This preserves audit history while allowing cleanup.
CLI Reference
| Command | Description |
|---|---|
dcg init <name> |
Create a new domain graph project |
dcg compose <manifest> |
Validate a dcg-stack.yml manifest |
dcg query <path> [--type T] [--domain D] |
Query entities in a project |
dcg purge <path> |
Permanently remove retracted entities and relations |
dcg ingest --project <path> --seeds <dir> |
Batch-ingest YAML seed files |
dcg export-static <manifest> -o data.json |
Export full stack as static JSON bundle |
dcg ui --stack <manifest> |
Launch the graph explorer web UI |
dcg ingest-mcp --stack <manifest> |
Launch the read/write MCP server |
All commands support --help for detailed usage.
Stack Composition
Stacks let you layer multiple domain graphs into a unified view. Each layer can be a DCG project directory or an adapter-backed external source.
Manifest format (dcg-stack.yml)
stack: my-appsec-stack
layers:
- name: security
source: ./graphs/security-domain
- name: product
source: ./graphs/product-domain
extends: [security]
- name: code
adapter: graphify
source: ./graphify-output
extends: [product]
mapping:
domain: my-service
code_only: true
joins:
- property: mitigates
rule: match entities by 'cwe_id' across layers
How it works
extendsdefines a resolution DAG. Querying thecodelayer walkscode->product->securityuntil an entity is found.- Cross-layer joins materialize virtual relations between entities that share property values across layers (e.g., a Vulnerability in the security layer with
cwe_id: CWE-89connects to a Function in the code layer with the samecwe_id). - Merged ontology — all type and property registrations from all layers are unified.
- Adapter layers use the
adapter:key instead ofsource:pointing to a DCG project. The adapter translates external formats on the fly.
Validate a stack
dcg compose dcg-stack.yml
Adapters
Adapters ingest external data sources as stack layers without pre-converting them to DCG format.
Built-in adapters
| Adapter | Source Format | Description |
|---|---|---|
graphify |
Graphify graph.json |
Code graph ingestion from Tree-sitter + NetworkX output. Automatic type inference (Function, Class, File, Module), relation mapping, multi-repo support. |
Graphify adapter
Graphify is an open-source code analysis tool that produces graph.json files in NetworkX node_link_data format. DCG's Graphify adapter:
- Infers entity types from metadata, file extensions, and naming patterns
- Maps Graphify edge types to DCG relation properties (
calls,imports,inherits from,depends on,contains, etc.) - Supports multi-repo analysis with automatic org-prefix stripping
- Loads the
codeontology pack automatically
# In dcg-stack.yml
- name: code
adapter: graphify
source: ./graphify-output # directory containing graph.json
extends: [product]
mapping:
domain: my-service # assign all entities to this domain
code_only: true # filter non-code nodes
Writing a custom adapter
from dcg.adapters import register
from dcg.core.store import GraphStore
from pathlib import Path
class MyAdapter:
def load(self, source: Path, store: GraphStore, config: dict) -> None:
# Read your data source and populate the store
data = json.loads((source / "data.json").read_text())
for item in data["items"]:
store.add_entity(...)
def source_exists(self, source: Path) -> bool:
return (source / "data.json").is_file()
register("my-adapter", MyAdapter)
Then use adapter: my-adapter in your dcg-stack.yml.
YAML Seed Ingestion
Batch-populate graphs from declarative YAML files with a 7-pass pipeline:
# seeds/security-domains.yaml
tier: T1
entities:
- label: SQL Injection
type: Vulnerability
domain: AppSecurity
description: Code injection via malicious SQL in user input
properties:
cwe_id: CWE-89
owasp_category: A03:2021
relations:
- target: Input Validation
property: mitigates
dcg ingest --project ./my-graph --seeds ./seeds/
Tiers
| Tier | Confidence | Destination |
|---|---|---|
| T1 | Official / verified | Main graph |
| T2 | Moderate confidence | Main graph |
| T3 | Draft / AI-generated | Draft subgraph (for human review) |
Pipeline passes
- Discovery — scan seed files, filter by modification time
- Ontology validation — check types and properties against registered ontology
- Domains — create Domain entities first (dependency ordering)
- Entities — create all non-domain entities
- Relations — resolve targets by label/alias and create edges
- Review items — generate ReviewItem entities for T3 draft entries
- Commit — save to disk and update ingestion timestamp
Use --dry-run to validate seeds without writing.
MCP Integration
DCG provides two Model Context Protocol servers for AI assistant integration:
Servers
| Server | Command | Purpose |
|---|---|---|
dcg-mcp |
dcg serve --stack manifest.yml |
Read-only exploration |
dcg-ingest-mcp |
dcg ingest-mcp --stack manifest.yml |
Read/write (all read tools + create, connect, classify, bulk ops) |
Both support stdio (default for MCP clients) and Streamable HTTP (--http --port 3001) transports.
Configuration
Add to your project's .mcp.json:
{
"mcpServers": {
"dcg-mcp": {
"command": "dcg-mcp",
"args": ["--stack", "./dcg-stack.yml"]
},
"dcg-ingest-mcp": {
"command": "dcg-ingest-mcp",
"args": ["--stack", "./dcg-stack.yml"]
}
}
}
For a single project (no stack):
{
"mcpServers": {
"dcg-ingest": {
"command": "dcg-ingest-mcp",
"args": ["--project", "./my-graph"]
}
}
}
Available tools
Query tools (both servers):
| Tool | Description |
|---|---|
dcg_query_snapshot |
Graph summary — entity count, relation count, domains, type distribution |
dcg_query_entities |
Filter entities by type and/or domain |
dcg_query_entity |
Fetch a single entity by UID |
dcg_query_relations |
Filter relations by source, target, and/or property |
dcg_query_by_name |
Get all relations for an entity by name |
dcg_query_uid |
Compute a content-addressed UID (dry run) |
dcg_query_ontology |
List all registered types and properties |
dcg_query_packs |
List available and loaded ontology packs |
Stack tools (both servers):
| Tool | Description |
|---|---|
dcg_stack_info |
Stack DAG structure, join rules, layer counts |
dcg_stack_switch_layer |
Change the active read/write layer |
dcg_stack_query |
Query entities across all or specific layers |
dcg_stack_resolve |
Resolve an entity by name following the extends DAG |
dcg_stack_cross_layer_relations |
Get materialized cross-layer join relations |
Project tools (both servers):
| Tool | Description |
|---|---|
dcg_project_info |
Project metadata and validation status |
dcg_project_reload |
Reload graph files from disk |
dcg_project_compact |
Purge retracted entities and save |
Ingest tools (ingest server only):
| Tool | Description |
|---|---|
dcg_ingest_create_domain |
Create a Domain entity |
dcg_ingest_create_entity |
Create an entity with type, domain, description, properties |
dcg_ingest_connect |
Create a relation between two entities by name |
dcg_ingest_bulk_create |
Batch-create multiple entities |
dcg_ingest_bulk_connect |
Batch-create multiple relations |
dcg_ingest_remove |
Soft-retract an entity by name |
dcg_ingest_classify |
Assign an entity to a domain |
dcg_ingest_register_type |
Register a custom entity type |
dcg_ingest_register_property |
Register a custom property |
dcg_ingest_load_pack |
Load an ontology pack into the active layer |
dcg_ingest_save |
Persist the active layer to disk |
Graph Explorer UI
DCG includes a React-based graph explorer with Cytoscape.js visualization, Zustand state management, and React Query for data fetching.
Live mode
Connect to a running MCP server for real-time exploration and editing:
dcg ui --stack dcg-stack.yml
# Opens http://localhost:5173
Features: graph visualization with multiple layouts (cola, dagre, cose, tree), entity detail panel, domain/type filtering, entity creation, relation connections, inline editing, layer switching.
Static mode
Export and host the graph with no backend:
dcg export-static dcg-stack.yml --output ./site/graph/data.json
The UI auto-detects data.json at its base URL and renders in read-only mode — write actions (Save, New, Connect, edit) are hidden automatically.
Static Export & Hosting
Export the full stack as a single JSON bundle for static hosting:
dcg export-static dcg-stack.yml --output data.json
The bundle contains: snapshot, stack_info, ontology, entities[], and relations[].
Host on GitHub Pages
Build the UI with a custom base path and combine with the exported data:
# Export data
dcg export-static dcg-stack.yml --output ./site/graph/data.json
# Build UI for /graph/ subdirectory
cd src/dcg/ui
DCG_BASE_PATH=/graph/ npm run build
# Copy built UI
cp -r dist/* ./site/graph/
Serve ./site/ with any static file server — the graph explorer loads at /graph/.
Host on S3 / CloudFront
Same build process, then sync to your bucket:
aws s3 sync ./site/graph/ s3://my-bucket/graph/ --delete
Ontology Packs
Packs are pluggable type and property registries. Four ship with DCG:
core (always loaded)
Types: Domain, Type
Properties: instance of, subclass of, part of, redirected to, depends on, related to, references, same as, triggers, contains, language, version
code
Types: Function, Class, Struct, Interface, Trait, File, Module, Endpoint
Properties: calls, imports, inherits from, handles route, tested by, implements, file path, line number
security
Types: Vulnerability, Category, Standard, Control
Properties: mitigates
dcg-development
Types: ReviewItem
Properties: confidence, source_url, external_id
Loading packs
In a stack manifest:
layers:
- name: security
source: ./graphs/security
packs: [security]
Via MCP: use the dcg_ingest_load_pack tool.
Via Python:
from dcg.core.ontology import PackStore
pack_store = PackStore()
pack_store.load_pack("security")
Extending DCG
Custom entity types
from dcg.core.ontology import register_global_type
register_global_type("Microservice", description="A deployable service unit")
Or via MCP: dcg_ingest_register_type(name="Microservice", description="...")
Custom properties
from dcg.core.ontology import register_property
register_property("sla_hours", datatype="quantity", description="SLA response time in hours")
Or via MCP: dcg_ingest_register_property(name="sla_hours", datatype="quantity")
Custom storage backends
Implement GraphStoreProtocol:
from dcg.core.store import GraphStoreProtocol
class MyStore(GraphStoreProtocol):
def add_entity(self, entity: dict) -> str: ...
def add_relation(self, relation: dict) -> str: ...
def get_entity(self, uid: str) -> dict | None: ...
def get_relations(self, **filters) -> list[dict]: ...
def query(self, instance_of=None, part_of=None) -> list[dict]: ...
def remove(self, uid: str) -> None: ...
def to_json(self) -> dict: ...
def load(self, data: dict) -> None: ...
Custom adapters
See Adapters section above.
Package Structure
src/dcg/
cli.py # CLI entry point (dcg command)
core/
uid.py # Content-addressed entity/relation IDs
model.py # Entity, Relation, Attribute dataclasses
ontology.py # Type/property registries + ontology packs
builders.py # Entity/attribute/relation construction helpers
store.py # GraphStore — in-memory graph with JSON persistence
stack.py # StackLoader — multi-layer composition + cross-layer joins
project.py # DomainProject — manifest-based project manager
purge.py # Retraction purge
packs/ # Built-in ontology pack YAML files
adapters/
base.py # AdapterProxy with enrichment overlay support
graphify.py # Graphify code graph adapter
registry.py # Adapter name -> class registry
ingest/ # YAML seed ingestion pipeline (7-pass)
mcp/ # MCP servers (read-only + read/write)
ops/ # Orchestration layer (ingest, lifecycle, ontology ops)
ui/ # React graph explorer (Cytoscape.js + Tailwind)
Contributing
git clone https://github.com/agentkg/dcg.git
cd dcg
pip install -e ".[dev]"
pytest
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file domain_context_graph-0.4.2.tar.gz.
File metadata
- Download URL: domain_context_graph-0.4.2.tar.gz
- Upload date:
- Size: 122.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
652229e08575cff6760dc6c17186dc495295c90bf6fa6b026fdf549d766624e0
|
|
| MD5 |
a0338ae72f71a3f6ddc794630ded2565
|
|
| BLAKE2b-256 |
7e18904148a906080de192b0ecd3d29d100cd2a865cb2e4b6033cde167edc6bf
|
Provenance
The following attestation bundles were made for domain_context_graph-0.4.2.tar.gz:
Publisher:
publish.yaml on agentkg/dcg
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
domain_context_graph-0.4.2.tar.gz -
Subject digest:
652229e08575cff6760dc6c17186dc495295c90bf6fa6b026fdf549d766624e0 - Sigstore transparency entry: 2061601210
- Sigstore integration time:
-
Permalink:
agentkg/dcg@33d5747e30ec8198010f5ef17e4260fca07f37ae -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/agentkg
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@33d5747e30ec8198010f5ef17e4260fca07f37ae -
Trigger Event:
release
-
Statement type:
File details
Details for the file domain_context_graph-0.4.2-py3-none-any.whl.
File metadata
- Download URL: domain_context_graph-0.4.2-py3-none-any.whl
- Upload date:
- Size: 101.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ab1287e2009dbd310678edb79d030095436a2dd3e43422e37415cd511f5539d
|
|
| MD5 |
95184b8e620c5aaa130be5938bcc6d39
|
|
| BLAKE2b-256 |
4fb74946072fd096d6715efc50db9b1d983817f3cb51e732f5ec5c5551a88a1c
|
Provenance
The following attestation bundles were made for domain_context_graph-0.4.2-py3-none-any.whl:
Publisher:
publish.yaml on agentkg/dcg
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
domain_context_graph-0.4.2-py3-none-any.whl -
Subject digest:
1ab1287e2009dbd310678edb79d030095436a2dd3e43422e37415cd511f5539d - Sigstore transparency entry: 2061601234
- Sigstore integration time:
-
Permalink:
agentkg/dcg@33d5747e30ec8198010f5ef17e4260fca07f37ae -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/agentkg
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@33d5747e30ec8198010f5ef17e4260fca07f37ae -
Trigger Event:
release
-
Statement type: