Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Rust Tool Base (RTB)
A batteries-included application framework for building Rust CLI tools — idiomatic, composable, and AI-ready.
Status: pre-0.1 scaffolding. Most crates are intentional stubs. The authoritative contract for each subsystem lives in
docs/development/specs/rust-tool-base.md.
RTB is a Rust sibling of Go Tool Base (GTB).
It is not a line-for-line port. Go Tool Base leans on Go's idioms
(context.Context, functional options, package-level init(),
interface{}-keyed containers); RTB leans on Rust's (? + miette,
typestate builders, linkme distributed slices, strongly-typed serde
config, tokio structured concurrency).
What RTB gives you
- Opinionated application scaffolding —
Application::builder()typestate assembler that wires clap, figment, tracing, miette, tokio, and a signal- boundCancellationTokenin one call. - Strongly-typed layered config — env > CLI flags > user file > embedded
defaults, materialised into your
serde::Deserializestruct. Hot-reload vianotify+arc-swapwith awatch::Receiverfor observers. - Embedded-assets + overlay FS —
rust-embedfor compile-time bundling (with dev-mode disk passthrough) +vfs::OverlayFSfor user-override layering. Structured formats (YAML/JSON/TOML) are deep-merged; binaries follow last-registered-wins. - Diagnostic errors, not error handlers — every crate derives
thiserror::Error + miette::Diagnostic;main()returnsmiette::Result<()>and a framework-installed hook renders them with labels, help, and severity. - Self-update —
self_update+self-replace, signed releases (ed25519-dalekover SHA-256), atomic binary swap on every platform. - VCS —
gix-first Git ops (fallback togit2for unsupported writes),octocrabfor GitHub (Enterprise-capable, GitHub-App-capable),gitlabfor self-hosted GitLab with nested groups. - AI —
genaifor multi-provider (Claude, OpenAI, Gemini, Ollama), with a direct-reqwestpath for Anthropic-only features (prompt caching, managed agents, extended thinking). Structured output validated withjsonschema. - MCP — official
rmcpSDK; commands opt in viaCommand::mcp_exposed = trueand surface theirclap::Argsschema throughCommand::mcp_input_schema.mcp serve(stdio default) andmcp listship as built-in subcommands. - TUI docs browser —
ratatui+termimad, with streaming AI Q&A. - Credentials —
keyringwrapped in aCredentialStoretrait;secrecy::SecretStringend-to-end, zeroed on drop. - Telemetry — opt-in, salted
machine-uid, pluggable sinks (noop/file/HTTP/OTLP).
Workspace layout
rust-tool-base/
├── Cargo.toml # workspace root
├── crates/
│ ├── rtb/ # umbrella crate (public API)
│ ├── rtb-app/ # App context, ToolMetadata, Features
│ ├── rtb-error/ # Error type + miette integration
│ ├── rtb-config/ # figment-backed typed config
│ ├── rtb-assets/ # rust-embed + vfs overlay
│ ├── rtb-cli/ # Application builder + built-in commands
│ ├── rtb-update/ # self-update subsystem
│ ├── rtb-vcs/ # gix + octocrab + gitlab
│ ├── rtb-ai/ # genai + structured output
│ ├── rtb-mcp/ # rmcp server
│ ├── rtb-docs/ # ratatui docs browser
│ ├── rtb-tui/ # reusable widgets (Wizard, tables)
│ ├── rtb-credentials/ # keyring wrapper
│ ├── rtb-telemetry/ # opt-in telemetry
│ └── rtb-cli-bin/ # the `rtb` scaffolder binary
├── examples/
│ └── minimal/ # smoke-test tool
├── docs/ # user-facing documentation
│ └── development/
│ └── specs/
│ └── rust-tool-base.md # ← authoritative spec
├── .github/workflows/ # ci.yaml, release.yaml
├── deny.toml # cargo-deny policy
├── rustfmt.toml
├── rust-toolchain.toml # pinned stable
├── justfile # common tasks
├── LICENSE # MIT
└── SECURITY.md
Quick start
A working end-to-end example lives at
examples/minimal. Run it with:
$ cargo run -p rtb-example-minimal -- version
$ cargo run -p rtb-example-minimal -- greet
$ cargo run -p rtb-example-minimal -- doctor
$ cargo run -p rtb-example-minimal -- --help
Anatomy
A minimal RTB-based tool has three parts: (1) a custom Command
implementation, (2) a linkme registration that inserts it into the
framework's command slice, and (3) an Application::builder() call
in main.
use async_trait;
use distributed_slice;
use App;
use ;
use *;
// 1. Implement the Command trait.
;
// 2. Register into the framework's command slice at link time.
// 3. Wire the Application.
async
Downstream tools need rtb, tokio, miette, async-trait, and
linkme as direct dependencies. linkme must be direct because its
#[distributed_slice] attribute expands to ::linkme::… paths.
Development
License
MIT — see LICENSE.