Skip to content

Choose how avenir-mcp runs

avenir-mcp is configured with environment variables, set in your MCP client’s env block. The full list is in Configuration.

Setting Effect
nothing (default) 11 read-only tools; the 9 write tools are neither listed nor callable
AVENIR_MCP_WRITE=1 all 20 tools; every write but approve_transactions is previewed and confirmed

Any other value (0, true, yes) keeps the server read-only: only 1 enables writes.

Your client starts avenir-mcp as a subprocess and talks to it over its standard input and output. Nothing listens on the network. This is what every example in Install does.

For a client that connects to a URL, or to share one server between several clients on your machine. First create a long random token, which clients will have to present:

Terminal window
export AVENIR_MCP_HTTP_TOKEN=$(openssl rand -hex 32)

Then start the server:

Terminal window
AVENIR_MCP_TRANSPORT=http \
AVENIR_MCP_HOST=127.0.0.1 \
AVENIR_MCP_PORT=8103 \
YNAB_API_KEY=your-token \
uvx avenir-mcp

It listens on http://127.0.0.1:8103/mcp (streamable HTTP). Point your client there with the token in an Authorization header — with Claude Code:

Terminal window
claude mcp add --transport http avenir-mcp http://127.0.0.1:8103/mcp \
--header "Authorization: Bearer $AVENIR_MCP_HTTP_TOKEN"

Over HTTP, every request is checked before it reaches a tool:

Check Refused with Stops
the Host header names this machine (127.0.0.1, localhost, ::1) 421 a web page reaching the server through DNS rebinding
an Origin header, when present, is this server’s 403 a page from another site, running in your browser
Authorization: Bearer <AVENIR_MCP_HTTP_TOKEN>, when a token is set 401 any other program on your machine or network

With AVENIR_MCP_WRITE=1, the token is required: without it the server refuses to start. Read-only over HTTP works without a token, with the first two checks only.

Applied operations are recorded so they can be undone. By default the journal is $XDG_STATE_HOME/avenir-mcp/journal.jsonl, or ~/.local/state/avenir-mcp/journal.jsonl when XDG_STATE_HOME is not set. Choose another file with AVENIR_MCP_JOURNAL. See Journal and undo.

avenir-mcp writes diagnostics to stderr — never stdout, which belongs to the protocol in stdio mode — at the level of AVENIR_MCP_LOG_LEVEL, WARNING by default:

Level You see
WARNING (default) only problems
INFO each tool call and each YNAB request
DEBUG everything, including the MCP library’s own messages

An expected error (a malformed month, an unknown account) is logged on one line; a real failure keeps its traceback. The token is never logged.

For a collector such as Vector, Fluent Bit, Promtail or a Datadog agent, ask for JSON and write stderr to a file the collector reads. In the client’s configuration:

"command": "/bin/sh",
"args": ["-c", "exec uvx avenir-mcp 2>>\"$HOME/.local/state/avenir-mcp/avenir.log\""],
"env": { "YNAB_API_KEY": "your-token", "AVENIR_MCP_LOG_FORMAT": "json", "AVENIR_MCP_LOG_LEVEL": "INFO" }

Each line then reads:

{"time":"2026-09-25T09:12:04.120+00:00","level":"INFO","logger":"avenir_mcp.client","message":"Fetching accounts for budget demo-budget"}

Running over HTTP as a service, the service manager keeps stderr: systemd sends it to the journal, launchd to the file named by StandardErrorPath.

At INFO and above, messages hold identifiers and counts only — never payees, amounts or category names — so logs can leave your machine without your financial data. Keep DEBUG for local troubleshooting.

AVENIR_MCP_CONFIDENCE_THRESHOLD (default 0.90) is the share of a payee’s history that must agree before a category is suggested. Lower it to get more suggestions, less often right. See Suggestions.

Unofficial project. We are not affiliated, associated, or in any way officially connected with YNAB or any of its subsidiaries or affiliates. YNAB and You Need A Budget are registered trademarks of YNAB. avenir-mcp is provided as is, without warranty, and is not financial advice. Legal notice