agentleFS
radimsemradimsem/mithril/CLAUDE.md

mithril

CLAUDE.md16 starsChanged 7 months agoApache-2.0View on GitHub

Sandboxed MCP server that replaces the generic shell tool with validated, purpose-built execution tools for AI agents. No shell, no escapes — every command goes through typed arguments, injection guards, path confinement, and OS-level isolation. Every tool call flows through 4 sequential layers: Each tool is a struct implementing ToolDef + ToolExec:

  • Reads credentials

The file

We split this CLAUDE.md into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every tool call flows through 4 sequential layers:

    line 37
  2. Very specific:

    All structs derive Debug

    line 131

≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

Mithril

Sandboxed MCP server that replaces the generic shell tool with validated, purpose-built execution tools for AI agents. No shell, no escapes — every command goes through typed arguments, injection guards, path confinement, and OS-level isolation.

Quick Reference

cargo build                        # Build all crates
cargo build -p mithril             # Binary only
cargo test                         # All non-ignored tests
cargo test -- --ignored            # Include sandbox + ecosystem tests
cargo test -p server               # Single crate
cargo test -p server cat_reads_file # Single test by name
cargo clippy --workspace           # Lint
cargo fmt --all -- --check         # Format check

Workspace Structure

crates/
  bin/        CLI binary entry point (clap args, config loading, MCP transport)
  common/     Shared types: Config, ExecContext, ToolDef/ToolExec traits, errors, validation rules
  patterns/   Compiled regex patterns for validation (melody DSL, lazy_static)
  tools/      ~160 tool implementations across 10 domains (system, git, docker, go, js, python, rust, gh, glab, run_chain)
  server/     MCP ServerHandler, tool/prompt/resource routing, execution pipeline, history buffer
  runner/     Process spawning layer: timeouts, stdout streaming, progress notifications
  validator/  Argument validation layer: injection guard, path confinement, env blocklist, elicitation
  sandbox/    OS isolation layer: BubbleWrap (Linux) / sandbox-exec (macOS) / Noop fallback
  proxy/      Optional RTK (Rust Token Killer) prefix layer for token-optimized output

Architecture

Execution Pipeline

Every tool call flows through 4 sequential layers:

MCP Request → Router → build_context() → [ Validate → Proxy → Sandbox → Runner ] → format() → MCP Response
  1. ValidateLayer — checks argument types, string patterns, injection characters, path confinement, env blocklist, elicitation approval
  2. ProxyLayer — optionally prepends rtk binary for supported commands
  3. SandboxLayer — prepends OS-specific sandbox command prefix (bwrap/sandbox-exec)
  4. RunnerLayer — spawns process via tokio::process::Command, streams stdout, enforces timeout

Key Types

TypeLocationPurpose
ToolDefcommon/src/tool.rsTrait: name, description, parameters, available, elicitable
ToolExeccommon/src/tool.rsTrait: Args type, build_context(), format()
ExecContextcommon/src/context.rsFull execution state passed through pipeline
MithrilLayercommon/src/lib.rsPipeline layer trait: async fn apply(ctx) -> Result<ctx>
ValidationRulecommon/src/validation.rsEnum: String, Integer, StrVector, PathConfined, AllowList
SandboxLevelcommon/src/config.rsEnum: Dir (default), Readonly, Container
SandboxMetacommon/src/context.rsStruct: needs_network, ro_binds, rw_binds
GlobalArgstools/src/lib.rsStruct: cwd, sandbox, envs, isolated_env (merged into every tool call)
ToolRegistryserver/src/registry.rsRegisters all tools, stores metadata + context builder closures
ServerRouterserver/src/router.rsMCP routing: tool dispatch, prep_ctx, run_chain
MithrilServerserver/src/lib.rsMCP ServerHandler: initialize, list_tools, call_tool, prompts, resources

Tool Implementation Pattern

Each tool is a struct implementing ToolDef + ToolExec:

  • Args struct with Deserialize + Serialize + JsonSchema — defines the JSON schema
  • build_context() — pushes CLI args to ctx.cmd, sets validation rules on ctx.tool.validation_rules, configures ctx.sandbox.meta
  • format() — converts ExecOutput to MCP CallToolResult
  • Tool files live in crates/tools/src/<domain>/<tool_snake>.rs
  • Registration in crates/server/src/registry.rs via register::<ToolStruct>()
  • Router method in crates/server/src/router.rs with #[tool(name, description)] macro

Tool Domains

DomainCountBinaryExamples
system~29VariousCat, Ls, Grep, Rm, Sed, Find, Wc
git18gitGitStatus, GitCommit, GitDiff, GitLog
docker~27dockerDockerRun, DockerBuild, DockerExec
go12goGoBuild, GoTest, GoModTidy
js13node/npmNode, NpmInstall, Jest, Prettier
python17python/pip/uvPython, Pytest, Ruff, UvRun
rust13cargoCargoBuild, CargoTest, CargoClippy
gh11ghGhPrList, GhIssueView, GhRunList
glab11glabGlabMrList, GlabPipelineView
chain1—RunChain (pipe/and composition)

Configuration

Config file: .mithril.toml (TOML, loaded at startup, defaults if missing)

[server]
timeout_secs = 180        # Process timeout
max_output_lines = 2048   # Output truncation
history_size = 8           # Tool call history buffer

[project]
ecosystem = "rust"         # Language/framework
root.abs_path = "/path"    # Project working directory

[sandbox]
default_level = "dir"      # dir | readonly | container
path_blocklist = [".env", ".env.*", "*.pem", "*.key", "*.p12", "*.pfx"]

CLI overrides: --timeout, --max-output-lines, --history-size, --project-root, --ecosystem, --sandbox

Security Model

  • No shell — commands are Vec<OsString>, never passed through a shell
  • Injection guard — blocks ;|&<>$(){} backticks, quotes, =*?[]! in arguments (per-rule exemptable)
  • Path confinement — canonicalized paths must start with cwd, .git blocked by default
  • Path blocklist — rejects .env, *.pem, *.key, *.p12, *.pfx
  • Env blocklist — blocks LD_PRELOAD, LD_LIBRARY_PATH, PYTHONPATH, DYLD_*, etc.
  • Elicitation — destructive tools (docker, etc.) require user approval via MCP elicitation protocol
  • Sandbox — OS-level isolation wraps every command execution

Conventions

Detailed rules are in .claude/rules/:

  • rust-patterns.md — Rust code conventions (error handling, iterators, borrows, etc.)
  • cli-testing.md — Test organization, harness usage, patterns and anti-patterns

Key points:

  • expect("reason") in tests, .context()/? in production — never unwrap()
  • .to_owned() over .clone() for string/value copies
  • Iterator chains over loops (unless early ? return needed)
  • All structs derive Debug
  • Tool tests go in crates/server/tests/tools/ — tools crate has zero unit tests
  • TempEnv for test directories (uses /var/tmp/mithril_tests to survive bwrap overlay)
  • Availability guards for external binaries (early return, not #[ignore])

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.