wallet-watch-mcp

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.

Category
Visit Server

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:

  1. Transport Type: Streamable HTTP
  2. URL: http://localhost:8000/mcp
  3. Connect → open ToolsList Tools → all eight should appear.
  4. Run get_spend_summary (no args) → expect real JSON from your backend.
  5. Try snooze_or_downgrade with id=1, action="snooze", then list_subscriptions to confirm the status changed.
  6. 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 in config.py doesn't match your backend. An AttributeError for a missing config attribute means a path constant is missing from config.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-summary
  • GET /subscriptions/unused?days=
  • GET /subscriptions/price-changes?sinceDays=
  • GET /subscriptions/forecast?months=
  • PATCH /subscriptions/{id}/status
  • PATCH /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, required tier on downgrade) before calling the backend.
  • find_duplicate_services reasons 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; stdio via 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

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.

Official
Featured
TypeScript
Magic Component Platform (MCP)

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.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

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.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

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.

Official
Featured
TypeScript
Kagi MCP Server

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.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

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.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured