# Graph Data Model in Codebase-Memory-MCP: Node Labels and Edge Types Explained

> Understand the graph data model in Codebase-Memory-MCP. Learn about node labels and edge types representing code entities and relationships for analysis and visualization. Explore the TypeScript interfaces.

- Repository: [Martin Vogel/codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)
- Tags: deep-dive
- Published: 2026-07-13

---

**Codebase-Memory-MCP represents source code as a property graph where typed nodes represent code entities (functions, classes, variables) and typed edges represent relationships (calls, inherits, references), defined in TypeScript interfaces for visualization and analysis.**

Codebase-Memory-MCP transforms your source code repository into a navigable graph structure that powers its web-based visualization interface. Understanding this graph data model is essential for developers who want to extend the tool, build custom queries, or integrate the MCP server with other systems. The model is formally defined in [`graph-ui/src/lib/types.ts`](https://github.com/DeusData/codebase-memory-mcp/blob/main/graph-ui/src/lib/types.ts) and implemented by the Python backend indexing engine.

## Core Components of the Graph Data Model

The graph data model consists of three primary TypeScript interfaces that define how code entities and their relationships are structured, aggregated, and transported.

### GraphNode Structure and Node Labels

The `GraphNode` interface, defined at **lines 3-16** in [`graph-ui/src/lib/types.ts`](https://github.com/DeusData/codebase-memory-mcp/blob/main/graph-ui/src/lib/types.ts), represents a concrete code entity with both semantic and visual properties.

Each node includes:
- **Positional data**: `x`, `y`, and `z` coordinates for 3D graph layout
- **Entity metadata**: `name`, `qualified_name`, `file_path`, `start_line`, and `end_line`
- **Visual attributes**: `color`, `size`, and `status` (using the `NodeStatus` type)
- **Analytics**: `in_calls` count tracking incoming references

The **`label`** field (line 8) encodes the entity type as a string, enabling the UI to color-code nodes and display human-readable badges. Valid node labels include:
- `function`
- `class`
- `module`
- `enum`
- `variable`
- `type_alias`
- `import`

### GraphEdge Structure and Relationship Types

The `GraphEdge` interface, defined at **lines 39-44** in [`graph-ui/src/lib/types.ts`](https://github.com/DeusData/codebase-memory-mcp/blob/main/graph-ui/src/lib/types.ts), connects two nodes via directed relationships.

Each edge contains:
- **`source`**: The ID of the originating node
- **`target`**: The ID of the destination node
- **`type`**: A string specifying the relationship kind (line 42)

Valid edge types include:
- `calls` – Function invocations
- `references` – Variable or symbol usage
- `inherits` – Class inheritance relationships
- `contains` – Parent-child containment (e.g., methods within a class)
- `exports` – Module export relationships
- `imports` – Import dependencies

The UI uses the `type` field to render different line styles and colors for each relationship category.

### SchemaInfo and GraphData Containers

Two additional interfaces manage graph metadata and transport:

**`SchemaInfo`** (lines 76-80) provides aggregated statistics about the graph composition:
- `node_labels`: Array of objects tallying count per label type
- `edge_types`: Array of objects tallying count per relationship type
- `total_nodes` and `total_edges`: Aggregate counts

**`GraphData`** (lines 62-68) serves as the top-level payload sent to the frontend:
- `nodes`: Array of `GraphNode` objects
- `edges`: Array of `GraphEdge` objects
- `total_nodes`: Count for pagination and progress tracking
- Optional `linked_projects` and `missed_graph` sections for multi-project views

## Backend Implementation and Data Flow

The Python backend implements this graph data model through a multi-stage pipeline:

1. **AST Extraction**: The backend walks the abstract syntax tree of each indexed file, creating a `GraphNode` for every discovered entity.

2. **Relationship Mapping**: For each detected relationship (e.g., a function calling another function), the backend emits a `GraphEdge` with the appropriate `type` string.

3. **Schema Aggregation**: During indexing, the system builds a `SchemaInfo` object that tallies node labels and edge types for statistical reporting.

4. **Serialization**: All nodes, edges, and schema information serialize as JSON conforming to the `GraphData` interface.

5. **Transport**: The data travels via the RPC endpoint `/api/graph` to the frontend.

6. **Rendering**: The `useGraphData` hook (located in [`graph-ui/src/hooks/useGraphData.ts`](https://github.com/DeusData/codebase-memory-mcp/blob/main/graph-ui/src/hooks/useGraphData.ts)) consumes the payload, rendering nodes at their coordinates and styling connections according to their `type`.

The CLI entry point in [`pkg/pypi/src/codebase_memory_mcp/_cli.py`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pkg/pypi/src/codebase_memory_mcp/_cli.py) drives this indexing process, while [`pkg/pypi/src/codebase_memory_mcp/graph_builder.py`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pkg/pypi/src/codebase_memory_mcp/graph_builder.py) contains the core logic for AST traversal and graph construction.

## Practical Code Examples

The following TypeScript examples demonstrate how to construct valid graph data structures conforming to the model:

```typescript
// Building a minimal graph with two functions and a call relationship
import {
  GraphNode,
  GraphEdge,
  GraphData,
  NodeStatus,
} from "./lib/types";

const fnA: GraphNode = {
  id: 1,
  x: 0,
  y: 0,
  z: 0,
  label: "function",
  name: "foo",
  file_path: "src/foo.py",
  qualified_name: "module.foo",
  start_line: 10,
  end_line: 14,
  size: 5,
  color: "#ffcc00",
  status: "normal",
  in_calls: 0,
};

const fnB: GraphNode = {
  id: 2,
  x: 200,
  y: 0,
  z: 0,
  label: "function",
  name: "bar",
  file_path: "src/bar.py",
  qualified_name: "module.bar",
  start_line: 20,
  end_line: 25,
  size: 6,
  color: "#66ccff",
  status: "normal",
  in_calls: 1,
};

const callEdge: GraphEdge = {
  source: fnA.id,   // foo calls bar
  target: fnB.id,
  type: "calls",
};

const graph: GraphData = {
  nodes: [fnA, fnB],
  edges: [callEdge],
  total_nodes: 2,
};

```

```typescript
// Consuming schema statistics returned by the backend
interface SchemaInfo {
  node_labels: { label: string; count: number }[];
  edge_types: { type: string; count: number }[];
  total_nodes: number;
  total_edges: number;
}

const schema: SchemaInfo = {
  node_labels: [
    { label: "function", count: 342 },
    { label: "class",    count: 87 },
    { label: "module",   count: 12 },
  ],
  edge_types: [
    { type: "calls",      count: 590 },
    { type: "inherits",   count: 73 },
    { type: "references", count: 210 },
  ],
  total_nodes: 441,
  total_edges: 873,
};

```

## Summary

- **GraphNode** entities carry positional coordinates, metadata, and a `label` field identifying the code entity type (function, class, variable, etc.).
- **GraphEdge** connections specify relationship semantics through the `type` field (calls, inherits, references, etc.).
- **SchemaInfo** aggregates node and edge statistics for UI dashboards and filtering controls.
- The **GraphData** interface serves as the canonical transport format between the Python backend and TypeScript frontend.
- All type definitions reside in [`graph-ui/src/lib/types.ts`](https://github.com/DeusData/codebase-memory-mcp/blob/main/graph-ui/src/lib/types.ts), with line-specific references to `GraphNode` (3-16), `GraphEdge` (39-44), `GraphData` (62-68), and `SchemaInfo` (76-80).

## Frequently Asked Questions

### What are the valid node labels in Codebase-Memory-MCP?

According to the `GraphNode` interface in [`graph-ui/src/lib/types.ts`](https://github.com/DeusData/codebase-memory-mcp/blob/main/graph-ui/src/lib/types.ts), the `label` field accepts strings identifying code entity types. Common values include `function`, `class`, `module`, `enum`, `variable`, `type_alias`, and `import`. The UI uses these labels to apply color-coding and display badges for each node.

### How does the backend determine edge types?

The Python backend analyzes AST relationships during indexing. When it detects a function call, it creates a `GraphEdge` with `type: "calls"`; for inheritance relationships, it uses `type: "inherits"`; for variable usage, `type: "references"`. These type strings are defined at line 42 of the types file and consumed by the frontend to style connection lines.

### What is the purpose of SchemaInfo?

`SchemaInfo` provides a statistical summary of the entire graph, defined at lines 76-80 in [`graph-ui/src/lib/types.ts`](https://github.com/DeusData/codebase-memory-mcp/blob/main/graph-ui/src/lib/types.ts). It counts occurrences of each node label and edge type, enabling the web UI to display distribution charts, filtering options, and project health metrics without loading the full node list.

### How is graph data transported between backend and frontend?

The backend serializes nodes and edges into JSON conforming to the `GraphData` interface (lines 62-68). This payload includes the complete `nodes` and `edges` arrays plus a `SchemaInfo` object. The data travels via the `/api/graph` RPC endpoint and is consumed by the `useGraphData` React hook in the frontend for rendering.