integra-agentic-terms
The buyer side of the Legal Context Protocol: packages that let an agent confirm, before it pays, that the payment it signs carries the hash of the exact record the seller serves.
What this repository is
A seller that follows the Legal Context Protocol (LCP) publishes the agreement's record, an Agentic Transaction
Record (ATR), at an https link, and advertises its SHA-256, the ATR hash (H), beside its payment request. Where
the payment the buyer approves carries H, that approval is the buyer's acceptance of that exact record; where it does
not, the pairing's statement of what it proves says so.
The packages here are the buyer's half of that pattern. Their centre is the buyer gate: it fetches the ATR, compares the SHA-256 of the served bytes with H, and only on a match builds the payment with that hash for the buyer's own signer. After the signer answers, the pairing reads H back from the completed payment, and the gate returns the payment only if it is the hash of the bytes received, or, where the proof is the agreement payment, without that reading. The gate holds no keys, reads none of the record's content, and carries no business or legal logic: what the record says is for the buyer and its principal to judge.
It works across payment protocols and rails. Each pairing of protocol, scheme and rail (such as
x402/exact/eip155/eip3009: x402's exact scheme on an EVM chain, paid with an EIP-3009 authorization) has a
binding: the field of the pairing's payment, as the protocol's own specification defines that payment, that carries
H. The gate serves every pairing of @integraledger/lcp: x402,
MPP, card, AP2, UCP, ACP and ACK, on EVM chains, Tempo, Solana, Stellar, the XRP Ledger, Hedera, Algorand, Aptos, Sui,
NEAR, Starknet, Polkadot, TRON, TON, Cardano, Casper, Concordium, Stacks and Lightning.
How the packages fit together
flowchart LR
agent["Your agent"] -->|MCP tools| mcp["@integraledger/terms-mcp"]
agent -->|TypeScript| terms["@integraledger/terms"]
agent -->|Python| py["integraledger-terms"]
mcp --> terms
terms --> lcp["@integraledger/lcp"]
vectors[("Shared vectors")] -.->|fix the rules| terms
vectors -.->|fix the rules| py
@integraledger/termsis the buyer gate in TypeScript. It takes its bindings, one per pairing, from@integraledger/lcp, the protocol package in integra-protocol.@integraledger/terms-mcpserves the gate's operations as MCP tools, with a skill that tells an agent how to use them. Each tool call is one call of@integraledger/terms.integraledger-termsis the same gate in Python, with its own bindings. It is a second implementation of the same rules, not a wrapper.- The shared vectors, shipped in
@integraledger/lcp'svectors/directory, fix the rules byte for byte. Both gates run every vector for the pairings and buyer rules they serve, and must produce the same hashes, the same requests and the same declines.
Packages
Each package's README is complete on its own: concepts, a quickstart that runs as printed, every flow, the API and the pairings it serves.
Quickstart
- Your agent is TypeScript: start with
@integraledger/terms.transact(offer, binding, signer, fetch)compares and pays in one call; for a pairing that needs an agreement payment, the first call returns it for your agent's approval, and a second call, withapproved, pays. - Your agent is Python: start with
integraledger-terms.await transact(offer, binding, signer, client)does the same, withapproved=…on the second call. - Your agent uses MCP tools: add
@integraledger/terms-mcpto its client, and give it the skill.
The documentation goes further: concepts, a getting-started walk-through, a guide for each flow, and the full reference, including every pairing and every decline code. It is also published at agenticterms.integraledger.com.
Building and testing
You need Node.js 26.11.1 (.node-version), pnpm 12.11.2 (the packageManager field) and, for the Python package,
uv. These are the commands CI runs:
pnpm install --frozen-lockfile
pnpm -r --if-present run build
pnpm -r --if-present run typecheck
pnpm -r --if-present run test
cd agentic-terms-py
uv run --locked --python 3.11 pytest -q
uv run --locked --python 3.14 pytest -q
uv run --locked --python 3.14 mypy --strict src tests
cd ..
node scripts/docs.mjs check
- The TypeScript tests, and the Python tests, run the shared vectors. The Python tests read them from
agentic-terms/node_modules/@integraledger/lcp/vectors, so runpnpm installfirst. node scripts/docs.mjs checkchecks the samples in the READMEs, the skill anddocs/against the packages you just built. It type-checks each TypeScript sample and compiles each Python one, runs every sample not markedno-run, and compares a run's printed output with the output shown after it. It parses each JSON sample, and checks the generated pairing tables against the code's registries. Shell blocks are not run. After you change a pairing, runnode scripts/docs.mjs generate.- The documentation site in
website/has its own lockfile and is built separately; see its README.
Contributing
Contributions are welcome. Read CONTRIBUTING.md first. Every commit must carry a Developer Certificate of Origin sign-off:
git commit -s -m "Describe what the change does"
-s adds the Signed-off-by: line that certifies you wrote the change or have the right to submit it under this
repository's license (developercertificate.org). On every push to main, CI reads
every commit in main's history and fails if a commit has no Signed-off-by: trailer or its message matches the agent
pattern in .github/workflows/ci.yml. It runs after the push and cannot hold a commit back.
This project follows the Contributor Covenant.
Security
Report a bug in a public issue. Report a vulnerability privately, through GitHub's private vulnerability reporting on this repository; never in a public issue. See SECURITY.md.