Skip to content

Rust workspace · MIT

Tooling for AI-assisted development, in one workspace.

trusty-tools is one Cargo workspace for the trusty-* ecosystem: hybrid code search, a memory palace, and a code-analysis sidecar, each with an MCP server.

License
MIT
MSRV
Rust 1.94
Prebuilt for
macOS arm64, Linux x86_64, Linux arm64

What trusty-tools is

A single Cargo workspace holding the whole trusty-* family — shared libraries, daemons and MCP servers, a multi-agent platform, and an orchestrator. Everything is co-located under crates/, so a change spanning several of them is one commit against one lockfile.

Each crate versions, tags, and publishes independently, and everything is MIT licensed. Five of the seven flagship tools below speak the Model Context Protocol, so they plug into Claude Code and any other MCP client without a bespoke integration; the other two are command-line tools.

Seven flagship tools

Each one has its own page — what it does, how it works, and how to install it.

UNIT 01

trusty-search

Hybrid code search

  • BM25, vector, and knowledge-graph retrieval fused with Reciprocal Rank Fusion
  • One machine-wide daemon, unlimited named project indexes
  • Query-intent routing across definition, usage, conceptual, and bug/debt lookups
  • Branch-aware ranking and caller/callee chain expansion

trusty-search →

What’s new

0.54.2· 2026-09-18

  • Added GET /indexes?details=true — and so the MCP list_indexes tool, which proxies it — carries per-index vector-lane health: semantic_coverage (vectors_present, vectors_unavailable_reason, vector_quant, chunk_count, embedded_this_boot), stages, search_capabilities, chunk_count, lexical_only and skip_vector. A zero-vector index reports stages.semantic: ready and so appears in neither /health's indexes_stage_failed_ids nor the console's Indexes roster; the roster now has the same three inputs — a nonzero chunk_count, vector among the capabilities, and vectors_present: 0 — that the per-index expanded panel already flags on (#6699, follows #6689). Every field is computed by service::server::vector_health, the one function GET /indexes/{id}/status calls, so the roster and the panel cannot disagree about an index. Additive: existing entry fields keep their names, types and presence rules, and the plain GET /indexes arm still returns a bare array of ids. Costs two O(1) reads per index (Index::size() on the wired store, one redb table.len()) beside the per-index directory walk the endpoint already pays for size_bytes — no corpus scan.
  • Added GET /indexes?details=true also carries last_indexed, the same RFC 3339 timestamp GET /indexes/{id}/status reports. The endpoint's directory walk already produced it and this arm discarded it, so serving it costs nothing and lets a roster drop its per-row /status call (#6699).
  • Added GET /health reports resident_index_cap and resident_index_cap_source. The cap is the acting number (null when it is off); the source is "env", "env (off)", or "tier default". The same pair is logged once at startup. Without them the number that decides whether an index gets parked was only readable from the daemon's environment (#6821)

All changes →

UNIT 02

trusty-memory

Memory palace storage

  • Named palaces, one per project, with rooms and wings inside them
  • Hybrid BM25 + vector recall over an HNSW index and a redb store
  • A knowledge graph of subject/predicate/object triples alongside the prose
  • A dream cycle that consolidates near-duplicates instead of hoarding them

trusty-memory →

What’s new

0.26.2· 2026-09-23

  • Fixed serve --stdio answers initialize and tools/list from its own process, so a daemon that is unreachable during the MCP handshake no longer costs a client session its memory tools. The client marks a server that fails its handshake dead and never re-spawns it, which is how ten seconds of daemon downtime ended memory for a whole session (#8351).
  • Fixed serve --stdio no longer exits when the daemon cannot be started. The failure is reported on stderr and the bridge keeps serving: tool calls answer with an error naming the socket while the daemon is down, and succeed on the next call once it returns, with no restart. This deliberately replaces the exit-on-unreachable-daemon behaviour of #1152, whose no-spawn half is unchanged — the bridge still never starts an unmanaged daemon (#8351).
  • Fixed serve --stdio re-resolves the daemon socket for every forwarded request instead of trusting the path resolved at startup, so a bridge that resolved a stale path heals on the next call (#8351).

All changes →

UNIT 03

trusty-mpm

Multi-agent orchestration

  • One `tm` binary: daemon, CLI, TUI dashboard, and MCP server
  • Sessions and worktrees per project, tracked across restarts
  • Claude Code lifecycle hooks relayed into the daemon
  • A statusline estimate of the tokens the harness kept out of the session
  • Remote control from Telegram or Slack when you are away from the terminal

trusty-mpm →

What’s new

1.7.1· 2026-09-23

  • Added tm doctor has a launchd_process_type row. It fails when the com.trusty.mpm or com.trusty.mpm.supervisor LaunchAgent declares ProcessType Background, which clamps tmux and every session it hosts to background QoS, and warns on any other value short of Interactive. The message names the plutil and launchctl commands for the plist on disk; the deploy supervisor template now declares Interactive (Refs #8415)
  • Added tm doctor has a tmux_priority row. It fails when the running tmux server's Darwin priority is below 20 and warns from 20 to 30 (launchd Standard throttling), naming the server PID, the observed priority and the remedy: fix the plist, then restart the tmux server. It runs on macOS only and reports not applicable elsewhere. A server keeps its class until it exits, so a plist fix alone does not lift it. It reports Unknown, never Ok, when tmux or ps cannot be read (Refs #8415)
  • Added TRUSTY_MPM_LAUNCH_AGENTS_DIR points the launchd_process_type row at another LaunchAgents directory; unset, it reads ~/Library/LaunchAgents (Refs #8415)

All changes →

UNIT 04

trusty-analyze

Code analysis sidecar

  • Cyclomatic and cognitive complexity per chunk, file, and index
  • Code-smell detection with configurable thresholds and named categories
  • Git-blame temporal decay, so stale complex code sorts to the top
  • Tree-sitter adapters for 14 languages, behind a Unix socket and one MCP server

trusty-analyze →

What’s new

0.12.6· 2026-09-03

  • Changed The MCP dispatcher dials the daemon through the shared trusty_mcp::daemon_bridge_json_rpc. mcp::rpc_client::call built its own JSON-RPC frame, called trusty_common::uds::send_framed_request_capped and unpacked an RpcResponse by hand — the same transport trusty-memory's stdio bridge carried a second copy of. Both now run one implementation (#6316) The 32 MiB response budget and core::mcp_client_timeout() are unchanged; they are passed to the bridge rather than to the client. No request rewriter: the dispatcher has already built the exact params each analyze.* method expects mcp::stdio::run is untouched. This crate's MCP surface is a tool translator with its own tools/list and its own #917 response-size guard, not an envelope forwarder, so the stdio loop stays where it is A transport failure and a daemon-side JSON-RPC error still both surface as DispatchError::Transport naming the failing method. The message now carries the daemon's error code as well: <method> over <socket>: <message> (<code>)

All changes →

UNIT 05

trusty-review

LLM code review

  • Reviews a GitHub PR, a git ref range, or a diff on stdin
  • Injects code context from trusty-search and metrics from trusty-analyze
  • A letter grade alongside an APPROVE / REQUEST_CHANGES / BLOCK verdict
  • Skips a review it cannot ground rather than issue a confident guess

trusty-review →

What’s new

0.36.0· 2026-09-13

  • Added FindingCategory::Style (wire token "style") tags a pure taste, naming, formatting or idiom nit. A review whose only substantive findings are style nits now grades APPROVE — grade::derive_verdict_with applies it as a ceiling, so a model-proposed REQUEST_CHANGES or BLOCK is brought down too, not merely floored. Style findings also contribute nothing to the severity floor, so a High-effort style opinion can never reach the BLOCK tier. The ceiling lifts the moment one non-style substantive finding is present: a style nit alongside a real blocker still blocks. The reviewer response schema offers "style" and tells the model when to pick it, and an inline comment on a style finding leads with "Informational (style / preference) — does not block." FindingCategory is now #[non_exhaustive], so future categories are additive for downstream matchers.
  • Added trusty-review version [--json]. --json emits the DOC-1 capability-discovery envelope (contract_version, tool, tool_version, verbs) that tctl doctor --self-check trusty-review spawns and parses. The subcommand did not exist, so clap exited 2 with a usage error and the probe reported trusty-review version --json exited with exit status: 2 (#6913). It answers from the binary alone — no config file, no tokio runtime, no network.
  • Fixed Bedrock Converse failures now report the AWS error code and message (for example ResourceNotFoundException: Model use case details have not been submitted for this account.) instead of the SDK's flattened literal service error, which made a wrong region, a missing credential, and an unapproved model read identically (#6912).

All changes →

UNIT 06

trusty-git-analytics

Developer analytics from git

  • Walks local repositories into SQLite, then classifies every commit
  • A tiered classification cascade, with an optional LLM tier at the end
  • Per-author and per-week velocity, quality, and DORA reporting
  • CSV, JSON, and Markdown output from one `tga analyze` run

trusty-git-analytics →

What’s new

7.1.0· 2026-09-04

  • Fixed tga collect and tga audit can now fetch from an SSH-scheme origin. The git2 dependency was built without the ssh feature, so libgit2 had no libssh2 transport and rejected every git@host:org/repo.git or ssh:// remote with unsupported URL protocol; class=Net (12) before the fetch's credential callback ran — 59 of 59 repositories in a client audit, each collected from clone-time refs. Adding the feature links libssh2 from its own vendored source and reuses the openssl this crate already vendors, so no new system library or runtime dependency (#6782).
  • Fixed The non-interactive credential chain now offers each source at most once per fetch instead of answering from the top every time libgit2 re-enters the callback. ssh-agent running with no identities loaded reports success, so the old behaviour re-offered the empty agent until libgit2 gave up — 120 seconds per repository — and never reached ~/.ssh/id_ed25519 (#6782).
  • Fixed A repository collected from stale local refs now leads the report's Gaps & Caveats section with git history is stale: fetch failed (…), ahead of the failed stages, and is named on stderr during the run. It was one unemphasised sentence mid-list, which a reader taking the commit and pull-request figures at face value could pass over (#6782).

All changes →

UNIT 07

trusty-audit

Audit engagements at a client site

  • One command downloads the macOS binary, verifies its checksum, and launches it
  • Installs and version-pins the tga, trusty-search, trusty-analyze and trusty-review it runs
  • Registers GitHub repositories and JIRA or Linear boards, checking each can be read first
  • One resumable run — install, clone, audit, package — ending in a zip to send back

trusty-audit →

What’s new

0.14.2· 2026-09-06

  • Fixed Declared trusty-common's uds feature, which the grounding daemons, hotspots, and search_rpc modules need for their UDS framed-request client. Workspace feature unification hid the missing declaration from every gate except cargo publish's isolated verification build, which failed with 11 x E0433 could not find 'uds' in 'trusty_common' and burned the trusty-audit-v0.14.1 tag before it could ship.

All changes →

The rest of the lineup

What else you can install today, and what is still being built. Shared libraries and internal tooling are left out — the workspace glob in the root Cargo.toml is the authoritative list of everything under crates/.

Also shipped

  • trusty-installer

    The tctl install and upgrade control plane

  • trusty-console

    Web dashboard over the trusty services you run

  • trusty-code

    Per-project coding harness (tcode)

  • trusty-gworkspace

    Google Workspace MCP server

In development

  • trusty-agents

    Agentic harness with multi-model routing (tagent)

  • trusty-channels

    Chat-channel MCP servers, starting with Slack

  • trusty-kb

    Personal knowledge base as an MCP server

  • trusty-sld-lint

    Linter for spec-linked documentation

  • trusty-mpm-gui

    Desktop dashboard for trusty-mpm

  • trusty-code-gui

    Desktop shell for the tcode daemon

Install

A bare tctl install brings up the eight managed crates in dependency order. Name one to install just that crate and whatever it needs at runtime. trusty-audit is not one of them — it installs itself.

Bootstrap, then tctl

Recommended. No Rust toolchain needed on a supported platform. Resolves the runtime dependency graph, and keeps macOS signing grants stable across upgrades.

curl -sSf https://raw.githubusercontent.com/bobmatnyc/trusty-tools/main/install.sh | sh
tctl install

Homebrew

Ten formulae in the tap. Installs one binary, without the dependency resolution tctl does.

brew tap bobmatnyc/trusty
brew install bobmatnyc/trusty/trusty-search

From source

Requires Rust 1.94. cargo install writes atomically — never copy a built binary onto your PATH on macOS.

git clone https://github.com/bobmatnyc/trusty-tools
cd trusty-tools
cargo install --path crates/trusty-search --locked

Managed by tctl
trusty-search · trusty-memory · trusty-analyze · trusty-review · tga · trusty-console · trusty-mpm · trusty-installer

The bootstrap installer verifies every downloaded tarball against its published SHA-256 checksum. The install script itself is unsigned — read it first if you need higher assurance.

Installing one specific product? The install walkthrough has the exact sequence for each of the nine, what it needs first, and the macOS permission it asks for.

Read the documentation

Guides, references, and architecture decisions for every crate.

Browse docs