The Model Context Protocol authorization spec is excellent at deciding which tools an agent can reach. It is silent on whether the specific invocation about to execute was approved by a human. For tools that touch money, infrastructure, or user data, that gap matters.
The two questions every MCP server has to answer
When an agent invokes a tool on your MCP server, the server has to answer:
Is this client allowed to call this tool at all? — answered by MCP authorization (OAuth 2.1 + scopes).
Was this specific invocation, with these specific arguments, approved by a named human? — answered (or not) by whatever you wire on top.
For most tools — read-only data lookups, search, summarization — the answer to (1) is sufficient. The cost of a bad invocation is small. For a meaningful subset — payments, infrastructure changes, data exports, account modifications, anything irreversible — you need (2).
Tier your tools by blast radius
Before you write authorization code, classify every tool. A simple three-tier model goes a long way:
Tier 0 — read-only. Search, retrieval, summarization, status checks. Scope-level MCP authorization is enough. Don't add friction.
Tier 1 — bounded write. Creating drafts, posting comments, adding rows to a sandbox table. Scope-level auth + rate limits. Maybe per-tenant quotas. Still don't gate on a human signoff.
Tier 2 — consequential. Money movement, infrastructure changes, permission changes, data exports, anything irreversible or hard to undo. Scope-level auth is necessary; per-invocation pre-action authorization is non-negotiable.
The mistake is treating every tool as Tier 0. The other mistake is treating every tool as Tier 2 — that's how you make agent integrations unusable.
Anatomy of a Tier 2 invocation
A Tier 2 tool needs to refuse to execute unless three things hold:
The client's OAuth token is valid and carries the right scope (MCP authorization layer).
A pre-action handshake exists for this exact tool, this exact actor, these exact arguments — and was issued recently enough to still be valid.
A named human signed off on that handshake. The signoff binds to the action context, not to the session.
With EMILIA Protocol the wrap is short: import the SDK, declare the tool as gated, and the SDK enforces all three checks before your handler runs. A failed check returns a structured error that the client surfaces as a request for human signoff.
What good looks like in 2026
Every tool is tagged with a tier in the manifest — discoverable by the agent runtime so it can prompt for signoff before it tries to invoke.
Scope claims are tight enough that a single token can't authorize cross-tenant action across Tier 1 tools.
Tier 2 invocations emit a self-verifying receipt — useful for audit, useful for replaying authorization to a different system.
Receipts verify offline. Auditors don't need to call back into the issuing server.
What to avoid
Letting "the agent has the payments:write scope" mean anything more than "the agent's runtime is trusted." It says nothing about whether the prompt that just instructed the agent was authentic.
Treating the OAuth refresh token as evidence of human intent. A refresh token is evidence the user once consented to the integration. It is not evidence the user authorized today's wire transfer.
Burying the human-in-the-loop check inside your application layer. The check belongs at the MCP server boundary so every client honoring the protocol gets the same enforcement.
Try the integration
The EP MCP server is open source (Apache 2.0) and ships with 34 reference tools. The SDK pattern wraps any other MCP tool you operate.