Skip to main content

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.

PyPI Python License


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

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

  • extends defines a resolution DAG. Querying the code layer walks code -> product -> security until 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-89 connects to a Function in the code layer with the same cwe_id).
  • Merged ontology — all type and property registrations from all layers are unified.
  • Adapter layers use the adapter: key instead of source: 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 code ontology 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

  1. Discovery — scan seed files, filter by modification time
  2. Ontology validation — check types and properties against registered ontology
  3. Domains — create Domain entities first (dependency ordering)
  4. Entities — create all non-domain entities
  5. Relations — resolve targets by label/alias and create edges
  6. Review items — generate ReviewItem entities for T3 draft entries
  7. 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

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

domain_context_graph-0.4.2.tar.gz (122.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

domain_context_graph-0.4.2-py3-none-any.whl (101.9 kB view details)

Uploaded Python 3

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

Hashes for domain_context_graph-0.4.2.tar.gz
Algorithm Hash digest
SHA256 652229e08575cff6760dc6c17186dc495295c90bf6fa6b026fdf549d766624e0
MD5 a0338ae72f71a3f6ddc794630ded2565
BLAKE2b-256 7e18904148a906080de192b0ecd3d29d100cd2a865cb2e4b6033cde167edc6bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for domain_context_graph-0.4.2.tar.gz:

Publisher: publish.yaml on agentkg/dcg

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file domain_context_graph-0.4.2-py3-none-any.whl.

File metadata

File hashes

Hashes for domain_context_graph-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1ab1287e2009dbd310678edb79d030095436a2dd3e43422e37415cd511f5539d
MD5 95184b8e620c5aaa130be5938bcc6d39
BLAKE2b-256 4fb74946072fd096d6715efc50db9b1d983817f3cb51e732f5ec5c5551a88a1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for domain_context_graph-0.4.2-py3-none-any.whl:

Publisher: publish.yaml on agentkg/dcg

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page