Dynamic Observability
Dynamic observability provides real-time visibility into active and historical agent sessions managed by the Virtue Gateway. Every session is automatically traced, giving you a complete audit trail of agent behavior across all connected frameworks.
Session Traces
The Observability → Sessions tab shows every agent session of each users (Admin can see the sessions of all users). We first show a summary of all sessions of an user.

Each session represents one conversation. Click a session to see the full action sequence.

What Is Captured
Each session trace includes:
- User messages — the input queries sent to the agent each turn
- Tool calls — every MCP tool invocation, including tool name and arguments
- Tool responses — the output returned by each tool
- Prompt and Action Guard decisions — whether each action was allowed or blocked, along with the explanation and any violated policies
- Session metadata — gateway ID, session ID, timestamps, and turn count
API Reference
The sessions and observability scan APIs are served by the MCP Gateway. All
endpoints accept JWT (Authorization: Bearer <jwt>) or an API key
(X-API-Key: <api_key>), except where noted.
Sessions
GET /api/sessions/overview
Dashboard overview of sessions with tool call metrics. Non-admins always see
only their own sessions; admins can filter by user_id.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
gatewayId | string[] | — | Filter by one or more gateway IDs |
user_id | string | — | Filter by user ID (admin only) |
days | int | — | Look back N days (1–365). Ignored if start_date/end_date are set |
start_date | string | — | ISO 8601 start datetime |
end_date | string | — | ISO 8601 end datetime |
Response:
{
"sessions": [
{
"session_id": "ses_abc123",
"gateway_id": "gw_xyz",
"user_id": "usr_abc",
"created_at": "2026-05-19T10:00:00Z",
"duration": 42.3,
"tool_calls_total": 8,
"tool_calls_success": 6,
"tool_calls_failed": 1,
"tool_calls_blocked": 1,
"violation_categories": { "Data Privacy": 1 }
}
],
"count": 1
}
GET /api/sessions
List sessions with pagination. JWT only.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | int | 1 | 1-based page number |
page_size | int | 50 | Sessions per page (max 200) |
user_id | string | — | Filter by user ID (admin only) |
days | int | — | Look back N days |
start_date | string | — | ISO 8601 start datetime |
end_date | string | — | ISO 8601 end datetime |
Response:
{
"items": [
{
"session_id": "ses_abc123",
"user_id": "usr_abc",
"gateway_id": "gw_xyz",
"created_at": "2026-05-19T10:00:00Z",
"summary": "User asked to create a Salesforce lead.",
"metadata": {
"step_count": 10,
"actions_count": 4,
"tool_count": 2,
"user_turn": 2,
"duration": 42.3,
"timestamp": "2026-05-19T10:00:42Z"
}
}
],
"count": 1,
"total": 38,
"page": 1,
"page_size": 50
}
GET /api/sessions/{session_id}
Get a specific session with its full trace, including token usage metrics.
Response:
{
"session_info": {
"session_id": "ses_abc123",
"user_id": "usr_abc",
"gateway_id": "gw_xyz",
"created_at": "2026-05-19T10:00:00Z",
"summary": "User asked to create a Salesforce lead.",
"metadata": {
"step_count": 4,
"actions_count": 2,
"tool_count": 1,
"user_turn": 1,
"duration": 12.5,
"timestamp": "2026-05-19T10:00:12Z",
"total_input_tokens": 840,
"total_output_tokens": 210,
"total_tokens": 1050
}
},
"trace": [
{
"role": "user",
"step_id": 0,
"timestamp": "2026-05-19T10:00:00Z",
"state": "Create a Salesforce lead for John Doe"
},
{
"role": "agent",
"step_id": 1,
"timestamp": "2026-05-19T10:00:05Z",
"action": "create_lead(name='John Doe', email='john@example.com')",
"metadata": {
"tool_name": "create_lead",
"tool_params": { "name": "John Doe", "email": "john@example.com" },
"server_name": "salesforce"
},
"guard": {
"action_guard": {
"allowed": true,
"checked": true,
"violations": [],
"explanation": "Action is within permitted scope."
}
},
"token_usage": { "input_tokens": 420, "output_tokens": 105 }
},
{
"role": "tool",
"step_id": 2,
"timestamp": "2026-05-19T10:00:10Z",
"state": { "content": [{ "type": "text", "text": "Lead created: id=lead_001" }], "isError": false }
}
]
}
Trace step role values:
| Role | Description |
|---|---|
user | User message turn |
agent | Agent tool call or reasoning step |
tool | Tool response returned by the upstream MCP server |
POST /api/sessions
Create a new session. Used by standalone gateways to start recording. Returns 201 Created.
Request:
{ "gateway_id": "gw_xyz" }
Response:
{
"session_id": "ses_abc123",
"gateway_id": "gw_xyz",
"user_id": "usr_abc",
"created_at": "2026-05-19T10:00:00Z"
}
POST /api/sessions/{session_id}/trace
Append a trace step to an existing session. Used by standalone gateways.
Returns 204 No Content.
Request body (a single trace step):
{
"role": "agent",
"step_id": 1,
"timestamp": "2026-05-19T10:00:05Z",
"action": "create_lead(name='John Doe')",
"metadata": { "tool_name": "create_lead", "tool_params": { "name": "John Doe" } }
}
PATCH /api/sessions/{session_id}/trace/guard
Merge guard results into a trace step's guard field without replacing the
whole step. Returns 204 No Content.
Patches the step matching step_id, or the last agent step if step_id is
omitted. Guard keys (access_control, action_guard, prompt_guard) are
merged independently.
Request:
{
"step_id": 1,
"action_guard": {
"allowed": false,
"checked": true,
"violations": ["Financial Controls → rul_001: unauthorized transfer"],
"explanation": "Transfer exceeds permitted amount."
}
}