Skip to content

Observability Reference

This page documents access-log and MCP audit event types.

Prerequisites

Read Security and MCP. These hooks report framework events; they do not replace auth or approval policy.

python
from quater import AccessLogEvent, AccessLogHook, ToolAuditEvent

AccessLogEvent

Added in 0.1.0a1.

Structured event emitted after Quater creates a response.

python
AccessLogEvent(
    request_id: str,
    method: str,
    path: str,
    status_code: int,
    duration_ms: float,
    source: RequestSource,
    entrypoint: RequestEntrypoint,
    scheme: str,
    client: str | None = None,
    tool_name: str | None = None,
    action_name: str | None = None,
)
FieldTypeDefaultDescription
request_idstrrequiredCorrelation id.
methodstrrequiredHTTP method.
pathstrrequiredRequest path.
status_codeintrequiredFinal response status.
duration_msfloatrequiredHandler duration in milliseconds.
source"api" | "mcp" | "cli"requiredSurface that reached Quater.
entrypoint"server" | "local"requiredHosted or local CLI entrypoint.
schemestrrequiredRequest scheme.
clientstr | NoneNoneClient address.
tool_namestr | NoneNoneMCP tool name for tool calls.
action_namestr | NoneNoneCLI action name for action calls.

to_dict() returns a plain dictionary.

Example:

python
from quater import AccessLogEvent, Quater


async def log_access(event: AccessLogEvent) -> None:
    print(event.to_dict())


app = Quater(access_logger=log_access)

Expected shape:

json
{
  "request_id": "req_123",
  "method": "GET",
  "path": "/health",
  "status_code": 200,
  "duration_ms": 1.4,
  "source": "api",
  "entrypoint": "server",
  "scheme": "http",
  "client": "127.0.0.1",
  "tool_name": null,
  "action_name": null
}

AccessLogHook

Added in 0.1.0a1.

python
AccessLogHook = Callable[[AccessLogEvent], Awaitable[None]]

If the hook raises, Quater suppresses the exception. Access logging should not change the caller's response.

ToolAuditEvent

Added in 0.1.0a1.

Structured event emitted for MCP tool calls.

python
ToolAuditEvent(
    tool_name: str,
    subject: str | None,
    success: bool,
    duration_ms: float,
    arguments: Mapping[str, object],
)
FieldTypeDefaultDescription
tool_namestrrequiredTool that was called.
subjectstr | NonerequiredAuthenticated subject when present.
successboolrequiredWhether the call completed successfully.
duration_msfloatrequiredTool-call duration.
argumentsMapping[str, object]requiredRedacted argument map.

Example:

python
from quater import ToolAuditEvent


async def audit_tool(event: ToolAuditEvent) -> None:
    print(event.tool_name, event.success)

If this hook raises, Quater returns a JSON-RPC internal error for that tool call.

What Can Go Wrong

Access logs missing from local CLI : access_logger is part of the server request path. Local CLI runs in process and does not represent a server access log.

MCP audit hook failure : The tool call fails with a JSON-RPC internal error. Fix the audit hook or intentionally remove mcp_audit.

Also See

  • Security: request ids and access logging.
  • MCP: MCP audit behavior.
  • Testing: assert emitted events in app tests.

Released under the MIT License.