Reference

Events

Full catalog of lifecycle and runtime events emitted by the Routecraft context.

Event payload

All events share the same envelope:

{
  ts: string       // ISO timestamp
  context: CraftContext
  details: {...}   // event-specific fields (see tables below)
}

Context events

EventWhen it firesDetails
context:startingBefore the context starts{}
context:startedAfter all capabilities have started{}
context:stoppingBefore shutdown begins{ reason? }
context:stoppedAfter all capabilities have stopped{}

Route events

"Route" here refers to a registered capability internally.

EventWhen it firesDetails
route:registeredCapability registered with the context{ route }
route:startingJust before a capability starts{ route }
route:startedCapability is running{ route }
route:stoppingCapability is stopping{ route, reason?, exchange? }
route:stoppedCapability has stopped{ route, exchange? }

Exchange events

Fired per exchange, scoped to the capability that owns it. routeId is the capability ID.

EventWhen it firesDetails
route:{routeId}:exchange:startedExchange enters the pipeline (parent or child){ routeId, exchangeId, correlationId }
route:{routeId}:exchange:completedExchange finished successfully (or consumed by aggregate){ routeId, exchangeId, correlationId, duration }
route:{routeId}:exchange:failedExchange encountered an unrecoverable error{ routeId, exchangeId, correlationId, duration, error }
route:{routeId}:exchange:droppedExchange intentionally removed from the pipeline{ routeId, exchangeId, correlationId, reason }
route:{routeId}:exchange:restoredExchange restored from cache, skipping steps{ routeId, exchangeId, correlationId, source }

The exchangeId field is the exchange's own ID, not the correlation ID. Use correlationId to group related exchanges (e.g. a parent and its split children share the same correlation ID).

Lifecycle guarantee: every exchange:started is eventually followed by exactly one of completed, failed, or dropped.

Operation events

Operation events are scoped to a capability and an operation type. They fire for individual steps in the pipeline.

Adapter operations

EventWhen it firesDetails
route:{routeId}:operation:from:{adapterId}:startedSource adapter activated{ routeId, exchangeId, correlationId, operation, adapterId, metadata? }
route:{routeId}:operation:from:{adapterId}:stoppedSource adapter completed{ routeId, exchangeId, correlationId, operation, adapterId, duration, metadata? }
route:{routeId}:operation:to:{adapterId}:startedDestination adapter invoked{ routeId, exchangeId, correlationId, operation, adapterId, metadata? }
route:{routeId}:operation:to:{adapterId}:stoppedDestination adapter completed{ routeId, exchangeId, correlationId, operation, adapterId, duration, metadata? }

The metadata field is populated by the adapter's getMetadata() method. For example, the HTTP adapter returns { method, url, statusCode, contentLength }.

Batch operations

EventWhen it firesDetails
route:{routeId}:operation:batch:startedBatch accumulation started{ routeId, batchId, batchSize }
route:{routeId}:operation:batch:flushedBatch released for processing{ routeId, batchId, batchSize, waitTime, reason }
route:{routeId}:operation:batch:stoppedBatch accumulation stopped{ routeId, batchId }

reason is 'size' when the batch hit its size limit, 'time' when the flush interval elapsed.

Split and aggregate

Split and aggregate use standard step:started/step:completed events (not dedicated operation events). Operation-specific data is in the metadata field:

  • Split step:completed includes metadata.childCount: the number of child exchanges created
  • Aggregate step:completed includes metadata.inputCount: the number of exchanges merged

After a split, each child exchange emits its own exchange:started. When aggregate consumes children, it emits exchange:completed for each child before continuing on the parent exchange.

Retry operations

EventWhen it firesDetails
route:{routeId}:operation:retry:startedRetry sequence started{ routeId, exchangeId, correlationId, maxAttempts }
route:{routeId}:operation:retry:attemptOne retry attempt made{ routeId, exchangeId, correlationId, attemptNumber, maxAttempts, backoffMs, lastError? }
route:{routeId}:operation:retry:stoppedRetry sequence ended{ routeId, exchangeId, correlationId, attemptNumber, success }

Error handler operations

EventWhen it firesDetails
route:{routeId}:operation:error:invoked.onError() handler called{ routeId, exchangeId, correlationId }
route:{routeId}:operation:error:recoveredHandler succeeded{ routeId, exchangeId, correlationId }
route:{routeId}:operation:error:failedHandler also failed{ routeId, exchangeId, correlationId, error }

Plugin events

Plugin events are scoped to a plugin ID.

EventWhen it firesDetails
plugin:{pluginId}:registeredPlugin registered{ pluginId, pluginIndex }
plugin:{pluginId}:startingPlugin is about to start{ pluginId, pluginIndex }
plugin:{pluginId}:startedPlugin has started{ pluginId, pluginIndex }
plugin:{pluginId}:stoppingPlugin is about to stop{ pluginId, pluginIndex }
plugin:{pluginId}:stoppedPlugin has stopped{ pluginId, pluginIndex }

Authentication events

Emitted by auth-enabled adapters (currently MCP HTTP) on every auth attempt. The source field identifies which adapter emitted the event.

EventWhen it firesDetails
auth:successToken validated and principal resolved{ subject, scheme, source }
auth:rejectedAuth failed (missing header, bad scheme, or invalid token){ reason, scheme, source }

reason is one of "missing_header", "unsupported_scheme", or "invalid_token".

MCP plugin events

Events emitted by the MCP plugin during server and tool lifecycle. Subscribe with wildcards (e.g. plugin:mcp:tool:**) for broad observability.

Server events

EventWhen it firesDetails
plugin:mcp:server:listeningHTTP server is ready to accept connections{ host, port, path }
plugin:mcp:server:tools:exposedTool list logged for the first time{ tools, count }

Session events

EventWhen it firesDetails
plugin:mcp:session:createdNew HTTP client session initialized{ sessionId }
plugin:mcp:session:closedHTTP client session transport closed{ sessionId }

Tool call events

EventWhen it firesDetails
plugin:mcp:tool:calledTool invocation started{ tool, args }
plugin:mcp:tool:completedTool invocation succeeded{ tool }
plugin:mcp:tool:failedTool invocation failed{ tool, error }

Events

How to subscribe, use wildcards, emit custom events, and common patterns.

Configuration

Subscribe to events via craft.config.ts.

Previous
Operations