dproxy — Transport
dproxy is the universal CLI adapter in dtoolkit. It provides a single interface for invoking AI coding agents across multiple providers — Claude Code, Codex CLI, Gemini CLI, and OpenCode — without changing your workflow. Whether you need a one-shot prompt, an interactive REPL, or a REST API for programmatic access, dproxy handles provider differences behind a unified abstraction.
Overview
Section titled “Overview”AI coding CLIs each have their own invocation patterns, streaming formats, and context conventions. dproxy normalizes all of this into one tool:
- One CLI, four providers — switch between Claude Code, Codex, Gemini, and OpenCode with a single
--providerflag - Context pipeline — automatically assembles prompts from chat history, workspace context, memory, and life/PARA data
- REST API — expose the same capabilities over HTTP with SSE streaming for real-time output
- Template system — define reusable prompt templates for common tasks
- History and memory — persistent conversation logs and memory snippets across sessions
Data is stored in ~/.dproxy/ (config.json, history.jsonl, memory/, templates/).
Installation
Section titled “Installation”pnpm add @dtoolkit/dproxyOr install globally:
pnpm add -g @dtoolkit/dproxyThen initialize your configuration:
dproxy initProviders
Section titled “Providers”dproxy supports four AI coding CLI providers. Each provider has a corresponding adapter package that handles the specifics of invocation, streaming format, and output parsing.
| Provider | Adapter Package | Streaming Format | Default |
|---|---|---|---|
| Claude Code | @dtoolkit/adapter-claude | stream-json + deltas | Yes |
| Codex CLI | @dtoolkit/adapter-codex | JSONL streaming | No |
| Gemini CLI | @dtoolkit/adapter-gemini | stream-json | No |
| OpenCode | @dtoolkit/adapter-opencode | JSONL streaming | No |
Switch providers with the --provider flag on any command:
dproxy ask "Explain this function" --provider claudedproxy ask "Explain this function" --provider codexdproxy ask "Explain this function" --provider geminidproxy ask "Explain this function" --provider opencodeCLI Commands
Section titled “CLI Commands”dproxy ask — Single-shot prompt
Section titled “dproxy ask — Single-shot prompt”Send a one-shot prompt and get a response. This is the most common command for scripting and quick questions.
dproxy ask "What does this regex do: ^(?=.*[A-Z])(?=.*\d).{8,}$"Pipe input from other commands:
cat src/lib/runner.ts | dproxy ask "Review this file for bugs"With a specific provider:
dproxy ask "Generate unit tests for this module" --provider geminidproxy chat — Interactive REPL
Section titled “dproxy chat — Interactive REPL”Start a conversational REPL session with persistent context across turns:
dproxy chatdproxy chat --provider codexThe REPL maintains conversation state for the duration of the session. History is persisted to ~/.dproxy/history.jsonl.
dproxy serve — REST API server
Section titled “dproxy serve — REST API server”Launch a Fastify HTTP server that exposes the full CLI functionality over REST:
dproxy servedproxy serve --port 7880The default port is 7880. See the REST API section for endpoint details.
dproxy history — View past interactions
Section titled “dproxy history — View past interactions”Browse and search conversation history:
dproxy historydproxy memory — Manage memory snippets
Section titled “dproxy memory — Manage memory snippets”View and manage memory snippets that are injected into the context pipeline:
dproxy memorydproxy template — Manage prompt templates
Section titled “dproxy template — Manage prompt templates”Create, list, and use reusable prompt templates:
dproxy templateSee the Templates section for details.
dproxy init — Initialize configuration
Section titled “dproxy init — Initialize configuration”Set up the ~/.dproxy/ directory and default configuration:
dproxy initCommand summary
Section titled “Command summary”| Command | Purpose | Key Flags |
|---|---|---|
ask | Single-shot prompt execution | --provider, piped stdin |
chat | Interactive REPL session | --provider |
serve | Launch REST API server | --port |
history | Browse conversation history | — |
memory | Manage memory snippets | — |
template | Manage prompt templates | — |
init | Initialize configuration | — |
Context Pipeline
Section titled “Context Pipeline”One of dproxy’s most valuable features is its automatic context assembly. Before every prompt is sent to a provider, dproxy builds a rich context from multiple sources in priority order:
-
Day chat log — Recent conversation history from the current day, providing continuity across interactions.
-
Workspace bootstrap — Project-level context gathered from the current working directory (README, CLAUDE.md, package.json, etc.).
-
Memory snippets — Persistent memory fragments stored in
~/.dproxy/memory/, surfaced by relevance to the current prompt. -
Life/PARA context — Broader personal and organizational context following the PARA method (Projects, Areas, Resources, Archives).
This pipeline means your prompts carry relevant context without you needing to manually paste files or repeat background information. The context builder (src/lib/context-builder.ts) assembles everything into a unified prompt before handing it to the resolved adapter.
How it connects to dbrain and dcontext
Section titled “How it connects to dbrain and dcontext”While dproxy has its own local memory system (~/.dproxy/memory/), it integrates with the broader dtoolkit memory layer:
- dbrain provides persistent, searchable memory with tiers and federation
- dcontext injects dbrain facts into AI CLI sessions at startup
- dproxy can pull memory from dbrain via the SDK when both are running
REST API
Section titled “REST API”The dproxy serve command launches a Fastify REST API that mirrors the full CLI functionality. This is useful for integrating dproxy into other tools, dashboards, or automated workflows.
Configuration
Section titled “Configuration”| Setting | Default | Description |
|---|---|---|
| Port | 7880 | Configurable via --port flag |
| Auth | Bearer token | Set in ~/.dproxy/config.json |
| Streaming | SSE | Enabled via stream: true in request body |
Authentication
Section titled “Authentication”All API requests require a Bearer token in the Authorization header:
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:7880/ask \ -X POST \ -H "Content-Type: application/json" \ -d '{"prompt": "Explain dependency injection"}'Streaming with SSE
Section titled “Streaming with SSE”To receive streaming responses, set stream: true in your request body. The server responds with Server-Sent Events:
curl -N -H "Authorization: Bearer YOUR_TOKEN" http://localhost:7880/ask \ -X POST \ -H "Content-Type: application/json" \ -d '{"prompt": "Write a haiku about TypeScript", "stream": true}'Each SSE event contains an AdapterStreamEvent — the same typed event structure used internally by all adapters.
Selecting a provider
Section titled “Selecting a provider”Pass the provider field in your request body:
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:7880/ask \ -X POST \ -H "Content-Type: application/json" \ -d '{"prompt": "List files in this directory", "provider": "gemini"}'Templates
Section titled “Templates”Templates let you define reusable prompt patterns for common tasks. They are stored in ~/.dproxy/templates/ and can include variable placeholders.
Managing templates
Section titled “Managing templates”# List available templatesdproxy template
# Use a templatedproxy ask --template code-reviewTemplate structure
Section titled “Template structure”Templates are simple files with placeholder syntax that gets resolved at invocation time. This avoids repeating long system prompts or detailed instructions for tasks you run frequently — code reviews, test generation, documentation, and similar workflows.
Adapter Architecture
Section titled “Adapter Architecture”Under the hood, dproxy delegates all provider interaction to adapter packages. Understanding this architecture is useful if you want to extend dproxy or debug provider-specific behavior.
The adapter contract
Section titled “The adapter contract”Every adapter implements two core methods:
| Method | Purpose | Return Type |
|---|---|---|
stream() | Stream tokens as they arrive | AsyncGenerator<AdapterStreamEvent> |
execute() | Run to completion, return full result | Promise<string> |
The resolveAdapter() function in src/lib/adapter.ts maps a provider name string to the corresponding adapter instance.
Execution flow
Section titled “Execution flow”-
Context building — The context builder assembles
ContextBlock[]from all sources (history, workspace, memory, PARA). -
Adapter resolution —
resolveAdapter()maps the--providerflag to the correct adapter package. -
Execution — The adapter’s
stream()orexecute()method is called, shelling out to the underlying CLI. -
Persistence — Results are written to
history.jsonlfor future reference.
ContextBlock contract
Section titled “ContextBlock contract”The ContextBlock type from @dtoolkit/core is the universal currency for context in dtoolkit:
interface ContextBlock { type: string; // e.g., "workspace", "memory", "history" source: string; // origin identifier content: string; // the actual context text}Every component in dtoolkit that produces or consumes context speaks this contract — from dproxy’s context builder to dcontext’s session injection to dbrain’s memory retrieval. This shared type is what makes the tools composable without tight coupling.
AdapterStreamEvent
Section titled “AdapterStreamEvent”Streaming responses use the AdapterStreamEvent type, also defined in @dtoolkit/core. This provides a consistent event structure regardless of whether the underlying provider uses JSON streaming, JSONL, or another format. The adapter handles the translation.
Relationship to Other Products
Section titled “Relationship to Other Products”dproxy sits at the transport layer of the dtoolkit stack:
| Product | Role | Relationship to dproxy |
|---|---|---|
| dbrain | Memory | dproxy reads memory for context pipeline |
| dcontext | Hooks | Uses the same adapters for CLI integration |
| dwork | Project management | Can invoke dproxy for AI-assisted sync |
| dops | Observability | Ingests transcripts from dproxy sessions |
| @dtoolkit/sdk | HTTP clients | DProxyClient provides typed access to the REST API |
Configuration Reference
Section titled “Configuration Reference”All configuration lives in ~/.dproxy/config.json:
| Field | Type | Description |
|---|---|---|
defaultProvider | string | Default provider when --provider is omitted |
port | number | Default port for dproxy serve |
token | string | Bearer token for REST API authentication |
Quick Start
Section titled “Quick Start”-
Install dproxy:
install pnpm add -g @dtoolkit/dproxy -
Initialize configuration:
terminal dproxy init -
Send your first prompt:
terminal dproxy ask "What is the ContextBlock contract in dtoolkit?" -
Start an interactive session:
terminal dproxy chat -
Launch the REST API:
terminal dproxy serve
Further Reading
Section titled “Further Reading”- Getting Started guide — install the full dtoolkit suite
- CLI Reference — complete flag and option reference for all dtoolkit CLIs
- MCP Tools Reference — MCP tool documentation across all products
- dbrain product guide — persistent memory that feeds into dproxy’s context pipeline
- dcontext product guide — hooks that use the same adapter layer as dproxy