cd /news/ai-agents/faaah-filesystem-as-an-ai-handler-ag… · home › topics › ai-agents › article
[ARTICLE · art-164461] src=github.com ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

Faaah (Filesystem as an AI Handler) – Agent Subscription as OpenAI API via Files

Developer Sebastian Carlos released FAAAH, a 308-line, dependency-free Python tool that turns an existing AI coding-agent subscription (such as Claude Code or opencode) into an OpenAI-compatible local server by writing requests to `.txt` files in a queue directory and having the agent write responses back. FAAAH runs on Python's `http.server`, listens on 127.0.0.1:8000 by default, installs via `uv tool install`, and works with any tool expecting the OpenAI API format, including GraphRAG, LangChain, LlamaIndex, LiteLLM and the `openai` SDK. Carlos states it is his understanding that local, non-commercial use does not break any agent provider's terms of service, while warning users against processing massive datasets because some providers may deploy telemetry to detect infractions.

read7 min views3 publishedNov 5, 2026
Faaah (Filesystem as an AI Handler) – Agent Subscription as OpenAI API via Files
Image: Michielbdejong (auto-discovered)

The simplest OpenAI-compatible LLM proxy you will ever need.™️

FAAAH allows you to reuse your AI Agent subscription as a generic OpenAI-compatible local server.

FAAAH is dependency-free, implemented as a plain-text file protocol (UNIX-philosophy certified):

  1. Instead of sending your prompts to cloud LLM APIs, send them to FAAAH, which reads OpenAI-compatible requests and dumps them into a folder as .txt files.
  2. Then, tell your existing AI coding agent (Claude Code, opencode, etc) to read the files and write responses to other .txt files.
  3. FAAAH then packages the responses into OpenAI-compatible JSON, and returns them to your app.

Because you already pay for an AI coding assistant. Stop paying for API keys just for your weekend side projects! faaah!

It's also an agnostic proxy between any OpenAPI-expecting tool, and any LLM.

As an example, check GraphRAG fully driven through FAAAH.

demo-9mb.mp4 #

It is my understanding that local, non-commercial use of this tool doesn't break the existing ToS of any AI agent provider.

But if any lawyer disagrees, kindly send me a message. I would then introduce you to a friend of mine: Miss Barbra Streisand.

Be cautious about using FAAAH to process massive datasets. Some providers (you know which ones) might do some Kafkaesque interpretations of their ambiguous ToS, and deploy Orwellian telemetry to detect infractions (hasn't happened to me yet, YOLO!)

  • Zero Dependencies: Uses Python'shttp.server . That's it.
  • 308 lines of code: Have you seen thebloat of other tools in this space? Yuck.
  • Unix Philosophy: Everything is a file. Do one thing well. Keep it KISS, ya YAGNI.
  • Universal Compatibility: If a tool supports thede-facto OpenAI API format (GraphRAG, LangChain, LlamaIndex, LiteLLM, theopenai SDK), it supports FAAAH.
  • Agent Agnostic: Due to the agent entrypoint beinga prompt , it's not tied to any specific agent provider/version. Future-proof.
  • Human-in-the-loop Fallback: If the AI agent gets stuck or hits usage limits, you can literally open the current response file (sayresponse-0004.txt ), type the answer yourself (or copy-paste the request to your favorite web chatbot), and hit save. FAAAH will succeed.

Install with uv, from inside this repo:

uv tool install .              # installs the `faaah` command on PATH
uv tool install .[embeddings]  # with the local embeddings extra (see later)

Or straight from the git repository:

uv tool install git+https://github.com/sebastiancarlos/faaah
faaah                       # listens on 127.0.0.1:8000, queue ~/.cache/faaah/queue
faaah --port 8080           # override port
faaah --queue /tmp/q        # override queue directory
faaah --log-dir /tmp/logs   # override session log root (see below)
faaah -c                    # also copy the agent prompt to the clipboard

Each run creates a session-log dir (~/.cache/faaah/sessions/<TIMESTAMP>-<RANDOM> by default) that mirrors every queue file written or answered during that run, so you can debug a session even after the queue is wiped on restart:

  • prompt-<id>.txt ,response-<id>.txt — same files as the queue
  • request-<id>.json ,response-<id>.json — the raw OpenAI request/response
  • embed-<id>-request.json ,embed-<id>-response.json — embeddings traffic
  • session.log — plain-text copy of all log lines

Pass --log-dir "" to disable session logging.

The agent prompt is printed on startup. To grab it again:

faaah --agent-message

Paste it into your coding agent, which then starts a FAAAH coordinator loop:

  • Call faaah --watch to obtain the next request (blocks until one exists).
  • Delegate the request to a worker subagent (to prevent accumulating context).
  • Repeat. If a worker leaves no response file, faaah --watch simply returns the same path again, so the coordinator retries it.

Note: FAAAH uses subagents to prevent exhaustion of context on multiple requests. Thereby, your AI Agents must support creation of subagents on request by prompt.

You can use curl, for example:

curl http://127.0.0.1:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer anything" \
  -d '{
    "model": "faaah",
    "messages": [{"role": "user", "content": "Write a haiku."}]
  }'

Or any OpenAI-API shaped client:

from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="anything")
response = client.chat.completions.create(
    model="faaah", # this field is ignored anyway
    messages=[{"role": "user", "content": "Write a haiku."}],
    timeout=None,           # agents can be slow
).choices[0].message.content
print(response)

A dependency-free example lives in examples/chat.py.

For an advanced usage, GraphRAG fully driven through FAAAH, see graphrag-faaah.

FAAAH supports the OpenAI tools parameter, including multi-turn tool loops. Send a non-empty tools array and the prompt tells the agent which tools exist and how to request them. Without tools, the classic text-only behavior is unchanged.

The agent requests tool calls by committing a JSON object whose only key is tool_calls:

{"tool_calls": [{"name": "get_weather", "arguments": {"city": "Lisbon"}}]}

FAAAH mints the call ids, returns finish_reason: "tool_calls", and expects the client to execute the tool and send the result back as a tool message. On the next request, tool results are rendered as <tool_result> blocks and the agent answers in plain text with finish_reason: "stop".

Supported tool_choice values are auto (default), none, required, and a forced function. parallel_tool_calls: false limits the reply to one call. Malformed tool replies are retried up to twice with the error fed back to the agent; after that FAAAH returns 502.

Streaming is not supported; requests with stream: true get a 400.

A dependency-free example lives in examples/tools.py:

./examples/tools.py "What's the weather in Lisbon?"

FAAAH stays dependency-free by default, but can serve local embeddings via the optional embeddings uv extra (Installs a spaCy model, en_core_web_md):

uv tool install '.[embeddings]'   # global tool with embeddings (from inside this repo)
uv sync --extra embeddings        # or just the dev environment

When installed, POST /v1/embeddings returns OpenAI-shaped vectors computed locally. Without the extra dependencies, the endpoint just returns 503.

curl http://127.0.0.1:8000/v1/embeddings \
  -H "Content-Type: application/json" \
  -d '{"model": "en_core_web_md", "input": ["hello world"]}'
usage: faaah [-h] [--host HOST] [--port PORT] [--queue QUEUE] [--log-dir LOG_DIR] [--timeout TIMEOUT] [--agent-message] [-c] [-d] [--watch]

Filesystem As An AI Handler: an OpenAI-compatible proxy backed by an AI agent working over text files.

options:
  -h, --help         show this help message and exit
  --host HOST        Address to bind (default: 127.0.0.1).
  --port PORT        Port to listen on (default: 8000).
  --queue QUEUE      Directory where prompt/response files live (default: ~/.cache/faaah/queue).
  --log-dir LOG_DIR  Parent dir for per-session logs (default: ~/.cache/faaah/sessions). A new <TIMESTAMP>-<RANDOM> subdir is created each run; pass empty string to disable.
  --timeout TIMEOUT  Abort each call after N seconds. 0 (default) waits forever.
  --agent-message    Print ONLY the agent prompt and exit (it's also printed on launch).
  -c, --copy         Copy the agent prompt to the system clipboard on startup (uses wl-copy, xclip, xsel, pbcopy or clip.exe if available).
  -d, --debug        Print the full request/response flow for each call once it completes.
  --watch            Block until a pending prompt exists, print its path.

The protocol relies on files on the queue directory (~/.cache/faaah/queue by default).

Each request produces a prompt-<id>.txt file, where the first one's ID will be 00001 and increase monotonically.

FAAAH then expects the agent (or anything really) to generate a corresponding response-<id>.txt.

The subagent workers are prompted to write a first pass as response-<id>.txt.draft, which they may revise, before renaming it to the final response-<id>.txt they consider final.

File Who writes Meaning
prompt-<id>.txt server an incoming request for the agent
response-<id>.txt.draft agent an in-progress, editable draft
response-<id>.txt agent the answer

Retry is automatic: a prompt with no response file is simply re-offered by faaah --watch to the coordinator until one appears. Tool-call validation retries also use a fresh prompt id, with the rejected reply and the reason included in the new prompt.

If the client disconnects, or the server-side --timeout fires, faaah removes the prompt so --watch does not keep re-offering work nobody is waiting for.

Other projects put an API in front of a CLI subscription:

  • CLIProxyAPI is a Go proxy that exposes several CLI providers such as Claude Code, Codex, Gemini, and Grok through OpenAI, Gemini, Claude, Codex, and Grok compatible endpoints. It handles OAuth, streaming, multimodal input, tool calling, and multi-account load balancing.
  • opencode2api is a Go gateway for OpenCode Zen and Zen Go.

Unlike the above, FAAAH doesn't talk to a provider at all: FAAAH tells you how to prompt the model you already have to act as an OpenAI API, so in principle any model that you can prompt locally works.

MIT

── more in #ai-agents 4 stories · sorted by recency
── more on @faaah 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/faaah-filesystem-as-…] indexed:0 read:7min 2026-11-05 · —