
koala73/worldmonitor88kWorld Monitor
Live markets, conflicts, country risk, chokepoints, energy, and China decision signals. 90 tools.
AI 与智能体
搜索文档、Skill 和 MCP

MCP Server for use with Monarch Money
A Model Context Protocol (MCP) server for integrating with the Monarch Money personal finance platform. This server provides seamless access to your financial accounts, transactions, budgets, and analytics through Claude Desktop and Claude Code.
My MonarchMoney referral: https://www.monarchmoney.com/referral/ufmn0r83yf?r_source=share
Built with the MonarchMoneyCommunity Python library - An actively maintained community fork of the Monarch Money API with full MFA support.
If you plan to use this MCP server locally / on the same computer as Claude Desktop or similar, start with the Local Installation section.
For other deployment scenarios - like containerized deployment or cloud hosting - start with the Containerized Deployment section.
Clone this repository:
git clone https://github.com/robcerda/monarch-mcp-server.git
cd monarch-mcp-server
Install dependencies:
Using uv (recommended):
uv sync --locked
--locked installs exactly what uv.lock pins, verified against the
hashes it records, and refuses to re-resolve. Without it, uv sync is free
to pick up whatever versions happen to satisfy the ranges today.
Using pip:
pip install -r requirements-lock.txt --require-hashes
pip install -e . --no-deps
requirements-lock.txt is generated from uv.lock and pins every transitive
dependency with hashes, so --require-hashes gives the pip path the same
guarantee as the uv one. --no-deps on the second command stops pip
re-resolving what the first command just pinned.
pip install -r requirements.txt still works and installs exactly the same
set. That file is now a one line include of requirements-lock.txt, kept so
existing setups and scripts do not break. The pins moved out of it because a
root requirements.txt gets resolved as an independent manifest, which had
started producing a pinned set that disagreed with uv.lock.
Configure Claude Desktop: Add this to your Claude Desktop configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"Monarch Money": {
"command": "/opt/homebrew/bin/uv",
"args": [
"run",
"--locked",
"--project",
"/path/to/your/monarch-mcp-server",
"monarch-mcp-server"
]
}
}
}
Important: Replace /path/to/your/monarch-mcp-server with your actual path!
uv run --locked --project resolves dependencies from the repo's
uv.lock, and monarch-mcp-server is the console script declared in
pyproject.toml. --locked matters: without it, a lockfile that has
drifted from pyproject.toml is silently re-resolved against PyPI and the
recorded hashes stop being enforced. With it, drift is a startup error.
Earlier versions of this README used uv run --with 'mcp[cli]', which
builds a fresh unpinned environment on every launch and silently picks up
whatever the newest release happens to be. That is what broke every install
when the MCP SDK published 2.0, and the client only reported it as the
server disconnecting. Pinning the launch to the lockfile means a new
upstream release cannot change what your server runs.
Restart Claude Desktop
OR
Configure Claude Code (CLI): Add this to your Claude Code configuration file:
Global (all projects):
macOS/Linux: ~/.claude.json
Windows: %USERPROFILE%\.claude.json
{
"mcpServers": {
"Monarch Money": {
"command": "/opt/homebrew/bin/uv",
"args": [
"run",
"--locked",
"--project",
"/path/to/your/monarch-mcp-server",
"monarch-mcp-server"
]
}
}
}
Project-level (specific directory):
Create .mcp.json in your project directory:
{
"Monarch Money": {
"command": "/opt/homebrew/bin/uv",
"args": [
"run",
"--locked",
"--project",
"/path/to/your/monarch-mcp-server",
"monarch-mcp-server"
]
}
}
If installed via pip instead of uv, use:
{
"command": "python",
"args": ["/path/to/your/monarch-mcp-server/src/monarch_mcp_server/server.py"]
}
Important: Replace /path/to/your/monarch-mcp-server with your actual path!
Restart Claude Code
Important: For security and MFA support, authentication is done outside of Claude.
Open a terminal and run:
cd /path/to/your/monarch-mcp-server
uv run python login_setup.py # or: python login_setup.py
The script offers three login paths:
Long-lived sessions, supports SSO accounts, and sidesteps Cloudflare CAPTCHA gates on programmatic login. Steps:
Log in to https://app.monarch.com in Chrome or Firefox.
Open DevTools (F12) → Network tab.
Click any request whose Name starts with graphql (or any request to api.monarch.com).
Scroll to Request Headers, find the cookie: header, and copy the full value.
Save it to the cookie file for your platform (recommended), then re-run the script — it reads the file automatically:
macOS / Linux — ~/.config/monarch-mcp/cookie.txt (respects $XDG_CONFIG_HOME):
mkdir -p ~/.config/monarch-mcp
# paste the cookie value into the file with your editor, then:
chmod 600 ~/.config/monarch-mcp/cookie.txt
Windows — %APPDATA%\monarch-mcp\cookie.txt:
New-Item -ItemType Directory -Force "$env:APPDATA\monarch-mcp" | Out-Null
notepad "$env:APPDATA\monarch-mcp\cookie.txt" # paste the cookie value, save, close
Files under your user profile are already ACL-restricted to your account on Windows; no chmod equivalent is needed for typical single-user machines.
To use a different location on any platform, set the MONARCH_MCP_COOKIE_FILE environment variable to the full path.
Alternatively, paste the value at the interactive prompt — but note that
POSIX terminals silently truncate pasted input at the canonical-mode
buffer limit (MAX_CANON, 1024 bytes on macOS/Linux), and real Monarch
cookie headers are usually longer than that, so the prompt path fails
with a confusing auth error for most users. The cookie file has no
length limit and survives repo updates.
The script verifies the cookies against the live API before saving them to your system keyring. The cookie file is only read at setup time; the running MCP server uses the keyring session.
Standard interactive login. The script handles:
The resulting long-lived session token is saved to your system keyring.
Kept for users with an existing token captured before the May 2026 API change. Monarch may no longer accept token-only auth on the GraphQL endpoint; if the verification call returns 401, fall back to option 1.
Once authenticated, use these tools directly in Claude Desktop or Claude Code:
get_accounts - View all your financial accountsget_transactions - Recent transactions with filteringget_budgets - Budget information and spendingget_cashflow - Income/expense analysisThe Docker image uses Astral's uv/Python 3.12 slim base, installs from uv.lock,
and defaults to HTTP on 0.0.0.0:8000 inside the container.
docker build -t monarch-mcp-server .
Authenticate once using a persistent session volume:
docker run --rm -it \
-v monarch-session:/home/app/.monarch-mcp-server \
monarch-mcp-server python login_setup.py
The login script supports a cookie file for browser-cookie authentication.
To use it, also mount your cookie file at /tmp/monarch-cookie.txt:ro and set MONARCH_MCP_COOKIE_FILE=/tmp/monarch-cookie.txt for the login container.
The file must be readable by the container's uid 10001, which conflicts with
the chmod 600 advised for the local flow: a 0600 file owned by your host user
is not readable by uid 10001 inside the container. For the container login,
either chown 10001 cookie.txt and keep it at 0600, or run the login container
with --user $(id -u) so it reads the file as you. Do not widen it to 0644.
Delete the file once the login has succeeded.
Once saved, the session volume is sufficient for normal server launches.
Important
The session is stored unencrypted in that volume. This differs from a local install, and the difference is easy to miss.
On macOS and Windows the session goes to the system keyring. A container has no keyring backend, so storage falls back to a file. That file is encrypted at rest only on Windows, through DPAPI, so in a Linux container it holds your Monarch session in plaintext. Permissions are as tight as a file can be, mode 0600 inside a 0700 directory owned by uid 10001, but file permissions do not help against anyone who can reach the volume from outside the container.
Treat
monarch-sessionas a secret. It can be read by root on the Docker host, by any user in thedockergroup, by any other container that mounts the same volume, bydocker cpanddocker exec, and by anything that backs up/var/lib/docker. A Monarch session grants full read and write access to your accounts and does not expire on its own, so a copy of this volume is a lasting credential. Back it up only to somewhere you would keep a password, and delete the volume withdocker volume rm monarch-sessionwhen you are done with it.The cookie file described below is the same kind of secret. Delete it once the login has succeeded; it is only needed for that one run.
Reuse the session volume when starting the server:
$ docker run -d --name monarch-mcp --restart unless-stopped \
-p 127.0.0.1:8000:8000 \
-v monarch-session:/home/app/.monarch-mcp-server \
monarch-mcp-server
Connect your MCP client to http://127.0.0.1:8000/mcp using Streamable HTTP.
See HTTP transport configuration for all settings.
The image runs in read only mode by default,
because the HTTP transport does not authenticate callers. Anything that can
reach the port would otherwise be able to call monarch_logout, or
monarch_login_with_token to swap your saved session for another Monarch
account. Login happens in the separate login_setup.py container above, so the
running server never needs those tools.
To allow writes, add -e MONARCH_MCP_READ_ONLY=0. That registers every
mutating tool, including the login and logout tools, on the listening socket,
so only do it where every client that can reach the port is trusted.
Warning
This MCP server is not multi-user or multi-account. All connected clients share the same session and permissions. Ensure that you understand the security implications before exposing the server to a network.
To connect from another machine, put the container behind an authenticated HTTPS reverse proxy or a private network with access controls, publish the port on the appropriate interface, and allow the hostname used by the client:
docker run -d --name monarch-mcp --restart unless-stopped \
-p 127.0.0.1:8000:8000 \
-e MONARCH_MCP_ALLOWED_HOSTS=mcp.example.com \
-v monarch-session:/home/app/.monarch-mcp-server \
monarch-mcp-server
Here a reverse proxy on the Docker host forwards https://mcp.example.com/mcp to http://127.0.0.1:8000/mcp, preserving the public Host header.
The proxy must support streaming responses without buffering.
For direct access on a private network, allow the client's Host value including the port, such as server.lan:8000.
Let me stress this point: This is a single-account server! All connected clients share the same saved Monarch session and permissions, including enabled write tools. Basic Host/origin checks protect against DNS rebinding; they do not authenticate callers. Use one server and session volume per Monarch account if you need to.
To run the Docker image over STDIO instead:
docker run --rm -i \
-e MONARCH_MCP_TRANSPORT=stdio \
-v monarch-session:/home/app/.monarch-mcp-server \
monarch-mcp-server
The server supports MCP Streamable HTTP at /mcp but only when explicitly selected:
uv run --locked monarch-mcp-server --transport http --host 127.0.0.1 --port 8000
Connect an MCP client using Streamable HTTP to http://127.0.0.1:8000/mcp.
| Setting | CLI flag | Environment variable | Default outside Docker |
|---|---|---|---|
| Transport | --transport | MONARCH_MCP_TRANSPORT | stdio (http aliases streamable-http) |
| Listen address | --host | MONARCH_MCP_HOST | 127.0.0.1 |
| Listen port | --port | MONARCH_MCP_PORT | 8000 |
| Additional allowed Host headers | --allowed-host (repeatable) | MONARCH_MCP_ALLOWED_HOSTS (comma-separated) | None; loopback hosts are always allowed |
| Additional allowed browser Origins | --allowed-origin (repeatable) | MONARCH_MCP_ALLOWED_ORIGINS (comma-separated) | None; HTTP loopback origins are always allowed |
CLI flags override their environment settings.
Host entries include the port when clients send one; server.lan:* allows any port.
Origin entries include the scheme, for example https://client.example.com.
Clients without an Origin header are supported.
Browser clients may additionally require CORS handling at the reverse proxy.
Works great with Meta Muse, Meta's AI assistant, alongside Claude Desktop and Claude Code. Muse speaks MCP, so it connects the same way as any other client: give it the stdio launch command from the installation section, or point it at the Streamable HTTP endpoint if you are running the container.
Using Muse? Ask it to install this server from this repo. Muse can handle the install and register the server with itself, but authentication is a step only you can do: run login_setup.py once and paste a browser cookie, or enter your password and MFA. After that, ask Muse to list your Monarch accounts to confirm it is working.
Check out Muse, your personal AI agent. Redeem my code in Settings within 48 hours of joining and we'll both get 1 billion Muse tokens.
Code: O63W0U
get_recurring_transactions() includes merchant forecasts and synced liability
bills (such as credit cards and loans). Set include_liabilities=False to
request only merchant recurring items. Omit both dates for the current calendar
month, or provide both start_date and end_date in YYYY-MM-DD format.
The default response remains a JSON list with the existing merchant fields.
Each item also exposes account_id, category_id, amount_diff, and the stream's
name and merchant_id. A liability item can have a null merchant. Its
stream.credit_report_liability_account contains the liability id, linked
account_id/account name, and last_statement with id, due_date,
bill_amount, minimum_payment_amount, payment_status, and remaining_balance.
Missing statements and unknown balances stay null; paid balances stay zero.
These are not interchangeable amounts. The item's amount and stream's
amount are recurring forecasts. last_statement.bill_amount is the original
synced statement amount; remaining_balance is the remaining synced statement
balance. The latest statement's due date can differ from the forecast item's
date. Payment status is returned as supplied by Monarch, not inferred. These
values reflect the latest sync, not a guaranteed real-time amount owed.
Merchant forecasts and liability bills can describe the same payment. The tool preserves both with their identities: it does not sum, deduplicate, or substitute forecast amounts for unknown statement balances.
With limit omitted, the tool reads every page itself and returns the complete
range, so the default list is the whole month. Pass limit to read a single page
instead, and use include_metadata=True to opt into the standard envelope
(data, args, count, total_count, truncated, tool, search):
get_recurring_transactions(
start_date="2026-02-01", end_date="2026-02-28",
include_liabilities=True, limit=100, offset=0, include_metadata=True,
)
The API supplies no total, so total_count is null. With an explicit limit, a
full page is conservatively marked truncated=True (more rows may exist). Keep
the dates and filters fixed, advance offset by count, and continue until
truncated=False. An exactly full final page requires one more request, which
may return an empty page.
Synced bills require bill sync to be available and configured in Monarch; the tool does not enable it or refresh institutions.
monarch_login_with_token to paste a session token from your browserAll 60 registered tools. Required parameters are listed first, optional ones are marked with a trailing question mark. This table is generated from the live tool registry and the functions' signatures, so it does not drift.
| Tool | Description | Parameters |
|---|---|---|
add_transaction_tag | Add a tag to a transaction, preserving any tags already on it | transaction_id, tag_id |
bulk_categorize_transactions | Apply the same category to multiple transactions at once | transaction_ids, category_id, mark_reviewed?, dry_run? |
bulk_update_transactions | Apply the same edit to many transactions in one request | transaction_ids, category_id?, merchant_name?, notes?, goal_id?, needs_review?, business_entity_id?, dry_run? |
categorize_transaction | Assign a category to a transaction | transaction_id, category_id |
check_auth_status | Report the stored session and its auth mode | None |
create_transaction | Create a new transaction in Monarch Money | date, account_id, amount, merchant_name, category_id, notes?, update_balance? |
create_transaction_category | Create a new transaction category | group_id, transaction_category_name, icon?, rollover_enabled?, rollover_type? |
create_transaction_rule | Create a new transaction auto-categorization rule | merchant_criteria_operator?, merchant_criteria_value?, merchant_criteria_values?, merchant_criteria?, original_statement_operator?, original_statement_values?, original_statement_criteria?, use_original_statement?, amount_operator?, amount_value?, amount_lower?, amount_upper?, amount_is_expense?, set_category_id?, set_merchant_name?, add_tag_ids?, link_goal_id?, hide_from_reports?, review_status?, account_ids?, category_ids?, apply_to_existing? |
create_transaction_tag | Create a new transaction tag | name, color |
debug_session_loading | Diagnose session loading problems | None |
delete_transaction | Delete a transaction from Monarch Money | transaction_id |
delete_transaction_rule | Delete a transaction rule | rule_id |
get_account_balance_history | Get historical balance data for a specific account | account_id |
get_account_holdings | Get investment holdings for a specific account | account_id |
get_account_sync_health | Report the health of each linked institution connection | stale_after_days? |
get_accounts | Get all financial accounts from Monarch Money | None |
get_budgets | Get budget information from Monarch Money | start_date?, end_date? |
get_business_entities | List the business entities on the Monarch account (id and name) | None |
get_cashflow | Get cashflow analysis from Monarch Money | start_date?, end_date? |
get_cashflow_by_month | Get spending trends over time, broken down by category and month | start_date, end_date |
get_category_details | Get a single category's details including budget amounts for a month | category_id, month? |
get_debt_paydown | Get the debt paydown plan and the accounts feeding it | method? |
get_goal_contributions | Show a goal's budgeted contributions, broken down by funding account | goal_id, month? |
get_goals | List Monarch savings and debt-paydown goals | None |
get_merchant | Get a merchant's details including recurring transaction stream configuration | merchant_id |
get_net_worth | Get net worth history over time | start_date?, end_date?, account_type? |
get_net_worth_by_account_type | Get net worth breakdown by account type over time | start_date, timeframe? |
get_recurring_transactions | Get upcoming recurring transactions | start_date?, end_date?, include_liabilities?, limit?, offset?, include_metadata? |
get_spending_summary | Get a spending summary broken down by category, category group, and merchant | start_date?, end_date? |
get_transaction_categories | Get all available transaction categories from Monarch Money | None |
get_transaction_category_groups | Get all transaction category groups (parent groupings for categories) | None |
get_transaction_details | Get full details for a specific transaction | transaction_id |
get_transaction_rules | Get all transaction auto-categorization rules from Monarch Money | None |
get_transaction_splits | Get the splits for a transaction | transaction_id |
get_transaction_tags | Get all available transaction tags from Monarch Money | None |
get_transactions | Get transactions from Monarch Money | limit?, offset?, start_date?, end_date?, account_id?, search?, category_ids?, category_group_ids?, account_ids?, tag_ids?, has_notes?, is_split?, is_recurring?, wide_search?, search_scan_limit? |
get_transactions_needing_review | Get transactions that need review based on various criteria | needs_review?, days?, uncategorized_only?, without_notes_only?, limit?, offset?, account_id? |
get_transactions_summary | Get a high-level summary of transactions | None |
mark_transaction_reviewed | Mark a transaction as reviewed (clears the needs_review flag) | transaction_id |
monarch_login | Sign in via a secure form in the client UI | None |
monarch_login_with_token | Sign in with a browser copied session token | None |
monarch_logout | Clear the stored session and drop the cached client | None |
monarch_whoami | Report who is signed in and what the account's plan entitles it to | None |
refresh_accounts | Request account data refresh from financial institutions | account_ids? |
reorder_transaction_rule | Move a transaction rule to a new position in the evaluation order | rule_id, new_order |
review_recurring_stream | Set the review status of a recurring transaction stream | stream_id, review_status |
search_transactions | Search and filter transactions with comprehensive filtering options | search?, limit?, offset?, start_date?, end_date?, category_ids?, account_ids?, tag_ids?, has_attachments?, has_notes?, hidden_from_reports?, is_split?, is_recurring? |
set_budget_amount | Set or update a budget amount for a category or category group | amount, category_id?, category_group_id?, start_date?, apply_to_future? |
set_business_entity | Set (or clear) the business entity on one transaction | transaction_id, business_entity_id |
set_goal_contribution | Set the budgeted monthly contribution to a goal from one funding account | goal_id, account_id, amount |
set_transaction_tags | Set tags on a transaction | transaction_id, tag_ids |
setup_authentication | Get setup instructions | None |
split_transaction | Split a transaction into multiple parts with different categories/merchants | transaction_id, splits |
update_account | Update an account's name, balance, type or visibility settings | account_id, name?, balance?, account_type?, account_sub_type?, include_in_net_worth?, hide_from_summary_list?, hide_transactions_from_reports?, dry_run? |
update_category | Update an existing category's settings | category_id, name?, icon?, group_id?, category_type?, exclude_from_budget?, budget_variability?, rollover_enabled?, rollover_start_month?, rollover_starting_balance?, rollover_frequency?, rollover_target_amount?, rollover_type?, confirm_rollover_reset?, dry_run? |
update_merchant | Update a merchant's name and/or recurring transaction stream settings | merchant_id, name?, is_recurring?, frequency?, base_date?, amount?, is_active? |
update_savings_goal | Update a savings goal's target or monthly contribution | goal_id, target_amount?, target_date?, name?, priority?, goal_type?, is_sinking_fund? |
update_transaction | Update an existing transaction in Monarch Money | transaction_id, category_id?, merchant_name?, goal_id?, amount?, date?, hide_from_reports?, needs_review?, notes? |
update_transaction_notes | Update the notes/memo for a transaction | transaction_id, notes, receipt_url? |
update_transaction_rule | Update an existing transaction rule | rule_id, merchant_criteria_operator?, merchant_criteria_value?, merchant_criteria_values?, merchant_criteria?, original_statement_operator?, original_statement_values?, original_statement_criteria?, use_original_statement?, amount_operator?, amount_value?, amount_lower?, amount_upper?, amount_is_expense?, set_category_id?, set_merchant_name?, add_tag_ids?, link_goal_id?, hide_from_reports?, review_status?, account_ids?, category_ids?, clear_category?, clear_merchant?, clear_tags?, clear_goal_link?, clear_review_status?, apply_to_existing? |
upload_account_balance_history | Upload corrected balance snapshots for an account | account_id, corrections, dry_run? |
Use get_accounts to show me all my financial accounts
Show me my last 50 transactions using get_transactions with limit 50
get_transactions returns a JSON object with tool, args, count, total_count, truncated, search, and data so large agent-tools/<uuid>.txt responses are self-describing. Transaction rows live in data and include original_statement / plaid_description when Monarch provides the underlying Plaid statement text, plus currency, direction, direction_source, transaction_type, category_group, and category_group_id when those values can be derived from Monarch response data. When Monarch's server-side search errors or returns no rows, wide_search scans recent transactions locally across merchant, original statement, description, notes, category, account, and tags.
Use get_budgets to show my current budget status
Set my grocery budget to $600 for this month using set_budget_amount
Set my entertainment budget to $150 and apply it to all future months using set_budget_amount with apply_to_future=true
Show my net worth trend for the past year using get_net_worth
Show me how my savings account balance has changed over time using get_account_balance_history
Show my net worth breakdown by account type using get_net_worth_by_account_type
Get my cashflow for the last 3 months using get_cashflow
Show me all available categories using get_transaction_categories
Show me transactions from the last 7 days that need review using get_transactions_needing_review
Categorize these three transactions as "Groceries" using bulk_categorize_transactions
Add the "Tax Deductible" tag to this transaction using set_transaction_tags
Find all Amazon transactions from the last month using search_transactions
Show me my upcoming recurring transactions using get_recurring_transactions
Create a rule to automatically categorize Amazon transactions as "Shopping" using create_transaction_rule
Split this $100 Costco transaction into $60 for Groceries and $40 for Household using split_transaction
Give me a quick summary of my transactions using get_transactions_summary
Show my spending breakdown by category for last month using get_spending_summary
Update PennyMac's recurring stream to $1,460.93 monthly using update_merchant
Approve the Netflix recurring stream using review_recurring_stream
YYYY-MM-DD format (e.g., "2024-01-15")If you see "Authentication needed" errors:
cd /path/to/your/monarch-mcp-server && python login_setup.py (or uv run python login_setup.py)get_accountsMonarch may require an email one-time code for a new device or session, even if MFA is not enabled. If you see an email-code prompt:
login_setup.pyIf your session dies quickly (under a couple of hours), the most common cause is that Monarch returned a short-lived token. The login script now requests trusted_device=True and rejects any short-lived token, so a fresh login produces a long-lived session. If you re-run login_setup.py and the issue persists, switch to option 1 (browser cookies); cookie sessions track the lifetime of the underlying browser login.
If login_setup.py reports "Programmatic login is blocked by Cloudflare CAPTCHA", choose option 1 (browser cookies) instead. Email/password POSTs to Monarch's login endpoint are sometimes gated by Cloudflare for unfamiliar IPs or rapid retries; cookie-based auth bypasses that endpoint entirely.
'Context' object has no attribute 'elicit'The monarch_login and monarch_login_with_token tools require the MCP Python SDK 1.10.0 or newer (released June 2025). If your environment cached an older mcp install, refresh it:
uv cache clean mcp
Then fully quit and reopen Claude Desktop or Claude Code so it relaunches the server with a fresh resolution. As a fallback while you upgrade, run python login_setup.py from the repo to authenticate via the terminal.
python login_setup.py (or uv run python login_setup.py)python login_setup.py and complete email verificationget_accounts to see valid account IDsmonarch-mcp-server/
├── src/monarch_mcp_server/
│ ├── __init__.py
│ ├── app.py # FastMCP app instance and entry point
│ ├── client.py # Cached MonarchMoney client factory
│ ├── monarch_auth.py # Current Monarch auth compatibility (host, email OTP, device-uuid)
│ ├── secure_session.py # Keyring-backed token storage (file fallback)
│ ├── server.py # Backward-compatibility shim re-exporting the tools
│ └── tools/ # MCP tools grouped by domain (accounts, transactions, budgets, …)
├── login_setup.py # Terminal authentication script
├── pyproject.toml # Project configuration
├── requirements-lock.txt # Generated from uv.lock, hash pinned
└── README.md # This documentation
device-uuid captured at login is stored alongside the token so it reloads cleanlySet MONARCH_MCP_READ_ONLY=1 in the server's environment and the mutating
tools are never registered. They do not appear in the tool list and cannot be
called at all, which is stronger than an approval prompt: a model that was
talked into a write by a merchant name or memo it read back cannot invoke a
tool that is not there.
{
"mcpServers": {
"Monarch Money": {
"command": "/opt/homebrew/bin/uv",
"args": ["run", "--project", "/path/to/your/monarch-mcp-server", "monarch-mcp-server"],
"env": { "MONARCH_MCP_READ_ONLY": "1" }
}
}
}
This leaves 30 of the 58 tools available, covering everything that reads.
Read only is off by default outside Docker, so existing setups are unaffected;
the Docker image turns it on (see Start the HTTP server). Note that it
also removes the login and logout tools, since those change durable state, so
authenticate with login_setup.py before enabling it.
These tools mutate your Monarch data. The list is every registered tool that writes, checked against the source rather than maintained by hand:
Accounts: update_account
Transactions: create_transaction, update_transaction, delete_transaction, categorize_transaction, update_transaction_notes, mark_transaction_reviewed, bulk_categorize_transactions, bulk_update_transactions, split_transaction, set_business_entity, upload_account_balance_history
Tags: set_transaction_tags, add_transaction_tag, create_transaction_tag
Rules: create_transaction_rule, update_transaction_rule, delete_transaction_rule, reorder_transaction_rule
Categories and budgets: create_transaction_category, update_category, set_budget_amount
Goals: update_savings_goal, set_goal_contribution
Merchants: update_merchant, review_recurring_stream
Session: monarch_login, monarch_login_with_token, monarch_logout
refresh_accounts is side effecting too, since it posts a refresh request to your institutions, though it does not change your ledger.
Because the LLM can be influenced by data it reads back (a malicious-looking memo or merchant name in a transaction), the safest setup is to configure your MCP client to require manual approval before any mutating tool runs. In Claude Desktop and Claude Code this is the default behavior for unknown tools; keep it that way for the tools listed above rather than allow-listing them.
bulk_categorize_transactions, bulk_update_transactions, upload_account_balance_history, update_account and update_category accept a dry_run=True argument that returns the planned changes without executing them, useful for previewing before approving.
update_category additionally requires confirm_rollover_reset=True before rollover_start_month or rollover_starting_balance will be applied. Those two restart a category's rollover period and discard the balance accumulated in it, which cannot be undone, so they cannot ride along unnoticed in a call that otherwise reads like a rename.
This MCP server is built on top of the MonarchMoneyCommunity Python library, an actively maintained community fork of the original MonarchMoney library by @hammem. The community fork provides:
Thank you to @hammem for creating and maintaining this essential library!
MIT License
For issues:
check_auth_statuscd /path/to/your/monarch-mcp-server && python login_setup.pyTo update the server:
python login_setup.py
koala73/worldmonitor88kLive markets, conflicts, country risk, chokepoints, energy, and China decision signals. 90 tools.
AI 与智能体

ahujasid/mcp-for-blender30kCommunity plugin to control Blender 3D with any LLM of your choice. Not affiliated with the official Blender Foundation.
AI 与智能体

oraios/serena30kA powerful MCP toolkit for coding, providing semantic retrieval and editing capabilities - the IDE for your agent
AI 与智能体

agentskills/agentskills26kSearch and discover Agent Skills from the skills.sh registry. Powered by HAPI MCP server.
AI 与智能体

activepieces/activepieces25kAI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents
AI 与智能体

czlonkowski/n8n-mcp23kA MCP for Claude Desktop / Claude Code / Windsurf / Cursor to build n8n workflows for you
AI 与智能体