Kartik N V J K
AI Developer | Making AI reliable, trustworthy & accessible to everyone | Active community contributor
Nice dataset. The scary case is retrying non-idempotent tools: an agent that blindly retries a payment or transfer call can double-charge. Worth checking whether the 489 tools expose idempotency keys, and whether retries apply exponential backoff only to idempotent calls. For side-effecting tools like payments, the safer pattern is a unique operation ID per attempt so the receiving service can dedupe. That is the kind of guardrail agent payment rails need built in.
Thanks Mike, you're right, and this was a real bug in the default rather than an edge case. The log had no expiry, so with ["*"] a deliberate repeat a week later was answered with the first result and nothing happened, which is worse than a duplicate because the agent thinks it worked. The README's "nothing legitimate is ever refused" hid that: it wasn't refused, it was silently replayed.
Fixed in mcp/v0.6.0: policies now have a replay_window, 10 minutes by default for ["*"] since that identity is only a guess. After the window, the same arguments are a new operation with a new key, so a server that deduplicates on the key doesn't swallow it either. An unknown outcome never expires, since that would bring back the double charge. I went with a window rather than a run id because a restart after a crash starts a new run, and that's exactly the retry that has to be recognised.
The marker idea is good. It turns "unknown, go check" into a lookup, which is the part I most want to improve. The limits I see are that it needs a free-text field and changes the caller's arguments, and that search indexing lags, so "not found" isn't proof. As an opt-in per tool, with the lookup configured alongside it, I think it works. Would you use it that way?
The ["*"] identity that inspect writes needs a time window, or it will eventually swallow real work. Your mcp README describes a log that continues across restarts, and I couldn't find an expiry in it. So an agent that comments "LGTM" on the same issue a week later, or charges one customer 10.00 for a second order, sends the same arguments and gets the first answer replayed. Stripe prunes idempotency keys once they are at least 24 hours old and treats a reused key after that as a new request. A bounded window, or a run id added to the identity, would separate a retry from a deliberate repeat.
For the unknown case on servers with no key, the proxy could also write its operation id into what it creates, such as a line in the issue body. Then "go check" becomes one lookup for that id before deciding to retry, which GitHub's issue search can already do.
Zero of 266 effectful tools taking an idempotency key is a stark number, and the GitHub repro with issues 6 and 7 from one intended call makes it concrete. I've hit the same thing with agent retries after a timeout and ended up deduping on business arguments too. How does agentsafe-mcp handle two legitimately identical calls, like an agent that really does want two comments with the same text?