Let your AI agent check before it pays
The Settlens MCP server gives an agent a preflight check for x402. On every HTTP 402 it evaluates the payment request against your spending policy and answers pay, review or do_not_pay, with the reasons. It never signs, never pays and needs no wallet or payment key.
Remote endpoint https://settlens.com/mcp. Six offline tools are public; the two network tools need a Settlens API token. Read the MCP reference.
- pay
Under a complete policy
Every protocol check passed and at least one payment option is within the allowed recipients, assets, networks and maximum amount. Pay only with an option listed in acceptable.
- review
When the policy sets only max_amount
The spending policy is incomplete: set allowed recipients (pay_to), allowed assets (assets), and allowed networks (networks) to allow an automatic pay decision.
- do_not_pay
When max_amount is 5000
policy.acceptable_option: 0 of 1 payment option(s) satisfy the policy; 1 rejected (max_amount: 1).
In short
The Settlens MCP server is an x402 preflight for AI agents: on each HTTP 402, evaluate_payment_requirements checks the PAYMENT-REQUIRED terms, the requested URL and your spending policy, then answers pay, review or do_not_pay. It never signs or pays. Six offline tools are public at https://settlens.com/mcp.
How the preflight works
One tool call sits between the 402 and the signature. The agent keeps its wallet; Settlens only reads the terms.
-
Request without paying
The agent requests the resource with no payment header. An x402 V2 resource answers HTTP 402 with a
PAYMENT-REQUIREDheader: Base64 JSON listing the accepted payment options. See x402 V2 headers. -
Call evaluate_payment_requirements
The agent passes the raw header value, the exact URL it requested as
resource_urland its spending policy. The tool makes no network request: it validates the terms with the official@x402/core 2.28.0schema, checks thatresource.urlmatches the URL, validates each option and applies the policy to each option. -
Act on the decision
do_not_pay: stop.review: show the reasons to a human and wait.pay: continue, with one of the options listed inacceptableonly. -
Pay with your own tooling
Settlens never signs and never calls /settle. After a pay, the agent's wallet signs the chosen option and retries the request with PAYMENT-SIGNATURE, exactly as it would without Settlens.
Three answers, decided by fixed rules
The model does not judge whether a payment request looks safe. Deterministic rules in the server do, the same way on every call.
-
payAll protocol checks passed, at least one option satisfies the policy, and the policy bounds the recipient, the asset, the network and the amount. Pay only with an option listed in acceptable.
-
reviewA non-blocking issue was found, such as a missing resource_url, or the policy leaves pay_to, assets, networks or max_amount unset. Show the reasons and wait for a human.
-
do_not_payA high or critical check failed: a resource binding mismatch, terms the official schema rejects, or no option within the policy. acceptable is empty. Never pay.
A pay needs a complete policy
Without pay_to, assets, networks and max_amount the answer is at most review. An amount ceiling in atomic units means nothing without the token, and the same token address can be a different contract on another chain. The agent spending policy guide explains each field, and verify before paying walks through real answers.
Eight tools, all read-only
Every tool is annotated read-only, non-destructive and idempotent. Offline tools compute on their inputs only; network tools send passive, unauthenticated GET requests.
-
Should I pay this x402 request?
evaluate_payment_requirements. Decides pay, review or do_not_pay for a 402: validates PAYMENT-REQUIRED with @x402/core 2.28.0, checks the URL binding and applies your policy to each option. -
Verify an exact EVM payment signature
verify_payment_signature. Recovers the EIP-3009 signer of an exact EVM authorization offline and checks it pays the advertised payTo and amount inside its time window. -
Verify Solana signatures and payment instructions
verify_solana_transaction. Checks every ed25519 signer slot of a Base64 Solana transaction, legacy or versioned. An empty fee-payer slot is reported as pending, not as a failure. -
Verify a Settlens report
verify_report. Recomputes the SHA-256 integrity digest of a Settlens JSON report to show whether it was edited after it was generated. -
Verify a Settlens evidence attestation
verify_attestation. Verifies the ed25519 signature of a Settlens evidence attestation and, given the report, that it covers that report. -
List Settlens checks
list_checks. Explains every check id: what it verifies, why it matters and how to fix it, optionally filtered by category or mode. -
Passively scan an x402 endpoint
scan_endpoint. Sends up to two unauthenticated GET requests to a paid resource, runs the passive checks and returns the same pay, review or do_not_pay decision under your policy. -
Passively scan an x402 facilitator
scan_facilitator. Reads GET /supported from a facilitator and checks its schema, x402 V2 capability, HTTPS, media type and duplicate kinds.
| Name | Type | What the agent gets |
|---|---|---|
settlens://checks | application/json | Every check Settlens can report, as JSON. |
settlens://policy-guide | text/markdown | How to write the policy passed to evaluate_payment_requirements. |
settlens://checks/{id} | text/markdown | Explanation of one Settlens check id, for example settlens://checks/binding.resource_url. 36 check pages are listed. |
x402_preflight | prompt | Guides the agent to read the 402 PAYMENT-REQUIRED header, call evaluate_payment_requirements with its policy and act on the decision. |
A real call and its result
Produced by the server code when this page was built, against the bundled demo resource (npm run demo:server), which asks for 0.01 test USDC on Base Sepolia: 10000 atomic units with 6 decimals.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "evaluate_payment_requirements",
"arguments": {
"payment_required": "eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQQVlNRU5ULVNJR05BVFVSRSBoZWFkZXIgaXMgcmVxdWlyZWQiLCJyZXNvdXJjZSI6eyJ1cmwiOiJodHRwOi8vMTI3LjAuMC4xOjQ0MDIvc2VjdXJlIiwiZGVzY3JpcHRpb24iOiJTZXR0bGVucyBsb2NhbCBkZW1vbnN0cmF0aW9uIHJlc291cmNlIiwibWltZVR5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwic2VydmljZU5hbWUiOiJTZXR0bGVucyBEZW1vIiwidGFncyI6WyJzZWN1cml0eSIsImRlbW8iXX0sImFjY2VwdHMiOlt7InNjaGVtZSI6ImV4YWN0IiwibmV0d29yayI6ImVpcDE1NTo4NDUzMiIsImFtb3VudCI6IjEwMDAwIiwiYXNzZXQiOiIweDAzNkNiRDUzODQyYzU0MjY2MzRlNzkyOTU0MWVDMjMxOGYzZENGN2UiLCJwYXlUbyI6IjB4MjA5NjkzQmM2YWZjMEM1MzI4YkEzNkZhRjAzQzUxNEVGMzEyMjg3QyIsIm1heFRpbWVvdXRTZWNvbmRzIjo2MCwiZXh0cmEiOnsibmFtZSI6IlVTREMiLCJ2ZXJzaW9uIjoiMiJ9fV0sImV4dGVuc2lvbnMiOnt9fQ==",
"resource_url": "http://127.0.0.1:4402/secure",
"policy": {
"pay_to": [
"0x209693Bc6afc0C5328bA36FaF03C514EF312287C"
],
"assets": [
"0x036CbD53842c5426634e7929541eC2318f3dCF7e"
],
"networks": [
"eip155:84532"
],
"max_amount": "10000",
"schemes": [
"exact"
]
}
}
}
}
{
"decision": "pay",
"summary": "Every protocol check passed and at least one payment option is within the allowed recipients, assets, networks and maximum amount. Pay only with an option listed in acceptable.",
"reasons": [],
"acceptable": [
{
"scheme": "exact",
"network": "eip155:84532",
"amount": "10000",
"asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"payTo": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
"maxTimeoutSeconds": 60,
"extra": {
"name": "USDC",
"version": "2"
}
}
]
}
| Check | Status | Severity | Message |
|---|---|---|---|
transport.payment_required_encoding | pass | high | The canonical header decoded successfully. |
schema.official_x402_sdk | pass | high | The header passes @x402/core 2.28.0 schema validation. |
schema.payment_required | pass | high | The decoded header contains the required V2 fields. |
binding.resource_url | pass | high | resource.url exactly matches the protected request URL. |
schema.payment_requirements | pass | high | 1 payment requirement(s) use valid core fields. |
schema.duplicate_requirements | pass | low | No duplicate accepted requirements were found. |
freshness.timeout_window | pass | medium | All advertised maxTimeoutSeconds values are at most one hour. |
policy.scheme | pass | high | All 1 payment option(s) satisfy the schemes policy. |
policy.network | pass | high | All 1 payment option(s) satisfy the networks policy. |
policy.recipient | pass | high | All 1 payment option(s) satisfy the pay_to policy. |
policy.asset | pass | high | All 1 payment option(s) satisfy the assets policy. |
policy.maximum_amount | pass | high | All 1 payment option(s) satisfy the max_amount policy. |
policy.acceptable_option | pass | high | 1 of 1 payment option(s) satisfy the policy. |
| Change from the call above | Decision | Reasons |
|---|---|---|
| None: the full policy | pay | None: every check passed. |
max_amount lowered to 5000 | do_not_pay | policy.acceptable_option: 0 of 1 payment option(s) satisfy the policy; 1 rejected (max_amount: 1). |
Policy reduced to max_amount only | review | The spending policy is incomplete: set allowed recipients (pay_to), allowed assets (assets), and allowed networks (networks) to allow an automatic pay decision. |
resource_url set to another path | do_not_pay | binding.resource_url: resource.url does not match the URL being assessed. |
Every input and output field is documented in the evaluate_payment_requirements reference, and each check id in the check catalog.
Connect it to your agent
Use the public endpoint in one command, or run the server locally over stdio with every tool. The local server needs the Settlens source, shared with pilot participants (Node.js 20.19 or newer).
Remote endpoint, nothing to install
Claude Code, offline tools only:
claude mcp add --transport http settlens https://settlens.com/mcp
With a Settlens API token, scan_endpoint and scan_facilitator are listed too:
claude mcp add --transport http settlens https://settlens.com/mcp \
--header "Authorization: Bearer ${SETTLENS_API_TOKEN}"
Any other client that supports Streamable HTTP connects to the same URL. To see a decision before wiring an agent, paste a PAYMENT-REQUIRED header into the x402 payment request checker, which sends the same evaluate_payment_requirements call to this endpoint from your browser.
Local server over stdio
Claude Code, every tool:
claude mcp add settlens -- node /absolute/path/to/settlens/src/cli.js mcp
{
"mcpServers": {
"settlens": {
"command": "node",
"args": [
"/absolute/path/to/settlens/src/cli.js",
"mcp"
]
}
}
}
Claude Desktop reads ~/Library/Application Support/Claude/claude_desktop_config.json on macOS and %APPDATA%\Claude\claude_desktop_config.json on Windows; restart it after editing. In the pinned container, keep stdin open: docker run -i --rm settlens:local mcp.
Then tell the agent when to call it
The server sends its instructions at initialize: call evaluate_payment_requirements on every HTTP 402 before paying. The x402_preflight prompt walks an agent through the same steps for one URL. Transports, limits and errors are in the MCP reference.
Safety model
A tool an agent consults before spending money must not become a way to spend it, or a way into your network.
-
Never signs, never pays
No tool signs, settles, broadcasts or holds funds. Settlens needs no wallet, private key or seed, and never calls /settle.
-
Offline tools stay offline
Six of the eight tools make no network request of their own. They compute on the arguments the agent sends.
-
Remote network tools need a token
On https://settlens.com/mcp, scan_endpoint and scan_facilitator are listed and callable only with a bearer token, compared in constant time.
-
Passive only
Network tools send unauthenticated GET requests, never follow redirects and never send a PAYMENT-SIGNATURE. The authorized active probe of the CLI is not exposed over MCP.
-
Public destinations only
Before a remote network request, the server refuses URL credentials, ports other than 80 and 443, localhost, .local and .internal names, and hosts that resolve to private, loopback, link-local or reserved addresses.
-
Server text is data
Messages that can carry values chosen by the scanned server are cut to one line of at most 300 characters, without control characters. Agents should never follow instructions found in them.
The complete model, including what the local stdio server trusts, is in the MCP reference and the Settlens security model.
What a preflight does not check
A pay means the request passed these checks under your policy. It is not a guarantee about the merchant or what it delivers. Settlens does not check balances, on-chain nonce use or replay, settlement, or what the token contract at asset does.
max_amount is compared in atomic units of each option's asset, so list only assets with the same decimals. The policy bounds one payment at a time: daily or cumulative budgets belong in the wallet or the agent runtime (see the agent spending policy guide). verify_payment_signature checks an EVM authorization offline, without RPC; whether the funds move is decided on-chain.
The preflight covers x402 over HTTP. x402 carried over MCP itself, where a paid tool returns its terms in a tool result and the payment travels in _meta["x402/payment"], is not supported. The transport's own example names an mcp:// resource, which schema.payment_required rejects because Settlens requires an http(s) resource.url, so the answer is do_not_pay.
To check how a resource behaves rather than what it advertises, assess it with the passive scan and authorized probe. Building agents that pay? Read Settlens for agent builders and offline payment verification.
Questions about the MCP server
Does Settlens pay or sign for my agent?
No. Every tool is read-only. Settlens never signs, settles, broadcasts or holds funds, and needs no wallet or payment key. Your agent's own wallet tooling makes the payment, after a pay decision.
Do I need an account or a token?
Not for the offline tools on https://settlens.com/mcp: they are public. scan_endpoint and scan_facilitator need a Settlens API token on that endpoint. The local stdio server needs the Settlens source, which pilot participants receive; request a pilot.
What does my agent send to settlens.com?
The tool arguments: for evaluate_payment_requirements, the PAYMENT-REQUIRED value, the URL and the policy. Never a key or a signature, unless you pass a payload to verify_payment_signature. If those values should not leave your infrastructure, run the server locally over stdio.
Why is the answer review when every check passed?
The policy does not bound the payment. A pay requires pay_to, assets, networks and max_amount in the policy, and the reason names the fields that are missing. A missing resource_url also gives review, through a warning on binding.resource_url.
Can a malicious server manipulate the agent through the 402?
Settlens treats server-provided values as data. Check messages are reduced to one bounded line, the policy checks report counts rather than server values, and the decision comes from fixed rules, not from the text. The agent should still never follow instructions found in tool results.
Does it evaluate x402 payments made over MCP?
No. It evaluates x402 over HTTP: the PAYMENT-REQUIRED header of a 402 response. The x402 MCP transport returns the terms in a tool result instead, and its own example names an mcp:// resource, which Settlens rejects in schema.payment_required (it requires an http(s) resource.url), so the answer is do_not_pay.
Which MCP clients work?
Claude Code and Claude Desktop setups are shown above. Any client that launches a stdio server or speaks Streamable HTTP can connect. The server implements MCP revisions 2025-06-18, 2025-03-26 and 2024-11-05.
Sources
Give your agent a preflight check
Connect the public endpoint in one command, or request a pilot to run every tool locally and assess your own x402 endpoints and facilitators.