lunchmoney-readonly-mcp
A read-only MCP server for Lunch Money that provides secure, retrieval-only access to financial data through ChatGPT Business, with OAuth authentication and enforced read-only restrictions.
README
Read-only Lunch Money MCP for ChatGPT
A single-user remote MCP server for Lunch Money, designed for ChatGPT Business and deployed on Cloudflare Workers. It uses Google OAuth only to identify an allowlisted user; the Lunch Money API token is stored as a Cloudflare encrypted secret and is never returned to ChatGPT or an MCP tool.
This project was originally based on the bm1549/lunchmoney-mcp-cloudflare project and has been adapted into a read-only Lunch Money MCP template for Cloudflare Workers and ChatGPT. The bundled upstream implementation is retained under vendor-lunchmoney-mcp, including its original MIT license and attribution. Thanks to Brian Marks for the original work.
This repository is a template. It contains no live deployment URL, API token, Google OAuth secret, email address, or Cloudflare resource ID.
What makes it read-only
The server enforces read-only access in two independent layers:
createReadonlyServer()exposes a positive allowlist of 25 retrieval tools. Create, update, delete, upload, sync, refresh, split, grouping, and budget mutation tools are not registered.runWithReadonlyConfig()rejects any non-GETrequest to the Lunch Money API before a network request is made.
All exposed tools declare readOnlyHint: true, destructiveHint: false, and
openWorldHint: false.
Requirements
- A Lunch Money API token
- A Cloudflare account with Workers and KV available
- A Google Cloud OAuth 2.0 web client
- A ChatGPT Business workspace where you are an admin or owner
Deploy your own copy
-
Clone this repository, then install and verify dependencies:
npm install npm run typecheck npm run lint npm run test:readonly -
In
wrangler.jsonc, choose a unique Workernameand create the OAuth KV namespace:npx wrangler kv namespace create OAUTH_KVCopy the returned namespace ID into
REPLACE_WITH_OAUTH_KV_NAMESPACE_IDinwrangler.jsonc. -
Deploy once to obtain your Worker URL:
npx wrangler deploy -
Create a Google OAuth 2.0 Web application. Add this redirect URI, replacing the host with your Worker URL:
https://YOUR-WORKER.YOUR-SUBDOMAIN.workers.dev/authorize/callback -
Set the production secrets interactively. Never put their values in Git:
npx wrangler secret put GOOGLE_CLIENT_ID npx wrangler secret put GOOGLE_CLIENT_SECRET npx wrangler secret put ALLOWED_EMAILS npx wrangler secret put STATE_SECRET npx wrangler secret put LUNCHMONEY_API_TOKENALLOWED_EMAILSis a comma-separated list of Google accounts allowed to connect. The server fails closed when this is empty. -
Deploy again. Your MCP endpoint is:
https://YOUR-WORKER.YOUR-SUBDOMAIN.workers.dev/mcp
Connect ChatGPT Business
- In ChatGPT, open Workspace settings → Apps → Create.
- Enter the
/mcpendpoint above and choose OAuth authentication. - Review the custom-app warning, create the draft, then publish and enable it.
- Each user connects from Settings → Plugins → [your app] → Connect and signs in with an allowlisted Google account.
- Start a fresh Work chat, select the app, and verify the tool list before asking it to inspect Lunch Money data.
Before making the repository public
Run:
npm run check:public-release
Also review git status, confirm .dev.vars is untracked, and ensure the
Worker name, endpoint, Cloudflare resource IDs, and example documentation do
not identify your personal deployment.
If you are sanitizing an existing deployment, keep its configuration outside
the repository or in a gitignored wrangler.personal.jsonc file. Deploy that
private configuration with npx wrangler deploy --config wrangler.personal.jsonc.
Verification
The focused security test verifies the exact allowlist, its annotations, the absence of representative mutation tools, and rejection of outbound POST requests:
npm run test:readonly
See THIRD_PARTY_NOTICES.md for attribution details.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.