LiveFolders — Expose tools to LLMs as plain files
★ LiveFolders v0.9.2 — Expose tools to LLMs via plain files — New: agent auto-setup (Claude Code / Cursor / Copilot), LLM tool-authoring via create_tool.md — Apache 2.0 — Star us on GitHub! ★
What Is It?
LiveFolders mounts a virtual filesystem on your machine. Every tool you install appears as<br>a directory of plain files. An LLM reads a file to call the tool — no JSON protocol,<br>no SDK, no special client. Any agent that can run cat or echo can use it.
cat .livefolders/tools/users/list<br># → # Users<br># → ## Mr. Rudolph Robel-Fay<br># → ID: 1<br># → Created: 2024-01-15<br># → Avatar: https://cdn.example.com/avatars/1.jpg
ℹ️ How the blocking works:<br>The write call blocks until the tool finishes — by the time<br>cat runs, the result is ready. The filesystem never returns stale data.
Quick Start
# 1. Create a config file (offers to set up CLAUDE.md / AGENTS.md / Copilot automatically)<br>livefolders init
# 2. Install a tool from GitHub<br>livefolders install github.com/natanloterio/LiveFolders/tree/master/examples/users
# 3. Mount (runs in background, returns to prompt immediately)<br>livefolders mount
# 4. Use it<br>cat .livefolders/tools/users/list # fetches users from the API
echo "hello world" > .livefolders/tools/demo/shout<br>cat .livefolders/tools/demo/shout # → HELLO WORLD
# 5. Stop<br>livefolders stop
Giving Tools to Your Agent
livefolders init does this automatically — it detects your agent and writes the snippet to the right file:
AgentFile written
Claude CodeCLAUDE.md<br>Cursor / Windsurf / AiderAGENTS.md<br>GitHub Copilot.github/copilot-instructions.md
Or paste it manually into any agent's instruction file:
## Tools
LiveFolders is mounted at `.livefolders/tools/`. Before using any tool:<br>1. `cat .livefolders/tools/index.md` to see what's available<br>2. `cat .livefolders/tools//how_to.md` to read usage instructions<br>3. Write input with `echo "..." > .livefolders/tools//`<br>4. Read output with `cat .livefolders/tools//`
LLMs can also author new tools from inside the filesystem.<br>A virtual create_tool.md is mounted at the filesystem root — it contains<br>the complete folder.yaml reference: file types, input validation, secrets,<br>state, and pipelines. An LLM reads it and writes a working tool without ever leaving<br>the mounted filesystem:
cat .livefolders/create_tool.md
The agent then follows this sequence on its own:
1. Discover tools
cat .livefolders/tools/index.md
→ weather — forecast for any city<br>→ users — fetch users from API
2. Read usage instructions
cat .livefolders/tools/weather/how_to.md
→ endpoint: forecast (write_invoke)<br>→ input: string, min_length: 1
3. Invoke the tool
echo "London" > .livefolders/tools/weather/forecast
cat .livefolders/tools/weather/forecast
→ ☁️ Overcast, 15°C
4. Handle errors
echo "" > .livefolders/tools/weather/forecast
→ [ERROR:INVALID_INPUT] input too short: minimum 1 characters required
5. Check timing & diagnostics
cat .livefolders/tools/weather/forecast.log
→ duration_ms: 342<br>→ exit: ok<br>→ stderr: (empty)
How It Works
.livefolders/tools/<br>├── index.md ← all tools listed here<br>├── demo/<br>│ ├── how_to.md ← LLM reads this first<br>│ ├── schema.json ← machine-readable schemas<br>│ ├── shout ← write text, read UPPERCASED<br>│ ├── shout.log ← last run: duration + stderr<br>│ └── status ← read-only status<br>└── users/<br>├── how_to.md<br>├── schema.json<br>└── list ← reads from REST API
1. Mount the filesystem
livefolders mount — runs in background, returns to prompt immediately.
2. LLM reads or writes a file
cat tools/users/list fetches users.
echo "London" > tools/weather/forecast sends a query.
3. Handler runs, result returns
Your shell command, Python script, or curl call executes.<br>Output is returned as file content.<br>★ Changes hot-reload in ~1s
10 Lines vs 18 Lines
Same task: fetch users from a REST API and return markdown.<br>From the peer-reviewed paper, measured on live experiments:
LiveFolders — folder.yaml (10 lines)
name: users<br>description: List users from the mock API.<br>files:<br>- name: list<br>type: read_invoke<br>handler: >-<br>curl -s https://mockapi.io/users<br>| jq -r '"# Users\n",<br>(.[] | "## \(.name)\nID: \(.id)\n")'<br>- name: how_to.md<br>type: readonly
MCP — server.py (18 lines)
import httpx<br>from mcp.server.fastmcp import FastMCP<br>mcp = FastMCP("users")
@mcp.tool()<br>def list_users() -> str:<br>"""Fetches all users."""<br>response = httpx.get(<br>"https://jsonplaceholder.typicode.com/users"<br>response.raise_for_status()<br>users = response.json()<br>lines = ["# Users", ""]<br>for u in users:<br>lines.append(f"## {u['name']}")<br>lines.append(f"ID: {u['id']}")<br>lines.append("")<br>return "\n".join(lines)
if __name__ == "__main__":<br>mcp.run()
LiveFolders: no Python, no imports, no server lifecycle. The handler is a shell one-liner.<br>The gap grows with tool complexity — every MCP tool must navigate a server framework;<br>every LiveFolders tool is independently a shell command.
Key Features
⚡ Hot-Reload
Edit folder.yaml or a handler script — changes take effect in ~1 second.<br>No...