MCP Servers for Agents You Don't Trust

On this page

Most MCP servers assume a human is watching. Someone who will see the confirmation dialog before anything gets deleted. That assumption breaks when the agent is automated.

The gap

The consent_required flag in your declaration signals to MCP clients that a capability needs user confirmation before executing. Claude Desktop shows a dialog. Cursor prompts you. A human makes the call.

But not every MCP client enforces this. And in headless environments like CI pipelines, automated agents, and programmatic MCP clients, there’s no human in the loop at all. The dialog never appears. The capability runs.

If you’ve declared consent_required: true on a destructive action, you’ve done the right thing for supervised clients. You haven’t necessarily protected yourself from unsupervised ones.

usepaso serve —strict

usepaso serve --strict
Strict mode: consent-gated tools require two-phase confirmation.
usepaso serving "Stripe" (12 capabilities). Agents welcome.
Transport: stdio. Waiting for an MCP client...

In strict mode, paso enforces consent gates at the server level, not the client level. Any capability marked consent_required: true requires a two-phase MCP tool call: the agent first calls the tool with a confirm: false parameter to get a description of what will happen, then calls it again with confirm: true to execute. If the second call doesn’t come, nothing runs.

This happens regardless of whether the client would have shown a dialog. The server requires it.

When to use it

CI pipelines. If you’re running usepaso serve in a CI step as part of an automated workflow, there’s no human available to confirm destructive actions. Strict mode makes the confirmation a protocol requirement, not a UI suggestion.

Third-party agents. If you’re exposing your MCP server to agents you didn’t write and don’t control, you can’t assume they’ll respect the consent_required semantics. Strict mode enforces them server-side.

Shared infrastructure. If a single paso server is being accessed by multiple agents simultaneously, strict mode ensures none of them can bypass consent gates regardless of how they’re implemented.

What it doesn’t change

Strict mode only affects capabilities marked consent_required: true. Read capabilities and unconstrained write capabilities work the same way. The performance overhead is negligible: one extra tool call for each gated action.

It also doesn’t change the declaration. The same usepaso.yaml runs with or without --strict. Whether to enforce strict mode is a deployment decision, not a declaration decision.

The full picture

# In usepaso.yaml
capabilities:
  - name: delete_record
    description: Permanently delete a record
    method: DELETE
    path: /records/{id}
    permission: admin
    consent_required: true    # Signals intent to clients
    inputs:
      id:
        type: string
        required: true
        in: path
# In a supervised environment (Claude Desktop, Cursor)
usepaso serve

# In a headless or untrusted environment
usepaso serve --strict

You declare the intent once. You control the enforcement at serve time.

A note on the forbidden list

Strict mode is for capabilities you want agents to be able to call, with confirmation. If there are capabilities you never want automated agents to call under any circumstances, use the forbidden list instead:

permissions:
  forbidden:
    - delete_record

Forbidden capabilities are never registered as MCP tools. They don’t exist as far as any agent is concerned. Strict mode and forbidden serve different purposes: one controls how, the other controls whether.

Related: