Verify before sign.
As a type, and as a runtime guarantee.
None of the agentic commerce protocols carries a fingerprint of the terms it is settling. The Legal Context Protocol (LCP) defines one. Agentic Terms is the buyer-side check: it fetches the terms the seller advertised, recomputes that fingerprint over the bytes actually served, and refuses to reach your signing key if the two disagree.
npm install @integraledger/agentic-termsThe failure is not the one people expect
Told that a fingerprint disagrees, agents already halt — reliably and unprompted. That is not the gap. The gap is that nothing tells them: a seller who advertised no fingerprint reads as nothing to check.
Reading is not verifying
Fetching a terms document tells you what was served to you. Only a fingerprint the seller advertised binds the seller to it.
Your own hash proves nothing
Hashing the bytes you were handed records what you saw. It is not a commitment, because the seller never made one — in a dispute it proves only that you hashed something.
Gaps resolve by policy
Paying at Level 1 can be correct. What must not happen is paying while believing the terms were verified — so a gap is your stated disposition, never a silent default.
The whole integration
Parse the challenge into a typed proposal, hand it to transact with your policy and your signer. The key is reachable on one path only.
import {
makeCachingFetcher,
nodeDnsLookup,
parseProposalFromChallenge,
transact,
} from "@integraledger/agentic-terms";
const now = () => new Date().toISOString();
const fetcher = makeCachingFetcher({ httpFetch: fetch, now, lookup: nodeDnsLookup });
// `challenge` is the 402 body the seller returned.
const proposal = parseProposalFromChallenge(challenge, {
level: 3,
sellerAssurance: "domain-controlled",
});
const result = await transact(proposal, policy, { fetcher, now }, signer);
// result.kind === "signed" only on Proceed.
// On Decline or Escalate the signer is never called.Three outcomes, and only one reaches the key
A step’s four-valued status maps totally onto a disposition. A failure always declines; gaps are resolved by the buyer’s stated policy.
Proceed
The terms served hash to the fingerprint the seller advertised, and the typed record satisfies your policy. The signer is called exactly once.
Decline
A fingerprint mismatch, an unfetchable document, a level below your floor, a forbidden clause, an offer over your cap. Carries a halt class, a code, and a detail you can report to the seller.
Escalate
Hands back the exact bytes and their hash, so what a human approves is what a key would sign. Reached only when your policy elects it.
Works on the protocol you are already on
Reading the advertised reference is universal. Parsing a full proposal is not — and the difference is a fact about the protocols, not a gap in the library.
| Capability | Reach | Why |
|---|---|---|
readAdvertisedTerms | All nine registered protocols | The reference is read out of each protocol’s own placement manifest — every carrier it declares, not the first that answers. |
parseProposalUniversal | x402, ACP | A proposal also carries an offer, and an amount with its unit is protocol-native economics no manifest declares. |
| Parsers reached by name | AP2, MPP | Every AP2 envelope is also an A2A message, and an MPP request body carries nothing that names MPP. Ambiguity refuses rather than guesses. |
detectProtocol | Never a guess | Collects every discriminant that fires, not the first. A document that is legitimately two protocols’ comes back named twice. |
Or hand the checks to your agent host
@integraledger/lcp-mcp-server is a read-only Model Context Protocol server. Every tool reads; nothing publishes, transmits, or holds a credential.
{
"mcpServers": {
"lcp": {
"command": "npx",
"args": [
"-y",
"@integraledger/lcp-mcp-server"
]
}
}
}Properties worth relying on
The prompt-injection boundary is architectural
The typed proposal cannot carry natural-language prose, so the terms body can never reach policy evaluation. That is a property of the type, not a matter of discipline.
The fetcher is the SSRF guard
HTTPS-only, refuses redirects, re-checks every resolved address is public unicast on every network fetch, and caps the body while streaming. The URL came off the seller’s challenge.
Runs wherever your agent runs
Node, Bun and Deno are measured on every release — against the packed tarball, installed the way you would install it. The package’s own source imports no Node built-in.
Nothing calls home
No telemetry, no callback, no registry check — no network request other than fetching the terms the seller pointed you at.
Start here
Both packages implement the buyer side of the Legal Context Protocol, co-stewarded by Integra Ledger and AAA-ICDR. The seller-side application is separately licensed and is not part of this repository.
On npm: @integraledger/agentic-terms · @integraledger/lcp-mcp-server