Install
$ agentstack add mcp-thru-echoes-trace ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
[](https://doi.org/10.5281/zenodo.21711455) [](https://github.com/Thru-Echoes/TRACE/actions/workflows/ci.yml) [](https://github.com/Thru-Echoes/TRACE/blob/main/LICENSE) [](https://github.com/Thru-Echoes/TRACE/blob/main/pyproject.toml)
Why TRACE?
In the age of AI, how do we know who proposed what in a scientific or coding dev workflow? Was the idea for that methodological decision made by AI or by a human? And when decisions are proposed by AI, are they being accepted, rejected, or iterated on?
What does the solution to this look like?
Every row above is a real event from session trace_20260730_32c108, captured as the work happened. Note what a diff could not have told you: one decision is still awaiting resolution because the AI is not permitted to resolve its own proposal, and the last event retracts an earlier contribution that turned out to be wrong. Regenerate it from any session with python3 scripts/make_provenance_animation.py .
One sentence from you, fully-scoped session from Claude:
- From inside
TRACE/, ask Claude to start a session and review the manuscript (which is inside sibling dir,TRACE-research/). - Past-session memory makes Claude pivot to that sibling repo before logging anything.
trace_start_sessionruns there, learnings auto-recall, and a five-item task plan emerges.
TRACE: Transparent Recording of AI-assisted Collaboration Experiments
TRACE is an MCP server that provides a standardized audit trail for AI-assisted research workflows. It records tool calls, decisions, annotations, contributions, and actor attribution — who proposed what, who accepted or revised it, and why.
TRACE runs as a sidecar alongside your domain MCP servers. It doesn't proxy or intercept calls — the AI client explicitly logs events to TRACE, creating a complete, human-readable provenance record.
Version: 0.5.0 | Spec: v0.5.0 | Schema: https://trace-protocol.org/v0.3 | License: Apache 2.0
> The schema URI is an identifier (per W3C PROV convention) and is not currently a resolvable URL. The machine-readable JSON Schema lives at schemas/trace-v0.5.json in this repository.
New in 0.5.0 — canonical project identity. Additive; every v0.3.x and v0.4.x session loads unchanged. A project is identified by a stable canonical key rather than a free-text label, so case and separator variants of one name stop reading as separate projects, and two genuinely different projects can no longer be merged by a case-insensitive filesystem. A TRACE_PROJECT pin binds one server process to one project, and cross-project reads and writes fail closed. No capture record is ever rewritten — a mislabelled project is repaired by adding an alias.
See CHANGELOG.md for the full entry and for 0.4.x, which added the Proposer Identity Rule, the discovery annotation category, URI-form corrections, and host / parent_event_id on tool calls. Design rationale lives in the ADRs; worked examples in docs/examples.md.
Why decision provenance?
Existing AI observability stacks (LangSmith, Langfuse, OpenTelemetry GenAI semconv) capture call-level traces — what tool an agent called, with what inputs, and what came back. They do not capture decision-level provenance — who proposed each step, whether a human reviewed it, what alternatives were rejected. The cost is visible in practice: in a preliminary rubric audit of agentic-AI deployments in environmental science, analytical decision provenance scored markedly lower than basic workflow description, and several recently-published papers showed discrepancies such as model details that did not match the cited models, or analyses that could not be reproduced from the reported description.
The need is also moving from norm to regulation. The EU AI Act (Articles 12, 19; applicable to high-risk systems August 2, 2026), California SB 942 (Transparency AI Act) (applicable August 2, 2026), Colorado SB 24-205 (effective June 30, 2026), the FDA PCCP final guidance (December 2024), the NIST AI Risk Management Framework, and ISO/IEC 42001:2023 all require some form of decision-process documentation. TRACE is designed so that documentation is a workflow byproduct, not an after-the-fact compilation.
Core concept: the decision chain
Every TRACE decision carries an actor (who proposed, who resolved), a disposition (proposed → accepted / revised / rejected), a rationale, a suggestion_type (proactive / requested / collaborative), and an optional revises_event_id linking to a prior decision. Decisions form a provenance DAG, not a flat log — a future reader can reconstruct who proposed what, why it landed where it did, and how the approach evolved during the session.
Three events from a real corp-sus-report-extractor session: a human-proposed scope decision (evt_002, accepted), an AI-proposed alternative kept for provenance after rejection (evt_003), and a correction annotation linked to the rejection via corrects_event_ids (evt_004). Rejected alternatives and corrections are first-class events — they don't get discarded.
Preliminary deployment results
Between 2026-03-18 and 2026-07-30, TRACE was used across 7 sustained research and development projects:
| Project | Domain | Sessions | Decisions | Contributions | Corrections | |---|---|---:|---:|---:|---:| | trace-mcp (self-host / meta) | Protocol research | 89 | 132 | 206 | 26 | | corp-sus-report-extractor | Corporate sustainability disclosure | 54 | 91 | 132 | 18 | | REAP | Environmental discourse analysis | 38 | 65 | 112 | 18 | | When-Algorithms-Meet-Artists | Computational art / cultural studies | 31 | 56 | 95 | 5 | | trace-research | Manuscript / literature synthesis | 30 | 48 | 76 | 18 | | waggle | Applied agentic tooling | 24 | 31 | 76 | 6 | | green-narrative | Environmental narrative analysis | 23 | 38 | 40 | 8 | | Total | | 289 | 461 | 737 | 99 |
Decisions: 68% AI-proposed / 32% human-proposed. Of the 344 resolved decisions, 89% accepted, 7% revised, 4% rejected; a further 117 remain in the proposed state, because an AI may not resolve its own proposal and not every proposal gets answered. The acceptance rate is not rubber-stamping — the 23 revisions, 15 rejections, and 99 separately-logged corrections are the active human steering this protocol exists to surface, and each one is an alternative that a commit history would have discarded.
Contributions: 68% human-directed, 24% collaborative, 8% AI-directed; 65% are human-directed and AI-executed. Pure AI-directed-and-executed work is a small minority. The dominant pattern is human direction with AI execution — which existing authorship and attribution norms cannot describe.
> What these counts include. Figures were taken on 2026-07-30 from per-session logs in ~/.trace/sessions/, which are not committed here (they contain project-internal content), and cover the seven named projects only. The store also holds meeting-transcription namespaces, throwaway test keys, and short exploratory sessions; those are excluded, since a transcript namespace accumulates thousands of machine-written annotation events and no decisions, and counting them would inflate a raw event total by more than an order of magnitude without adding a single act of provenance. Counts here are the deliberately logged event types. Sessions recorded before v0.5 under the display label TRACE are counted under trace-mcp, which is the same project under its canonical key. Reproducible from those logs via trace_project_summary; an aggregated, de-identified export can be provided on request.
Architecture
AI Client (any MCP-aware client: Claude Code, Cursor, ChatGPT, Codex, ...)
|
+-- connects to: Domain MCP Server(s)
| (corpus search, NLP pipeline, data retrieval, etc.)
| --> does the actual work
|
+-- connects to: TRACE MCP Server (this project)
--> records what happened to JSON files
--> persists learnings across sessions (trace-learn)
Storage model: One self-contained JSON file per session in ~/.trace/sessions/. Files are human-readable (pretty-printed with indent=2), git-diffable, and shareable.
Core stack: Python 3.11+, Pydantic v2, async throughout, zero external dependencies beyond mcp and pydantic (OpenAI optional for LLM-enhanced features).
Quick Start
Install
uv pip install -e ".[dev]"
Configure your MCP client
Add to your project's .mcp.json:
{
"mcpServers": {
"trace": {
"command": "uvx",
"args": [
"--from", "/path/to/TRACE",
"--with", "openai", "--with", "numpy", "--with", "model2vec",
"--refresh-package", "trace-mcp", "trace-mcp"
],
"env": { "TRACE_PROJECT": "your-project-key" }
}
}
}
Using uvx builds the package into an isolated environment, avoiding .venv breakage from Python upgrades. --refresh-package rebuilds TRACE from the source tree on the next server start, without re-resolving the whole dependency set each time.
Two parts of that config are easy to omit and worth keeping:
- The three
--withpackages are what make this a 22-tool server. They are the optional dependencies of the trace-learn extension. Without them the server still starts and still records provenance, but the extension does not load and you get the 17 core tools with no error to tell you why. TRACE_PROJECTpins the process to one project. With it set you omitprojectfromtrace_start_session, and cross-project reads and writes fail closed. Without it, passproject="..."explicitly on every session start — an unpinned server rejects the call rather than guessing.
Install hooks
trace-mcp-init installs the host-side enforcement: hook scripts under .claude/hooks/, registrations merged into .claude/settings.json, and a marker block appended to CLAUDE.md.
trace-mcp-init # auto-detect host (default)
trace-mcp-init --client claude-code # explicit
trace-mcp-init --dry-run # preview, no writes
The Claude Code adapter installs four hooks:
| Hook | Event | Purpose | |------|-------|---------| | session-reminder.sh | SessionStart | Reminds you to start a TRACE session if one isn't active for the current project. Project detection: CLAUDE.md → git repo basename → cwd basename. | | prompt-reminder.sh | UserPromptSubmit | Periodic nudge after several prompts without a session. Per-project rate-limited. | | pretool-guard.sh | PreToolUse (Edit\|Write) | Warns (or blocks) edits when no TRACE session is active. | | decision-audit.sh | PostToolUse (trace_end_session) | Echoes the session-end attribution audit into the conversation. |
Project detection uses, in order: a TRACE project name: "..." line in CLAUDE.md, the git repository basename, then the current working directory basename. Add the explicit marker if your repo name differs from the project name you want logged.
Codex support is scaffolded as a placeholder; see src/trace_mcp/adapters/codex/README.md for the hook primitives a Codex adapter would need.
Worked examples for logging decisions, corrections, contributions, and decision chains live in docs/examples.md.
Hook environment variables
| Variable | Default | Effect | |---|---|---| | TRACE_GUARD | soft | pretool-guard.sh mode: off (no-op), soft (warn-only), strict (exit 2 to block when no session is active). | | TRACE_PROMPT_MIN_TURNS | 3 | Minimum prompt turns before prompt-reminder.sh will nudge. | | TRACE_PROMPT_COOLDOWN_SEC | 300 | Wall-clock cooldown between nudges from prompt-reminder.sh. | | TRACE_RUNTIME_DIR | ~/.trace/runtime | Per-project nudge state (.state.json). Safe to delete to reset. | | TRACE_SOURCE_PATH | unset | Override what trace-mcp-init writes into .mcp.json as uvx --from . Set to a local TRACE clone path. Required when running init from an installed wheel — with no override, init fails closed rather than writing the PyPI name trace-mcp, which belongs to an unrelated package (dependency confusion). |
Run a first session
Once configured, TRACE tools are available to the AI client:
You: "Start a TRACE session for our climate NLP analysis"
Claude: -> trace_start_session(project="climate-nlp", ...)
"Session started: trace_20260205_a1b2c3"
"Relevant learnings from past sessions:
- [correction] Always use ml-dev conda env, not base (relevance: 87%)"
You: "Search for adaptation passages in the IPCC corpus"
Claude: -> [calls corpus-search-mcp/search_passages]
-> trace_log_tool_call(server="corpus-search-mcp", ...)
-> trace_propose_decision(description="Focus on chapters 14-17", ...)
You: "Also include chapter 6"
Claude: -> trace_resolve_decision(disposition="revised", ...)
You: "End the session"
Claude: -> trace_end_session(summary="Analyzed 47 passages...")
(learnings auto-extracted and persisted for future sessions)
Available tools (22 total)
Core tools (17)
| Tool | Description | |------|-------------| | trace_start_session | Start a new audit session (auto-recalls relevant past learnings) | | trace_end_session | End a session with summary (auto-extracts learnings) | | trace_log_tool_call | Record a tool invocation on another MCP server | | trace_log_annotation | Record a learning, gotcha, correction, observation, todo, or question | | trace_log_contribution | Record a deliverable with direction (who had the idea) vs execution (who did the work) attribution | | trace_log_state_change | Record an environment or configuration change | | trace_propose_decision | Propose a methodological decision (with suggestion_type: proactive/requested/collaborative) | | trace_resolve_decision | Accept, revise, or reject a proposed decision | | trace_get_session | Get session metadata | | trace_get_events | List events (filterable by type) | | trace_get_decisions | List decisions (filterable by disposition and/or proposed_by_type) | | trace_get_decision_chain | Walk linked decision revisions via revises_event_id | | trace_search | Search events by text content | | trace_export | Export as JSON, Markdown, or PROV JSON-LD | | trace_list_sessions | List all sessions (filterable by project) | | trace_project_summary | Aggregated metrics across all sessions for a project | | trace_health_check | System health and event-level statistics |
Extension: trace-learn (5) — default for new sessions
| Tool | Description | |------|-------------| | trace_learn_recall | Find relevant past learnings via text similarity and tag matching | | trace_learn_add | Manually add a learning to the knowledge store | | trace_learn_list | List all learnings (optionally filtered by category) | | trace_learn_forget | Remove a learning by ID | | trace_learn_extract | Extract learnings from session events (annotations, rejected decisions, contributions) |
Event types
| Type | Description | Key Fields | |------|-------------|------------| | tool_call | Invocation of an MCP server, host-internal helper, or external tool | server, name, input, output, status, retries_event_id, host (v0.4.1: mcp/internal/external), parent_event_id (v0.4.1: links dispatched child to controller) | | **deci
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Thru-Echoes
- Source: Thru-Echoes/TRACE
- License: Apache-2.0
- Homepage: https://doi.org/10.5281/zenodo.21711455
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.