Bruno nailed local-first. Here's what API teams still hit when they let agents touch the spec A developer describes how AI agents given a Bruno API collection as their map of an API will call stale endpoints after an OpenAPI spec rename, because Bruno's import is a one-time snapshot with no re-run or drift check against the live server. The team built Powerduck, a local-first tool that re-runs the OpenAPI spec against the live endpoint and returns a drift report, diff and regenerated paths to the agent instead of a stale collection. Last quarter, three of us sat down to debug why an AI agent kept hitting a 404 on an endpoint we'd renamed the week before. We opened Bruno, searched for the old path, found nothing, and then we sat quiet for a second. The rename had happened in our OpenAPI spec. None of us had re-generated the collection. Bruno had no idea it was out of sync, and neither did the agent that was reading the collection as its map of the API. That moment is the subject of this post. Bruno is, genuinely, one of the best things to happen to API tooling in years. The cloud-first model was a trap — your collections lived on someone else's server, your team's access was gated on a subscription, and diffing a request across branches meant opening two browser tabs. Bruno killed that with a Git-native, file-on-disk, no-lock-in model that feels like using a code editor, not a SaaS console. If you haven't used it, you should. What Bruno did not solve is the drift problem. It solved where your requests live. It did not solve what they are true against . In Bruno, a collection is a set of .bru files. You can import an OpenAPI spec once, and you can hand-write requests, and you can commit everything to Git. That works beautifully when a human is the one clicking through: you change a path, you notice the collection still has the old one, you fix it in five minutes, you move on. Drift is a tax you pay when you remember. An AI agent does not remember. An agent that is given a Bruno collection as its view of the API will call the old path, get a 404, and either retry with variations it invents now you're watching it probe your live endpoint or give up and report that the endpoint doesn't exist. It will not, on its own, re-read the spec file on disk and notice that the path moved. The collection was presented as the map, so the collection is the map. This is the gap that showed up for us. Bruno's import is a snapshot. There is no step that says, before you call anything, re-run the spec against the live endpoint and tell me what moved. There is no diff between what the spec promises and what the server actually returns. The tool assumes a human will look at the screen and feel that something is off. The local-first bet was correct and important. Cloud lock-in for developer tools is real, and Postman's pricing over the years made the case for it. But once you accept that the files should live on your disk and in your repo, the next question is: what does the tool do with those files? Most local-first API tools treat them as a place to store requests you've already written. We started treating them as something to re-run. The difference is small in words and large in practice. A tool that stores requests lets you replay them. A tool that re-runs the spec tells you, before you call anything, that the GET /v2/widgets the spec describes returns a schema the live endpoint no longer matches, that the auth header the collection assumes was renamed in the spec, that the parameter you marked as optional is now required. For a human, that's a useful heads-up. For an agent, that's the difference between a task that finishes and a task that spends ten minutes guessing. We built Powerduck https://www.powerduck.com/ around this. It's local-first in the same bet as Bruno — your spec and your state live on disk, in Git, no tenant in the middle — but the unit of work is not a request you replay, it's the OpenAPI spec you re-run against your live endpoint. The agent gets the drift report, the diff, and the regenerated paths back, instead of a stale collection to hallucinate against. If you're a solo developer or a small team clicking through requests by hand, Bruno is still the right call and I wouldn't argue with you. The local-first, Git-native, no-subscription model is a real step up, and the ecosystem around it is good. The question changes the moment an agent is in the loop. Once an AI tool is reading your API as a map, you need that map to be re-derivable from the source of truth, not hand-maintained. The source of truth for an API is the OpenAPI spec, not a collection someone imported last quarter. Any tool — local or cloud — that stores requests without re-running the spec is going to drift, and the drift is going to land on your agent's error messages, not your human's. So the framing I'd use when you're evaluating tools now is not "cloud vs local." That fight is over; local won, and Bruno won it. The next fight is "does your tool re-run the spec, or just store your requests." The answer to that question is what decides whether an agent can trust the tool, or whether you'll be sitting with your team at 4 PM wondering why it's still calling the old path.