Isaac Daniel
Back to Blog
Isaac May 2026 8 min read

D4C: Building a Terminal Coding Agent in Rust from Scratch

Most coding agents optimize for freeform chat — and you find out the model misunderstood you only after your files change. D4C makes planning a first-class, interactive step. Built from scratch in Rust with a native TUI.

Rust
TUI
AI Agent
MCP
Open Source

What is D4C?

D4C — short for Dirty Deeds Done Dirt Cheap — is a lightweight, modular terminal coding agent built from scratch in Rust with a native TUI. It shares no source code with Claude Code, OpenCode, or any existing agent — it's inspired by their usability, then rebuilt around a different core idea.

That idea: guided workflows over open-ended chat. Most agents take your request and immediately start editing files — you discover scope or misunderstanding only after changes are made. D4C integrates model providers through APIs and treats planning as a first-class, interactive step: repository context is gathered, ambiguities are resolved through a structured questionnaire, assumptions are surfaced for review, and only an approved plan is executed, with checkpoints along the way.

The name is a nod to the JoJo's Bizarre Adventure reference. It stuck.

Why Rust, Why from Scratch

I use coding agents daily, and three frustrations kept coming up — none of them fixable by tweaking someone else's tool:

The problems: freeform chat wastes iterations on misunderstandings; autonomous edits on real codebases are hard to trust; and nothing records why a change was made. On top of that, most agents lock you into one vendor's CLI and treat local models as an afterthought.

So D4C is built from scratch in Rust. Three reasons:

Startup under 100ms

A coding agent should feel like a terminal tool, not a web app. Rust plus Ratatui gets D4C to its first interactive UI frame in under 100ms — no Node runtime booting, no framework hydration.

Provider-agnostic by design

D4C integrates model providers through APIs, not through one vendor's CLI. Self-hosted and local models get first-class support, not a bolted-on compatibility layer.

Guided, auditable workflows

The planning-first interaction model is the core differentiator. Every change traces back to an approved plan, and checkpoints make autonomous edits reviewable instead of scary.

"Most terminal agents optimize for freeform chat. D4C optimizes for getting it right before touching your files."

Fig 1 — D4C's planning workflow: structured breakdown, questionnaire, and an approved plan before any code is written.

Key Features

D4C's feature set follows from the planning-first philosophy. Each one exists to reduce surprise, not to add surface area.

Planning-First Workflows

The flagship feature. Before any code changes, D4C gathers repository context, resolves ambiguities through a structured questionnaire, and surfaces its assumptions for review. Only after you approve the plan does execution begin — with checkpoints along the way. This separation of thinking and doing dramatically reduces hallucination and builds trust in autonomous edits.

Native Ratatui TUI

D4C renders with Ratatui + crossterm — a true terminal UI, not a REPL with colored text. Fast startup, full keyboard control, and a layout that stays responsive while streaming model output in the background.

Native MCP Client

D4C implements the Model Context Protocol natively in the Rust core — no external MCP launcher process. Tools and context servers plug in through a standard protocol instead of vendor-specific glue.

Automatic Model Selection

A small embedded router picks the model based on task complexity — cheap models for routine edits, stronger ones for gnarly refactors. No separate heavy service, no external dependency, and it's transparent: you can always see and override what was chosen.

Slash-Command Architecture

Slash commands are the primary interaction surface — not buried menus or chat keywords. Everything the agent can do is discoverable, scriptable, and consistent.

Why an embedded router instead of a bigger service? Model choice is a per-task decision, not a per-session config. Keeping the router small and inside the agent means startup stays fast, there's nothing else to deploy, and the selection logic stays auditable in one place.

Feature Summary

<100ms
First UI Frame
1
Approved Plan Before Execution
Native
MCP Client in Rust
Auto
Model Router
Fig 2 — Execution with checkpoints: each step from the approved plan, tracked as it completes.

Setup & Architecture

D4C is a Rust workspace split into three crates, each independently testable:

Core Stack

  • Rust 2024 — single language, no runtime
  • d4c-core — agent logic, tools, MCP client
  • d4c-tui — Ratatui + crossterm terminal UI
  • d4c-cli — headless / non-interactive entry
  • Tokio — async runtime for streaming model I/O
  • reqwest — provider API calls over rustls

Architecture Principles

  • Crates split: core / TUI / CLI independently testable
  • Provider abstraction — no vendor lock-in
  • MCP implemented natively in the core crate
  • Plans, checkpoints, and tool calls are first-class records
  • Model router embedded — no external service
Fig 3 — MCP client configuration in the Rust core: context servers plug in over the standard protocol.

Challenges & Fixes

Building an agent from scratch means building everything twice: once as code, once as an interaction model. These four problems shaped the project the most:

01

The Trust Problem

The whole reason D4C exists. Early prototypes edited files directly from chat and I stopped trusting them on real codebases. The fix wasn't a confirmation dialog — it was restructuring the interaction: context gathering, a structured questionnaire for ambiguities, surfaced assumptions, and an approved plan with checkpoints before execution starts.

02

Streaming Output in a TUI

Rendering live model output while keeping a Ratatui layout responsive is trickier than printing to stdout. The solution was an event-driven design on Tokio: model streams push events into a channel, and the TUI redraws from state snapshots — the render loop never blocks on the network.

03

MCP Without the Glue

Most agents shell out to an external MCP launcher process. D4C implements the protocol natively in the Rust core, which means better error handling and no process-management headaches — but it also meant implementing the protocol's lifecycle, tool discovery, and error semantics by hand.

04

Provider Abstraction

Every provider's API differs in streaming format, tool-call shape, and error behavior. The abstraction layer normalizes all of it into one internal format — which is also what makes the automatic model router possible: routing is just choosing among normalized providers per task.

"Building from scratch wasn't the hard part. Deciding what the agent should ask before it acts was."

Fig 4 — Slash commands are the primary interaction surface: discoverable, scriptable, consistent.

What's Next

D4C is in active development as my daily coding agent. Here's the direction:

In Progress

Session Memory Persistence

Remember decisions and repository context across sessions. If the agent mapped your project structure yesterday, it shouldn't rediscover it today.

In Progress
Planned

Richer Checkpoint Review

Deeper diff inspection at each checkpoint, plus plan revision mid-execution when reality disagrees with the approved plan.

Planned
Exploring

Multi-Agent Orchestration

Specialized sub-agents for parallel task execution — one builds while another researches, coordinated through the planning layer.

Exploring
Exploring

Local Model Hardening

D4C is provider-agnostic by design; the next step is first-class support for self-hosted inference (Ollama, vLLM) with the same streaming and tool-call guarantees as hosted APIs.

Exploring

Try D4C

Browse the source, read the PRD, or build it yourself. D4C is open and built in the open — contributions and ideas welcome.