A person confirms which tools and values the agent may call on an MCP server. The guard refuses every other call before the server receives it. Permission is not proof: with no compiled integration the verdict is UNVERIFIABLE, never VERIFIED.

The guard costs one connection and one confirmation. A VERIFIED verdict costs a compiler run and a conformance run.

  1. Your agent calls a tool on the MCP server.
  2. The guard compares the call with the permission envelope: the tool names and argument values a person confirmed.
  3. The call runs, or the guard refuses it and the server receives nothing.
  4. The verifier reads the provider on a separate connection.
  5. The runtime evaluates the completion contract against that evidence and signs an Ed25519 receipt.

What is an MCP server? What is an integration?

An MCP server is a process that publishes a list of tools over the Model Context Protocol. Your agent calls them to act on a provider.

An integration is the package Provely compiles for one provider and signs. It states what "done" means there, and what proves it.

Explain: MCP servers, integrations, and Agent Skills

A server answers tools/list with one declaration per tool: a name and a JSON Schema for its arguments. One method, callTool({ name, arguments }), runs every tool. Provely reads that catalogue on connection, with no compiler run and no language model call.

An integration holds one completion contract for each completion level, the evidence channels each contract reads, the correlation strategy, the conformance results, and the certification. Provely signs the manifest with Ed25519, so a receipt names the version that judged an action.

Example: the Stripe integration holds 2 contracts, stripe.refund.created and stripe.refund.succeeded. Each one is a different completion level, and a lower level never proves a higher one. Read the Stripe integration.

An Agent Skill is the other object: one SKILL.md file in the Anthropic format that an agent loads and follows. Provely ships two kinds. The product skill provely-outcome-verification teaches any agent to verify before it claims done, and it renders for each host. Each integration also ships its own skill, for example provely-stripe, so an agent knows how to verify that provider. The machine plan stays in the signed manifest, and never in that file. An Agent Skill from someone else can call a provider itself, and Provely guards it at the call.

Provely publishes its own MCP server, with the four tools begin, verify, status, and receipt. Each handler reads the bearer token from the request, never from a tool argument. Read the Provely MCP server documentation.

What does the guard refuse?

Every call that the confirmed envelope does not name, before the MCP server receives it.

Example: a person confirmed 500 on charge ch_1001. A call for 5,000 never reached Stripe.

Explain: how the guard derives and enforces the envelope

deriveEnvelope reads the tool declarations of the server and the confirmed input, and it writes a policy. Every bound comes from a declaration: a value bound is a const on an argument whose declared name equals a confirmed input key. The comparison is exact, never a similarity.

The envelope is an allow list, not a checklist. A checklist asks whether the confirmed steps happened; an allow list also refuses everything else, so the policy states unlisted: 'refuse'. Provely closes each derived schema with additionalProperties: false, because an undeclared member is how a compromised server smuggles a payload past a check.

Every argument that no confirmed value bounds is marked REQUIRES_REVIEW. Provely never drops a part of a call in silence. The check compares two documents: it reads no text as an instruction, and it asks no language model. A schema that the checker cannot evaluate refuses the call, so the check fails closed.

Every refusal happens before the provider. The provider receives nothing.
What the agent calledWhat the guard doesThe reason code
A tool that the envelope does not nameThe call does not runstep_not_in_confirmed_plan
A named tool with an argument value that no person confirmedThe call does not runargument_outside_confirmed_input
An argument that the server never declaredThe call does not runargument_outside_confirmed_input
A declared schema that the checker cannot evaluateThe call does not runargument_check_undecidable
A permitted tool of a provider that no integration coversThe call runs, and the verdict is UNVERIFIABLEoutcome_not_compiled

A refusal happens before the provider call, and never after it. A control that reports a call after it ran is honest, and the money has already moved.

The envelope answers permission. The completion contract answers completion.
The questionAn MCP server with no integrationA compiled provider
Which calls may run?The envelope, derived from the tool declarationsThe envelope, derived from the confirmed contract input
A call outside the envelopeRefused before the providerRefused before the provider
The verdict on the outcomeUNVERIFIABLE, reason outcome_not_compiledVERIFIED, CONTRADICTED, FAILED, or PENDING
What you do firstConnect the serverCompile the provider
What that costsOne connection and one confirmationA compiler run and a conformance run

Does a permitted call prove the outcome? No.

Permission and completion are separate answers. With no integration the verdict is UNVERIFIABLE, reason outcome_not_compiled.

Explain: why a tool declaration cannot state completion

A tool schema states that a call takes an object and answers an object. It cannot state that a Shopify Refund object does not prove that money moved, or that a Square APPROVED payment is a hold.

Each sentence comes from a signed manifest. A tool declaration states none of them.
ProviderCompletion levelWhat only a signed contract knows
Shopify`created`The created level proves that the Refund record exists with the requested amount and a refunds/create webhook. It does not prove that money moved.
Shopify`financially_completed`A Refund record does not prove money movement. This level proves the SUCCESS status on the refund transaction with the requested amount.
Square`approved`The card issuer authorised the amount, and Square holds the authorisation. This level does not prove a capture. The money did not move.
Square`completed`An approved payment is an authorisation hold, not a captured payment. This level reads the payment status and the card timeline together.

The Square integration 0.1.0 records the row above under provider API version 2026-08-19. The compiler read it from the provider document below. A tool named create_payment declares an object, and the declaration names no hold and no capture.

Source: square.docs.payments · retrieved 2026-09-08

A completion contract derived from a tool schema could assert only "the tool answered". That is an acknowledgement at evidence level E1, and safety rule 5 forbids an acknowledgement as terminal success. So Provely writes no contract from a tool schema, and it states UNVERIFIABLE. Read the UNVERIFIABLE definition and what each verdict obliges an agent to do.

Provely publishes 16 compiled integrations today. Each one states the levels it certifies and its last conformance run. Read the compiled integrations.

A call to a provider with no integration never reaches VERIFIED. Only a compiled provider reaches VERIFIED.

Why not read the provider through that server?

That server sits on the action path. You give the verifier a separate connection.

Explain: the independence rule for a mediator

An MCP server is a transport. It is not an evidence channel. A verifier that reads a provider through the server that the agent used is no longer independent of the action path.

The evidence hierarchy rests on that independence. It runs from E0, a bare agent assertion, to E5, an outcome in an external system. E2 means a provider readback that the verifier made itself, and a reading that the action path returns is E1 at best. A compromised server would otherwise report a success and supply the evidence for it, which is a false VERIFIED.

  1. Give the verifier a separate connection to the provider.
  2. Make that credential read only, where the provider permits it. The agent never holds it.
  3. The verifier calls the provider directly, and never through the server of the agent.
  4. A provider that offers no direct read has no E2 channel, and the verdict is UNVERIFIABLE.

Never give an MCP server the credentials of the verifier. A hop on the action path is never new evidence. Read the evidence level definition.

What does the envelope not cover?

The envelope bounds the calls of the wrapped client. Three limits follow.

Explain: the three limits
The envelope bounds the calls that pass through the wrapped client. No more.
The limitWhat the guard does not stopWhat you must do
A side effect beside the guarded callAn Agent Skill that opens its own socket, writes a file, or calls a second server that no wrapper coversWrap every client that the file can reach, and read the file
An unbounded argumentAn argument that no confirmed input names carries only the schema of the serverRead each argument that the envelope marks REQUIRES_REVIEW
A host with no blocking pointA host that reports a tool call after it ran cannot refuse itUse a host that can block a call, and read the page of your agent host

Provely contains the consequence of an attack. It reads no prompt, and it judges no reason for an action. The contract states what a person authorised, the evidence states what happened, and the difference decides the verdict.

How do you guard a server?

Read the tool declarations, let a person confirm them, wrap the client.

Explain: the code, and the questions readers ask

Guard a third-party MCP server with Provely

  1. Read the catalogueAsk the server for its tool declarations under tools/list.
  2. Confirm the planShow the person the tools and the input. Their decision bounds the envelope.
  3. Derive the envelopeCall deriveEnvelope. It answers a policy and a review list.
  4. Wrap the clientCall guardMcpClient. Every later call passes the check first.
Guard an MCP client · guard-server.ts
import { createToolGuard, deriveEnvelope, guardMcpClient, Provely } from '@provely/sdk';

const provely = new Provely();

// The declarations of the server. Provely reads them, and it reads no prose.
const declared = await client.listTools();

const envelope = deriveEnvelope({
  source: 'payments-mcp',
  tools: declared.tools,
  // The input that the person confirmed. Each name bounds the argument of that name.
  confirmed: { charge: 'ch_1001', amount: 500 },
});

// Every argument that no confirmed value bounds. A person reads each one.
for (const part of envelope.review) console.log(part.reason);

const guard = createToolGuard(provely, { policy: envelope.policy });
// The same client, with the one member replaced. The agent code does not change.
const guarded = guardMcpClient(guard, client);

The wrapper reads the tool name from each call, so one guard covers every tool of the server.

Does Provely need a compiler run before it guards a new MCP server?

No. The envelope comes from the tool declarations of the server and from the confirmed input. It guards a server that nobody has ever compiled, on the day you connect it.

What is the difference between an integration and an Agent Skill?

An integration is the signed package of completion contracts, evidence channels, and conformance results that Provely compiles for one provider. An Agent Skill is one SKILL.md file in the Anthropic format that an agent loads and follows. Each integration ships one, so an agent knows how to verify that provider.

May the verifier use the same MCP server as the agent?

No. That server is on the action path, so its reading is not independent evidence. You give the verifier its own connection, and the verifier calls the provider directly.