# How do I show a human the actual change (diff, target, amount) before they approve an AI agent's action, instead of the agent's summary?

**Short answer:** Build the approval screen from the exact tool call that will run, not from text the model wrote about it. The model's summary ('updating the config', 'sending the refund') is a claim; the tool name and arguments are the action. Render those arguments yourself, in a fixed layout: for a file change, a diff of the current file against the proposed one; for a message, the real recipients, channel and full body; for money, the payee, amount with currency and decimals, and network; for an API or database write, the resolved target (full URL, account, table, record ids) and the fields that change, with before and after values. Then bind the yes to what was shown: hash the canonical arguments, store the hash with the approval, and check it again right before execution, so an edited call needs a new approval. The MCP specification says clients SHOULD show tool inputs to the user before calling the server and prompt for confirmation on sensitive operations, and the OpenAI Agents SDK gives your code the tool name and arguments of each pending call to render. Treat those arguments as untrusted display content: escape them, show hidden characters, and never let a description or summary field decide what the approver sees.

## Checklist
1. Render from the pending tool call: the tool name and the parsed arguments your runtime will execute (OpenAI Agents SDK interruptions expose name and arguments; a LangGraph interrupt() payload is whatever you put in it, so put the arguments there, not a summary).
2. Show the model's explanation, if at all, in a separate box labelled as the agent's description, below the facts. If the two disagree, the facts win and the approver should be told.
3. File edits: show a unified diff against the file as it is on disk now, with the full path, and flag new files, deletions, permission changes and files outside the project. Line counts alone ('12 changes') are not a review.
4. Messages and posts: show every recipient (to, cc, bcc, channel, thread), the sender identity, the full body and attachments, not a preview.
5. Payments and spend: payee or payTo address, amount with currency and decimals, network (mainnet or testnet), what is bought, and whether the figure is a ceiling or exact.
6. API, database and infrastructure writes: the resolved target (full URL with host, account or project, environment, table and record ids), the operation, and before/after values for each changed field. For bulk actions, the count plus a sample, and a way to see all of them.
7. Make hidden things visible: escape HTML, show invisible and look-alike characters (zero-width, bidi controls, homoglyph domains), and expand shortened URLs and templated variables to the values that will be sent.
8. Bind the approval to the facts: hash the canonical JSON of the tool name plus arguments at display time, store it with the decision, and compare right before execution. Any change (another retry, an edited amount, a new recipient) means a new approval.
9. Expire and single-use approvals, keep approval state on your server, and record who approved, what they saw (or its hash) and when.

## Why the summary is the wrong thing to approve
- The summary is written by the same model whose action is being checked. If the model was misled by injected text in a ticket, web page or tool result, or simply got the target wrong, its summary can be confidently wrong too, and it will usually describe what it meant to do rather than what the arguments do.
- The arguments are what reach the server. A one-character change in an account id, a recipient added to bcc or an amount in the wrong units is invisible in a sentence and obvious in a field-by-field view.

## What the specs and SDKs say
- MCP (2026-07-28, tools, security considerations): clients SHOULD prompt for user confirmation on sensitive operations and show tool inputs to the user before calling the server, to avoid malicious or accidental data exfiltration. The same page says a human SHOULD be in the loop with the ability to deny tool invocations.
- OpenAI Agents SDK (JavaScript): tools with needsApproval pause the run and appear in result.interruptions with the tool name and arguments; your code approves or rejects each one. The SDK re-runs input guardrails after approval in case the call became unsafe while waiting. Its docs warn that a serialized RunState holds pending tool calls and arguments and that RunState.fromString() does not authenticate the snapshot, and they say to treat tool names and arguments as untrusted display content: filter sensitive values and escape them when rendering HTML.
- OWASP LLM06:2025 Excessive Agency lists requiring user approval for high-impact actions as a mitigation, implemented either in a downstream system or in the extension itself.

## Common ways the shown change and the run change drift apart
- The model re-plans after approval and calls the tool again with different arguments. Fix: the approval carries a hash of the arguments, and the executor refuses a call whose hash isn't approved.
- The diff was computed against an old copy of the file or record. Fix: compute the diff at approval time against the live state, and re-check that state (ETag, version, row hash) before writing.
- Defaults and server-side expansion: a template, a default recipient list or a relative path resolves only on the server. Fix: resolve on your side and show the resolved values, or show that a value is server-decided.

## Ask Rightshold (free, no key)
Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code (one-click setup: https://www.rightshold.com/start?ref=seo), then ask: "Before you run this tool call, request my approval with the exact tool name and arguments as the action, and wait for my yes or no."

```json
{
  "tool": "request_human_approval",
  "arguments": {
    "action": {
      "tool": "<tool name>",
      "arguments": "<the exact arguments object you will send>"
    },
    "summary": "<one line, no personal data>",
    "expires_in_minutes": 30
  }
}
```
- Needs your account API key. Rightshold hashes the canonical JSON of the action you send and returns an approval id plus a one-time token. Only your account key can decide it (decide_human_approval), once; delegated agent keys are refused.
- Before executing, call verify_human_approval with the decision receipt and the same action object: if the arguments changed since approval, action_matches is false and the approval is not valid for that call.
- Rightshold stores the hash and your one-line summary, not the action itself, and it does not draw your approval screen. Rendering the diff, target and amount for the approver is your app's job; the receipt proves which exact action that yes covered.

_Rightshold records and signs approval requests and decisions and checks that an action matches its approved hash. It does not render diffs, run your tools or see your data. Not legal advice._

## Sources
- [MCP specification 2026-07-28: Tools (security considerations, human in the loop)](https://modelcontextprotocol.io/specification/2026-07-28/server/tools)
- [OpenAI Agents SDK (JS): Human in the loop](https://openai.github.io/openai-agents-js/guides/human-in-the-loop/)
- [LangGraph docs: Interrupts](https://docs.langchain.com/oss/javascript/langgraph/interrupts)
- [OWASP GenAI: LLM06:2025 Excessive Agency](https://genai.owasp.org/llmrisk/llm062025-excessive-agency/)

## Related
- [How to require human approval before an AI agent spends money](https://www.rightshold.com/answers/how-to-require-human-approval-before-an-ai-agent-spends-money)
- [How to audit which human authorized an AI agent action](https://www.rightshold.com/answers/how-to-audit-which-human-authorized-an-ai-agent-action)
- [How to treat MCP tool output from Slack, tickets and logs as untrusted](https://www.rightshold.com/answers/how-to-treat-mcp-tool-output-from-slack-tickets-and-logs-as-untrusted)
- [How to stop an AI agent from paying twice when it retries](https://www.rightshold.com/answers/how-to-stop-an-ai-agent-from-paying-twice-when-it-retries)

_Not legal advice. Updated 2026-10-30. JSON: https://www.rightshold.com/answers/how-to-show-a-human-the-actual-change-before-approving-an-ai-agent-action.json_