Docs / Integrations / Mastra

Mastra

Mesedi ships as a first-class Mastra observability exporter. Wire a MesediExporter into your Observability config and every agent run, workflow run, LLM call, and tool call flows into Mesedi. No changes to your agent code; no wrap() call required.

Install

npm install mesedi@^0.6 @mastra/core @mastra/observability

Mesedi's adapter treats @mastra/core and @mastra/observability as optional peer dependencies. If you never import mesedi/integrations/mastra, neither library is loaded and there is no install cost for non-Mastra customers.

Wire it up

import { configure } from "mesedi";
import { MesediExporter } from "mesedi/integrations/mastra";
import { Mastra } from "@mastra/core";
import { Observability } from "@mastra/observability";

// Configure Mesedi once (usually at app startup).
configure({ apiKey: process.env.MESEDI_API_KEY });

// Attach the exporter to Mastra's Observability instance.
// Mastra 1.x requires the `configs` shape below; the pre-1.x
// `exporters: {...}` root shape is silently ignored.
const mastra = new Mastra({
  observability: new Observability({
    configs: {
      mesedi: {
        serviceName: "my-app",
        exporters: [new MesediExporter()],
        sampling: { type: "always" },
      },
    },
  }),
  // ...your agents / workflows
});

That's the whole surface. Every subsequent agent.generate(...) or workflow execution opens a Mesedi failure_group scope on the root span and forwards child spans as events. Cross-cutting Mesedi features (per- project detector thresholds, custom security patterns, hard-halt budgets) all keep working through Mastra runs without any additional wiring.

Optional: tenant attribution

new MesediExporter({ tenantId: "acme-corp" });

Attach a tenant identifier to every execution the exporter opens. Surfaces on the dashboard's cost-by-tenant report and enables provider_incident's cross-tenant clustering. Absent means "unattributed."

Span-to-event mapping

Mastra emits an OTel-shaped span for every operation. The exporter translates each span type into the corresponding Mesedi event on span-end.

Mastra spanMesedi eventNotes
AGENT_RUNOpens execution + checkpoint enter/exitRoot span. Also emits execution end with status.
WORKFLOW_RUNOpens execution + checkpoint enter/exitSame treatment as AGENT_RUN.
MODEL_GENERATIONllm_callExtracts model, provider, and token counts from attributes.
TOOL_CALL / CLIENT_TOOL_CALLtool_callTool name, input, output. Errors → status = "error".
MCP_TOOL_CALLmcp_callSeparate event type to keep MCP failure attribution clean.
WORKFLOW_STEPcheckpointStep name lands on the checkpoint payload.

Detector coverage

All 20 Mesedi failure-class detectors fire when driven through this adapter. Nine are native: the exporter's span-to-event mapping above feeds them directly, no changes to your Mastra code. Eleven are hybrid: you call an SDK emit helper inside the same code path where Mastra runs, and the detector picks up the shape it needs. The Mastra integration harness exercises all 20 end-to-end against a real backend.

DetectorModeFires via
loopsNativeMODEL_GENERATION + WORKFLOW_STEP spans (identical_call, similar_call, step_count)
tool_failuresNativeTOOL_CALL span with errorInfo
driftNativeMODEL_GENERATION user_message divergence
cost_velocityNativeMODEL_GENERATIONtoken counts + provider pricing (wrap the loop in a workflow so it's one execution)
prompt_injectionNativeMODEL_GENERATION user_message pattern match
data_leakageNativeMODEL_GENERATION user_message DLP match
semantic_loopNativeWORKFLOW_STEP metadata equality across 3+ steps in one workflow_run
context_overflowNativeMODEL_GENERATION prompt-size vs model window
token_wasteNativeMODEL_GENERATION shared prefix across 3+ user_messages
crashesHybridthrow inside wrap() — same pattern every SDK language uses
validator_failuresHybridCall validatorResult() after your schema check
infrastructure_throttledHybridCall emitInfrastructureEvent() when you observe a rate-limit / retry
tool_schema_driftHybridWrap the tool with tool() — structured return_value fingerprints the shape
sandbox_escapeHybridWrap the tool with tool() — arguments match the dangerous-call regex directly
grounding_failureHybridCall emitEvalScore() with your RAG / faithfulness score
cascading_failureHybridCall emitAgentHandoff() to a child execution
coordination_deadlockHybridCall emitAgentHandoff()— Tarjan's SCC catches the cycle
provider_incidentHybridEmit a failed llm_call event with error_class="timeout" / "rate_limited" when your provider client throws
hitl_timeoutHybridrequestHumanIntervention() + completeHumanIntervention() with timeout kind
hitl_rejection_spikeHybridRepeated validatorResult() with human_verdict=rejected over a window

Hybrid rows use exactly the same SDK helpers you'd call from any Mesedi integration (or from plain wrap()-only code). The Mastra exporter and the helpers coexist in one execution — no double-counting, no setup order dependency.

Execution status

  • error attribute set on the root span → execution status crashed.
  • tripwireAbort attribute set (Mastra processor tripwire fired) → execution status halted.
  • Otherwise → execution status completed.

Current limitations

  • RAG spans (RAG_INGESTION, RAG_EMBEDDING, RAG_VECTOR_OPERATION, RAG_ACTION) are not currently mapped. They flow through the exporter as no-ops.
  • Memory + workspace spans (MEMORY_OPERATION, WORKSPACE_ACTION) are not currently mapped.
  • Scorer spans (SCORER_RUN, SCORER_STEP) are not consumed — Mesedi runs its own AI root-cause analysis downstream.
  • Finer-grained model spans (MODEL_STEP, MODEL_INFERENCE, MODEL_CHUNK) are intentionally ignored. MODEL_GENERATIONis the aggregating span for a full model call; the finer spans would duplicate the same event to Mesedi's detectors.
  • Multi-agent handoff detection emits checkpoint events rather than dedicated agent_handoffevents. Mastra's workflow step topology doesn't map cleanly onto Mesedi's handoff shape without ambiguity.

Related