Skip to content
mcpd
no daemon
Source

Coming from Mastra

mcpd is a free, self-hosted alternative to Mastra's observability and to its durable workflows. This page says where it is ahead, where it is behind, and how to move.

What this is

Mastra is an agent framework: agents, workflows, memory, RAG and observability, in one TypeScript dependency. mcpd is a daemon beside your code: it holds a workflow between its steps and records every step, and it leaves the models, the prompts and the tools to you. It is not a framework around your agent, and it is written to stay out of one.

That difference decides most of what follows. Mastra's observability knows about your agent because it is inside it. mcpd knows about your agent because your agent emits OpenTelemetry, which means it also works for the services around your agent, and for agents that were never written in TypeScript.

The differences that matter

The workflow's bodies stay in your process, in any language

Both run durable workflows. Mastra's steps are TypeScript functions inside the Mastra process, suspended and resumed through its storage. mcpd's definition is data the daemon holds, and its step bodies are code your process holds, claimed one lease at a time through an HTTP protocol that six SDKs speak and any language can. The daemon never sees a model, a prompt or a credential, and a body can change without the definition changing.

What the daemon does hold is the part that has to survive: the cursor, the journal, the retry budget, the timers, and a wait for an event that may take a week to arrive. A run outlives the process that started it and the worker that served its last step. See Workflows.

It receives OpenTelemetry rather than exporting it from one framework

This is the whole thesis. Mastra's observability exports from inside a Mastra application, so what it can see is what that application does, in the language it is written in. mcpd is the collector: it receives OTLP from any OpenTelemetry SDK, in any language, with no mcpd code in your application, and records the services around the agent as readily as the agent.

It also emits OTLP, so mcpd can sit in the middle of a pipeline you already have rather than at the end of one you have to build. See Forwarding.

Redaction covers all six signals

Mastra's SensitiveDataFilter is a span processor. It runs on spans and nothing else, so a key passed to a structured log, or a secret quoted in a score's reason or a piece of feedback, reaches every exporter unredacted.

mcpd redacts spans, logs, metric labels, scores, feedback and aspect notes, on by default, before anything is written and before anything is forwarded.

Its key matching is also a substring rather than an exact name, so awsSecretAccessKey and X-API-Key are caught by the rules for secret and x-api-key. A rule set that requires the whole name to match misses both.

Be clear about the limit: redaction matches on the name of a field, not on the shape of its contents. A token pasted into the middle of a prompt, or into a URL stored under a harmless key, is not removed by either tool. Redaction reduces what you leak by accident. It is not a guarantee.

What mcpd adds for that case is a scorer rather than a filter. The built-in no_leaked_secret reads a run's answer and matches on the shape of a credential, so a key that made it into a completion is at least reported to you. See Regression testing.

Ingest pipeline
  1. Decode

    OTLP or native, gzip or plain

  2. Sample

    Decided once, at the root

  3. Redact

    Before anything is written

  4. Price

    From the configured price book

  5. Store

    One transaction per batch

Redaction is stage three, not a cleanup job. A value that a rule matches never reaches storage at all.

Sampling is deterministic

Mastra's ratio sampling calls Math.random(). Every replica behind a load balancer therefore decides differently about the same trace, and a run that crosses two services can be kept by one and dropped by the other.

mcpd hashes the trace id, so every instance reaches the same answer with no coordination and a kept trace is kept whole. The daemon's flags reach two strategies, keep everything and this deterministic fraction; a tail strategy that would keep every error whatever the rate says exists in the policy type and is not reachable from the command line in this build. See Sampling.

The rest, briefly

AreaWhat mcpd does
Deployment One static binary with the store and the interface compiled in. No Node, no sidecar.
Storage SQLite for a laptop, Postgres or ClickHouse for a team. All three tested against a real server in CI.
Search Full text over every stored prompt and completion.
Metrics Aggregated at ingest, with exact quantiles and exemplars back to a run.
Cost Priced at ingest and stored. Cached tokens charged at their own rate. An unknown model is left unpriced rather than reported as free.
SDKs TypeScript, Python, Rust, Go, Kotlin and Elixir, generated from one specification so they cannot drift. Each carries a workflow builder and a worker.
Workflows Nine constructs, held by the daemon: steps, agent turns, sleeps, waits on events, parallel branches, foreach, bounded loops and child runs. Retries, effects and limits are per step. A conformance suite serves the same run from all six languages.
Evaluation Thirteen deterministic scorers, plus model-graded scoring against any OpenAI-shaped endpoint. Datasets captured from production runs, and experiment comparison that reports its sample size.
Licence Apache-2.0. Self-hosted with no account, or free hosted at mcpd.sh.

Where mcpd is behind

Stated here rather than left for you to discover, because a comparison that only lists wins is an advertisement.

  • Not a framework around your code. Mastra gives you agents, memory, RAG and a model router in one dependency. mcpd gives you the durable run and the record of it, and leaves models, prompts and tools to your code. If you want one dependency that does everything, Mastra is the one dependency.
  • No named vendor exporters. Mastra ships integrations for Langfuse, LangSmith, Braintrust, Arize, Datadog and others by name. mcpd forwards OTLP, which reaches most of them through one implementation, but a destination that speaks only its own protocol is out of reach.
  • No SSO, SCIM or RBAC. Authentication is six API key scopes and a project list per key. Put it behind the identity proxy you already run.

The full account, updated as things land, is in PARITY.md.

Moving over

If your agent already emits OpenTelemetry, this is two environment variables. mcpd speaks OTLP over HTTP, on the endpoints every OpenTelemetry SDK already knows how to talk to. Traces can be JSON or protobuf; logs and metrics must be JSON.

point an existing OpenTelemetry setup at mcpd

export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 export OTEL_EXPORTER_OTLP_PROTOCOL=http/json

The protocol line matters. Port 4317 is conventionally gRPC, and mcpd speaks HTTP on it, so an SDK left on its gRPC default connects to the right port and fails. OpenTelemetry goes through this and the rest of the settings.

Run both for a fortnight. mcpd forwards the spans it stores on to whatever you were using before, so you can compare the two on the same traces rather than on a migration you cannot undo. It forwards spans only: logs, metrics, scores, feedback and aspect notes stay in mcpd.

keep the old destination while you decide

mcpd serve --forward-endpoint https://your-existing-collector

If your agent does not emit OpenTelemetry yet, start with Quickstart, or pick your language under Instrument in the sidebar.

How this comparison was made

The Mastra claims on this page come from reading its source in August 2026, not from its documentation and not from running a benchmark. There are no performance numbers here because we have not measured any we would stand behind.

Mastra is actively developed and any of this can stop being true. If you find something out of date, it is a bug in this page: open an issue and it will be corrected.

Next