SubTrack
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@SubTrackWhat's my total monthly subscription spend?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
SubTrack — Subscription & Recurring Bill Tracker (MCP Server)
The problem it solves: almost everyone is quietly bleeding money from subscriptions and recurring bills they forgot about — a streaming trial that converted to paid, a gym membership, a yearly domain renewal that hits once and gets forgotten for 11 months. SubTrack lets an LLM (Claude, or any MCP client) track all of it, tell you what's renewing soon, and show you total spend normalized to a monthly figure — even though your subscriptions bill weekly, monthly, quarterly, yearly, or on a custom cycle.
What it does
Tool | Purpose |
| Add a subscription/bill with any billing cycle |
| Fetch one, with computed next renewal date |
| List all (or filter by category), soonest renewal first |
| Update any field on an existing entry |
| Soft-delete (marks inactive, keeps history) |
| Hard delete |
| "What's renewing in the next N days?" |
| Total recurring spend, normalized to monthly/yearly, by category |
Plus a subtrack://categories resource (editable category list) and a
renewal_digest_prompt prompt template that asks the assistant to write a
friendly summary of what's coming up.
The interesting engineering bit is next_renewal_date(): it correctly steps
forward day-based cycles (weekly/biweekly/custom) with modular arithmetic,
and calendar-based cycles (monthly/quarterly/yearly) by adding real calendar
months (so a subscription that started Jan 31st correctly lands on Feb 28th,
not "31 days later").
Related MCP server: subscription-tracker-mcp
Why the tools are async def
Every tool here is async def, and all SQLite access goes through
aiosqlite instead of the stdlib sqlite3. Worth understanding why,
since it's a common point of confusion:
FastMCP already runs plain
deftools in a thread pool by default, so a sync version of this server wouldn't literally freeze under light load.But
async def+ a blocking driver (sqlite3) inside it is worse than staying sync — FastMCP doesn't thread-offloadasync deftools (they run directly on the event loop), so a blocking call inside one would stall every other concurrent request.So: either keep tools
defand let the framework thread-offload them, or goasync defand use a genuinely async driver all the way down. This server does the latter, which is the more scalable pattern for a remote server that may see concurrent tool calls from multiple clients — it doesn't consume a worker thread per in-flight DB call, and it composes cleanly if you add other awaitable I/O later (HTTP calls, etc).The one exception: the tiny
categories.jsonread stays plain sync. It's a few hundred bytes read once per call — making it "async" would mean addingaiofilesfor no real concurrency benefit.
Project structure
subtrack-mcp/
├── server.py # the whole server — module-level `mcp` object
├── pyproject.toml # project metadata + deps (managed by uv)
├── uv.lock # locked, reproducible dependency versions
├── .python-version # pins the Python version uv uses
├── .gitignore
└── README.mdcategories.json and subscriptions.db are not committed — server.py
creates them automatically on first run (see init_categories() /
init_db()). If you want your own fixed category list to survive redeploys,
remove categories.json from .gitignore and commit your edited version.
Run it locally (uv)
No manual venv step needed — uv run creates and syncs .venv from
uv.lock automatically the first time you use it.
The __main__ block in server.py runs the server over HTTP on
0.0.0.0:8000 by default (override with the PORT env var) — the same
transport FastMCP Cloud uses in production, so local testing matches
what you'll actually deploy:
uv run server.py
# Starting MCP server 'SubTrack' with transport 'http' on http://0.0.0.0:8000/mcpNote: this block only runs when you execute the file directly. FastMCP
Cloud ignores it entirely — it imports the mcp object and serves it
itself, so nothing here affects the deployed server.
Test it with a quick client script (uv run python client_test.py):
import asyncio
from fastmcp import Client
async def main():
async with Client("http://127.0.0.1:8000/mcp") as client:
result = await client.call_tool("add_subscription", {
"name": "Netflix", "amount": 15.99, "billing_cycle": "monthly",
"start_date": "2026-08-05", "category": "Streaming", "subcategory": "Video"
})
print(result.data)
asyncio.run(main())If you want to test with an MCP client that expects stdio instead
(e.g. wiring this into Claude Desktop for local use), run it via the
FastMCP CLI, which overrides the transport regardless of what's in
__main__:
uv run fastmcp run server.py:mcp --transport stdioAdding or updating dependencies
Don't hand-edit pyproject.toml's dependency list — let uv manage it so
uv.lock stays in sync:
uv add some-package # add a new dependency
uv add some-package --upgrade # bump one dependency
uv lock --upgrade # re-resolve everything to latest compatible versionsDeploy to FastMCP Cloud
Push this folder to a GitHub repo — commit
pyproject.tomlanduv.lock(don't commit.venv/, that's gitignored).Sign in at fastmcp.cloud with GitHub and create a new project from the repo.
Set the entrypoint to:
server.py:mcpDeploy. FastMCP Cloud auto-detects dependencies from
pyproject.toml(it also understands a plainrequirements.txt, but you don't need one here). You'll get a URL likehttps://<project>.fastmcp.app/mcpthat any MCP client — including Claude, via a custom connector — can call.
A note on storage
This server uses SQLite on local disk for simplicity, which is great for
learning and for a single-instance deployment. It is not guaranteed to
survive a redeploy on most managed platforms (a fresh deploy usually means
a fresh filesystem). Once you're happy with the tool logic, the natural next
step — and a good exercise for learning remote MCP servers further — is
swapping sqlite3 for a hosted database (Turso/libSQL, Postgres via
asyncpg, Supabase, etc.) using an environment variable for the connection
string, set in the FastMCP Cloud dashboard (os.getenv("DATABASE_URL")).
Ideas to extend it
Add an
mcp.tool()that emails/pushes a digest using therenewal_digest_promptoutput.Add a
price_historytable and a tool to log price increases over time.Add authentication (FastMCP supports bearer-token auth) once you're ready to make the server private instead of open.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables personal finance management through Budgetsco, supporting transaction tracking, budget management, recurring transactions, custom categories, and multi-currency support for comprehensive financial tracking.1814MIT
- AlicenseNot gradedqualityCmaintenanceAn intelligent MCP server that integrates Gmail and MySQL to track subscriptions, detect gaps, and send proactive renewal alerts (3 days in advance) to reduce costs.MIT
- AlicenseNot gradedqualityAmaintenanceTrack SaaS subscriptions, renewal dates, spending, and find duplicate services.7MIT
- FlicenseAqualityCmaintenanceAn MCP-powered AI agent that audits your Gmail for recurring subscriptions, detects silent price increases, and flags unused services.6
Related MCP Connectors
Track, analyze, and act on your streaming and SaaS subscriptions from any AI agent.
Scheduling, availability, clients, billing and CRM for appointment-based services.
Receipt tracker with no friction: receipts arrive by email and file themselves
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/4hmad69/subtrack-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server