PERMISSION/PROTOCOL
← Integrations

MCP tool call authorization

Require authorization before MCP tool calls execute.

MCP servers expose powerful tools to AI agents — filesystem access, code execution, API calls, database operations. Once an MCP server is trusted, the agent can invoke any tool it exposes without further approval. Permission Protocol adds an authorization gate at the tool level: a signed receipt must exist before the tool handler runs. The MCP server calls the gate; the gate calls the human.

The problem

MCP's trust model is binary: once you trust a server, the agent can call any tool it exposes. There's no built-in mechanism to require human approval for specific tools, produce a verifiable record of tool invocations, or fail closed when a tool with production impact fires without authorization. Permission Protocol adds that layer inside the MCP tool handler.

Code example.

Before — no gate

TypeScript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "deploy-server" });

server.tool("deploy_service", { service: z.string() }, async ({ service }) => {
  // No authorization check — agent can deploy freely
  const result = await deploy(service);
  return { content: [{ type: "text", text: result }] };
});

After — authorization gate

TypeScript — MCP server tool with authorization gate
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { authorize } from "permission-protocol";

const server = new McpServer({ name: "deploy-server" });

server.tool("deploy_service", { service: z.string() }, async ({ service }) => {
  const receipt = await authorize({
    action: "deploy",
    resource: `${service}:production`,
    policy: "production-deploy",
  });

  if (!receipt.verified) {
    throw new Error(`Authorization required. Approval link: ${receipt.approvalUrl}`);
  }

  // Proceeds only with a valid receipt
  const result = await deploy(service);
  return { content: [{ type: "text", text: result }] };
});

// MCP client sees:
// Tool call: deploy_service({ service: "billing-api" })
// Error: Authorization required.
// Approval: https://app.permissionprotocol.com/approve/3fe72
// [Human approves]
// Tool call: deploy_service({ service: "billing-api" })  ← retried
// ✓ Receipt pp_r_9d3a2f verified — deploying

How it works.

01

Add authorize() to the tool handler

Call authorize() at the top of your MCP tool handler. If no valid receipt exists, it returns an approvalUrl and verified: false. The tool throws, surfacing the approval link to the agent.

02

Agent surfaces the approval link

The tool error contains the approval URL. The agent includes it in its response to the user, who clicks through to the Permission Protocol approval interface.

03

Human approves, agent retries

On approval, a receipt is issued. The agent retries the tool call. This time authorize() returns verified: true and the tool proceeds. The receipt is stored with the action for audit.

The receipt it produces.

AuthorityReceipt — JSON
{
  "receipt_id": "pp_r_9d3a2f55",
  "action": "deploy",
  "resource": "billing-api:production",
  "actor": "mcp-agent",
  "approved_by": "[email protected]",
  "policy": "production-deploy",
  "context": {
    "mcp_server": "deploy-server",
    "tool": "deploy_service"
  },
  "timestamp": "2026-05-16T18:20:07Z",
  "signature": "pp_sig_Wr8n..."
}

Full receipt format specification →

FAQ.

Does this work with any MCP server?

Yes. The authorize() call is standard TypeScript/Python and works in any MCP server handler. You can add it to any tool in any server you control.

Can I gate some tools in a server and not others?

Yes. Add authorize() only to the tools that need it. Read-only tools, search tools, and low-risk operations can remain ungated while destructive or production-impacting tools require receipts.

What if the MCP server is third-party and I can't modify it?

Use the Permission Protocol MCP proxy. It sits between the agent and the upstream MCP server, intercepts tool calls matching your policy, and fires the authorization gate before forwarding the call.

How does this relate to the TrustFall MCP vulnerability?

TrustFall showed that repo-defined MCP configuration can trigger agent tool execution without specific authorization. Permission Protocol's tool-call gate addresses exactly this: even if the MCP server starts, individual tool calls require a receipt before execution.

Get the gate running today.

Free for individual developers. The quickstart takes under five minutes. Enterprise plans for teams that need audit trails, policy management, and self-hosted authority nodes.