Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/theonetrade/ai-trading-mcp/llms.txt

Use this file to discover all available pages before exploring further.

When an LLM makes trading decisions, “what did it know and when did it know it?” must have a precise answer. The audit trail built into this rig answers that question by design: every get_status response — the complete input the model received before each decision — is written to disk before it ever leaves the trading process. Nothing is reconstructed after the fact.

What Gets Logged

get_status snapshots

Every call to get_status triggers StatusMarkdownService.dumpStatus(). The full response — engine portfolio state, command history, and all 15 Telegram feed posts — is serialised to a markdown file at dump/mcp/<minute-stamp>.md. Images are extracted from MCP image blocks and written separately to dump/images/<id>.png, then referenced with relative paths in the markdown so the file renders correctly anywhere.

Position notes

Every position carries a note field written by the agent at the moment open_position is called. The note records the agent’s stated basis: which Telegram post triggered the decision, its timestamp, and any reliability caveats the agent added. The engine echoes the note back in every subsequent get_status response until the position is closed.

Engine event streams

Four JSONL files stream engine events continuously into dump/report/:
  • live.jsonl — every engine event
  • performance.jsonl — closed-trade records
  • max_drawdown.jsonl — drawdown events
  • highest_profit.jsonl — profit peak events

Live state persistence

config/setup.config.ts wires *Live.usePersist() for every state class: signals, storage, notifications, recent, memory, state, and sessions all survive process restarts under dump/data/.

The Dump Directory Structure

dump/
├── data/                   # Live state — persists across restarts
│   ├── signals/
│   ├── storage/
│   ├── notifications/
│   ├── recent/
│   ├── memory/
│   ├── state/
│   └── sessions/
├── mcp/                    # One markdown file per minute-stamp
│   └── 2026-08-02T09:34.md
├── images/                 # Chart screenshots extracted from MCP image blocks
│   └── <id>.png
└── report/                 # JSONL event streams
    ├── live.jsonl
    ├── performance.jsonl
    ├── max_drawdown.jsonl
    └── highest_profit.jsonl
dump/data/ holds the live engine state that makes restarts non-destructive — an open position, its OCO brackets, and its full signal history are all restored when the process comes back up. dump/mcp/ and dump/images/ hold the audit record of what the model saw. dump/report/ holds the quantitative record of what the engine did.

Reading the Markdown Dumps

The web UI served on http://localhost:60050 ships a built-in dump viewer. Open it in any browser after starting the trading process to browse every get_status snapshot with images rendered inline. No separate tooling required.
Each file in dump/mcp/ is a complete transcript of one get_status call: engine portfolio block, command history, and the full Telegram feed slice the model evaluated. Image references use relative paths (../images/<id>.png), so the files also render correctly in any markdown viewer that can resolve relative links — VS Code preview, GitHub, Obsidian, or a static site. Here is a real position note from a recorded session (translated from Russian), showing exactly what the audit trail captures about the agent’s basis for a decision:
Active position: short (note: Paper trade at user's request. Basis — signal from
Telegram feed -1002833393903, 2026-08-02 09:34 UTC ("Working BTC — short, sized
for a possible add"), entry ~63 285.75. No own technical confirmation; the source
shows signs of unreliability.)
This note appears verbatim in every get_status response for the lifetime of the position, and it is preserved in the dump/mcp/ file for the minute the position was opened.

How StatusMarkdownService.dumpStatus() Works

StatusMarkdownService.dumpStatus(messages, context, when) is called at the end of every get_status composition, before the response is returned to the caller. It:
  1. Creates dump/mcp/ and dump/images/ if they do not exist
  2. Iterates the IMCPMessage[] array — text messages are appended directly; image messages are decoded from base64 and written to dump/images/<id>.png, with a relative markdown image tag inserted into the text content
  3. Derives a minute-precision timestamp from when using getMomentStamp(when, "minute")
  4. Writes the assembled markdown to dump/mcp/<minute-stamp>.md
The minute-stamp filename means concurrent calls within the same minute overwrite each other rather than producing duplicates, and the directory can be sorted chronologically by filename with no additional metadata.

Why This Matters

LLM trading decisions are non-deterministic: the same feed post on a different day, with a different portfolio state or a slightly different phrasing in the system prompt, might produce a different action. Logging the model’s output (the trade) is not enough — you need the model’s input (what it actually saw) to reconstruct the decision. The audit trail closes this gap. For any position in the engine — open or closed, paper or live — you can answer:
  • Which Telegram post did the agent cite as its basis?
  • What was the exact portfolio state at the time of the decision?
  • What other posts were in the 15-post feed window the model evaluated?
  • Did the agent note any reliability concerns about the source?
The dump/mcp/<minute-stamp>.md file for the minute of the open_position call contains all of this. The note field on the signal echoes the agent’s stated basis back through every subsequent status call. Together they make the full reasoning chain reconstructable without re-running the model.

Build docs developers (and LLMs) love