Lunchmoney Server Oauth
БесплатноНе проверенSelf-hostable remote MCP server for Lunch Money with built-in OAuth 2.1, enabling Claude to access transactions, budgets, and more on mobile, web, and desktop.
Описание
Self-hostable remote MCP server for Lunch Money with built-in OAuth 2.1, enabling Claude to access transactions, budgets, and more on mobile, web, and desktop.
README
Latest release Build Container image License: MIT PRs welcome
Self-hostable remote MCP server for Lunch Money with a built-in OAuth 2.1 authorization server — so it works as a claude.ai custom connector on Claude mobile, web, and desktop, as well as Claude Code and any other Streamable-HTTP MCP client.
Wraps @akutishevsky/lunchmoney-mcp (40+ tools covering transactions, budgets, categories, recurring items, assets, crypto, tags) and serves it over HTTP.
Why this exists
If you want Claude on your phone to see your Lunch Money data, your options were all bad:
| Option | Problem |
|---|---|
| stdio MCP servers (most community servers) | Local-only; Claude mobile can't use them |
| HTTP server + static bearer token | claude.ai custom connectors have no field for a static header — OAuth is the only supported auth (anthropics/claude-ai-mcp#112) |
| Hosted MCP platforms | You hand a third party your Lunch Money API token — full read/write access to your finances |
| No auth | Your finances, public |
This server closes the gap: it implements the minimal OAuth 2.1 surface Claude needs (RFC 8414 + RFC 9728 discovery, RFC 7591 dynamic client registration, authorization-code grant with mandatory S256 PKCE, rotating refresh tokens), with a single shared secret as the consent "login". Your API token never leaves your box.
How it works
- You add
https://lm.example.com/mcpas a custom connector in Claude. - Claude discovers the OAuth metadata, registers itself as a client, and opens a browser to the consent page.
- You paste your
MCP_AUTH_TOKEN(a secret you generated) once. - Claude receives access + refresh tokens and keeps them fresh on its own, across all your Claude surfaces.
Stateless by design: every artifact the server issues — client IDs,
authorization codes, access and refresh tokens — is an HMAC-signed blob
keyed off MCP_AUTH_TOKEN via HKDF. There is no database and no session
store, which means:
- container restarts don't log Claude out
- the container runs with a read-only filesystem
- rotating
MCP_AUTH_TOKENinstantly revokes every client and token — that's your kill switch
| Artifact | Lifetime |
|---|---|
| authorization code | 2 min, single-use |
| access token | 1 hour |
| refresh token | 90 days, rotated on every refresh |
Quick start
# 1. Secrets
cp docker-compose.example.yml docker-compose.yml
cat > .env <<EOF
LUNCHMONEY_API_TOKEN=<lunchmoney.app -> Settings -> Developers>
LUNCHMONEY_MCP_TOKEN=$(openssl rand -base64 48)
EOF
# 2. Set BASE_URL in docker-compose.yml to your public https URL, then:
docker compose up -d
# 3. Put a TLS reverse proxy in front (see below), then add the connector
# in Claude: Settings -> Connectors -> Add custom connector ->
# https://lm.example.com/mcp
The image is multi-arch (amd64/arm64), built on Google's distroless Node 22
(no shell, no package manager, runs as non-root uid 65532), published by
CI from this repo:
ghcr.io/squixx/lunchmoney-mcp.
Reverse proxy requirements
The server speaks plain HTTP and must sit behind a TLS-terminating reverse proxy. Recommendations:
- Forward only what's needed:
/mcp,/authorize,/consent,/token,/register,/.well-known/oauth-authorization-server*,/.well-known/oauth-protected-resource*. 404 everything else at the edge. - Rate-limit the auth endpoints hard (e.g. 20 req/min per IP on
/register,/authorize,/consent,/token) and/mcploosely (Claude bursts several tool calls per turn — 20 req/s is comfortable). - Don't strip or rewrite the
Authorizationheader.
Caddy example
lm.example.com {
@allowed path /mcp /authorize /consent /token /register /.well-known/oauth-authorization-server* /.well-known/oauth-protected-resource*
handle @allowed {
reverse_proxy lunchmoney-mcp:3000
}
respond "Not Found" 404
}
(Add rate limiting with your module of choice, e.g. mholt/caddy-ratelimit.)
Environment
| Variable | Required | Default | Notes |
|---|---|---|---|
LUNCHMONEY_API_TOKEN |
yes | — | From Lunch Money → Settings → Developers |
MCP_AUTH_TOKEN |
yes | — | OAuth consent password and HKDF seed for the token-signing key. Min 32 chars; use openssl rand -base64 48 |
BASE_URL |
yes | — | Public URL the OAuth issuer advertises |
PORT |
no | 3000 |
Listen port |
The process exits non-zero at startup if anything required is missing.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET |
/healthz |
Liveness (unauthenticated, reveals nothing) |
GET |
/.well-known/oauth-authorization-server[/mcp] |
RFC 8414 metadata |
GET |
/.well-known/oauth-protected-resource[/mcp] |
RFC 9728 metadata |
POST |
/register |
RFC 7591 dynamic client registration |
GET |
/authorize |
Consent form |
POST |
/consent |
Password check → authorization code |
POST |
/token |
Code exchange (PKCE) + refresh grant |
POST |
/mcp |
MCP JSON-RPC (stateless Streamable HTTP, Bearer auth) |
Security model & limitations
Honest list — read before exposing your finances to the internet:
- Single-user, single-secret. Anyone with
MCP_AUTH_TOKENgets full read/write access to your Lunch Money account. There are no scopes, no per-client permissions, no user accounts. This is a personal server. - Open dynamic client registration is intentional and spec-conformant: registering grants nothing; only the consent password turns a client into an authorized one, and client IDs are self-signed blobs (nothing is stored, so registration spam costs nothing).
- PKCE S256 is mandatory; redirect URIs must match registration exactly
and be
https(or loopbackhttpfor local dev tools). - Consent password comparison is constant-time, with a 750 ms delay on failure — but your real brute-force defense is the secret's entropy (256+ bits) plus edge rate limiting.
- Authorization codes are replay-guarded in memory only: a container restart inside a code's 2-minute lifetime would allow one replay. Accepted for a single-user server behind TLS.
- The Lunch Money API token sits in the container's environment. Anyone with Docker host access owns your data anyway.
- MCP prompt-injection caveat: any tool-using LLM can be manipulated by data it reads. Transaction payees/notes are attacker-influenceable strings (anyone who sends you a payment names the payee). Claude processes those through the same context that can call write tools. Consider Lunch Money's data sensitivity before enabling write-heavy workflows.
Versioning & releases
Semver, independent of the upstream tools package (encoding the upstream
version in the tag breaks semver tooling — 2.1.0-1 sorts before 2.1.0
as a prerelease, and four segments aren't semver at all):
| Bump | When |
|---|---|
| major | Breaking wrapper contract: env var renames, endpoint changes, token-format changes that force reconfiguration |
| minor | @akutishevsky/lunchmoney-mcp upgrade (the tool surface Claude sees changed), or new wrapper features |
| patch | Wrapper fixes and other dependency bumps |
Mechanics:
- The image tag is the
package.jsonversion; CI publishes it and creates a matching git tag + GitHub Release on the first build of each version. - Renovate PRs bump the version automatically in the same PR
(
bumpVersioninrenovate.json), so every dependency change publishes a new tag that downstream version pins can track. - CI rejects PRs that change image contents without a version bump.
- The upstream tools version an image carries is exposed as the OCI label
app.lunchmoney-mcp.upstream-versionand stated in each release's notes. - The weekly scheduled rebuild republishes the same version with fresh base layers (distroless/Alpine security patches) — pull to refresh; no release is created.
Development
corepack enable
pnpm install --frozen-lockfile
pnpm test # boots a throwaway server, runs the full OAuth dance
# + authenticated MCP initialize/tools/list (no Lunch
# Money API calls)
LUNCHMONEY_API_TOKEN=<token> MCP_AUTH_TOKEN=$(openssl rand -base64 48) \
BASE_URL=http://localhost:3000 pnpm start
Supply-chain posture: committed lockfile + --frozen-lockfile everywhere,
pnpm minimumReleaseAge: 1440 (24 h cool-off on new releases), dependency
install scripts disabled, Corepack strict pinning (pnpm pinned by sha512),
pnpm audit gating CI, weekly image rebuilds for base-image patches.
Contributing
Contributions are welcome — issues and pull requests both. This is a small, single-purpose project, so the bar is just: keep it self-contained, keep the security posture, and keep it honest about its limitations.
- Found a bug or have an idea? Open an issue.
- Sending a PR? Run
pnpm testfirst — it drives the full OAuth flow plus an authenticated MCP round-trip and must pass. CI runs the same checks (pnpm audit, smoke test, multi-arch build) on every PR. - Dependency and image bumps are handled by Renovate; you don't need to touch versions by hand (see Versioning & releases).
See CONTRIBUTING.md for the short version of the workflow.
Credits
- @akutishevsky/lunchmoney-mcp — the actual MCP tool implementations this wraps
- Lunch Money — and its developer API
License
MIT © Squixx. Not affiliated with or endorsed by Lunch Money.
Установка Lunchmoney Server Oauth
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/Squixx/lunchmoney-mcp-server-oauthFAQ
Lunchmoney Server Oauth MCP бесплатный?
Да, Lunchmoney Server Oauth MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Lunchmoney Server Oauth?
Нет, Lunchmoney Server Oauth работает без API-ключей и переменных окружения.
Lunchmoney Server Oauth — hosted или self-hosted?
Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.
Как установить Lunchmoney Server Oauth в Claude Desktop, Claude Code или Cursor?
Открой Lunchmoney Server Oauth на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Fetch
Web content fetching and conversion for efficient LLM usage.
AWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
автор: modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
автор: xuzexin-hzCompare Lunchmoney Server Oauth with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории ai
