MCP server for AI agents to record and query their reasoning steps. SQLite-backed, zero-dependency beyond mcp SDK.
Project description
SciTrace
An MCP server that moves AI agents' reasoning chains out of the context window and into a database.
One line of MCP config. Two tools. The agent calls build_trace to record each reasoning step and query_trace to pull history back on demand. Data lives in SQLite, not in the context window.
Why not prompts or skills?
Prompts and skills can force an agent to emit structured reasoning, but they cannot do the following five things.
1. The context window is a scarce resource, not a warehouse
| Prompt-instructed output | SciTrace | |
|---|---|---|
| Context after 10 steps | 10 full JSON blocks (500–1500 tokens) stacked in the window | 10 short call records; data lives in SQLite |
| After 50 steps | The agent starts "forgetting" earlier steps — the window fills with history | Context stays clean; query_trace fetches exactly what's needed |
| Across sessions | New session = everything lost | SQLite persists; new sessions query directly |
With prompts, reasoning chains accumulate and steal token budget from the real task. SciTrace moves the data out — the context window is for thinking, SQLite is for storage.
2. Prompts only write; SciTrace can query
Prompt: "What was that earlier hypothesis again?" → agent rummages through 3000 tokens of chat history → maybe finds it, maybe not
SciTrace: query_trace(type="hypothesis") → exact result, no chat history involved.
Structured queries = type=backtrack finds every failed backtrack point, type=experiment lists all experiments, trace_id=xxx returns the full chain. Prompts cannot do this.
3. A DAG is not flat
Prompts force agents to output sequential lists. But scientific reasoning is not linear — it forks, backtracks, and has dependencies.
h1 (hypothesis) → a1 (analysis) → e1 (experiment) → b1 (backtrack) → e2 (revision) → v1 (verification) → c1 (conclusion)
↑
parent_id declares the dependency explicitly
parent_id turns a flat list into a directed acyclic graph. This graph structure doesn't consume context — it lives in SQLite foreign-key relationships.
4. Write once, every agent can use it
| Prompt | Skill | SciTrace | |
|---|---|---|---|
| Claude | One per agent | One per agent | ✅ Same MCP config |
| Cursor | One per agent | — | ✅ Same MCP config |
| Hermes | One per agent | One per agent | ✅ Same MCP config |
| Codex | One per agent | — | ✅ Same MCP config |
MCP is a protocol standard. Write the server once and every MCP-compatible agent gets reasoning tracing automatically. No need to port prompts per agent.
5. Data can be consumed by programs
Structured output produced by prompts is readable only by an LLM. SciTrace's data lives in SQLite — any tool can read it:
Python analysis scripts → read SQLite directly
Visualization → scitrace-viz renders an HTML report
CI/CD pipelines → sqlite3 CLI queries
Jupyter → import sqlite3 and analyze
No LLM required — the consumer of the data can be code.
Architecture
Agent (Claude/Cursor/Hermes/Codex)
│
│ MCP protocol (stdio)
│
▼
┌─────────────────────────┐
│ SciTrace MCP Server │
│ │
│ build_trace ← writes │
│ query_trace ← reads │
│ │
│ ↓ SQLite │
│ steps table │
│ - id, parent_id (DAG) │
│ - type (6 step types) │
│ - summary, artifacts │
└─────────────────────────┘
Quick start
pip install scitrace
Add to your MCP client config:
{
"mcpServers": {
"scitrace": {
"command": "python",
"args": ["-m", "scitrace"]
}
}
}
The agent can now call build_trace and query_trace.
Storage
| Item | Default | Override |
|---|---|---|
| Database path | ~/.scitrace/traces.db |
SCITRACE_DB env var, or --db <path> in MCP args |
| Visualization output dir | current working directory | SCITRACE_OUTPUT env var |
{
"mcpServers": {
"scitrace": {
"command": "python",
"args": ["-m", "scitrace", "--db", "/path/to/custom.db"]
}
}
}
Visualization
pip install ships a scitrace-viz command — it renders a reasoning chain as HTML (Mermaid DAG + step table):
scitrace-viz # visualize the most recent trace
scitrace-viz <trace_id> # visualize a specific trace
scitrace-viz --out ./viz # specify the output directory
The two tools
build_trace
Records a reasoning step. The agent calls it after each verifiable subtask.
| Parameter | Description |
|---|---|
step_id |
Unique identifier for this step |
trace_id |
Which reasoning chain this step belongs to |
type |
hypothesis / analysis / experiment / verification / conclusion / backtrack |
summary |
One-line summary of what this step did |
parent_id |
Which step this depends on (builds the DAG) |
artifacts |
Associated file paths |
query_trace
Queries historical reasoning steps.
| Parameter | Description |
|---|---|
trace_id |
Filter by reasoning chain |
type |
Filter by step type |
limit |
Max steps returned (default 50, max 1000) |
Example
A complete reasoning chain:
build_trace: { "step_id": "h1", "trace_id": "exp-001", "type": "hypothesis", "summary": "Assume P != NP" }
build_trace: { "step_id": "a1", "trace_id": "exp-001", "type": "analysis", "summary": "SAT is hard", "parent_id": "h1" }
build_trace: { "step_id": "e1", "trace_id": "exp-001", "type": "experiment", "summary": "Run benchmarks", "parent_id": "a1", "artifacts": ["results.csv"] }
build_trace: { "step_id": "c1", "trace_id": "exp-001", "type": "conclusion", "summary": "Conclusion: ...", "parent_id": "e1" }
query_trace: { "trace_id": "exp-001" } → the full chain
query_trace: { "type": "experiment" } → all experiment steps
query_trace: { "limit": 10 } → the 10 most recent steps
Development
git clone https://github.com/Mobai-read/scitrace
cd scitrace
pip install -e ".[dev]"
pytest
See CONTRIBUTING.md for the full contribution workflow.
Summary comparison
| Prompt | Skill | SciTrace | |
|---|---|---|---|
| Data location | context window | context window | SQLite |
| Cross-session persistence | ❌ | ❌ | ✅ |
| Structured queries | ❌ | ❌ | ✅ |
| DAG dependencies | ❌ | ❌ | ✅ (parent_id) |
| Program-readable | ❌ | ❌ | ✅ (SQLite) |
| Multi-agent | one per agent | one per agent | ✅ one config |
| Long reasoning chains | blows up the context | blows up the context | context stays clean |
Documentation
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file scitrace-0.1.0.tar.gz.
File metadata
- Download URL: scitrace-0.1.0.tar.gz
- Upload date:
- Size: 17.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a88328ac28c67e78807e0746dfad739671992740df82b53edc71c36114dcb3ab
|
|
| MD5 |
f55246b13b333098c197d8503872bdc3
|
|
| BLAKE2b-256 |
beb0317eb960ac8c4c4318f2483ce13749e38664aa131811c0d47fcfd6427181
|
File details
Details for the file scitrace-0.1.0-py3-none-any.whl.
File metadata
- Download URL: scitrace-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdf0f9610a9eb5ea7e9397a238ac2ff1c2316e50582e8200f73018c08bef0cac
|
|
| MD5 |
1a2fa246793d9f708cad8d97dc3da108
|
|
| BLAKE2b-256 |
f86c64db3423c4285ed1608817aab098f0cbf2b6dfb13519c1662d63d149d206
|