wallet-watch-mcp
MCP server that exposes the wallet-watch subscription-tracking REST API as tools for AI assistants, enabling natural language management of subscriptions including listing, renewal forecasts, spend summaries, and actions like snoozing or downgrading.
README
wallet-watch-mcp
An MCP server that exposes the wallet-watch subscription-tracking REST API (a Spring Boot service) as tools an AI model can call.
Ask an assistant "what's renewing this week?", "where am I wasting money?", or "did anything get more expensive lately?" and it calls these tools against your wallet-watch backend — reading, reasoning over, and acting on your subscriptions.
What it does
Exposes the wallet-watch subscription API as tools an AI assistant can call, so you can manage subscriptions in plain language. Through it, an assistant can:
- List your subscriptions and filter them by category.
- Tell you what's renewing soon and forecast spend for the months ahead.
- Summarize monthly spend by category.
- Surface unused subscriptions and overlapping (duplicate) services.
- Report subscriptions whose price recently went up.
- Snooze, resume, or downgrade a subscription on your behalf.
It talks to the wallet-watch backend over HTTP, so that service (or your own API at the same routes) needs to be running.
Files
Three files of code — everything configurable lives in config.py.
wallet-watch-mcp/
├── config.py ← ALL config: connection settings + endpoint paths
├── client.py ← HTTP helpers (get_json / patch_json): auth, timeout, errors
├── server.py ← the MCP server + the tools
├── requirements.txt
├── .env.example
├── Dockerfile
├── docker-compose.yml
└── .gitignore
Tools
Read
| Tool | What it does |
|---|---|
list_subscriptions(category?) |
All subscriptions, optionally filtered by category. |
get_upcoming_renewals(days=30) |
Renewing within N days, soonest first. |
get_spend_summary() |
Total monthly spend + per-category breakdown. |
find_unused_subscriptions(days=30) |
Unused subscriptions + potential savings. |
find_duplicate_services() |
Overlapping subscriptions in the same category. |
forecast_spend(months=6) |
Month-by-month spend forecast (annual bills as lumps). |
get_recent_price_increases(since_days=90) |
Subscriptions whose price went up. |
Act
| Tool | What it does |
|---|---|
snooze_or_downgrade(id, action, tier?) |
Pause, resume, or downgrade a subscription. |
Every tool returns clean JSON and degrades gracefully: if the backend is down, it
returns {"error": true, "message": "..."} instead of crashing.
Run it (local)
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # then set WALLET_WATCH_BASE_URL
python server.py
Serves at http://localhost:8000/mcp (streamable HTTP transport). Make sure the
wallet-watch backend is running (default http://localhost:8080).
Test it with the MCP Inspector
The MCP Inspector lists the tools and lets you call them by hand — no AI client needed.
npx @modelcontextprotocol/inspector
It opens a UI at http://localhost:6274 (if the terminal prints a URL with a session
token, open that one — you don't need to copy the token manually). Then:
- Transport Type:
Streamable HTTP - URL:
http://localhost:8000/mcp - Connect → open Tools → List Tools → all eight should appear.
- Run
get_spend_summary(no args) → expect real JSON from your backend. - Try
snooze_or_downgradewithid=1, action="snooze", thenlist_subscriptionsto confirm the status changed. - Stop the backend and re-run any tool → you get a graceful
{"error": true, ...}.
Troubleshooting: a 404 on connect usually means the URL needs
/mcp(try a trailing slash too). A"...returned HTTP 404"inside a tool result means the connection is fine but an endpoint path inconfig.pydoesn't match your backend. AnAttributeErrorfor a missing config attribute means a path constant is missing fromconfig.py— add it there.
Connect a real AI client
Point an HTTP MCP client at the URL. In Claude Desktop's config:
{
"mcpServers": {
"wallet-watch": { "url": "http://localhost:8000/mcp" }
}
}
Restart the client, then ask: "What am I paying for?", "What renews this week?", "Where am I wasting money?", "Snooze my gym membership."
Run both services together
docker compose up
Set the api service in docker-compose.yml to your wallet-watch image or build:
path first. The MCP container reaches the API at http://api:8080.
Config reference
| Variable | Default | Purpose |
|---|---|---|
WALLET_WATCH_BASE_URL |
http://localhost:8080 |
Base URL of the wallet-watch API. |
WALLET_WATCH_API_KEY |
(none) | Optional bearer token. |
WALLET_WATCH_TIMEOUT |
10 |
Per-request timeout (seconds). |
MCP_SERVER_NAME |
wallet-watch-mcp |
Server identity. |
MCP_TRANSPORT |
streamable-http |
Use stdio for local desktop clients. |
Backend endpoints used
All defined in config.py — remap there if your backend differs.
GET /subscriptions?category=GET /subscriptions/upcoming?days=GET /subscriptions/spend-summaryGET /subscriptions/unused?days=GET /subscriptions/price-changes?sinceDays=GET /subscriptions/forecast?months=PATCH /subscriptions/{id}/statusPATCH /subscriptions/{id}/plan
find_duplicate_services needs no dedicated endpoint — it reasons over
GET /subscriptions.
Requirements
Functional
- Expose subscription reads as MCP tools: list/filter, upcoming renewals, spend summary, unused, duplicates, forecast, recent price increases.
- Expose a write/action tool to snooze, resume, or downgrade a subscription.
- Each tool returns clean, structured JSON — not raw passthrough or verbose text.
- Each tool carries a clear docstring describing when to use it (this is what the model reads to decide).
- Validate arguments (e.g. positive
days/months, requiredtieron downgrade) before calling the backend. find_duplicate_servicesreasons over existing subscription data without a dedicated backend endpoint.
Non-functional
- Graceful degradation: if the backend is unreachable, times out, errors, or returns non-JSON, tools return
{"error": true, "message": "..."}— never crash the server. - Single configuration point: all connection settings and endpoint paths live in
config.py. - Small and readable: three code files; logic easy to follow top-to-bottom.
- Transport-flexible: streamable HTTP by default;
stdiovia config for local desktop clients. - Portable: points at any wallet-watch deployment (local, Docker, remote) via one env var.
Design decisions
All configuration in one place. Connection settings and endpoint paths live in
config.py and nowhere else, so pointing at a different backend or remapping a route is
a single-file change.
One HTTP helper, centralized error handling. Every request goes through get_json /
patch_json in client.py, which own auth headers, timeout, and translating any failure
into a readable BackendError. Tools never touch transport concerns and never crash on a
dead backend — they return a structured error object instead.
Docstrings are the interface. Each tool leads with what it's for in plain language, because that text is what the model reads to decide when to call it. Clear descriptions matter more here than in ordinary code.
Structured JSON, shaped for a model. Tools return tidy dicts and do light work the model shouldn't — sorting renewals by urgency, summing potential savings, grouping duplicates — rather than passing raw backend output straight through.
Reads and actions, not just reads. The server includes a write tool
(snooze_or_downgrade) so an assistant can act, not only report — with argument
validation and a returned updated state to confirm the change.
Scheduling/notifying is out of scope — by design. MCP is request/response; it has no
background loop. Proactive notifications (e.g. price-increase alerts) belong in the
backend as a scheduled job that shares the same detection logic. The MCP server exposes
the reactive view (get_recent_price_increases) only.
License
MIT
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.
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.
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.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
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.
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.
E2B
Using MCP to run code via e2b.
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.