A private MCP server that gives Claude 25+ tools for paid SEO and analytics data — every paid call is priced before it runs, over-budget calls are refused with an estimate instead of run halfway, and overlapping queries only pay for what's new.

Paid SEO data APIs bill per call, and an AI agent with open access can run up a bill fast. I built a private MCP server that gives Claude 25+ tools for keyword and SERP research, competitor analysis, backlinks, AI-search visibility, Search Console and site analytics — with cost control built into the protocol layer, not bolted on after. Every paid call is estimated before it runs; going over budget means a refusal plus the estimate, never a call that starts and then gets cut off. Caching is per-record, so a query that overlaps a previous one only pays for the new rows. Upstream failures come back as typed errors instead of generic 500s. I use it myself to research and track SEO for my own sites. Personal project, not a paying client; private repository.
Keyword, SERP, competitor and backlink data from paid SEO providers is billed per call. Give an AI agent open access to that kind of API and it will happily call it as many times as it takes to answer a question thoroughly — which is exactly how you end up with a surprise bill. I wanted Claude to be able to use these tools freely for my own SEO research, but with a hard ceiling on what any single session could spend, enforced where the calls actually happen rather than left to the model's judgment.
The server exposes 25+ tools to Claude: keyword and SERP research, competitor analysis, backlinks, AI-search visibility tracking, Search Console data and general site analytics. Every tool that hits a paid upstream API goes through the same gate first: estimate the cost of this specific call, compare it against what's left of the session budget, and only then execute. If the estimate exceeds the remaining budget, the call is refused outright and the estimate is returned instead — Claude (or me) gets to decide whether it's worth spending on, rather than discovering the cost after the fact.
Results are cached per individual record rather than per whole query. When a new query partially overlaps one already run, the server only pays the upstream provider for the rows it doesn't already have — the overlap is served from cache for free. Combined with the budget gate, this means the same exploratory back-and-forth Claude needs to actually research a topic doesn't multiply the cost every time the question gets refined.
When an upstream provider fails — rate limited, out of quota, malformed response, timeout — the server surfaces a typed error rather than letting it collapse into a generic failure. That matters for an AI client as much as a human one: Claude can tell the difference between "try again later" and "this query is invalid" and act accordingly instead of just reporting that something went wrong.
TypeScript, deployed on Cloudflare Workers.