{"slug": "show-hn-aict-unix-coreutils-that-output-xml-json-built-for-ai-agents", "title": "Show HN: Aict – Unix coreutils that output XML/JSON, built for AI agents", "summary": "A new open-source project called Aict reimplements 33 Unix coreutils to output structured XML or JSON instead of plain text, reducing token waste and parsing errors for AI agents. The tools, including ls, grep, and cat, provide labeled fields, absolute paths, and Unix timestamps, and can be used via command line or an MCP server for AI assistants like Claude.", "body_md": "**Unix coreutils with XML/JSON output — built for AI agents, not humans.**\n\n[Install](#install) · [Quick start](#quick-start) · [All tools](#tools) · [MCP server](#mcp-server) · [Claude Code](#claude-code-integration) · [Token cost](#token-cost) · [Benchmarks](#benchmarks) · [Contributing](/synseqack/aict/blob/master/CONTRIBUTING.md)\n\nAI agents run `ls`\n\n, `grep`\n\n, and `cat`\n\nand get back **human-readable plaintext**. Then they spend tokens parsing column positions, guessing field widths, and handling inconsistent formats. This is fragile and wasteful.\n\n```\n-rw-r--r-- 1 user staff  2048 Apr  6 10:00 main.go        ← which column is size?\n-rw-r--r-- 1 user staff  1024 Apr  6 10:00 utils.go       ← what's the language?\ndrwxr-xr-x 5 user staff   160 Apr  6 10:00 internal       ← is this a directory?\n```\n\n`aict`\n\nreimplements 33 Unix tools with **structured output** the agent can read directly — no parsing required.\n\n``` bash\n$ aict ls src/\n<ls timestamp=\"1746123456\" total_entries=\"3\">\n  <file name=\"main.go\" path=\"src/main.go\" absolute=\"/project/src/main.go\"\n        size_bytes=\"2048\" size_human=\"2.0K\" language=\"go\" mime=\"text/x-go\"\n        binary=\"false\" executable=\"false\" modified=\"1746120000\" modified_ago_s=\"3456\"/>\n  <file name=\"utils.go\" path=\"src/utils.go\" absolute=\"/project/src/utils.go\"\n        size_bytes=\"1024\" size_human=\"1.0K\" language=\"go\" mime=\"text/x-go\"\n        binary=\"false\" executable=\"false\" modified=\"1746120000\" modified_ago_s=\"3456\"/>\n  <directory name=\"internal\" path=\"src/internal\" modified=\"1746120000\"/>\n</ls>\n```\n\nEvery field is labeled. Paths are always absolute. Timestamps are Unix integers. Language and MIME type are detected automatically — zero parsing needed.\n\n```\nbrew tap synseqack/aict\nbrew install aict\n```\n\nThis installs `aict`\n\nplus shell completions for bash and zsh. The MCP server is built in: `aict mcp`\n\n.\n\n```\ngo install github.com/synseqack/aict@latest\ngit clone https://github.com/synseqack/aict\ncd aict\ngo build -o aict .\n```\n\nVerify install:`aict --help`\n\nshould list all available tools.\n\n```\n# Default: XML output (best for AI agents)\naict ls src/\naict grep \"func\" . -r\naict cat main.go\naict diff old.go new.go\n\n# JSON output\naict ls src/ --json\n\n# Plain text (same as the original Unix tools)\naict ls src/ --plain\n\n# Enable XML globally for all aict calls\nexport AICT_XML=1\n```\n\n33 tools across 6 categories. Every tool supports `--xml`\n\n(default), `--json`\n\n, and `--plain`\n\n.\n\n| Category | Tools |\n|---|---|\nFile inspection |\n`cat` `head` `tail` `file` `stat` `wc` |\nSearch & compare |\n`ls` `find` `grep` `diff` |\nPath utilities |\n`realpath` `basename` `dirname` `pwd` |\nText processing |\n`sort` `uniq` `cut` `tr` `sed` `awk` |\nData & archives |\n`jq` `tar` |\nSystem & environment |\n`env` `system` `ps` `df` `du` `checksums` `md5sum` `sha1sum` `sha256sum` |\n\nAdditional: `git`\n\n(status, diff, log, ls-files, blame) · `completions`\n\n(bash/zsh/fish) · `doctor`\n\n(self-diagnostic)\n\nAll tools follow the same conventions:\n\n| Field | Convention |\n|---|---|\n| Paths | Always absolute (`absolute` attr) |\n| Timestamps | Unix epoch integers + `_ago_s` companion |\n| Sizes | Bytes (`size_bytes` ) + human-readable (`size_human` ) |\n| Booleans | `\"true\"` / `\"false\"` strings |\n| Errors | `<error code=\"\" msg=\"\"/>` elements — never stderr |\n| Empty results | Valid XML with zero counts, never an error |\n\n`aict mcp`\n\nexposes all tools as callable MCP functions via stdio transport. AI assistants call them natively — no shell wrapping needed. The MCP server is a subcommand of the main binary.\n\n**Configure Claude Desktop** (`~/.config/claude/claude_desktop_config.json`\n\n):\n\n```\n{\n  \"mcpServers\": {\n    \"aict\": {\n      \"command\": \"aict\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\nIf `aict`\n\nis not in PATH, use its full path:\n\n```\n{\n  \"mcpServers\": {\n    \"aict\": {\n      \"command\": \"/usr/local/bin/aict\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\nAdd to `~/.claude.json`\n\n:\n\n```\n{\n  \"mcpServers\": {\n    \"aict\": {\n      \"command\": \"aict\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\nOnce connected, Claude Code can call `ls`\n\n, `grep`\n\n, `diff`\n\n, and all other tools as native functions with typed arguments and structured JSON results.\n\nHonest numbers first: **aict output costs 1.1–7.8× more tokens per task than terse GNU output** (measured with tiktoken `o200k_base`\n\n). What those tokens buy: fewer round-trips and zero parsing ambiguity. Where plaintext needs 2–4 chained calls (`ls`\n\nthen `file`\n\nfor languages, `find`\n\nthen `stat`\n\nper hit), aict answers in one.\n\n| Task | GNU | aict | Tokens (GNU → aict) |\n|---|---|---|---|\n| List dir with size/type/language | 2 calls | 1 call | 246 → 820 · 3.3× |\n| Read file + line count + type | 3 calls | 1 call | 173 → 274 · 1.6× |\nFind `.go` files with size/mtime |\n4 calls | 1 call | 47 → 367 · 7.8× |\n| Grep with file/line/context | 1 call | 1 call | 141 → 326 · 2.3× |\n| Diff with change types | 1 call | 1 call | 167 → 192 · 1.2× |\n\nEvery extra plaintext call is a full agent turn — model inference, tool-call overhead, and intermediate output all land in the context window anyway, none of which the token counts above include. And in this very benchmark, `file(1)`\n\nmisidentified a Go source file as \"C source\"; aict labeled it `go`\n\n.\n\nIn a live agent eval (opencode, same task 3× per toolchain), the aict-equipped agent generated **~46% fewer output tokens** (median 265 vs 487) and was correct 3/3 — the GNU-equipped agent shipped a flawed report in the run where it trusted `file(1)`\n\n's language detection. See [ benchmarks/TOKENS.md](/synseqack/aict/blob/master/benchmarks/TOKENS.md) for both methodologies; reproduce with\n\n`go run ./cmd/tokenbench`\n\n.Use `--plain`\n\nwhen you only need raw content.\n\naict trades some speed for semantic richness (language detection, MIME typing, absolute paths). The overhead is intentional. Startup cost is ~3.6 ms per invocation.\n\n| Tool | GNU | `--plain` |\n`--xml` |\nNotes |\n|---|---|---|---|---|\n`diff` (1000 lines) |\n0.9 ms | 1.9 ms · 2.1× | 2.1 ms · 2.4× | ✅ Myers O(ND) |\n`wc` (100k lines) |\n6.1 ms | 16 ms · 2.6× | 17 ms · 2.7× | ✅ |\n`awk` (10k lines) |\n4.1 ms | 12 ms · 2.9× | 11 ms · 2.6× | ✅ |\n`sed` (10k lines) |\n3.3 ms | 14 ms · 4.2× | 16 ms · 4.9× | ✅ |\n`find` (deep tree) |\n1.9 ms | 13 ms · 6.8× | 15 ms · 8.0× | ✅ |\n`ls` (1000 files) |\n4.0 ms | 51 ms · 12.9× | 70 ms · 17.7× | MIME+lang detection per file |\n`cat` (100k lines) |\n1.4 ms | 24 ms · 16.4× | 31 ms · 21.6× | line-by-line scan + encoding detect |\n`grep` (100k lines) |\n1.3 ms | 119 ms · 88× | 130 ms · 96× | Go regexp vs GNU SIMD |\n\nMedians from 5 runs on Linux/amd64. See [ benchmarks/](/synseqack/aict/blob/master/benchmarks) for methodology and\n\n`make bench`\n\nto reproduce.Use `--plain`\n\nto skip enrichment when you only need raw content.\n\n**Why XML and not JSON by default?**\n\nXML attributes are denser in a context window. `<file size=\"1024\" lang=\"go\"/>`\n\nis shorter than `{\"size\":1024,\"lang\":\"go\"}`\n\n. Use `--json`\n\nif you prefer JSON — the structure is identical.\n\n**Why not pipe GNU tools to jq?**\n\n`ls`\n\n, `cat`\n\n, `stat`\n\n, `find`\n\n, `diff`\n\n, and `wc`\n\ndon't output JSON. `jq`\n\ncan't help with them. aict provides structured output for the entire toolchain, not just grep. (aict also ships its own `jq`\n\nfor querying JSON files with path expressions.)\n\n**How does this compare to ripgrep?**\n\nripgrep is much faster for pure search. aict grep adds language detection, MIME type, and a consistent output format shared with every other tool. Use ripgrep for speed-critical search; use aict when the agent needs structured context.\n\n**How does this compare to eza / lsd?**\n\neza and lsd are better `ls`\n\nfor humans — great colors and formatting. aict outputs data structures, not formatted tables. They're solving different problems.\n\n**Does it work on Windows?**\n\n`ls`\n\n, `cat`\n\n, `stat`\n\n, `wc`\n\n, `find`\n\n, `diff`\n\n, `grep`\n\n, `head`\n\n, `tail`\n\n, `sort`\n\n, `uniq`\n\n, `cut`\n\n, `tr`\n\n, `sed`\n\n, `awk`\n\n, `jq`\n\n, `tar`\n\n, `checksums`\n\n, `df`\n\n, and path utilities work on Windows. `system`\n\nis Linux/macOS; `ps`\n\nis Linux-only (it reads `/proc`\n\n). Unsupported platforms get a structured `<error>`\n\nelement, never a crash.\n\n**Is this safe to run in a sandboxed environment?**\n\nYes. aict is strictly read-only. No network requests (MIME detection uses the Go stdlib, not HTTP). No telemetry. No data collection. It only reads paths you explicitly pass to it.\n\n**How many dependencies does it have?**\n\nOne: the official [MCP Go SDK](https://github.com/modelcontextprotocol/go-sdk), used only by the `aict mcp`\n\nsubcommand. All 33 tools and every internal package are pure Go standard library — enforced as a hard constraint in [AGENTS.md](/synseqack/aict/blob/master/AGENTS.md).\n\nBug reports, feature requests, and PRs are welcome. See [CONTRIBUTING.md](/synseqack/aict/blob/master/CONTRIBUTING.md) for guidelines, code style, and the tool implementation pattern.\n\nIssues tagged [ good first issue](https://github.com/synseqack/aict/issues?q=label%3A%22good+first+issue%22) are a good place to start.\n\n[MIT](/synseqack/aict/blob/master/LICENSE) — built entirely by AI tools, for AI tools.", "url": "https://wpnews.pro/news/show-hn-aict-unix-coreutils-that-output-xml-json-built-for-ai-agents", "canonical_source": "https://github.com/synseqack/aict", "published_at": "2026-07-15 13:39:54+00:00", "updated_at": "2026-07-15 13:48:09.460404+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "ai-tools"], "entities": ["Aict", "Claude", "MCP"], "alternates": {"html": "https://wpnews.pro/news/show-hn-aict-unix-coreutils-that-output-xml-json-built-for-ai-agents", "markdown": "https://wpnews.pro/news/show-hn-aict-unix-coreutils-that-output-xml-json-built-for-ai-agents.md", "text": "https://wpnews.pro/news/show-hn-aict-unix-coreutils-that-output-xml-json-built-for-ai-agents.txt", "jsonld": "https://wpnews.pro/news/show-hn-aict-unix-coreutils-that-output-xml-json-built-for-ai-agents.jsonld"}}