$ DOCUMENTATION
Kontext is the trust layer for agentic stablecoin and fiat payments. Cryptographic verifiable intent for org-wide payments using one line of code and a CLI. Available as a TypeScript SDK (npm), CLI, and Python client (PyPI).
Installation
The fastest way to get started is the CLI wizard:
npx kontext init
npm install kontext-sdkOr with yarn / pnpm:
yarn add kontext-sdk
# or
pnpm add kontext-sdkPython:
pip install kontext-sdkRequirements: Node.js 18+ and TypeScript 5.0+ for the SDK. Python 3.9+ for the Python client. The TypeScript SDK has zero runtime dependencies.
Quick Start
Run one command. Wrap your client. Every stablecoin transfer gets cryptographic verifiable intent automatically.
Step 1: Initialize your project
npx kontext initStep 2: Wrap your client (one line)
import { Kontext, withKontextCompliance } from 'kontext-sdk';
import { createWalletClient, http } from 'viem';
import { base } from 'viem/chains';
// Reads kontext.config.json (generated by npx kontext init)
const kontext = Kontext.init();
// Wrap your viem client — one line
const client = withKontextCompliance(
createWalletClient({ chain: base, transport: http() }),
kontext,
);
// Every stablecoin transfer is now auto-verified
await client.sendTransaction({ to: usdcAddress, data: transferCalldata });
// → OFAC screening, audit trail, trust score — automaticallyFor explicit control over individual transactions, use verify() directly:
import { Kontext } from 'kontext-sdk';
const ctx = Kontext.init({ projectId: 'my-project' });
// Explicit verify for individual transactions
const result = await ctx.verify({
txHash: '0xabc...def',
chain: 'base',
amount: '5000',
token: 'USDC',
from: '0xAgentWallet',
to: '0xRecipient',
agentId: 'payment-agent',
});
// result.compliant — true/false
// result.checks — OFAC, Travel Rule, CTR thresholds
// result.riskLevel — low | medium | high | critical
// result.digestProof — tamper-evident SHA-256 chainAuto-Instrumentation
Instead of manually calling verify() on every transaction, auto-instrumentation logs every stablecoin transfer automatically. Two layers work together for full coverage:
Layer 1 — Code wrap: withKontextCompliance(client, kontext) intercepts sendTransaction and writeContract calls on your viem client. Can block non-compliant transfers in pre-send mode.
Layer 2 — Chain listener: The SDK watches your monitored wallet addresses on-chain for ERC-20 Transfer events. Catches transfers from any source — other scripts, wallet UIs, Circle dashboard, autonomous agents.
Step 1: Run the CLI wizard
# Step 1: Run the CLI wizard
$ npx kontext init
? Project name: treasury-agent
? Agent ID: treasury-agent-v1
? Wallet addresses to monitor: 0xTreasury..., 0xAgent...
? Which tokens? USDC, USDT
? Which chains? base, ethereum
? Compliance mode: post-send
? RPC for base: https://mainnet.base.org
? From country (optional): US
✓ Created kontext.config.json
✓ Monitoring 2 wallets on base, ethereumStep 2: Wrap your client (2 lines)
import { Kontext, withKontextCompliance } from 'kontext-sdk';
// Step 2: Zero-arg init reads kontext.config.json automatically
const kontext = Kontext.init();
// Step 3: Wrap your viem client — 1 line
const client = withKontextCompliance(rawClient, kontext);
// Every stablecoin transfer is now auto-logged with:
// - OFAC screening
// - Tamper-evident audit trail
// - Trust scoring
// - Digest chain proof
// Wallet monitoring also runs in the background —
// catches transfers from ANY source (other scripts, wallet UIs, etc.)Config file format
The wizard generates a kontext.config.json that the SDK reads automatically via Kontext.init() (zero-arg). You can also create or edit this file manually.
// kontext.config.json (generated by npx kontext init)
{
"$schema": "https://getkontext.com/schema/config.json",
"projectId": "treasury-agent",
"agentId": "treasury-agent-v1",
"environment": "production",
"wallets": ["0xTreasury...", "0xAgent..."],
"tokens": ["USDC", "USDT"],
"chains": ["base", "ethereum"],
"rpcEndpoints": {
"base": "https://mainnet.base.org",
"ethereum": "https://eth.llamarpc.com"
},
"mode": "post-send",
"corridors": { "from": "US" }
}Deduplication is built-in — if both the code wrap and chain listener catch the same transaction, it is only verified once.
Action Logging
Every action your agents take should be logged for auditability. Kontext provides action logging, transaction logging, and reasoning logging -- each feeds into the digest chain.
import { Kontext } from 'kontext-sdk';
const ctx = Kontext.init({ projectId: 'my-project' });
// Log any agent action -- not just transfers
await ctx.log({
action: 'data_access',
agentId: 'research-agent',
details: 'Queried customer database',
metadata: { purpose: 'quarterly_report' },
});
// Log agent reasoning separately
// When regulators ask "why did your agent do that?" -- you can answer
await ctx.logReasoning({
agentId: 'payment-agent-v2',
action: 'approve-transfer',
reasoning: 'Transfer within daily limit. Recipient verified in allowlist.',
confidence: 0.95,
context: { dailyTotal: '32000', recipientVerified: true },
});
// Retrieve reasoning entries later
const entries = ctx.getReasoningEntries('payment-agent-v2');Reasoning entries are separate from action logs. When regulators ask "why did your agent approve that transfer?" -- reasoning logs are your answer.
Task Confirmation
For high-value or sensitive actions, create a task that requires human approval before the agent proceeds. Tasks track required evidence and who confirmed them.
import { Kontext } from 'kontext-sdk';
const ctx = Kontext.init({ projectId: 'treasury-app' });
// Create a task that requires human approval
const task = await ctx.createTask({
description: 'Approve $25,000 USDC transfer to 0xrecipient',
agentId: 'treasury-agent-v2',
requiredEvidence: ['txHash', 'recipientVerified'],
});
// ... human reviews and approves ...
// Confirm with evidence
const confirmed = await ctx.confirmTask({
taskId: task.id,
evidence: {
txHash: '0xabc...def',
recipientVerified: true,
},
confirmedBy: 'admin@company.com',
});
// Check task status at any time
const status = await ctx.getTaskStatus(task.id);
// List all pending tasks
const pending = ctx.getTasks('pending');Audit Export
Export your complete audit trail as JSON (CSV on Pro). The digest chain provides cryptographic proof that no records have been tampered with. Generate compliance certificates that bundle the audit trail, trust scores, and reasoning.
import { Kontext } from 'kontext-sdk';
const ctx = Kontext.init({ projectId: 'my-project' });
// ... log some actions and transactions ...
// Export the full audit trail as JSON
const audit = await ctx.export({ format: 'json' });
// audit.data contains all action logs with digest proofs
// Verify the digest chain is intact (no tampering)
const chain = ctx.verifyDigestChain();
console.log('Chain valid:', chain.valid);
console.log('Chain length:', chain.chainLength);
// Get the terminal digest -- your tamper-evident fingerprint
const terminal = ctx.getTerminalDigest();
// Export the full digest chain for external verification
const exported = ctx.exportDigestChain();
// { genesisHash, links, terminalDigest }
// Generate a compliance certificate (includes digest proof + trust score)
const cert = await ctx.generateComplianceCertificate({
agentId: 'treasury-agent-v2',
timeRange: { from: startOfMonth, to: endOfMonth },
includeReasoning: true,
});Trust Scoring
Every agent gets a trust score from 0 to 100, computed from five factors: history, amount patterns, transaction frequency, destination trust, and behavioral consistency. Use it to gate actions, set thresholds, or flag agents for review.
import { Kontext } from 'kontext-sdk';
const ctx = Kontext.init({ projectId: 'my-project' });
// Get trust score for any agent
const trust = await ctx.getTrustScore('payment-agent-v2');
console.log(trust.score); // 87 (0-100)
console.log(trust.level); // 'high'
console.log(trust.factors);
// {
// history: 0.95, -- agent's track record
// amount: 0.88, -- transaction amount patterns
// frequency: 0.92, -- how often the agent transacts
// destination: 0.85, -- recipient trust level
// behavior: 0.90, -- behavioral consistency
// }
// Evaluate a transaction before executing it
const evaluation = await ctx.evaluateTransaction({
txHash: '0xabc...def',
chain: 'base',
amount: '15000',
token: 'USDC',
from: '0xsender...',
to: '0xrecipient...',
agentId: 'payment-agent-v2',
});Anomaly Detection
Enable rule-based anomaly detection to flag or block suspicious agent behavior. The free tier includes two rules (unusualAmount and frequencySpike). Pro unlocks four more: newDestination, offHoursActivity, rapidSuccession, and roundAmount.
import { Kontext } from 'kontext-sdk';
const ctx = Kontext.init({ projectId: 'my-project' });
// Enable anomaly detection with rules
ctx.enableAnomalyDetection({
rules: ['unusualAmount', 'frequencySpike'],
thresholds: {
maxAmount: '50000',
maxFrequency: 20,
},
});
// React to anomalies in real time
const unsubscribe = ctx.onAnomaly((event) => {
console.log('Anomaly detected:', event.type);
console.log('Details:', event.details);
// Alert your compliance team via Slack, PagerDuty, etc.
});
// verify() automatically checks anomaly rules
const result = await ctx.verify({
txHash: '0xabc...def',
chain: 'base',
amount: '75000',
token: 'USDC',
from: '0xsender...',
to: '0xrecipient...',
agentId: 'payment-agent-v2',
});
// Turn it off when you don't need it
ctx.disableAnomalyDetection();Reserve Reconciliation
Query on-chain totalSupply() for USDC, USDT, DAI, and EURC. Compare against published reserve figures from the issuer. Get reconciliation status with block-level proof — all from one SDK call. Read-only, zero dependencies, uses native fetch() with JSON-RPC.
import { ReserveReconciler } from 'kontext-sdk';
const snapshot = await ReserveReconciler.querySupply({
token: 'USDC',
chain: 'base',
rpcUrl: process.env.BASE_RPC_URL!,
publishedReserves: '36241612000', // from issuer report
tolerance: 0.001, // 0.1%
});
// snapshot.reconciliationStatus
// → 'matched' | 'delta_within_tolerance' | 'discrepancy' | 'unverified'
// snapshot.onChainSupply → '36241847291'
// snapshot.snapshotBlockNumber → 28419032
// snapshot.snapshotBlockHash → '0x8f2a...d41c'
// snapshot.delta → '0.0000064...' (raw ratio)With Digest Chain Logging
Use the Kontext client method to automatically log each reserve snapshot into your tamper-evident digest chain:
// Via the Kontext client (logs to digest chain automatically)
const snapshot = await kontext.logReserveSnapshot({
token: 'USDC',
chain: 'base',
rpcUrl: process.env.BASE_RPC_URL!,
publishedReserves: '36241612000',
agentId: 'treasury-agent',
});
// The snapshot is now part of your tamper-evident digest chain
const chain = kontext.exportDigestChain();
console.log('Digest chain length:', chain.links.length);Reconciliation Status
| Status | Meaning |
|---|---|
matched | On-chain supply exactly matches published reserves |
delta_within_tolerance | Delta exists but within the configured tolerance (default 0.1%) |
discrepancy | Delta exceeds tolerance — investigate |
unverified | No published reserves supplied — supply-only snapshot |
Supported tokens: USDC, USDT, DAI, EURC across all 8 chains. Use ReserveReconciler.getSupportedChains(token) to list available chains for a token, and ReserveReconciler.getContractAddress(token, chain) to look up the contract address.
On-Chain Anchoring
The digest chain gives you tamper-evidence at the software level. On-chain anchoring takes it further -- write the terminal digest to a smart contract on Base or Arc. Now anyone can independently verify that your compliance checks ran at a specific block height. No Kontext account needed.
import { Kontext, verifyAnchor, getAnchor, anchorDigest } from 'kontext-sdk';
const ctx = Kontext.init({ projectId: 'my-project' });
// Option 1: Anchor automatically via verify()
const result = await ctx.verify({
txHash: '0xabc...def',
chain: 'base',
amount: '5000',
token: 'USDC',
from: '0xsender...',
to: '0xrecipient...',
agentId: 'payment-agent-v2',
anchor: {
rpcUrl: 'https://mainnet.base.org',
contractAddress: process.env.KONTEXT_ANCHOR_ADDRESS,
privateKey: process.env.ANCHOR_PRIVATE_KEY,
},
});
// result.anchorProof = { txHash, blockNumber, chain, ... }
// Option 2: Read-only verification -- zero dependencies
const verified = await verifyAnchor(rpcUrl, contractAddress, digest);
// verified.anchored = true/false
// Option 3: Get full anchor details
const details = await getAnchor(rpcUrl, contractAddress, digest);
// details = { anchorer, projectHash, timestamp }
// Option 4: Write an anchor manually (requires viem as peer dep)
const anchorResult = await anchorDigest(
{ rpcUrl, contractAddress, privateKey },
digest,
'my-project'
);The verifyAnchor() and getAnchor() functions have zero dependencies -- they use native fetch() with ABI-encoded RPC calls. The anchorDigest() write function requires viem as a peer dependency.
Deployed contracts
- Base mainnet (verified): 0x89725bc547c5e38f0c2a56758723514acf411a86
- Base Sepolia (testnet): 0xbc711590bca89bf944cdfb811129f74d8fb75b46
A2A Attestation
When two agents transact, both sides need proof that the other ran compliance. A2A attestation handles this automatically -- pass a counterparty config to verify() and the SDK exchanges digests via the counterparty's /.well-known/kontext.json agent card and /kontext/attest endpoint.
import { Kontext, fetchAgentCard, exchangeAttestation } from 'kontext-sdk';
const ctx = Kontext.init({ projectId: 'my-project' });
// Option 1: Attestation via verify()
const result = await ctx.verify({
txHash: '0xabc...def',
chain: 'base',
amount: '5000',
token: 'USDC',
from: '0xsender...',
to: '0xrecipient...',
agentId: 'sender-agent',
counterparty: {
endpoint: 'https://receiver.example.com',
agentId: 'receiver-v1',
},
});
// result.counterparty = { attested, digest, agentId, timestamp }
// Option 2: Discover a counterparty agent
const card = await fetchAgentCard('https://receiver.example.com');
// card = { agentId, kontextVersion, capabilities, attestEndpoint }
// Option 3: Exchange attestation directly
const attestation = await exchangeAttestation(
{ endpoint: 'https://receiver.example.com', agentId: 'receiver-v1' },
{
senderDigest: ctx.getTerminalDigest(),
senderAgentId: 'sender-agent',
amount: '5000',
token: 'USDC',
timestamp: new Date().toISOString(),
}
);The attestation protocol uses native fetch() with zero dependencies. Both agents end up with the other's digest linked in their audit trail -- bilateral, cryptographic proof of mutual compliance.
Agent Provenance
Agent provenance adds three layers of accountability on top of the digest chain. Each layer answers a different question regulators ask.
Layer 1: Session Delegation
Records who authorized the agent to act. Every session captures the delegator, the agent, the permitted scope, and an optional expiration. The agent cannot create its own session -- a human or upstream system delegates authority.
Layer 2: Action Binding
Every verify(), log(), and logReasoning() call accepts a sessionId. The action envelope binds the call to the session that authorized it. Actions without a sessionId still log normally but lack the provenance binding.
Layer 3: Human Attestation
After actions execute, a human reviewer creates a checkpoint that references specific action IDs, then attests to it with a signature. The attestation key is held by the reviewer -- the agent never touches it. This proves a human reviewed the actions, not just that they ran.
import { Kontext, FileStorage } from 'kontext-sdk';
const ctx = Kontext.init({
projectId: 'treasury-app',
storage: new FileStorage('.kontext'),
});
// Layer 1: Session delegation — record who authorized the agent
const session = await ctx.createAgentSession({
agentId: 'treasury-agent',
delegatedBy: 'user:vinay',
scope: ['transfer', 'approve'],
expiresAt: new Date(Date.now() + 3600_000).toISOString(),
});
// Layer 2: Action binding — every verify() call ties to the session
const result = await ctx.verify({
txHash: '0xabc...def',
chain: 'base',
amount: '5000',
token: 'USDC',
from: '0xAgentWallet',
to: '0xRecipient',
agentId: 'treasury-agent',
sessionId: session.sessionId,
});
// Layer 3: Human attestation — reviewer signs off
const checkpoint = await ctx.createCheckpoint({
sessionId: session.sessionId,
actionIds: [result.transaction.id],
summary: 'Reviewed $5K USDC transfer to known vendor',
});
// Attest with a key the agent never touches
const attested = await ctx.attestCheckpoint({
checkpointId: checkpoint.checkpointId,
attestedBy: 'compliance-officer@company.com',
signature: reviewerSignature,
});
// End the session when done
await ctx.endAgentSession(session.sessionId);
// List all sessions and checkpoints
const sessions = ctx.getAgentSessions('treasury-agent');
const checkpoints = ctx.getCheckpoints(session.sessionId);CLI Commands
# Create a session for an agent
npx kontext-sdk session create --agent treasury-agent --delegated-by user:vinay --scope transfer,approve
# List active sessions
npx kontext-sdk session list --agent treasury-agent
# End a session
npx kontext-sdk session end <sessionId>
# Create a checkpoint referencing specific actions
npx kontext-sdk checkpoint create --session <sessionId> --actions act_1,act_2 --summary "Reviewed transfers"
# Attest a checkpoint (human signs off)
npx kontext-sdk checkpoint attest <checkpointId> --attested-by compliance@company.com
# List checkpoints for a session
npx kontext-sdk checkpoint list --session <sessionId>Agent Identity
Register agent identities with wallet mappings, reverse-lookup which agent owns a wallet, and manage identity lifecycles. Requires the Pro plan (kya-identity gate).
import { Kontext } from 'kontext-sdk';
const ctx = Kontext.init({
apiKey: process.env.KONTEXT_KEY,
projectId: 'forensics',
plan: 'payg',
});
// Register an agent with wallet mappings
ctx.registerAgentIdentity({
agentId: 'treasury-agent-v2',
displayName: 'Treasury Agent',
entityType: 'autonomous', // 'autonomous' | 'semi-autonomous' | 'human-supervised'
wallets: [
{ address: '0xTreasury...abc', chain: 'base', label: 'primary' },
{ address: '0xReserve...def', chain: 'base', label: 'reserve' },
],
});
// Add a wallet later
ctx.addAgentWallet('treasury-agent-v2', {
address: '0xOps...ghi', chain: 'ethereum', label: 'operations',
});
// Reverse lookup: which agent owns this wallet?
const agent = ctx.lookupAgentByWallet('0xTreasury...abc');
console.log(agent?.agentId); // 'treasury-agent-v2'
// Retrieve identity
const identity = ctx.getAgentIdentity('treasury-agent-v2');Wallet Clustering
Detect wallets controlled by the same agent using a Union-Find algorithm with 5 heuristics. Each cluster includes evidence trails documenting why wallets were grouped.
import { Kontext } from 'kontext-sdk';
const ctx = Kontext.init({
apiKey: process.env.KONTEXT_KEY,
projectId: 'forensics',
plan: 'payg',
});
// Register agents and their wallets...
// Then detect clusters across all registered agents
const clusters = ctx.getWalletClusters();
for (const cluster of clusters) {
console.log('Cluster wallets:', cluster.wallets);
console.log('Heuristics matched:', cluster.heuristics);
// e.g. ['shared-owner', 'funding-chain', 'temporal-correlation']
console.log('Evidence:', cluster.evidence);
}
// 5 clustering heuristics:
// - shared-owner: wallets registered to the same agent
// - temporal-correlation: wallets active in the same time windows
// - funding-chain: one wallet funds another
// - amount-pattern: matching transaction amounts across wallets
// - network-overlap: shared counterpartiesConfidence Scoring
Compute a composite identity confidence score (0-100) for registered agents. The score combines 5 components: identity-completeness, wallet-verification, behavioral-consistency, historical-depth, and cluster-coherence.
import { Kontext } from 'kontext-sdk';
const ctx = Kontext.init({
apiKey: process.env.KONTEXT_KEY,
projectId: 'forensics',
plan: 'payg',
});
// Compute identity confidence for an agent
const score = ctx.getKYAConfidenceScore('treasury-agent-v2');
console.log(score.score); // 82 (0-100)
console.log(score.level); // 'high' | 'medium' | 'low' | 'very-low'
console.log(score.components); // breakdown by factor
// Components: identity-completeness, wallet-verification,
// behavioral-consistency, historical-depth, cluster-coherence
// Export all forensics data
const envelope = ctx.getKYAExport();
// { identities, clusters, embeddings, links, scores, generatedAt }Wallet Providers
Configure Kontext to work with your preferred wallet provider for compliance-wrapped wallet operations. The kontext init wizard sets up credentials, validates API access, and stores secrets securely. All transferWithCompliance() methods automatically run verify() before executing transfers.
Configuration
Run npx @kontext-sdk/cli init and select your wallet provider. The wizard generates a kontext.config.json with your provider config:
// kontext.config.json — generated by "kontext init"
{
"projectId": "my-agent",
"walletProvider": {
"type": "circle",
"apiKeyEnvVar": "CIRCLE_API_KEY",
"entitySecretEnvVar": "CIRCLE_ENTITY_SECRET",
"circleEnvironment": "production",
"secretsStorage": { "type": "dotenv", "path": ".env" }
}
}Circle Programmable Wallets
Developer-controlled wallets via Circle's W3S API. Create wallet sets, manage wallets, and execute transfers with automatic OFAC screening and audit trail logging.
import { Kontext, CircleWalletManager } from 'kontext-sdk';
// Option 1: Auto-configured from kontext.config.json
const ctx = Kontext.init();
const walletSet = await ctx.createCircleWalletSet({ name: 'treasury' });
const wallets = await ctx.createCircleWallet({
walletSetId: walletSet.id,
blockchains: ['base'],
});
// Transfer with automatic compliance verification
const result = await ctx.circleTransferWithCompliance({
walletId: wallets[0].id,
tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
destinationAddress: '0xRecipient...',
amount: '5000',
blockchain: 'base',
agentId: 'treasury-agent',
});
// result.complianceResult.compliant = true/false
// result.state = 'INITIATED' | 'BLOCKED'
// Option 2: Direct manager (no Kontext client)
const mgr = new CircleWalletManager({
apiKey: process.env.CIRCLE_API_KEY!,
entitySecret: process.env.CIRCLE_ENTITY_SECRET!,
});
const valid = await mgr.validateCredentials(); // true/falseCoinbase Developer Platform (CDP)
Server-side wallets via Coinbase CDP. Ed25519 JWT authentication with separate wallet auth for transaction signing.
import { Kontext, CoinbaseWalletManager } from 'kontext-sdk';
const ctx = Kontext.init(); // loads walletProvider from config
// Create an EVM account
const account = await ctx.createCoinbaseAccount({ network: 'base' });
// Transfer with compliance
const result = await ctx.coinbaseTransferWithCompliance({
fromAddress: account.address,
toAddress: '0xRecipient...',
amount: '1000',
token: 'USDC',
network: 'base',
agentId: 'payment-agent',
});
// Direct manager usage
const mgr = new CoinbaseWalletManager({
apiKeyId: process.env.CDP_API_KEY_ID!,
apiKeySecret: process.env.CDP_API_KEY_SECRET!,
walletSecret: process.env.CDP_WALLET_SECRET!,
});
const accounts = await mgr.listAccounts();MetaMask Embedded Wallets
Embedded wallets via Web3Auth Node SDK. Stateless and sessionless — each connection is independent. Requires @web3auth/node-sdk as a peer dependency. Infura RPC access is pre-integrated.
import { Kontext, MetaMaskWalletManager } from 'kontext-sdk';
const ctx = Kontext.init(); // loads walletProvider from config
// Connect with JWT auth
const account = await ctx.metamaskConnect(userIdToken);
// Transfer with compliance
const result = await ctx.metamaskTransferWithCompliance({
toAddress: '0xRecipient...',
amount: '500',
token: 'USDC',
chain: 'base',
idToken: userIdToken,
agentId: 'wallet-agent',
});
// Direct manager usage (requires @web3auth/node-sdk)
const mgr = new MetaMaskWalletManager({
clientId: process.env.METAMASK_CLIENT_ID!,
authConnectionId: 'my-auth-connection',
web3AuthNetwork: 'sapphire_mainnet',
});Screening Providers
The ScreeningAggregator orchestrates multiple sanctions screening providers with configurable consensus strategies. Route queries to compatible providers, apply blocklist/allowlist overrides, and get aggregated results with per-provider detail.
import {
ScreeningAggregator,
OFACAddressProvider,
OFACEntityProvider,
UKOFSIProvider,
TRMLabsProvider,
} from 'kontext-sdk';
const aggregator = new ScreeningAggregator({
providers: [
new OFACAddressProvider(), // built-in, no API key
new OFACEntityProvider(), // built-in, no API key
new UKOFSIProvider(), // built-in, no API key
new TRMLabsProvider({ // requires API key
apiKey: process.env.TRM_API_KEY!,
}),
],
consensus: 'ANY_MATCH', // flag if ANY provider matches
blocklist: ['0xbad...'], // always flag these
allowlist: ['0xsafe...'], // never flag these
});
const result = await aggregator.screen('0xSuspectAddress');
// result.hit → true/false (per consensus strategy)
// result.hitCount → number of providers that matched
// result.matches → detailed match info per provider
// result.errors → any provider errors (non-fatal)Available Providers
| Provider | Lists | API Key |
|---|---|---|
OFACAddressProvider | OFAC SDN (addresses) | No — built-in |
OFACEntityProvider | OFAC SDN (entity names) | No — built-in |
UKOFSIProvider | UK OFSI sanctions | No — built-in |
OpenSanctionsLocalProvider | OpenSanctions (local) | No — synced via CLI |
OpenSanctionsProvider | OpenSanctions (API) | Yes |
ChainalysisOracleProvider | Chainalysis on-chain oracle | Yes |
ChainalysisFreeAPIProvider | Chainalysis free API | Yes |
TRMLabsProvider | TRM Labs screening | Yes |
KontextCloudScreeningProvider | Kontext Cloud (hosted) | Yes — Kontext API key |
Consensus Strategies
ANY_MATCH— flag if any provider reports a hit (most conservative)MAJORITY— flag if more than half of providers report a hitALL_MATCH— flag only if all providers agree (fewest false positives)
Payment Compliance
Compliance checks for non-crypto payment rails: wire transfers, ACH, card payments. Performs name-based OFAC entity screening and BSA threshold checks ($3K Travel Rule, $10K CTR, $50K large transaction). Returns the same check format as UsdcCompliance for consistency across all rails.
import { PaymentCompliance, CardCompliance } from 'kontext-sdk';
// General payment compliance (wire, ACH, any fiat flow)
const check = PaymentCompliance.checkPayment({
amount: '15000',
currency: 'USD',
from: 'Acme Corporation',
to: 'Global Payments Inc',
agentId: 'ap-system',
paymentMethod: 'wire',
});
// check.compliant → true/false
// check.checks → OFAC entity screening + BSA thresholds
// Card payment compliance (agent virtual cards)
const cardCheck = CardCompliance.checkCardPayment({
amount: '2500',
currency: 'USD',
from: 'agent-card-v1',
to: 'merchant-name',
agentId: 'purchasing-agent',
mcc: '5411', // Grocery Stores
merchantCountry: 'US',
});
// cardCheck includes MCC risk classification + country screeningWallet Monitor
Watch monitored wallet addresses on-chain for stablecoin Transfer events. Catches all outgoing transfers regardless of origin and auto-runs verify() on each one. Uses viem's watchEvent with HTTP polling — works with any RPC endpoint.
import { Kontext, WalletMonitor } from 'kontext-sdk';
const kontext = Kontext.init({ projectId: 'my-app' });
const monitor = new WalletMonitor(kontext, {
addresses: [
{ address: '0xMyWallet...', chain: 'base' },
],
rpcUrls: { base: process.env.BASE_RPC_URL! },
pollingIntervalMs: 4000,
}, { agentId: 'wallet-watcher', tokens: ['USDC', 'USDT'] });
await monitor.start();
// Now watching for all outgoing stablecoin transfers
// Each transfer auto-runs verify() and logs to digest chainPython Client
The Python client (kontext-sdk on PyPI) provides typed sync and async HTTP bindings for the Kontext REST API. All compliance logic runs server-side — the Python package is a thin wrapper with zero local processing.
pip install kontext-sdkRequirements: Python 3.9+. Dependencies: httpx and pydantic.
Python Usage
Sync Client
from kontext import Kontext
ctx = Kontext(api_key="sk_...", project_id="my-agent")
# Log a transaction
ctx.log_transaction(
tx_hash="0xabc...",
chain="base",
amount="5000",
token="USDC",
from_address="0xsender...",
to_address="0xrecipient...",
agent_id="payment-agent",
)
# Trust score
trust = ctx.get_trust_score("payment-agent")
print(f"Trust: {trust.score}/100 ({trust.level})")
# Human-in-the-loop
task = ctx.create_task(
description="Approve $5K transfer",
agent_id="payment-agent",
required_evidence=["txHash"],
)
confirmed = ctx.confirm_task(task.id, evidence={"txHash": "0xabc..."})
# Export audit trail
audit = ctx.export_audit(format="json")
# Flush to server
ctx.flush()Async Client
from kontext import AsyncKontext
async with AsyncKontext(api_key="sk_...", project_id="my-agent") as ctx:
await ctx.log(action="transfer", agent_id="agent-1")
trust = await ctx.get_trust_score("agent-1")
print(f"Trust: {trust.score}/100")API Methods
| Method | Description |
|---|---|
log(action, agent_id) | Buffer an action log |
log_transaction(tx_hash, chain, ...) | Buffer a transaction log |
flush() | Send buffered actions to server |
create_task(description, agent_id) | Create human-in-the-loop task |
get_trust_score(agent_id) | Get agent trust score (0-100) |
export_audit(format) | Export audit trail (JSON/CSV) |
evaluate_anomalies(amount, agent_id) | Evaluate for anomalies |
health() | Check API health |
CLI Installation
The Kontext CLI (@kontext-sdk/cli) provides 12 commands for compliance operations from the terminal. Install globally or run via npx — no project setup required.
# Install globally
npm install -g @kontext-sdk/cli
# Or run directly with npx (no install)
npx @kontext-sdk/cli verify --chain base --amount 0.50
# Verify installation
kontext --version # 0.12.0CLI Commands
Every SDK operation has a CLI equivalent. Run compliance checks, verify transactions, generate certificates, export audit trails, and anchor digests — all from the command line.
# Initialize project — interactive wizard
kontext init
# Static compliance check (no digest chain)
kontext check --chain base --amount 0.50 --from 0xSender --to 0xRecipient
# Full verification with digest chain and trust scoring
kontext verify --chain base --amount 0.50 --token USDC \
--from 0xSender --to 0xRecipient --agent research-agent
# Log agent reasoning
kontext reason --agent payment-agent-v2 \
--action approve-transfer \
--reasoning "Within daily limit. Recipient verified."
# Generate compliance certificate
kontext cert --agent payment-agent-v2 --format json
# Export audit trail
kontext audit --format json --output ./audit-trail.json
# Anchor digest on-chain (Base mainnet)
kontext anchor --rpc https://mainnet.base.org --contract 0x8972...a86
# Anchor digest on-chain (Base Sepolia testnet)
kontext anchor --rpc https://sepolia.base.org --contract 0xbc71...b46
# Exchange A2A attestation
kontext attest --endpoint https://counterparty.example.com
# Sync OFAC SDN list
kontext sync --list ofac
# Manage agent sessions and checkpoints
kontext session create --agent treasury-agent --scope transfer,approve
kontext checkpoint create --session <sessionId> --summary "Reviewed batch"
# Reserve reconciliation — query on-chain supply
kontext reconcile --token USDC --chain base --rpc https://mainnet.base.org \
--published 36241612000 --tolerance 0.001 --agent treasury-bot
# Authenticate CLI (stores API key in OS keychain)
kontext loginInteractive Setup
The kontext init wizard requires an interactive terminal. It walks you through project configuration, wallet provider credentials, API key scope guidance, credential validation, and secret storage — decisions that involve security settings requiring human review.
What the wizard configures
- Project name and agent ID
- Chain selection (Base, Ethereum, Polygon, Arbitrum, Optimism, Avalanche)
- Token selection (USDC, USDT, DAI, EURC)
- Compliance mode (post-send, pre-send, both)
- Wallet provider (Circle, Coinbase CDP, MetaMask) with credential guidance
- Secret storage (.env, GCP Secret Manager, AWS Secrets Manager, Vault)
Config template
To preview the config schema without running the wizard, use --json. This prints a starter template to stdout without writing to disk:
kontext init --jsonFor AI agents
Agents interacting with Kontext use the MCP server (kontext mcp), which exposes compliance tools (verify, check, reason, cert, audit, trust, anchor). The MCP server assumes kontext init has already been run by a human in an interactive terminal. If an agent detects that initialization is needed, it should instruct the developer to run kontext init in their terminal.
MCP Server
The CLI includes a built-in MCP (Model Context Protocol) server that exposes 8 compliance tools to AI coding assistants like Claude Code, Cursor, and Windsurf. Start it with kontext mcp.
# Start the MCP server
kontext mcp
# Add to Claude Code / Cursor / Windsurf config:
{
"mcpServers": {
"kontext": {
"command": "npx",
"args": ["@kontext-sdk/cli", "mcp"]
}
}
}
# 8 MCP tools exposed:
# - kontext_check: static compliance check
# - kontext_verify: full verification
# - kontext_reason: log agent reasoning
# - kontext_cert: generate certificate
# - kontext_audit: export audit trail
# - kontext_trust: get trust score
# - kontext_anchor: on-chain anchoring
# - kontext_attest: A2A attestationAPI Reference
Complete reference for all Kontext SDK methods. The SDK uses a private constructor with a static Kontext.init(config) factory.
// Initialization
const ctx = Kontext.init(config: KontextConfig): Kontext;
// The main function -- compliance check + transaction log in one call
await ctx.verify(input: VerifyInput): Promise<VerifyResult>;
// Action logging
await ctx.log(input: LogActionInput): Promise<ActionLog>;
await ctx.logTransaction(input: LogTransactionInput): Promise<TransactionRecord>;
await ctx.logReasoning(input: LogReasoningInput): Promise<ReasoningEntry>;
ctx.getReasoningEntries(agentId: string): ReasoningEntry[];
await ctx.flushLogs(): Promise<void>;
// Task confirmation (human-in-the-loop)
await ctx.createTask(input: CreateTaskInput): Promise<Task>;
await ctx.confirmTask(input: ConfirmTaskInput): Promise<Task>;
await ctx.getTaskStatus(taskId: string): Promise<Task | undefined>;
await ctx.startTask(taskId: string): Promise<Task>;
await ctx.failTask(taskId: string, reason: string): Promise<Task>;
ctx.getTasks(status?: TaskStatus): Task[];
// Trust scoring
await ctx.getTrustScore(agentId: string): Promise<TrustScore>;
await ctx.evaluateTransaction(tx: LogTransactionInput): Promise<TransactionEvaluation>;
// Anomaly detection
ctx.enableAnomalyDetection(config: AnomalyDetectionConfig): void;
ctx.disableAnomalyDetection(): void;
ctx.onAnomaly(callback: AnomalyCallback): () => void;
// Audit export
await ctx.export(options: ExportOptions): Promise<ExportResult>;
await ctx.generateReport(options: ReportOptions): Promise<ComplianceReport>;
await ctx.generateComplianceCertificate(input): Promise<ComplianceCertificate>;
// Digest chain (tamper-evidence)
ctx.getTerminalDigest(): string;
ctx.verifyDigestChain(): DigestVerification;
ctx.exportDigestChain(): { genesisHash, links, terminalDigest };
ctx.getActions(): ActionLog[];
// Agent provenance
await ctx.createAgentSession(input: CreateAgentSessionInput): Promise<AgentSession>;
await ctx.endAgentSession(sessionId: string): Promise<AgentSession>;
ctx.getAgentSessions(agentId: string): AgentSession[];
await ctx.createCheckpoint(input: CreateCheckpointInput): Promise<Checkpoint>;
await ctx.attestCheckpoint(input: AttestCheckpointInput): Promise<Checkpoint>;
ctx.getCheckpoints(sessionId: string): Checkpoint[];
// Persistence
await ctx.flush(): Promise<void>;
await ctx.restore(): Promise<void>;
// Plan management
ctx.getUsage(): PlanUsage;
ctx.setPlan(tier: PlanTier): void;
ctx.onUsageWarning(callback): () => void;
ctx.onLimitReached(callback): () => void;
// Lifecycle
await ctx.destroy(): Promise<void>;Configuration
Kontext can be configured in two ways: explicitly via Kontext.init(config), or automatically via kontext.config.json (generated by npx kontext init). When called with no arguments, Kontext.init() searches for a config file walking up from the current directory.
import { Kontext, FileStorage } from 'kontext-sdk';
const ctx = Kontext.init({
// Required
projectId: 'my-project',
// Optional
environment: 'production', // 'development' | 'staging' | 'production'
apiKey: 'sk_live_...', // only needed for cloud mode
plan: 'free', // 'free' | 'payg' | 'enterprise'
// Persistence -- default is in-memory (resets on restart)
storage: new FileStorage('./compliance-data'),
// Event exporters -- where to send events
exporters: [
// new ConsoleExporter(), // prints to stdout (dev)
// new JsonFileExporter(path), // writes JSONL to disk
// new HttpExporter(config), // sends to any HTTP endpoint
// new KontextCloudExporter(), // ships to api.getkontext.com (payg)
],
});Environment Variables
KONTEXT_API_KEY=sk_live_... # API key for cloud mode (Pro)
KONTEXT_CHAIN=base # Default chain
KONTEXT_ENVIRONMENT=production # EnvironmentTypeScript Types
All types are exported from the main package. Full autocomplete in any TypeScript-aware editor.
import type {
// Core
KontextConfig,
KontextMode,
LogActionInput,
LogTransactionInput,
TransactionRecord,
ActionLog,
// Verify
VerifyInput,
VerifyResult,
// Tasks
Task,
CreateTaskInput,
ConfirmTaskInput,
// Trust & Anomaly
TrustScore,
AnomalyEvent,
AnomalyDetectionConfig,
// Export & Reports
ExportOptions,
ExportResult,
ComplianceReport,
DigestVerification,
// Reasoning & Certificates
ReasoningEntry,
ComplianceCertificate,
// On-chain anchoring
OnChainAnchorConfig,
AnchorResult,
AnchorVerification,
// A2A attestation
AgentCard,
CounterpartyConfig,
AttestationRequest,
AttestationResponse,
CounterpartyAttestation,
// Agent provenance
AgentSession,
CreateAgentSessionInput,
Checkpoint,
CreateCheckpointInput,
AttestCheckpointInput,
} from 'kontext-sdk';Need help?
If you run into issues or have questions, reach out through any of these channels: