models.md
C5 Inventory Item Data Models
Entity definitions for the AI agent visibility platform. All items are discovered by Qpoint at runtime — no agent SDK instrumentation required. Primary observation point is the TLS-terminating network proxy, supplemented by process/system-level observation where noted.
Entity Map
Endpoint (compute host)
└── User (OS identity)
└── Session (bounded unit of work)
├── Agent (software identity — Claude Code, Cursor, etc.)
├── Model (LLM model + provider)
├── API Key (credential used)
├── MCP Server (MCP server connected during session)
├── Agent Capability (tools + skills available to session)
├── File (files read/written by tools)
├── Subagent (child session spawned by this session)
├── Secondary Call (non-LLM HTTP call made by a tool)
└── LLM Turn ─ session-detail only
└── Tool Call (unified builtin + MCP invocations)
Inventory Items
Ten top-level items that form the navigable inventory:
| # | Entity | Category |
|---|---|---|
| 1 | Session | Core |
| 2 | Agent | Identity |
| 3 | User | Identity |
| 4 | Model | Provider |
| 5 | API Key | Identity |
| 6 | Endpoint | Identity |
| 7 | MCP Server | Capabilities |
| 8 | Agent Capability | Capabilities |
| 9 | File | Exposure |
| 10 | Secondary Call | Exposure |
Two additional entities are session-detail only — they appear in session drill-downs but are not top-level inventory items:
| Entity | Note |
|---|---|
| LLM Turn | Event record; navigated from session detail |
| Tool Call | Unified builtin + MCP invocation (event record) |
1. Session
What it is: The primary unit of observation. A bounded autonomous work episode — from first API call to process exit or sustained inactivity. Everything else is a tag on a session.
Identifier: session_id — from Claude Code's session.id attribute (proxy-visible); for other agents, a Qpoint-assigned UUID derived from source PID + first-call timestamp.
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
session_id | string | Proxy (Claude Code) / derived | Stable across all turns of a session |
prompt_id | string | Proxy (Claude Code) | Turn-level ID; event.sequence increments each turn |
agent_id | string (FK) | Derived from User-Agent / Stainless headers | Which agent software ran the session |
user_id | string (FK) | Proxy (user.email, OS user lookup) | Who initiated the session |
endpoint_id | string (FK) | Network (source IP / process metadata) | Where the session ran |
api_key_id | string (FK) | Proxy (x-api-key header) | Which API credential was used |
started_at | timestamp | Proxy (first API call timestamp) | Session start |
ended_at | timestamp | null | Process exit or inactivity heuristic | Null if ongoing |
duration_ms | integer | null | Derived | ended_at - started_at |
status | enum | Derived | active, ended, terminated |
terminal_type | string | Proxy (Claude Code terminal.type) | e.g. ghostty, vscode, iterm2 |
turn_count | integer | Derived | Number of LLM turns (API calls) |
tool_call_count | integer | Derived | Total tool calls across all turns |
total_input_tokens | integer | Proxy (usage fields) | Summed across all turns |
total_output_tokens | integer | Proxy (usage fields) | Summed across all turns |
total_cache_read_tokens | integer | Proxy (usage fields) | Tokens served from prompt cache |
total_cache_creation_tokens | integer | Proxy (usage fields) | Tokens written to prompt cache |
total_cost_usd | float | Derived | Σ(turn costs) |
parent_session_id | string | null | Derived (process tree / OTel traceparent) | Set if this is a subagent session |
cwd | string | Process (/proc/<pid>/cwd) | Working directory at session start |
stop_reason_last | enum | Proxy (last API response) | end_turn, max_tokens, stop_sequence, tool_use |
max_tokens_hit_count | integer | Derived | Times stop_reason = max_tokens — behavioral signal |
Relationships
- Has many LLM Turns
- Has many Tool Calls (through turns)
- Has many Files accessed
- Has many Secondary Calls
- Has one Agent
- Has one User
- Has one Endpoint
- Has one API Key
- May have one parent Session (if subagent)
- May have many child Subagent sessions
2. Agent
What it is: The software system running the session — an autonomous AI runtime (e.g. Claude Code, Cursor, a LangChain pipeline). Identified by User-Agent string and Stainless SDK headers. An agent is not a session — one agent (e.g. "Claude Code v1.2.0") can have thousands of sessions across many users.
Identifier: agent_id — derived from user_agent + stainless_package_version (normalized slug, e.g. claude-code@1.2.0).
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
agent_id | string | Derived | Normalized slug |
name | string | Proxy (User-Agent parse) | e.g. claude-code, cursor, langchain |
version | string | Proxy (User-Agent parse) | e.g. 1.2.0 |
sdk_language | string | Proxy (x-stainless-lang) | js, python, go, java, ruby |
sdk_runtime | string | Proxy (x-stainless-runtime) | node, python, deno |
sdk_version | string | Proxy (x-stainless-package-version) | Anthropic SDK version |
first_seen_at | timestamp | Derived | First session involving this agent version |
last_seen_at | timestamp | Derived | Most recent session |
session_count | integer | Derived | Total sessions observed |
user_count | integer | Derived | Distinct users who ran this agent |
Relationships
- Has many Sessions
- Used by many Users
3. User
What it is: The human identity behind a session. May be an authenticated developer (email from Claude Code session metadata), an OS user (from process uid), or an application service account.
Identifier: user_id — user.email from Claude Code metadata when available; otherwise <endpoint_id>:<uid> (OS user on host).
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
user_id | string | Proxy (Claude Code user.email) / Process uid | Stable identifier |
email | string | null | Proxy (Claude Code user.email) | Available for Claude Code sessions |
account_id | string | null | Proxy (Claude Code user.account_id) | Anthropic account ID |
os_username | string | null | Process (/proc/<pid>/status → uid → /etc/passwd) | OS-level identity |
organization_id | string | null | Proxy (Claude Code organization.id) | Anthropic org |
role | enum | Derived (heuristics) | developer, admin, ci, service, unknown |
first_seen_at | timestamp | Derived | |
last_seen_at | timestamp | Derived | |
session_count | integer | Derived | |
total_cost_usd | float | Derived | Aggregate across all sessions |
primary_agent | string (FK) | Derived | Most-used agent name |
primary_model | string (FK) | Derived | Most-used model |
Relationships
- Has many Sessions
- Runs on many Endpoints
- Uses many Agents
4. Model
What it is: A specific LLM model invoked by an agent, including the provider that serves it. Identified by the model field in API requests and responses — the response model is authoritative (it reflects actual routing, not just the requested model). Provider context (hostname, base URL) is a property of the model rather than a separate entity.
Identifier: model_id — the canonical model string from the API response, e.g. claude-opus-4-6, claude-sonnet-4-6, gpt-4o.
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
model_id | string | Proxy (response model field) | Canonical, authoritative |
model_family | string | Derived | e.g. claude-opus, claude-sonnet, gpt-4o |
provider | string | Derived (hostname → known provider map) | anthropic, openai, google, mistral, cohere, unknown |
provider_host | string | Proxy (SNI / HTTP Host) | e.g. api.anthropic.com, api.openai.com |
base_url | string | Proxy (HTTP Host + path prefix) | e.g. https://api.anthropic.com/v1 |
input_price_per_mtok | float | Known (published pricing) | USD per million input tokens |
output_price_per_mtok | float | Known | USD per million output tokens |
cache_write_price_per_mtok | float | Known | USD per million cache creation tokens |
cache_read_price_per_mtok | float | Known | USD per million cache read tokens |
context_window_tokens | integer | Known | Max context window size |
first_seen_at | timestamp | Derived | |
last_seen_at | timestamp | Derived | |
session_count | integer | Derived | |
total_cost_usd | float | Derived | |
avg_input_tokens | float | Derived | Average per turn |
avg_output_tokens | float | Derived | Average per turn |
avg_cache_hit_rate | float | Derived | cache_read / (cache_read + input) |
Relationships
- Used in many Sessions and LLM Turns
5. API Key
What it is: The Anthropic API credential used to authenticate sessions. A key is visible at the proxy layer (x-api-key header). Different keys may correspond to different organizational units, cost centers, or environments. Keys are stored as hashed tokens — only the first/last N chars shown in the UI.
Identifier: api_key_id — SHA-256 hash of the raw key value (never stored in plaintext).
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
api_key_id | string | Derived (hash of x-api-key) | Never stored in plaintext |
key_prefix | string | Proxy (first 8 chars of x-api-key) | Display hint: sk-ant-api03-XXXX... |
organization_id | string | null | Proxy (Claude Code organization.id) | Anthropic org (when available) |
rate_limit_requests | integer | null | Proxy (response header) | API key tier signal |
rate_limit_tokens | integer | null | Proxy (response header) | Token quota |
first_seen_at | timestamp | Derived | |
last_seen_at | timestamp | Derived | |
session_count | integer | Derived | |
total_cost_usd | float | Derived | Aggregate spend on this key |
Relationships
- Used by many Sessions
- May be associated with one User or many (shared org key)
6. Endpoint
What it is: The compute environment where an agent session ran — a laptop, cloud VM, CI runner, or container. The physical or virtual host. Identified by a combination of source IP and system metadata.
Identifier: endpoint_id — stable host identifier derived from: hostname (from process metadata) or source IP (from proxy), preferring hostname when available.
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
endpoint_id | string | Process metadata (hostname) or source IP | Stable identifier |
hostname | string | null | Process (/proc/<pid>/environ HOSTNAME or /etc/hostname) | Preferred identifier |
ip_address | string | Proxy (source IP of connections) | May be NAT gateway for shared environments |
os | string | Proxy (x-stainless-os) | MacOS, Linux, Windows |
arch | string | Proxy (x-stainless-arch) | arm64, x86_64 |
runtime | string | Proxy (x-stainless-runtime) | node, python |
runtime_version | string | Proxy (x-stainless-runtime-version) | e.g. v22.1.0, 3.11.0 |
environment_type | enum | Derived (heuristics) | developer_machine, ci_runner, cloud_vm, container, unknown |
first_seen_at | timestamp | Derived | |
last_seen_at | timestamp | Derived | |
session_count | integer | Derived | |
user_count | integer | Derived | Distinct users observed on this endpoint |
Relationships
- Hosts many Sessions
- Used by many Users
- Contains many Files accessed
7. MCP Server
What it is: A Model Context Protocol server that an agent connected to during a session. Provides tools, resources, or prompts to the agent. Identified from the MCP initialize exchange (serverInfo.name + serverInfo.version). Note: stdio-transport MCP servers are opaque at the proxy layer — observable only with process/eBPF instrumentation.
Identifier: mcp_server_id — <server_name>@<server_version> (e.g. filesystem@1.0.0, github@0.6.2).
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
mcp_server_id | string | MCP initialize response (serverInfo) | Derived slug |
name | string | MCP serverInfo.name | e.g. filesystem, github, postgres |
version | string | MCP serverInfo.version | |
transport | enum | Observation method | http, websocket, stdio (stdio = limited visibility) |
url | string | null | Proxy (HTTP Host / WebSocket URL) | For http/ws transports only |
client_name | string | MCP clientInfo.name | Agent that connected (e.g. claude-code) |
protocol_version | string | MCP initialize.protocolVersion | e.g. 2024-11-05 |
tools_available | string | MCP tools/list response | Names of tools exposed |
first_seen_at | timestamp | Derived | |
last_seen_at | timestamp | Derived | |
session_count | integer | Derived | Sessions that connected to this server |
total_tool_calls | integer | Derived | Total tools/call invocations |
avg_tool_latency_ms | float | Derived | Average tool execution time |
error_rate | float | Derived | isError: true / total calls |
Relationships
- Connected to during many Sessions
- Exposes many Agent Capabilities (tools)
- Has many Tool Calls (invocation records)
8. Agent Capability
What it is: A capability available to an agent during a session — either a tool (callable function from the API tools[] array or an MCP server) or a skill (named instruction file loaded into the system prompt). Both describe what an agent can do in a session and share an inventory view, differentiated by capability_type.
Identifier: capability_id — <type>:<source>:<name> (e.g. tool:builtin:bash, tool:filesystem:read_file, skill:claude-code:wireframe-builder).
Shared Fields
| Field | Type | Source | Notes |
|---|---|---|---|
capability_id | string | Derived | <type>:<source>:<name> slug |
capability_type | enum | Derived | tool | skill |
name | string | Proxy | e.g. bash, wireframe-builder |
agent_id | string (FK) | Derived | Agent type that uses this capability |
first_seen_at | timestamp | Derived | |
last_seen_at | timestamp | Derived | |
session_count | integer | Derived | Sessions where this capability was active |
Tool-Specific Fields (capability_type = tool)
| Field | Type | Source | Notes |
|---|---|---|---|
source | enum | Derived | builtin (Anthropic API tools array) or MCP server name |
description | string | Proxy (tools[].description) or MCP | Human-readable tool description |
input_schema | object | Proxy (tools[].input_schema) or MCP | JSON Schema for parameters |
category | enum | Derived | filesystem, shell, network, search, code, ui, data, mcp, other |
invocation_count | integer | Derived | Total times called across all sessions |
error_rate | float | Derived | Failed invocations / total |
avg_execution_ms | float | Derived | Average tool_use → tool_result latency |
Skill-Specific Fields (capability_type = skill)
| Field | Type | Source | Notes |
|---|---|---|---|
source_path | string | null | Proxy (system prompt parse) | e.g. .claude/skills/wireframe-builder.md |
content_hash | string | Derived (SHA-256 of skill content) | Detects skill version changes across sessions |
Relationships
- Referenced in many Sessions
- Tools: may belong to one MCP Server (if MCP-sourced)
- Tools: has many Tool Calls (invocation events)
9. File
What it is: A file on the host file system that was read or written by an agent tool during a session. Identified by absolute path. Multiple sessions may access the same file; each access is a distinct event.
Identifier: file_id — <endpoint_id>:<absolute_path> (file identity scoped to the host where it exists).
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
file_id | string | Derived | <endpoint_id>:<path> |
path | string | Proxy (tool input.file_path / input.path) or eBPF openat | Absolute path |
extension | string | Derived | File extension for categorization |
category | enum | Derived | source_code, config, data, credentials, notebook, binary, other |
is_sensitive | boolean | Derived (path heuristics) | ~/.ssh/, *.env, *secret*, *credential*, *key* |
endpoint_id | string (FK) | Derived from session | Host where file resides |
first_seen_at | timestamp | Derived | First time any session accessed this file |
last_seen_at | timestamp | Derived | |
access_count | integer | Derived | Total accesses across all sessions |
session_count | integer | Derived | Distinct sessions that touched this file |
File Access Event (join entity: Session ↔ File)
| Field | Type | Source | Notes |
|---|---|---|---|
session_id | string (FK) | ||
file_id | string (FK) | ||
operation | enum | Derived from tool name | read, write, edit, delete, rename, glob, grep |
tool_id | string (FK) | Which tool performed the access | |
accessed_at | timestamp | ||
bytes_read | integer | null | eBPF read syscall | File size proxy |
bytes_written | integer | null | eBPF write syscall or tool content field length |
Relationships
- Accessed during many Sessions
- Via many Tool Calls
- Exists on one Endpoint
10. Secondary Call
What it is: An outbound HTTP/HTTPS request made by a tool (not the LLM itself) — e.g. web_fetch fetching a URL, bash running curl github.com, or computer_use loading a web page. Represents the "hidden exposure" surface: indirect network access attributable to an agent session.
Identifier: secondary_call_id — Qpoint-assigned UUID.
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
secondary_call_id | string | Qpoint-assigned | |
session_id | string (FK) | Derived (source PID → parent session) | |
tool_call_id | string | null (FK) | Derived (temporal correlation) | Tool Call that triggered this call |
destination_host | string | Proxy (SNI / HTTP Host) | e.g. api.github.com, registry.npmjs.org |
destination_ip | string | Proxy (DNS resolution) | |
destination_port | integer | Proxy | |
method | string | null | Proxy (HTTP method) | GET, POST, etc.; null for non-HTTP |
url | string | null | Proxy | Full URL if HTTP |
protocol | string | Proxy | https, http, tcp, dns |
http_status | integer | null | Proxy | HTTP response status |
request_bytes | integer | Proxy | |
response_bytes | integer | Proxy | |
called_at | timestamp | Proxy | |
duration_ms | integer | Proxy | |
process_pid | integer | null | Process (source port → PID) | Originating process |
attribution_confidence | enum | Derived | high (PID match), medium (temporal), low (IP only) |
Relationships
- Attributed to one Session
- Triggered by one Tool Call (when correlatable)
11. LLM Turn (session-detail only)
What it is: A single request/response pair with the LLM API — one call to POST /v1/messages. The atomic unit of LLM interaction. A session is composed of many turns. Displayed in session drill-downs; not a top-level inventory item.
Identifier: turn_id — Anthropic's response id field (e.g. msg_01XFDUDYJgAACzvnptvVoYEL).
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
turn_id | string | Proxy (response id) | Anthropic message ID |
session_id | string (FK) | Derived | Parent session |
sequence | integer | Derived / event.sequence | Turn order within session |
model_id | string (FK) | Proxy (response model) | Actual model used |
requested_at | timestamp | Proxy | Request timestamp |
responded_at | timestamp | Proxy | Last byte of response received |
latency_ms | integer | Derived | Total round-trip time |
ttft_ms | integer | null | Proxy (streaming only) | Time to first token |
input_tokens | integer | Proxy (usage.input_tokens) | |
output_tokens | integer | Proxy (usage.output_tokens) | |
cache_read_tokens | integer | Proxy (usage.cache_read_input_tokens) | |
cache_creation_tokens | integer | Proxy (usage.cache_creation_input_tokens) | |
cost_usd | float | Derived | Token counts × model pricing |
stop_reason | enum | Proxy | end_turn, max_tokens, stop_sequence, tool_use |
tool_call_count | integer | Derived | Number of tool calls in this turn |
is_streaming | boolean | Proxy (Transfer-Encoding: chunked) | |
http_status | integer | Proxy | 200, 400, 429, 500, etc. |
Relationships
- Belongs to one Session
- Uses one Model
- Has many Tool Calls
12. Tool Call (session-detail only)
What it is: A single tool execution — either a built-in tool (tool_use/tool_result pair in the Anthropic API) or an MCP tools/call invocation. Both represent the same semantic event: a tool was invoked and produced a result. Unified under one entity with call_type indicating the protocol. Displayed in session drill-downs; not a top-level inventory item.
Identifier: tool_call_id — the tool_use_id for builtin calls (e.g. toulu_01A09q90...); derived from JSON-RPC id + MCP server ID + timestamp for MCP calls.
Fields
| Field | Type | Source | Notes |
|---|---|---|---|
tool_call_id | string | Proxy / Derived | See identifier note above |
call_type | enum | Derived | builtin | mcp |
session_id | string (FK) | Derived | |
turn_id | string | null (FK) | Derived | LLM Turn that triggered this call; null for MCP calls not tied to a turn |
capability_id | string (FK) | Derived | Which Agent Capability was invoked |
tool_name | string | Proxy | Denormalized tool name for query convenience |
mcp_server_id | string | null (FK) | MCP serverInfo.name | Set for call_type = mcp; null for builtin |
input | object | Proxy | Tool parameters (unified from content[].input or MCP params.arguments) |
result | string | object | null | Proxy | Tool output (unified from tool_result.content or MCP result.content) |
is_error | boolean | Proxy | True if tool failed |
error_message | string | null | Proxy | Error detail when is_error = true |
called_at | timestamp | Proxy | When the tool was invoked |
result_at | timestamp | Proxy | When the result was received |
latency_ms | integer | Derived | result_at - called_at |
input_size_bytes | integer | Derived | JSON size of input |
result_size_bytes | integer | Derived | JSON size of result |
Relationships
- Belongs to one Session and one LLM Turn (when
call_type = builtin) - References one Agent Capability
- May belong to one MCP Server (when
call_type = mcp) - May produce File access events (if file-touching tool)
- May produce Secondary Calls (if network-touching tool)
Observation Mechanism Summary
| Entity | Primary observation | Supplemental |
|---|---|---|
| Session | Proxy (API calls + Claude Code metadata) | Process (PID, cwd) |
| Agent | Proxy (User-Agent, Stainless headers) | — |
| User | Proxy (Claude Code user.email) | Process (OS uid → username) |
| Model | Proxy (API response model + Host header) | — |
| API Key | Proxy (x-api-key header, hashed) | — |
| Endpoint | Proxy (Stainless OS/arch headers, source IP) | Process (hostname, /proc) |
| MCP Server | MCP intercept (HTTP/WS transport) | eBPF (stdio transport) |
| Agent Capability (tool) | Proxy (API tools[] definitions) | MCP intercept |
| Agent Capability (skill) | Proxy (system prompt parse) | — |
| File | Proxy (tool input fields) | eBPF openat/write |
| Secondary Call | Proxy (outbound HTTP from tool processes) | Process (PID attribution) |
| LLM Turn | Proxy (full request/response) | — |
| Tool Call | Proxy (tool_use/tool_result) + MCP intercept | eBPF (stdio MCP) |