Tower is a Rust core engine that gives MCP clients a fast, shared view of a workspace: indexed files, content search, safe edits, semantic tools, lint fixes, and debug workflows.
It runs as one daemon per workspace. Each MCP session launched through Tower's stdio entrypoint connects to that daemon, so multiple agents can inspect and edit the same project through the same persisted index.
Architecture: Domain-Driven Design + Hexagonal Architecture + Microkernel.
| Capability | What it gives clients |
|---|---|
| Persistent workspace index | Fast file lookup and directory listing from a sled-backed VFS. |
| Parallel text search | Rayon-backed grep across indexed file contents. |
| Safe mutations | Atomic writes and CAS-style expected_version checks for agent-safe edits. |
| Shared daemon | One watcher, index, and extension registry per workspace; many MCP clients. |
| Native sidecar extensions | Out-of-process extension binaries that contribute tower_<ext>_* MCP tools. |
| Semantic workflows | AST outline/symbol tools, LSP diagnostics/navigation, lint fixes, and opt-in DAP debugging. |
| No runtime VM | Native binaries only; no JVM, Node, WASM runtime, or container required at runtime. |
Download a prebuilt binary from GitHub Releases:
curl --proto '=https' --tlsv1.2 -fsSL \
https://raw.githubusercontent.com/awf-project/tower/main/scripts/install.sh | shThe installer writes tower to $HOME/.local/bin by default. You can override the release or
install directory:
curl -fsSL https://raw.githubusercontent.com/awf-project/tower/main/scripts/install.sh \
| TOWER_VERSION=dev TOWER_INSTALL_DIR="$HOME/bin" shTo build from source instead:
git clone <repository-url> tower
cd tower
cargo build --workspace --binsThe main binary is target/debug/tower.
Run this once at the project root you want Tower to index:
tower initThis creates:
| File | Purpose |
|---|---|
.towerignore |
Authoritative ignore rules for the Tower index, independent of .gitignore. |
.tower/config.toml |
Local Tower configuration, including formatter/linter/debug settings. |
Secrets and generated output should be excluded in .towerignore before exposing a workspace to an
agent. If .towerignore is missing, Tower warns and indexes all non-hidden files except .git/.
Tower's MCP entrypoint is the mcp subcommand:
tower mcpMost MCP clients do not store that as one shell string. Configure the executable and arguments in the shape your client expects. In JSON-like configs, that usually means:
{
"command": "tower",
"args": ["mcp"]
}If the client provides a CLI for registering MCP servers, pass tower as the command and mcp as
its argument using that client's syntax.
The mcp subcommand connects to the workspace daemon, spawning it if needed. The daemon owns the
index, watcher, storage, and loaded extensions, then exits after its configured idle timeout when no
clients remain.
Useful local checks:
tower status
tower shutdownWorkspace resolution is consistent across commands:
| Priority | Mechanism |
|---|---|
| 1 | --workspace-dir <path> |
| 2 | TOWER_WORKSPACE=/path/to/project |
| 3 | current working directory |
The index is Tower-owned. Tower persists workspace metadata under .tower/db/, watches file
changes, and serves file/search tools from the current index.
.towerignore is the source of truth. Tower does not inherit .gitignore. This keeps the agent
visibility policy explicit and project-local.
Edits are CAS-aware. Mutating tools can use an expected_version token returned by
tower_read_file to reject writes when a file changed since it was read.
Extensions are native sidecars. Extension binaries are discovered at startup, supervised by the
host, and exposed as namespaced MCP tools such as tower_ast_get_outline or
tower_lint_check. A failed extension is skipped or quarantined without taking down the daemon.
Native tools are always available. Extension tools appear when their sidecars are installed and enabled.
| Area | Examples |
|---|---|
| Files and search | tower_read_file, tower_list_dir, tower_find_file, tower_search_text |
| Safe mutations | tower_create_file, tower_edit_range, tower_global_replace, tower_delete_file |
| AST | tower_ast_get_outline, tower_ast_find_symbols, tower_ast_read_symbol |
| LSP | tower_lsp_diagnostics, tower_lsp_definition, tower_lsp_references, tower_lsp_hover |
| Lint | tower_lint_check, tower_lint_fix |
| Debug | tower_debug_launch, tower_debug_eval_at, tower_debug_record_and_find_origin |
See docs/mcp-tools.md for the full wire protocol, tool schemas, responses, and stable error codes.
| Page | Contents |
|---|---|
| docs/getting-started.md | Build, first MCP session, quality gate, and copy-paste examples. |
| docs/towerignore.md | .towerignore behavior, defaults, migration notes, and watcher limits. |
| docs/architecture.md | Hexagonal boundary, ports/adapters, daemon flow, and invariants. |
| docs/extensions.md | Native sidecar extension protocol, manifests, capabilities, and supervision. |
| docs/mcp-tools.md | Complete MCP tool reference and JSON-RPC details. |
| docs/user-guide/semantic-edits.md | Safe AST and LSP edit workflows. |
| docs/user-guide/lint-fixes.md | Previewing and applying structured linter fixes. |
| docs/user-guide/debug-sessions.md | Interactive DAP sessions and rr-backed reverse-debug workflows. |
| docs/development.md | Contribution workflow, CI checks, tests, and project conventions. |
The merge gate is:
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo build --workspace --bins
cargo test --workspace
cargo deny checkOr run the project wrapper:
make gate