← blog

The Second Tool: Knowing If the Bus Is Actually Coming

2026-07-31

I asked a website when the next bus was actually coming, and it told me, live, off TheBus's own real-time feed. Try it: lukelenentine.com/tools/bus-check. Give it a stop number and ask in plain English.

This is the second one of these I've built, and building the second one taught me something the first one didn't.

TheBus publishes a proper, documented public API: send a stop number, get back upcoming arrivals with route numbers, headsigns, and whether each prediction is a real GPS estimate or the printed schedule filling in a gap. Access is a free registration. An MCP server wired against that feed is what makes the plain-English version possible — you ask a real question, it calls the API, it answers in real sentences instead of a table of numbers.

What was different this time is how little I had to think about the parts I'd already solved once. The rate limiting, the access key on the raw server, the narrow scope so the tool can only do the one thing it's supposed to do: none of that was new work. It was already built, from the surf tool, and it just applied here too.

That's the actual argument for building more than one of these. Build the security discipline once, thinking clearly about what the tool can touch and who can call it, and every tool after that inherits the same protection for free.

Concretely, that meant the rate-limiting code got reused directly, same file, same logic. Same two gates as the surf tool: a limit on how often one visitor can ask anything, and a separate, independent daily limit for the whole site. A public page calling a paid model should fail loud and cheap the moment it's overused. I didn't have to re-decide that. I just pointed the existing gate at a new tool.

The same is true of keeping the tool narrow. The surf tool can only look up conditions at a named spot. This one can only look up arrivals for a stop number you give it. That's the whole capability, on purpose — a tool this specific doesn't need a clever guardrail to stay in its lane, because there's nowhere else for it to go.

I built limits into this one too: rate limits on how often anyone can ask it anything, and the MCP server itself needs its own key before it'll talk to another AI directly.

The tool itself is one function: given a stop number, call TheBus's API, return the arrivals. Wiring that into something Claude can call is a matter of describing the function in plain language — what it does, what it needs, what it hands back — and letting the model figure out when to reach for it. The API integration and the MCP wiring are two genuinely separate pieces of work, and once you've done the second one once, doing it again for a new API is mostly a matter of writing the same shape of description around different data.

The part worth naming plainly: you can ask this thing "when's the next bus" in exactly those words, and it hands back a real answer with real route numbers. That means it parsed an ordinary sentence, figured out it needed live data, asked for the right stop, and phrased the result the way a person would actually say it out loud.

Two tools built on two different public feeds now, same pattern both times: find the data source, wire an MCP server around it, carry the same rate limits and access controls forward. That repetition is the actual point. A pattern you've only used once could be luck. A pattern that held up the second time, on a completely different API, with completely different data, is something you can actually plan around — which matters if the next one is going to be for something more useful than surf conditions and bus times.

What I haven't built yet: something that watches your regular stop on its own and tells you it's running late before you've thought to check. Both tools right now answer a question the moment you ask it and then forget you exist. A tool that watches on its own needs to remember something about you between visits, a saved stop or a saved route, which means it needs somewhere to keep that, and a real answer for what happens to it if you never come back. That's an honest design decision, and I'd rather get it right than rush it out to have a third post ready sooner.