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 ui [<path>] [--stack <manifest>] Graph explorer — export or serve locally
dcg ingest-mcp --project <path> Launch the read/write MCP server

dcg ui options

dcg ui ./my-project                          # Export static site to stdout
dcg ui --stack dcg-stack.yml --output ./site  # Export to directory
dcg ui ./my-project --serve --port 8080      # Serve locally
dcg ui ./my-project --serve --watch          # Serve with live reload on graph changes

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-mcp --stack manifest.yml Read-only exploration (prose output)
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-ingest": {
      "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

Prose query tools (both servers):

Tool Description
dcg_explore Explore an entity by name — type, domain, attributes, relationships as readable text
dcg_overview High-level graph summary — layers, domains, entity types, top relationships
dcg_search Search entities by name (case-insensitive substring, up to 20 results)

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

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 graph explorer built with vanilla TypeScript, Vite, and Cytoscape.js for visualization.

Live mode

Serve locally with live data from a project or stack:

dcg ui ./my-project --serve
# Opens http://localhost:8080

Features: graph visualization with multiple layouts (cola, dagre, cose, tree), entity detail panel, domain/type filtering, layer switching.

Static export

Export a self-contained static site for hosting (e.g., GitHub Pages):

dcg ui --stack dcg-stack.yml --output ./site

The exported site includes all graph data and runs with no backend — write actions are hidden automatically.

Host on GitHub Pages

# Export static site
dcg ui --stack dcg-stack.yml --output ./site/graph

# Serve locally to verify
cd ./site/graph && python -m http.server

Serve ./site/ with any static file server — the graph explorer loads at /graph/.


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 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: export, lifecycle, ontology, prose rendering
  ui/                      # Graph explorer — vanilla TypeScript, Vite, Cytoscape.js

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.8.tar.gz (130.1 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.8-py3-none-any.whl (102.6 kB view details)

Uploaded Python 3

File details

Details for the file domain_context_graph-0.4.8.tar.gz.

File metadata

  • Download URL: domain_context_graph-0.4.8.tar.gz
  • Upload date:
  • Size: 130.1 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.8.tar.gz
Algorithm Hash digest
SHA256 208fa5e33a28bbe11ee84c5c5bc57bce12e094738634f41232a200e70201e81c
MD5 b2b9b7965b5ada5b93b6c949371001f7
BLAKE2b-256 c64e6035bb36110883e7c1a5a305664e5894f3171d234a4d0586e2be106658a7

See more details on using hashes here.

Provenance

The following attestation bundles were made for domain_context_graph-0.4.8.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.8-py3-none-any.whl.

File metadata

File hashes

Hashes for domain_context_graph-0.4.8-py3-none-any.whl
Algorithm Hash digest
SHA256 e32d64bef2b66aa58cc22122648d1ce8f3a91e8daeef8dc9e2183e20eb3cf50c
MD5 3cb840f62992d363f649393df52e060b
BLAKE2b-256 c32d41bf3b6ab7753f3fae2dd15d3d2ba5e0563d91be1ab71378840dc722a773

See more details on using hashes here.

Provenance

The following attestation bundles were made for domain_context_graph-0.4.8-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