The agent never sees the credentials
rtfq holds the connection strings, the policy and the audit log. A caller gets a bearer token and that token's grants, nothing else. A source it isn't granted looks exactly like one that doesn't exist.
$ cd ~/nutrx-labs/tools/rtfq
rtfq runs on the box that can see your databases and gives agents and people one authenticated port to query through. Reads are parsed, capped and logged. Writes are tried, rolled back, and shown to a human as the statement and the rows it touches, and saved only once somebody says yes.
// what it does
rtfq holds the connection strings, the policy and the audit log. A caller gets a bearer token and that token's grants, nothing else. A source it isn't granted looks exactly like one that doesn't exist.
Every statement goes through a real per-dialect parser before it runs. A write hiding in a CTE, a SELECT INTO or an EXPLAIN ANALYZE is refused. Every response states its row count, whether it was truncated and how long it took.
A proposed change runs in a transaction, reports the real affected-row count and is rolled back. You see the statement and the rows as they are now. If the data moves while you decide, the commit is refused.
With require_unlock, a source stays closed to writes until someone runs rtfq unlock. The window is capped at an hour and a restart locks it again. Unqualified UPDATE and DELETE are refused either way.
rtfq mcp exposes nine tools and four workflow prompts. Getting oriented in an unfamiliar four-table database and answering a join question costs about 240 tokens end to end, a number checked in CI.
Every request, refusals included, lands in an append-only JSONL file with the caller, the statement, the outcome and the error code. It stays on the box. There is no control plane, and there won't be one.
// how it works
Grab a bundle from Releases. It's a single self-contained binary, no .NET runtime to install, with a sample config alongside. On macOS, clear the quarantine flag first.
The config references secrets through ${env:...} or ${file:...} rather than containing them. Validate it before anything listens; --production turns inline-secret warnings into errors.
Set RTFQ_SERVER and RTFQ_TOKEN, then ask what's there. Off loopback, TLS is required; a self-signed certificate is fine on a private network.
rtfq mcp speaks MCP on stdio and reads the server and token from its environment, so no secret ends up in a committed .mcp.json. Claude Code and other MCP clients use the same command.
Unlock a source for a fixed time. The agent proposes, you approve or deny from a second terminal, and a restart closes the window anyway. For a team, a webhook can route requests to people instead.
// good to know
rtfq approvals --watch open or configure a webhook, or proposals lapse unanswered.// the full manual
Everything else is in the README.
Configuration, every command, troubleshooting and the design notes.
Read the README ↗