Tool Schema Documentation -- cortex

September 10, 2026 ยท View on GitHub

Source Of Truth

The live MCP JSON schema is built in Rust, not generated from this markdown file.

Current source of truth:

  • src/mcp/actions.rs::ACTION_SPECS registers every action, its scope, cost, and description.
  • src/mcp/actions.rs::action_names() derives the schema action enum from ACTION_SPECS.
  • src/mcp/schemas.rs::tool_definitions() builds the MCP tools/list definition and the cortex://schema/mcp-tool resource from that action table.
  • src/mcp/tools.rs::tool_cortex() dispatches the action handlers.
  • src/app/models.rs defines request and response structs for typed action payloads.

docs/mcp/SCHEMA.md is a human-maintained reference for that generated runtime schema with drift tests; it is not itself automatically generated. If it disagrees with src/mcp/actions.rs or src/mcp/schemas.rs, the Rust source wins.

Current Actions

cortex exposes one MCP tool named cortex. The required action argument selects one of the actions below. The mechanically generated current count is in tests/TEST_COVERAGE.md:

ActionScopeCostPurpose
searchcortex:readcheapFull-text search over syslog messages
filtercortex:readcheapFilter logs by indexed fields without FTS5
tailcortex:readcheapMost recent log entries
errorscortex:readcheapError/warning summary
hostscortex:readcheapKnown source hostnames
mapcortex:readmoderateCached homelab inventory plus graph-backed topology answers
host_statecortex:readmoderateLatest bounded heartbeat state for one host
fleet_statecortex:readexpensiveFleet-wide heartbeat snapshot with pressure flags
correlatecortex:readmoderateTime-window event correlation
correlate_statecortex:readexpensiveCorrelate logs with heartbeat summaries around a reference time
statscortex:readexpensiveDB statistics and runtime observability
statuscortex:readcheapLightweight health and runtime status
appscortex:readcheapDistinct application names with counts
sessionscortex:readcheapAI transcript session inventory
search_sessionscortex:readcheapFTS5 search over AI transcript sessions
evidence_scopecortex:readmoderateHistorical Agent Observatory evidence for a Git branch or worktree
abusecortex:readmoderateAbuse-term hits with same-session context
abuse_incidentscortex:readmoderateGrouped abuse incident candidates
abuse_investigatecortex:readexpensiveEvidence bundles for abuse incidents
ai_correlatecortex:readmoderateAI transcript anchors with nearby non-AI logs
topic_correlatecortex:readmoderateResolve a topic to graph entities and correlate all related logs into a unified timeline
usage_blockscortex:readcheapAI activity in 5-hour UTC blocks
project_contextcortex:readmoderateAI project summary and recent entries
list_ai_toolscortex:readcheapAI tools observed in transcripts
list_ai_projectscortex:readcheapAI projects observed in transcripts
source_ipscortex:readcheapDistinct source identifiers with counts
timelinecortex:readcheapBucketed log counts over time
patternscortex:readexpensiveNear-duplicate message template clusters
contextcortex:readcheapLogs surrounding a pivot id or timestamp
getcortex:readcheapOne log entry by id, including raw frame
ingest_ratecortex:readexpensiveRecent ingest throughput and write-block state
silent_hostscortex:readmoderateHosts older than a staleness threshold
clock_skewcortex:readexpensivePer-host received_at minus timestamp distribution
anomaliescortex:readexpensiveRecent vs baseline volume/error comparison
comparecortex:readexpensiveSide-by-side comparison of two time ranges
compose_statuscortex:readmoderateRedacted self Compose status projection
compose_doctorcortex:readexpensiveStrict self Compose health diagnostics
unaddressed_errorscortex:readmoderateUnacknowledged repeating error signatures
notifications_recentcortex:readcheapRecent notification firings
similar_incidentscortex:readmoderateFTS5 historical incident clusters
recurring_error_comparisoncortex:readmoderateCompare recurring error signatures with redacted deterministic evidence bundles
incident_contextcortex:readmoderateWindow bundle: log aggregates, errors, AI sessions
graphcortex:readmoderateEntity lookup and one-hop graph neighborhoods
artifact_evidencecortex:readcheapQuery bounded source-attributed artifact ecosystem evidence
artifact_evidence_recordcortex:adminwriteAppend one bounded source-attributed artifact ecosystem evidence event
skill_eventscortex:readcheapList extracted AI skill-invocation events
skill_incidentscortex:readmoderateGrouped skill-usage incident candidates
skill_investigatecortex:readexpensiveEvidence bundles for skill-usage incidents, skill-first
mcp_eventscortex:readcheapList extracted AI MCP tool-call events
mcp_incidentscortex:readmoderateGrouped MCP-usage incident candidates
mcp_investigatecortex:readexpensiveEvidence bundles for MCP-usage incidents, server/tool-first
hook_eventscortex:readcheapList extracted/collected AI hook events (runtime + config inventory)
hook_incidentscortex:readmoderateGrouped hook-usage incident candidates
hook_investigatecortex:readexpensiveEvidence bundles for hook-usage incidents, hook-first
ack_errorcortex:adminwriteAcknowledge an error signature
unack_errorcortex:adminwriteRevoke an error acknowledgement
file_tailscortex:adminwriteManage Cortex-owned file-tail ingest sources
notifications_testcortex:adminwriteSend a test Apprise notification
llm_invocationscortex:admincheapRecent LLM invocation audit records (concurrency/rate-limit/circuit-breaker denials included)
helpnonecheapMarkdown action reference

Schema Pattern

The runtime tool definition is a hybrid action-dispatched JSON schema. Shared properties remain at the root for backward-compatible discovery, while exact per-action object branches are generated from ACTION_SPECS under oneOf:

{
  "name": "cortex",
  "description": "Query cortex logs with action-based subcommands...",
  "x-cortex-action-metadata": [
    { "name": "search", "cost": "cheap", "description": "..." }
  ],
  "x-cortex-agent-guidance": {
    "cost_order": ["cheap", "moderate", "expensive", "write"],
    "first_pass": ["status", "errors", "tail", "search", "timeline", "context"],
    "escalate_only_when_scoped": [
      "stats",
      "patterns",
      "anomalies",
      "compare",
      "clock_skew",
      "ingest_rate",
      "compose_doctor"
    ]
  },
  "inputSchema": {
    "type": "object",
    "properties": {
      "action": {
        "type": "string",
        "enum": ["...derived from ACTION_SPECS..."]
      }
    },
    "required": ["action"],
    "oneOf": [
      {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "action": { "const": "project_context" },
          "project": { "type": "string" },
          "tool": { "type": "string" },
          "limit": { "type": "integer" }
        },
        "required": ["action", "project"]
      },
      {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "action": { "const": "list_ai_projects" },
          "tool": { "type": "string" },
          "since": { "type": "string" },
          "until": { "type": "string" }
        },
        "required": ["action"]
      },
      {
        "type": "object",
        "properties": {
          "action": { "enum": ["...unmigrated actions..."] }
        },
        "required": ["action"]
      }
    ]
  }
}

Root properties remain available because MCP clients receive one schema for the cortex super-tool. project_context and list_ai_projects now have exact machine-enforced field sets generated from the action registry. Unmigrated actions use an explicit fallback branch that excludes those exact action names. Runtime request structs still use deny_unknown_fields as the final validation boundary.

Common Arguments

ArgumentUsed by
querysearch, search_sessions, correlate, similar_incidents
hostnamesearch, filter, tail, correlate, host_state, ai_correlate, apps, sessions, timeline, patterns, context, similar_incidents, incident_context
host_idAuthoritative heartbeat identity for host_state
hostOptional host_id-or-hostname filter for correlate_state
reference_timeRequired window center for correlate_state; for correlate, required unless query is given (then derived from an AI-session search)
source_ipsearch, filter, tail, correlate, ai_correlate
source_kindfilter only; aliases Docker, file-tail, command-history, shell-history, transcript, and AI-tool rows
projectfilter, sessions, search_sessions, abuse, ai_correlate, usage_blocks, project_context, list_ai_tools
toolfilter, sessions, search_sessions, abuse, ai_correlate, usage_blocks, project_context, list_ai_projects
branch, worktreeevidence_scope; at least one is required by service validation
kinds, include_payload, after_idevidence_scope filtering and durable pagination
session_idfilter, ai_correlate
ai_queryAI transcript anchor FTS5 query for ai_correlate
log_queryRelated non-AI log FTS5 query for ai_correlate
severityExact severity filter for search and filter
severity_minSeverity floor for tail, correlate, ai_correlate, timeline, patterns, similar_incidents, incident_context
app_namesearch, filter, tail, ai_correlate, timeline, patterns, similar_incidents, incident_context
from, toTime range for search/session/AI/analytics actions; required for incident_context
limit, offsetAction-specific bounds; offset is for apps and source_ips pagination
host_limit, per_host_limit, section_limit, include_sectionsNode and inventory-section bounds for map; per_host_limit is accepted for v1 compatibility and ignored by map v2
mode, host, domain, service, answer_limit, evidence_sample_limit, payload_budgetMap snapshot mode and graph-backed map answer controls: host_services, domain_routes, and service_dependencies
mode, entity_id, entity_type, key, alias_type, alias_key, depth, evidence_id, evidence_sample_limit, payload_budgetGraph controls. Targeted modes require exactly one lookup strategy: entity_id, entity_type + key, or alias_type + alias_key. evidence requires evidence_id. Service identity is logical_service (key=plex) or service_instance (key=nashost/plex); legacy nested keys (nashost:plex, nashost:plex:plex, plex/plex/plex) are rejected with rejected_legacy_shape.

Correlation Arguments

See CORRELATION.md for the full behavior matrix.

ActionKey arguments
correlatereference_time (or query alone, deriving the anchor from an AI-session search), window_minutes, severity_min, hostname, source_ip, query, limit
ai_correlateproject, tool, session_id, ai_query, log_query, hostname, source_ip, app_name, from, to, window_minutes, severity_min, limit, events_per_anchor
abuse_investigateproject, tool, from, to, limit, window_minutes, correlation_window_minutes, terms
similar_incidentsquery, hostname, app_name, severity_min, from, to, window_minutes, limit
recurring_error_comparisonOptional signature_hash, since, until, window_minutes, limit, include_acknowledged; defaults to a bounded focal window ending now
incident_contextfrom, to, hostname, app_name, query, severity_min, limit; query applies FTS5 filtering to returned error logs
graph`mode=entity
artifact_evidenceOptional exact filters: eventKind, artifactId, revisionId, contentDigest, correlationId, requestId, targetId, sourceSystem, since/until (or from/to wire aliases), limit; all filters are validated by the shared service and responses are bounded
artifact_evidence_recordRequired: schemaVersion=dinglebear.cortex-artifact-evidence/v1, eventId, eventKind, sourceSystem, sourceIssuer, observedAt, plus at least one artifact/revision/digest/provenance subject; optional bounded opaque references, outcome, and secret-safe bounded metadata; raw artifact/tool/request/result bodies are rejected
file_tailsop is required and enumerated as list, add, remove, enable, disable, or status; add requires only path, derives id and tag from the file name, and derives omitted host as stable synthetic owner file-tail-<id>; remove/enable/disable require id; optional facility, severity, start_at_end

Validation

Input validation is action-specific:

  • action is required and must match ACTION_SPECS.
  • Read actions require cortex:read when auth is mounted.
  • Admin actions require cortex:admin.
  • help has no scope gate, but auth policy still applies when the endpoint is protected.
  • Numeric parameters are capped by each action.
  • Timestamp parameters are parsed as RFC3339 and normalized where needed.
  • FTS5 parameters use SQLite FTS5 syntax; quote hyphenated terms because bare - means NOT.
  • Unknown parameters may be ignored by legacy extractor-style handlers, but typed payload handlers use deny_unknown_fields and reject unknown fields.

Response Format

All MCP tool responses use one text content block containing pretty-printed JSON:

{
  "content": [
    {
      "type": "text",
      "text": "{\"count\": 3, \"logs\": [...]}"
    }
  ]
}

Action validation failures and execution failures return tool errors with isError: true. Validation errors also include matching JSON text and structuredContent containing kind: "invalid_param", action, message, and retryable: false. JSON-RPC errors are reserved for failures that prevent normal tool execution.

Drift Checks

The test suite enforces several schema/documentation invariants:

  • src/mcp/schemas_tests.rs checks that the schema action enum equals actions::action_names().
  • src/mcp/tools_tests.rs::schema_actions_are_dispatchable dispatches every registered action.
  • src/mcp/tools_tests.rs::public_action_references_cover_schema_registry checks public references for every registered action.

There is no checked-in generator that rewrites this markdown file today.

See Also