databasedmcp

← Articles

How to build a subscription tracker with Claude

Keep a list of everything you pay for every month or year, what it costs you and what renews next, by telling Claude when you sign up or cancel.

7 min read

databasedmcp gives your AI assistant databases it keeps between conversations, so everything in this article works from the day you connect it. Free to start, no card.

Get started free

Why build it yourself

Subscriptions add up quietly. Apps like Rocket Money find them by reading your bank account, which works, but it means handing a third party your transactions to answer a simple question: what am I paying for, and what does it come to.

You can answer that without a bank connection. Tell Claude when you start a subscription, a trial or a price change, and it keeps the list. Once a month you ask what renews next and what the total is per month, with yearly plans spread out fairly.

Connect Claude to databasedmcp

databasedmcp is a remote MCP server that gives AI assistants private SQLite databases, with nothing to install.

In Claude on the web, desktop or mobile, open Settings → Connectors, choose Add custom connector and enter https://databasedmcp.com/mcp. Select Connect, sign in to databasedmcp with your email or Google, and select Allow. Then turn databasedmcp on for a conversation from the tools menu.

Claude asks before it runs anything that changes or deletes data. Reading runs without asking.

Any other MCP client works the same way; the docs have the details.

Copy this prompt to build it

Paste this into Claude to set up the database, its tables and its guide in one go. The rest of this article walks through what it makes and how you use it.

prompt
Set up a subscription tracker for me in databasedmcp, in one go.

1. Create a database called subscriptions, described as "Subscription tracker: what I pay for, how often and when it renews, kept by Claude. No bank connection."
2. Create two tables:
   - subscriptions: id, name (required), category, price_cents (required, in cents), currency (defaults to EUR), cycle (weekly, monthly or yearly, required), status (trial, active or cancelled, defaults to active), started_on (date, defaults to today), next_renewal (date of the next charge), trial_ends (date, for trials), cancelled_on (date), notes.
   - price_changes: id, subscription_id (references subscriptions, required), old_cents (required), new_cents (required), changed_on (date, defaults to today).
3. Write the database a guide that says what each table is for, that prices are in cents, that next_renewal moves on by one cycle when a renewal passes, that a price change is logged in price_changes and the subscription's price updated in the same session, and the queries for "monthly cost of active subscriptions, with weekly and yearly plans spread over the month" and "what renews in the next 30 days".

From then on: when I mention signing up, add the subscription with its price, cycle and next renewal date. When I start a trial, add it as a trial with the date it ends. When a price changes, log the old and new price and update the subscription. When I cancel, mark it cancelled with today's date and clear the next renewal. Show me the tables when you're finished.

Ask for the database

You don't write the schema. Describe what you want:

Set up a subscription tracker in databasedmcp: every subscription I pay for with its price, billing cycle and next renewal date, free trials and when they end, and a history of price changes. When I mention signing up, cancelling or a new price, record it.

Claude creates a database called subscriptions and its tables:

schema
CREATE TABLE subscriptions (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  category TEXT,
  price_cents INTEGER NOT NULL,
  currency TEXT NOT NULL DEFAULT 'EUR',
  cycle TEXT NOT NULL CHECK (cycle IN ('weekly', 'monthly', 'yearly')),
  status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('trial', 'active', 'cancelled')),
  started_on TEXT NOT NULL DEFAULT (date('now')),
  next_renewal TEXT,
  trial_ends TEXT,
  cancelled_on TEXT,
  notes TEXT
);

CREATE TABLE price_changes (
  id INTEGER PRIMARY KEY,
  subscription_id INTEGER NOT NULL REFERENCES subscriptions(id),
  old_cents INTEGER NOT NULL,
  new_cents INTEGER NOT NULL,
  changed_on TEXT NOT NULL DEFAULT (date('now'))
);

It also writes the database a guide on how the tables are meant to be used. The guide comes back with the schema whenever an assistant looks the database up. Claude files things the same way next week as today, and so does any other assistant you connect.

guide
# subscriptions: what I pay for

- **subscriptions**: one row per subscription. Prices in cents. cycle: weekly, monthly, yearly. status: trial, active, cancelled. `next_renewal` is the next charge date; `trial_ends` for trials; clear it when a trial becomes active. When a renewal passes, move `next_renewal` on by one cycle.
- **price_changes**: old and new price whenever a price changes. Update `subscriptions.price_cents` in the same session.

Monthly cost: `SELECT round(sum(CASE cycle WHEN 'weekly' THEN price_cents * 52 / 12.0 WHEN 'monthly' THEN price_cents WHEN 'yearly' THEN price_cents / 12.0 END) / 100.0, 2) AS per_month FROM subscriptions WHERE status = 'active'`

Renewing in 30 days: `SELECT name, price_cents / 100.0 AS price, next_renewal FROM subscriptions WHERE status = 'active' AND next_renewal <= date('now', '+30 days') ORDER BY next_renewal`

Use it

From here on you talk, and Claude writes the rows. Each request below is one statement:

Here's what I pay for: Streamwell is 12.99 a month, renews on the 3rd. Northpage news is 89 a year, renews in March. Cloudnest backup is 2.99 a month, renews on the 20th.
execute
INSERT INTO subscriptions (name, category, price_cents, cycle, next_renewal) VALUES (?, 'video', 1299, 'monthly', date('now', 'start of month', '+1 month', '+2 days')), (?, 'news', 8900, 'yearly', date('now', 'start of year', '+1 year', '+2 months')), (?, 'storage', 299, 'monthly', date('now', 'start of month', '+19 days'))
-- params: ["Streamwell","Northpage","Cloudnest"]

Claude turns "on the 3rd" and "in March" into dates with SQLite's date modifiers.

I started a free trial of Tunebox, 10.99 a month after 14 days.
execute
INSERT INTO subscriptions (name, category, price_cents, cycle, status, trial_ends, next_renewal) VALUES (?, ?, ?, 'monthly', 'trial', date('now', '+14 days'), date('now', '+14 days'))
-- params: ["Tunebox","music",1099]
Streamwell is going up to 14.99.
execute
INSERT INTO price_changes (subscription_id, old_cents, new_cents) SELECT id, price_cents, ? FROM subscriptions WHERE id = ?
-- params: [1499,1]
Update the price too.
execute
UPDATE subscriptions SET price_cents = ? WHERE id = ?
-- params: [1499,1]
I cancelled Cloudnest, I don't use it.
execute
UPDATE subscriptions SET status = 'cancelled', cancelled_on = date('now'), next_renewal = NULL WHERE id = ?
-- params: [3]

Ask it questions

Once there's data, each report you'd pay for is a single query:

What do my subscriptions cost me per month, by category?
query
SELECT category, round(sum(CASE cycle WHEN 'weekly' THEN price_cents * 52 / 12.0 WHEN 'monthly' THEN price_cents WHEN 'yearly' THEN price_cents / 12.0 END) / 100.0, 2) AS per_month FROM subscriptions WHERE status = 'active' GROUP BY category ORDER BY per_month DESC

The query spreads yearly plans over 12 months and leaves trials out until they start charging.

What renews or comes out of a trial in the next 30 days?
query
SELECT name, status, price_cents / 100.0 AS price, coalesce(trial_ends, next_renewal) AS charge_on FROM subscriptions WHERE status IN ('active', 'trial') AND coalesce(trial_ends, next_renewal) <= date('now', '+30 days') ORDER BY charge_on
What went up in price this year?
query
SELECT s.name, pc.old_cents / 100.0 AS was, pc.new_cents / 100.0 AS now, pc.changed_on FROM price_changes pc JOIN subscriptions s ON s.id = pc.subscription_id WHERE pc.changed_on >= date('now', 'start of year') ORDER BY pc.changed_on

You can also open the database on the website, page through its rows and run read-only SQL yourself.

What you give up

It only knows what you tell it. Rocket Money reads your bank and card transactions, so it finds the subscription you forgot about. That's the one thing a list you keep yourself can't do. Going through a few months of statements with Claude once gets you most of the way. After that, you only mention new ones.

Nothing warns you before a renewal or a trial ends, and nothing cancels or negotiates a bill for you. Ask what's coming up at the start of each month, or make it the first question in a Claude project's instructions. You still cancel on the service's own site.

Try it

databasedmcp is free to start, with no card. Free has 100 tool calls a week, enough to set this up and try it for a week. Starter has 1,000 for everyday use.

Create an account

More articles · databasedmcp · Docs