Logan Kelly
MCP calls cancellation fire-and-forget: the receiver must not answer it. A stop with no receipt is not a control. Govern it where calls are decided.

An agent kill switch that works by cancelling the request in flight inherits the cancellation semantics of whatever protocol carries it. In the Model Context Protocol, those semantics are written down. Cancelling an in-progress request means sending notifications/cancelled, and MCP's base protocol states the rule for every notification plainly: notifications are "a one-way message," and "the receiver MUST NOT send a response." The stop is issued. Whether it took effect is not something the protocol will tell you.
That is a design decision, not an oversight, and the specification is explicit about what follows from it. The cancellation page describes the behaviour as preserving the "fire and forget" nature of notifications. It says receivers SHOULD stop processing — and that they MAY ignore the notification entirely when the request is unknown, when processing has already completed, or when "the request cannot be cancelled." It then instructs the other side to let go of the outcome: "The client SHOULD ignore any response to the cancelled request that arrives afterward."
Read those three rules together and a governance problem appears that has nothing to do with any vendor's implementation. The operator presses stop. The stop may be declined. If the work finished anyway and the server reports what it did, the client is told to discard that report. The stop is unacknowledged going out and evidence-destroying coming back.
What the specification says a cancellation is
The current MCP revision, dated 28 July 2026, moved cancellation from the spec's utilities section into its message patterns and added a transport section that sharpens the point considerably.
Over Streamable HTTP, there is no cancellation message at all: "Closing the SSE response stream is the cancellation signal," and "the server MUST treat a client disconnect as cancellation of that request." Over stdio, where there is no per-request stream to close, the client MUST send the notification instead.
Compare that with the 18 June 2025 and 25 November 2025 revisions, both of which describe cancellation purely as a notification either side can send and carry no transport section. The normative line making a disconnect equivalent to a cancellation is new in the current text.
This matters because of what it does to attribution. On the Streamable HTTP transport, an operator deliberately stopping a runaway agent and a laptop dropping off hotel Wi-Fi produce the same event at the server: a closed stream. The server is instructed to treat both identically. The most privileged action in an agent fleet — the decision to halt it — arrives on the wire wearing the costume of a network fault, and nothing in the message distinguishes intent from accident.
The specification also acknowledges the race directly: "Due to network latency, cancellation notifications may arrive after request processing has completed, and potentially after a response has already been sent." The window between deciding to stop and the work stopping is not a bug to be engineered away. It is a documented property that both parties MUST handle.
A2A made the opposite choice, and the contrast is the lesson
The Agent2Agent protocol faces the same problem and resolves it differently. In the A2A v1.0 specification, Cancel Task is an operation with a return value, not a notification. Its own description is candid about the limits: it "requests the cancellation of an ongoing task. The server will attempt to cancel the task, but success is not guaranteed (e.g., the task might have already completed or failed, or cancellation might not be supported at its current stage)."
Success is not guaranteed in either protocol. The difference is that A2A tells you. The operation's output is an updated Task carrying cancellation status, and refusal has a name — TaskNotCancelableError — rather than silence. An operator who cancels an A2A task learns whether the task entered a cancelled state, whether it had already finished, or whether the remote agent declined.
Both specifications are candid about the limits. A2A is the one that answers. That difference — between a stop that is sent and a stop that is answered — is the architectural line worth drawing, and it is independent of which framework, model or vendor sits on either end.
A stop you cannot verify is a request, not a control
The structural point generalises past both protocols. Cancellation is addressed to a process: it asks something already running to please stop running. But the thing an operator actually needs to stop is an effect in the world — a transfer posted, a ticket closed, a record written, a message sent. Those live downstream of the process, and a message asking the process to wind down arrives, at best, concurrently with them.
This is why a stop built on cancellation is weakest in the case that prompts it. When nothing is outstanding there is nothing to race, and the cancellation is uneventful. The call an operator wants to stop is by definition one already dispatched and still open — which is precisely the condition the specification's race window describes, and precisely the call whose late result the client has been told to ignore.
A control that is reliable when you do not need it and silent when you do is not a kill switch. It is a cancel button.
The alternative is not a better cancellation message. It is to put the stop somewhere that does not have to ask. A layer that sits in the request path and decides whether each call proceeds does not need the agent's cooperation and does not need an acknowledgment, because refusal is the acknowledgment: the call did not happen, and the refusal is a record. The stop stops being a message and becomes a state change that the next call runs into.
How Waxell handles this
The Waxell MCP Gateway is positioned in the request path rather than beside it. Every MCP tools/call routed through it is evaluated against the tenant's policy rules before the upstream sees it, and again before the result returns to the agent. Because the decision happens there, a change to those rules does not have to be delivered to the agent or accepted by it — the gateway documents that rule changes take effect within seconds, with no restart and no redeploy. The next call meets the new rule.
The gateway's fingerprint states make the same shape explicit at the tool level. A tool an administrator has set to Blocked "cannot be called through the gateway," and a tool whose description or schema drifts after it was trusted returns to Drift Detected and goes back for admin review — with a deny_drift rule in place, the gateway blocks the changed tool at call time until an admin re-approves it. Neither of those is a message sent to a running agent; both are conditions the agent's next request encounters.
The record follows from the same placement. Every tools/call the gateway brokered is stored with the resolved user identity, the decision, and the rules that fired — so a refusal is not an absence in the log but an entry in it, attributable to a person and a rule. That is the difference between knowing an agent was stopped and being able to show it. The gateway's audit log is where those decisions are read back after the fact.
For agents built inside Waxell Runtime, the stop sits lower still. Runtime is the execution environment rather than a layer on top of one, and its kill switches operate at the agent, workflow and session level — the product page describes stopping any agent, any workflow, any session immediately: "No graceful shutdown. No waiting." Runtime does not request a halt from the workflow, because it is the thing running the workflow. The same 50+ policy categories gate each step before it executes rather than evaluating it afterwards.
Neither mechanism repeals the physics. A tool call already delivered to an upstream has already been delivered. What changes is the boundary: enforcement sits where the next action is authorised, which is the last place a decision can still be made and the first place it can be written down.
FAQ
Does sending notifications/cancelled stop an MCP tool call?
It requests that the call stop. The MCP specification says receivers SHOULD stop processing the cancelled request and free associated resources, and that they MAY ignore the notification if the request is unknown, has already completed, or cannot be cancelled. Because cancellation is a notification, the base protocol's rule that the receiver MUST NOT send a response applies, so the sender receives no confirmation either way.
Why does closing a connection count as cancelling an agent's request?
On the Streamable HTTP transport, the current MCP specification defines closing the SSE response stream as the cancellation signal and requires the server to treat a client disconnect as cancellation of that request. No separate message is sent or expected. The practical consequence is that a deliberate stop and an unintentional disconnect are indistinguishable to the server.
How is A2A task cancellation different?
A2A models cancellation as an operation that returns an updated Task with cancellation status, and defines a TaskNotCancelableError for tasks that are not in a cancelable state. The specification is explicit that success is not guaranteed, but the caller receives an answer rather than silence.
Where should an agent kill switch actually live?
At a layer that decides whether the next action is permitted, rather than one that asks a running process to stop. Enforcement in the request path does not depend on the agent cooperating and produces a record of the refusal. Enforcement inside the execution environment goes further, because there is no separate process to notify.
Does a kill switch undo work the agent already did?
No. Stopping future actions and reversing completed ones are different problems. A policy decision taken before a call reaches an upstream prevents that call; it has no effect on calls that already completed, which is why the audit record of what did complete matters as much as the stop itself.
What should be logged when an agent is stopped?
The decision, the identity it was attributed to, the rule that produced it and the time it took effect — stored as an entry rather than inferred from the absence of activity. A stop that leaves nothing behind cannot be distinguished later from an agent that simply had nothing to do.
Sources
Model Context Protocol, "Cancellation" (specification revision 2026-07-28), 28 July 2026.
Model Context Protocol, "Base Protocol" (specification revision 2026-07-28), 28 July 2026.
Model Context Protocol, "Cancellation" (specification revision 2025-06-18), 18 June 2025.
Model Context Protocol, "Cancellation" (specification revision 2025-11-25), 25 November 2025.
A2A Protocol, "Protocol Definition — Cancel Task" (v1.0).
Agent stop controls are easiest to evaluate against a real request path. See where the decision is made and what the record looks like afterwards — book a 30-minute demo of the Waxell MCP Gateway.
Agentic Governance, Explained





