monarch-mcp-ui

monarch-mcp-ui

Interactive UI for Monarch Money inside claude.ai, running on Monarch's official OAuth. Provides interactive widgets for transactions, spending, and accounts with inline editing and broad data-tool coverage.

Category
访问服务器

README

monarch-mcp-ui

Interactive UI for Monarch Money inside claude.ai, running on Monarch's official OAuth.

monarch-mcp-ui is a small Cloudflare Worker that sits in front of Monarch's official MCP server and adds an interactive UI layer. The protocol supports this now (MCP Apps / SEP-1865, the standard Anthropic and OpenAI co-published in late 2025), but no Monarch server ships it. You connect the Worker in claude.ai, log into your own Monarch account on Monarch's consent screen, and read and edit your finances in widgets, not plain text.

<p align="center"> <img src="assets/transactions-in-claude.png" width="840" alt="The transactions widget rendered inline in a claude.ai chat, with the inline category picker open on a transaction."> <br> <em>Ask in plain English. The table renders inline, and you recategorize a transaction without leaving the chat.</em> </p>

Three widgets render inline:

  • Transactions: a filterable, sortable, paginated table with inline category editing. The dropdown writes back to Monarch and reverts if the write is rejected.
  • Spending: spending-by-category bars you click to drill into the underlying transactions.
  • Accounts & net worth: accounts grouped by type, with balances and total net worth.

Plus broad data-tool coverage (cash flow, budgets, recurring, investments, goals, rules, bulk recategorize, and a one-call financial overview) so the model can reason over the rest of your Monarch data, not just what the widgets show.

Try it live (no clone, about a minute)

A hosted instance is running. In claude.ai go to Settings → Connectors → Add custom connector and paste:

https://monarch-mcp-apps.joshuasilets.workers.dev/mcp

Approve, and you'll be sent to Monarch's own login and consent screen. Back in a chat, ask "show my recent transactions." The interactive table renders inline. Change a category from the dropdown and it persists to your Monarch account.

It is multi-tenant: you log into your own Monarch account, your data is isolated from every other user, your tokens are encrypted at rest, and you can revoke access anytime from your Monarch account settings or by removing the connector in claude.ai. To run your own, see Self-host below.

What's different

Two things make it different from the other ways to use Monarch from an MCP client.

1. Official OAuth, brokered so anyone can connect their own account. The Worker acts as an OAuth client to Monarch's official MCP. Each person who connects logs in on Monarch's consent screen, against their own account. No passwords touch the server, each user's Monarch tokens are encrypted separately, and access is revocable from Monarch.

2. The interactive UI layer. Monarch's official MCP and the community servers return text or JSON. This one publishes ui:// MCP Apps resources, so claude.ai renders widgets: a table you edit inline, a dashboard you drill into, an accounts and net-worth view. I believe it's the first Monarch MCP with an interactive UI. If there's another, I'd like to see it.

Monarch's official MCP Community MCPs monarch-mcp-ui
Interactive widgets in claude.ai No No Yes (MCP Apps)
Auth to Monarch Official OAuth 2.1 + PKCE Your Monarch credentials, locally Official OAuth 2.1 (DCR + PKCE)
Each user connects their own account Yes Personal / single-user Yes, multi-tenant
Self-host, extend, add your own UI No (closed) Yes Yes

Under the hood the Worker plays two OAuth roles at once: provider to claude.ai, client to Monarch. The widgets use the official @modelcontextprotocol/ext-apps SDK and inherit claude.ai's design tokens (colors, type scale, light and dark), so they match the host's look.

Prior art and credit

This builds on a lot of community work. The unofficial monarchmoney library and the MCP servers built on it (robcerda, jamiew, and others) are what made Monarch programmable for most people. They are a great fit for personal, single-user setups where you run the tool against your own credentials on your own machine. monarch-mcp-ui does two things the community servers don't: official-OAuth multi-tenant access and an interactive UI.

Architecture

claude.ai ──OAuth(provider)──► Worker ──OAuth(client, upstream)──► Monarch OAuth (DCR + PKCE)
   │ Streamable HTTP /mcp        ├─ MonarchMcpAgent (Durable Object)
   │                             ├─ tools/call passthrough ─► api.monarch.com/mcp
   ▼                             └─ ui:// widget (embedded single-file build)
 renders the widget  ◄── ui/notifications/tool-result ──┘
   │ recategorize dropdown → app.callServerTool('recategorize_transaction') → UpdateTransaction

The Worker is an OAuth provider to claude.ai and an OAuth client to Monarch. Per-user Monarch tokens are AES-GCM encrypted in KV (keyed by an opaque userKey); only that key rides in the token issued to claude.ai, so a session can resolve its own Monarch tokens and nothing else. See spike/FINDINGS.md for the Phase 0 evidence the design rests on (the OAuth metadata, the verified write path, and the actual tool-result shapes).

Layout

Path What
src/index.ts OAuthProvider wiring (entrypoint)
src/auth/monarch-handler.ts /authorize + /callback broker (claude.ai to Monarch)
src/auth/{crypto,token-store}.ts AES-GCM + encrypted per-user token store
src/monarch/oauth.ts DCR / PKCE / authorize / token / refresh (TS port of the spike)
src/monarch/upstream-client.ts tools/call passthrough to Monarch /mcp (SSE or JSON)
src/mcp/tools.ts / tools-data.ts widget-backed tools / broad data-tool coverage
src/mcp/{agent,ui-resource,reshape}.ts MCP agent, ui:// resources (one URI per widget), result reshaping
widget/ React widgets, one bundle that routes by view (table / spending / accounts), built single-file and embedded
spike/ Phase 0 de-risk scripts + FINDINGS.md (captured personal data is gitignored)

Tools

Widget-backed (render an interactive UI):

  • list_transactions: filterable, sortable, paginated table with inline recategorize
  • spending_dashboard: spending-by-category bars, click to drill into transactions
  • accounts_overview: accounts grouped by type, plus net worth

Reads: get_accounts, get_net_worth_history, get_cashflow, get_spending_by_category, get_budget, get_recurring, get_investments, get_goals, list_rules, list_categories, financial_overview (one-call snapshot)

Writes: recategorize_transaction, bulk_recategorize_transactions

All proxy Monarch's official MCP with the connected user's OAuth token.

Self-host

To run your own instance instead of the hosted one, you need Node 20+ and a Cloudflare account.

npm install
npm --prefix widget install

# 1. KV namespace: paste the printed id into wrangler.jsonc (OAUTH_KV.id)
npx wrangler kv namespace create OAUTH_KV

# 2. Encryption key (32-byte base64) for tokens at rest
openssl rand -base64 32 | npx wrangler secret put ENCRYPTION_KEY

# 3. Build the widget and deploy
npm run deploy

Then in claude.ai: Settings → Connectors → Add custom connectorhttps://<your-worker>.workers.dev/mcp. Approve, get bounced to Monarch's login and consent (it asks for read and write), and back in chat try "show my recent transactions."

Local dev

npm run dev   # builds the widget, runs `wrangler dev` (localhost:8787)

For the fastest UI loop, run the widget alone with mock data and no Worker:

npm --prefix widget run dev   # http://localhost:5174/?view=transactions|spending|accounts

How it works

The widget is built with vite-plugin-singlefile into one self-contained HTML string and embedded in the Worker bundle, because Workers can't read files at runtime. The host loads it as a ui:// resource; inside the sandboxed iframe it speaks to claude.ai with the official @modelcontextprotocol/ext-apps SDK. The tool's structuredContent arrives via app.ontoolresult, and the recategorize dropdown calls back with app.callServerTool.

Two non-obvious problems I hit, with fixes in the git history:

  • Distinct ui:// URI per widget. Hosts key widget instances by resourceUri. Pointing all three tools at one shared URI made claude.ai reuse a single iframe, so the accounts tool rendered the spending view. Each widget now has its own URI, and each iframe is told its view so a cold re-mount fetches the right data.
  • A JS number-precision bug in Monarch's data. GetSpendingByCategory returns category_id as an 18-digit JSON number that exceeds Number.MAX_SAFE_INTEGER, so JSON.parse silently rounds it and the wrong icons and drill-downs showed up. The fix resolves the correct string id by category name against GetCategories, whose ids are strings.

Status and roadmap

v0.1, with a working hosted demo. Solid today: the official-OAuth broker, per-user encrypted tokens, 16 tools, three widgets with inline write-back, and host theming. On the list:

  • A disconnect tool (Monarch exposes /oauth/revoke/).
  • More widgets: budgets, cash flow over time, recurring.
  • A shared widget design system so every view uses the same components and host tokens.

Safety and disclaimer

  • Not affiliated with or endorsed by Monarch Money. This is an independent project.
  • Official endpoints only. Auth goes through Monarch's own OAuth (api.monarch.com, OAuth 2.1 + PKCE) and its official MCP. No scraped cookies, no stored passwords. You log in on Monarch's own screen and can revoke anytime.
  • Your data is yours. Per-user Monarch tokens are AES-GCM encrypted in KV and isolated per connection. Nothing is logged or shared.
  • Writes are optimistic and reversible in the UI. A recategorize updates the row immediately and reverts if Monarch rejects it.
  • Monarch caps integrations at 5 writes per day on the standard plan (shown in Monarch's own Integrations settings; Monarch Plus removes the cap, and other fair-use limits may apply). Recategorizations count against it, which is why bulk_recategorize_transactions takes a dry_run to preview how many rows would change before you spend writes.

A note to the Monarch team

Your official MCP is clean and well-built, and OAuth 2.1 + PKCE from day one is what made this broker possible. I built monarch-mcp-ui to show what an interactive UI layer on top of it can feel like, entirely on your own endpoints. MCP Apps is new, and a product with this much structured data (transactions, budgets, accounts) is a natural fit for native widgets. If you're thinking about shipping MCP Apps natively, please feel free to take inspo from this repo / reach out.

License

MIT. See LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选