Skip to content
Conduit

mcp server

aifr

CLI/MCP/Co-process tool for read-only filesystem & git access

PennockTech/aifrcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 26, 2026

aifr — AI File Reader

A read-only filesystem and git-tree access tool, with both a standalone CLI and a JSON-RPC co-process mode which happens to fit the MCP schema for AI agents.

AI agents (Claude Code, Cursor, etc.) resort to shell pipelines (sed -n, find | grep, head/tail) that trigger security checks and produce brittle, unstructured output. aifr replaces all of those with a single binary that is always safe (never writes) and always scoped (enforces allow/deny lists with a built-in sensitive-file blocklist).

The aifr tool can read files, read git state, read "getent" system files, some basic system information, and more. Everything read-only (except the MCP self reload task). No network access, but some network state querying. It never runs external commands, there is no possibility for shell injection attacks. All functionality is "native" to this tool.

A number of filters traditionally done with the Unix pipe handling are moved left into aifr, to limit the output without needing a pipeline. This avoids triggering security checks for a shell invocation, even when using aifr purely as a CLI tool, let alone when you start it as a co-process server so that it can quickly answer many questions. The queries often support options to filter which data rows are returned, which columns, to sort, and more.

Outside of AI, scripts which do a lot of git operations often end up repeatedly shelling out to git. With this agent running as a co-process, they can query configuration and contents and some history with a read-only tool: safe, because it will not touch anything or break the repo; at worst, it will fail to parse something, not break your setup.

Combine with tools such as ast-grep and ripgrep. aifr does not seek to replace good tools, it seeks to replace permission-triggering pipeline invocations.

Install

Binary releases are available; currently hosted at: https://github.com/PennockTech/aifr/releases

Or you can build from source.

# From source
go install go.pennock.tech/aifr/cmd/aifr@latest

# Or build from the repo
task build

MCP Server for Claude Code

claude mcp add --scope user aifr -- aifr mcp

This registers aifr as an MCP server using stdio transport. Claude Code will then have access to all 20 aifr tools (aifr_read, aifr_cat, aifr_stat, aifr_list, aifr_search, aifr_find, aifr_refs, aifr_log, aifr_diff, aifr_wc, aifr_hexdump, aifr_checksum, aifr_pathfind, aifr_rev_parse, aifr_reflog, aifr_stash_list, aifr_sysinfo, aifr_getent, aifr_git_config, aifr_self).

Skill File

The MCP server's built-in instructions are intentionally brief. For richer agent guidance (tool routing, advanced patterns, error handling), install the skill file:

# Symlink into user-level skills (recommended — stays in sync with repo)
mkdir -p ~/.claude/skills
ln -s "$(pwd)/skills/aifr" ~/.claude/skills/aifr

# Or copy if you prefer a snapshot
cp -r skills/aifr ~/.claude/skills/aifr

You can also generate the embedded (shorter) skill file at any time:

aifr skill > /tmp/aifr-skill.md

HTTP Transport

For HTTP transport (multi-client setups):

aifr mcp --transport http --addr :8080

Quick Start

# Read a file
aifr read src/main.go

# Read first 50 lines
aifr read --lines 1:50 src/main.go

# Read a file from git history
aifr read HEAD~3:src/main.go

# Concatenate all Go files, skipping vendor
aifr cat --name '*.go' --exclude-path '**/vendor/**' .

# Head: first 10 lines of each Go file with dividers
aifr cat --name '*.go' --lines 10 --divider plain --format text .

# Read with line numbers (like cat -n, but showing actual file line numbers)
aifr read -n src/main.go
aifr read -n --lines 50:100 src/main.go    # lines 50–100, numbered correctly

# Search for a pattern
aifr search 'func.*Handler' ./src/

# Find files by name
aifr find --name '*.yaml' --max-depth 2 .

# List directory
aifr list --depth -1 --type f .

# Git refs and log
aifr refs --branches --tags
aifr log --max-count 5
aifr log --oneline --max-count 10
aifr log --format=text --divider=xml --max-count 3
aifr log --verbose --max-count 1        # tree hash, parent hashes, committer
aifr log v2.12.6..v2.12.7               # range: commits between two tags
aifr log --first-parent main...feature  # symmetric diff, first-parent only
aifr log --grep '^fix:' --since 2024-01-01 HEAD
aifr log --path 'internal/**/*.go' v1.0..HEAD

# Compare files across refs
aifr diff HEAD~1:README.md README.md

# Count lines/words/bytes
aifr wc src/main.go
aifr wc --lines src/*.go              # just line counts

# System databases
aifr getent passwd root
aifr getent passwd --fields name,gecos_name,home

# System inspection
aifr sysinfo --categories os,network

All commands output JSON by default. Use --format text for human-readable output. Line numbering (-n / --number-lines) is available on read and cat in both formats.

Output Format

The default output format is JSON. Use --format text for human-readable, token-efficient output suitable for AI agents and shell pipelines.

Set the AIFR_FORMAT environment variable to change the default:

export AIFR_FORMAT=text              # all commands default to text
aifr getent passwd root              # text output
aifr getent passwd root --format json  # flag overrides env

AIFR_FORMAT accepts a colon-separated preference list — the first format supported by the invoked command wins:

export AIFR_FORMAT=short:text:json   # "version" uses short; others use text

Invalid values produce a diagnostic on stderr and exit 64 (EX_USAGE).

Configuration

Create .aifr.toml in the working directory or ~/.config/aifr/config.toml:

allow = ["~/projects/**"]
deny = ["~/projects/secrets/**"]

[git.repos]
myapp = "~/projects/myapp"

If no config is found, aifr operates in "current directory only" mode — it allows the cwd and everything beneath it.

See configs/aifr.example.toml for the full config reference.

Access Control

Every path request is evaluated in order:

  1. Resolve symlinks to canonical path
  2. Sensitive list (built-in, 120+ patterns) → blocked, always
  3. Deny list (from config) → blocked
  4. Allow list (from config, or cwd fallback) → permitted
  5. Default → blocked

Sensitive files (SSH keys, cloud credentials, .env, shell history, etc.) return a distinct ACCESS_DENIED_SENSITIVE error. The agent is expected to tell the user to read the file themselves if needed, and must not retry.

Run aifr sensitive to see the full pattern list.

Commands

CommandDescription
readRead file contents (chunked, with continuation tokens)
catConcatenate multiple files with dividers (find+cat in one)
statFile/directory metadata
listDirectory listing with depth, pattern, type filters
searchContent search (RE2 regexp, context lines, include/exclude)
findFind files by name, type, size, age
diffCompare files or git refs
wcCount lines, words, and bytes
hexdumpHex dump of file contents
checksumCompute file checksums
refsList git branches, tags, remotes
logGit commit log (text/oneline/xml/json, verbose mode)
reflogShow git reflog for a ref
stash-listList git stashes
rev-parseResolve a git ref to a commit hash
git-configQuery git configuration
pathfindFind commands in PATH-like search lists
getentQuery system databases (passwd, group, services, protocols)
sysinfoSystem inspection for fault diagnosis
configShow effective configuration
sensitiveList built-in sensitive file patterns
skillEmit SKILL.md for Claude Code
mcpStart MCP server (stdio or HTTP)
versionPrint version information

Git Path Syntax

Git objects are addressed as [repo:]<ref>:<path>:

Input SpecSemantic meaning
HEAD:README.mdauto-detected repo, HEAD
main:src/lib.gobranch "main"
v2.0:config.tomltag "v2.0"
HEAD~3:file.go3 commits back
a1b2c3d:pkg/auth.goshort commit hash
myrepo:main:terraform/main.tfnamed repo from config

All git reads go directly through the object store — no checkout, no side effects on the working tree.

Building

task build              # build with version ldflags
task test               # run tests with race detector
task check              # fmt + lint + test
task release:snapshot   # goreleaser snapshot build

Build targets: Linux (amd64), macOS (arm64), FreeBSD (amd64).

License

MIT-style license

↑↓ navigate openesc close