hledger-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@hledger-mcpshow my balance for the current month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
hledger-mcp
MCP server for hledger — exposes double-entry accounting tools to AI agents via the Model Context Protocol.
Built with fastmcp.
Tools
Tool | Description |
| Account balances, optionally filtered by account and period |
| Transaction history, optionally filtered by account, period, and limit |
| Budget report (requires |
| Append a new transaction to the journal |
Related MCP server: bookie
Requirements
Usage
Run directly with uvx
uvx --from /path/to/hledger-mcp hledger-mcpAdd to Claude Code
{
"mcpServers": {
"hledger": {
"command": "uvx",
"args": ["--from", "/path/to/hledger-mcp", "hledger-mcp"]
}
}
}Journal path
By default, the server reads and writes to ~/hledger.journal. Override with the HLEDGER_JOURNAL environment variable:
HLEDGER_JOURNAL=/path/to/my.journal uvx --from /path/to/hledger-mcp hledger-mcpOr in mcp.json:
{
"mcpServers": {
"hledger": {
"command": "uvx",
"args": ["--from", "/path/to/hledger-mcp", "hledger-mcp"],
"env": {
"HLEDGER_JOURNAL": "/home/user/finance/ledger.journal"
}
}
}
}Using with orbit
orbit is an AI session launcher that manages context — MCPs, instructions, and permissions — across a layered scope hierarchy: workspace → tenant → project → repository. hledger ships as a first-class orbit plugin.
Setup (3 commands)
# Register the plugin with orbit
curl -fsSL https://raw.githubusercontent.com/eloircorona/hledger-mcp/main/hledger.toml \
-o ~/.orbit/plugins/hledger.toml
# Install hledger if not already present
orbit plugins install hledger
# Configure the journal path for this instance
orbit plugins auth hledger
# Enable the MCP for the current scope (tenant, project, or global)
orbit plugins enable hledgerorbit plugins auth prompts for the instance name and journal path, then wires everything up. No config files to edit manually.
If you already cloned the repo, the one-liner becomes:
cp hledger.toml ~/.orbit/plugins/Launch
orbit launch <scope>orbit starts the session with hledger connected alongside any other MCPs in scope. Switch to a different tenant and hledger disappears automatically.
Multiple journals
Need separate instances for personal and business finances? Run orbit plugins auth hledger again with a different instance name — orbit tracks them independently:
orbit plugins auth hledger # instance: personal → ~/finance/personal.journal
orbit plugins auth hledger # instance: business → ~/finance/business.journalWhy this matters
A typical personal finance setup in orbit pairs hledger-mcp with:
MCP | Purpose |
| Typed access to the journal — query balances, add transactions |
| Browse receipts, bank exports, tax documents |
| Structured queries over imported CSV data |
Because orbit merges MCPs layer by layer, you can scope hledger to a specific tenant so it only loads when you're working on finances — never leaking into other sessions.
orbit handles context scoping, MCP lifecycle, engine selection (Claude, Gemini, local), and session instructions — so the AI always has the right tools for the current domain, with zero manual configuration per session.
Tool reference
get_balance
Returns the balance report (hledger bal).
get_balance(account="gastos", period="this month")
get_balance(account="activos:banco")
get_balance()Param | Type | Description |
|
| Account name pattern to filter |
|
| Period expression: |
get_register
Returns the register report (hledger reg).
get_register(account="gastos:alimentacion", period="this month")
get_register(limit=20)Param | Type | Description |
|
| Account name pattern to filter |
|
| Period expression |
|
| Max number of entries to return |
get_budget
Returns the budget report (hledger budget). Requires ~ monthly or similar budget directives in your journal.
get_budget(period="this month")Param | Type | Description |
|
| Period expression |
add_transaction
Appends a transaction to the journal file.
add_transaction(
date="2026-08-08",
description="Supermercado Walmart",
postings=[
{"account": "gastos:alimentacion", "amount": "850 MXN"},
{"account": "activos:banco:bbva"}, # no amount — hledger auto-balances
]
)Param | Type | Description |
|
| ISO date: |
|
| Payee or description |
|
| List of |
The resulting journal entry:
2026-08-08 Supermercado Walmart
gastos:alimentacion 850 MXN
activos:banco:bbvaAccount conventions (hledger standard)
activos: assets (bank, cash, investments)
pasivos: liabilities (credit cards, loans)
ingresos: income (salary, freelance)
gastos: expenses (food, transport, rent)
patrimonio: equity (opening balances)Development
git clone git@github.com:eloircorona/hledger-mcp.git
cd hledger-mcp
uv sync
uv run hledger-mcpLicense
MIT
Available Tools
4 toolsadd_transactionAdd TransactionC
Add a new transaction to the journal.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | ISO date string, e.g. '2026-08-08' | |
| postings | Yes | List of postings. Each is {"account": "gastos:alimentacion", "amount": "850 MXN"}. The last posting may omit 'amount' — hledger will auto-balance it. | |
| description | Yes | Payee/description, e.g. 'Supermercado Walmart' |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It only says that a transaction is added, but it does not mention persistence, side effects, idempotency, validation behavior, or the auto-balancing behavior partially described in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence with no filler. It loses a point because 'Add a new transaction' largely restates the tool name, though 'to the journal' adds useful context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple create tool with a complete input schema and an output schema, the description is minimally viable. However, it lacks usage guidance and behavioral context, so an agent still has to infer when to use it and what consequences the write operation has.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description itself adds no parameter-level meaning beyond the general 'journal' context, but the schema already documents date, description, and postings with examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Add a new transaction') and resource ('to the journal'), making the tool's core function clear. It is not as explicit as naming the sibling alternative, but it is obviously distinct from the read-only get_* siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives. It does not mention that sibling tools are for reading balances, registers, or budgets, nor does it state when add_transaction would or would not be appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_balanceGet BalanceA
Show account balances. Optionally filter by account name pattern and/or period (e.g. 'this month', '2026-08', 'Q1').
| Name | Required | Description | Default |
|---|---|---|---|
| period | No | ||
| account | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the disclosure burden. It conveys that this is a read/show operation and adds filter behavior (name pattern, period examples), but it does not disclose details like default output when filters are omitted, whether all accounts are included, or how period boundaries are handled. Still, the read-only nature is reasonably clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the primary purpose is stated first, followed by concise filter guidance. Both sentences add value, and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple read-only query tool with an output schema, so the description does not need to explain return values. It covers the purpose and both optional parameters adequately. Minor gaps remain around default behavior and explicit sibling differentiation, but the tool can be used correctly from the description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds meaningful semantics: 'account' is described as a name pattern, and 'period' is illustrated with concrete examples ('this month', '2026-08', 'Q1'). This goes well beyond the bare parameter names, though exact matching rules remain undefined.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb and resource: 'Show account balances'. It does not explicitly differentiate from siblings like get_register or get_budget, but the resource 'balances' is intuitively distinct from register/budget tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool—when you need account balances—and explains optional filtering by account name pattern or period. However, it does not explicitly mention when to prefer a sibling tool or state exclusions, leaving routing between alternatives to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_budgetGet BudgetA
Show budget report. Requires budget directives in the journal. Optionally filter by period.
| Name | Required | Description | Default |
|---|---|---|---|
| period | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. The word 'Show' implies a read-only operation, and the prerequisite about budget directives adds important context about a dependency. It does not mention error behavior, output format details, or side effects, but for a simple read-only report this is a reasonable level of transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no wasted words. The key action is front-loaded, and the prerequisite plus optional filter follow naturally, making it easy to parse and act on.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple tool with one optional parameter and an output schema, so the description covers the essential usage context: what is shown, a prerequisite, and an optional filter. Minor gaps like period format are not critical for this level of complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only defines 'period' without any parameter description, so the description's phrase 'Optionally filter by period' is valuable: it clarifies that the parameter acts as an optional filter. It does not specify the expected string format or allowed values, leaving some ambiguity for the agent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool's function clearly: 'Show budget report' specifies a distinct action and resource. It is implicitly distinguishable from siblings like get_balance and get_register because it focuses on a budget-specific report, though it does not explicitly name alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a useful prerequisite: 'Requires budget directives in the journal,' which helps the agent know when the tool is applicable. However, it does not explicitly explain when to prefer this tool over get_balance, get_register, or add_transaction, nor does it state exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_registerGet RegisterA
Show transaction register (history). Optionally filter by account, period, and max number of entries.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| period | No | ||
| account | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. 'Show transaction register (history)' implies a read-only query, but it does not explicitly state read-only behavior, ordering, defaults, pagination, or any other behavioral caveats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no filler. It states the purpose and all optional filters efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is adequate for a simple filtered history tool, and an output schema exists, but it lacks usage guidance, sibling differentiation, and parameter format details. With no annotations and zero schema description coverage, some context is still missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It maps all three parameters to concepts: account, period, and max number of entries. However, 'period' is vague and no format or value semantics are provided beyond the parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Show transaction register (history)'. This clearly conveys the tool's function and distinguishes it from siblings like get_balance, get_budget, and add_transaction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explain when to use this tool versus alternatives. It mentions optional filters but gives no guidance on choosing get_register over get_balance or get_budget, leaving usage context implied at best.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
add_transaction - First observed
get_balance - First observed
get_budget - First observed
get_register
TDQS
Scored across 4 tools
Each tool targets a distinct hledger concern: balances, transaction history, budget reports, and adding transactions. There is no meaningful overlap between them.
All tools follow the verb_noun pattern with 'get_' for read operations and 'add_' for the write operation. Naming is perfectly predictable and consistent.
Four tools is a compact, focused set for a hledger interface covering the most common actions. No tool is redundant, and the scope feels well-suited to an MCP server.
The core workflows of viewing balances, transactions, budgets, and adding entries are covered. However, there are notable gaps such as no way to list accounts, edit/delete transactions, or retrieve full transaction details, which are common hledger operations.
Maintenance
Related MCP Connectors
Log, query, and edit expenses, budgets, and accounts in Ledgy from any MCP-compatible AI assistant.
Personal finance for AI agents — onboard, import statements, categorize & budget over MCP.
Personal finance ledger for AI agents — query spending, track bills, forecast cash flow.
- ManiloOAuthapp.manilo
Log, query, and edit expenses, budgets, and accounts in Manilo from any MCP-compatible AI assistant.
Related MCP Servers
- AlicenseCqualityDmaintenanceA Model Context Protocol server that allows AI assistants to query and analyze financial data through Ledger CLI, enabling tasks like financial reporting, budget analysis, and accounting.951MIT
- AlicenseNot gradedqualityAmaintenanceA Model Context Protocol (MCP) server that keeps the books for your personal and business finances using double-entry accounting — driven entirely from an LLM.51 npmMIT
- FlicenseNot gradedqualityBmaintenanceA read-only MCP server that gives AI agents structured access to a Beancount personal finance ledger.1-
- AlicenseNot gradedqualityAmaintenanceDouble-entry accounting ledger MCP server for autonomous agents that enables creating accounts, posting journal entries, and generating financial reports.MIT