Register an agent, grant scoped permissions, and let it trade, reorder, and learn — with full audit trails and human-in-the-loop approval.
Every agent action follows the Draft / Approve pattern. Low-value actions are auto-approved. High-value actions require human review. Every action creates a FoodBlock.
POST /api/v1/agents
{
"name": "Bakery Inventory Agent",
"model": "claude-sonnet",
"capabilities": ["transfer.order", "substance.ingredient", "observe.preference"],
"max_amount": 500,
"auto_approve_under": 100,
"rate_limit_per_hour": 30
}
// Response:
{
"agent_hash": "f6a1b2c3d4e5...",
"public_key": "302a300506...",
"private_key": "302e020100...", // Save this! Cannot be recovered.
"capabilities": ["transfer.order", "substance.ingredient", "observe.preference"],
"status": "active"
}Three detailed stories showing how autonomous agents operate in the food system.
Monitors stock levels across all ingredient lines. When flour drops below the reorder threshold, the agent drafts a transfer.order to the preferred supplier. It learns from past orders — which supplier delivers fastest, which has the best price for organic flour, which one the bakery rejected last time. All preferences stored as observe.preference blocks.
// Bakery Inventory Agent
// Runs on schedule: every 30 minutes
// 1. Check current stock
const stock = await foodblock_query({
type: 'substance.ingredient',
ref_role: 'venue',
ref_value: bakeryHash
});
// 2. Flour is low → draft a reorder
await foodblock_agent_draft({
agent_hash: agentHash,
type: 'transfer.order',
state: {
items: [{ sku: 'organic-strong-flour',
qty_kg: 50, unit_price: 1.80 }],
total: 90.00,
delivery: 'next_day',
note: 'Auto-reorder: stock below 10kg'
},
refs: {
buyer: bakeryHash,
supplier: preferredSupplierHash
}
});
// → Auto-approved (amount < £100 threshold)
// 3. Store supplier preference
await foodblock_create({
type: 'observe.preference',
state: {
context: 'flour_reorder',
preferred: 'Wessex Mill',
reason: 'fastest_delivery',
learned_from: 'last_5_orders'
},
refs: { agent: agentHash }
});{
"type": "transfer.order",
"state": {
"items": [{
"sku": "organic-strong-flour",
"qty_kg": 50,
"unit_price": 1.80
}],
"total": 90.00,
"delivery": "next_day",
"draft": false,
"approved_at": "2026-02-18T14:32:00Z"
},
"refs": {
"buyer": "d4e5f6a1...",
"supplier": "a1b2c3d4...",
"agent": "f6a1b2c3..."
}
}Subscribes to transfer.donation blocks within a configurable radius. When a restaurant or bakery posts surplus, this agent evaluates the donation against registered charity needs — food type, quantity, dietary requirements, collection capacity. It auto-claims matching donations, then triggers a logistics agent to handle pickup. The entire flow happens in under 5 minutes with zero human intervention.
// Surplus Matching Agent
// Triggered by: new transfer.donation block
// 1. New surplus posted by bakery
const donation = event.block;
// donation.state = {
// items: ['sourdough_x20', 'rye_x12'],
// weight_kg: 18,
// available_until: '18:00',
// pickup_location: 'SE1 9SG'
// }
// 2. Check charity needs within 5km
const charities = await foodblock_query({
type: 'actor.sustainer',
state: { accepts: 'bread' }
});
const nearby = charities.filter(
c => distance(c.state.location, 'SE1 9SG') < 5
);
// 3. Auto-claim for best match
await foodblock_agent_draft({
agent_hash: charityAgentHash,
type: 'observe.claim',
state: {
donation_id: donation.hash,
charity: 'Southwark Food Bank',
eta_minutes: 45,
claimed_at: new Date().toISOString()
},
refs: {
donation: donation.hash,
charity: charityHash
}
});
// 4. Trigger logistics agent for pickup
// → Logistics agent bids on route
// → Driver dispatched, ETA 17:15{
"type": "observe.claim",
"state": {
"donation_id": "e5f6a1b2...",
"charity": "Southwark Food Bank",
"eta_minutes": 45,
"claimed_at": "2026-02-18T16:04:00Z",
"status": "confirmed"
},
"refs": {
"donation": "e5f6a1b2...",
"charity": "c3d4e5f6...",
"agent": "b2c3d4e5..."
}
}An MCP-powered agent that answers natural language questions about the supply chain. Ask it "which shipments are at risk?" and it queries observation blocks for temperature anomalies, cross-references ETAs, and suggests rerouting. Ask "trace this salmon to the farm" and it walks the provenance tree in one tool call. It understands food — not just data.
// Supply Chain Copilot via MCP
// Model: Claude with FoodBlock MCP server
// User asks: "Which chilled shipments
// arriving tomorrow have had temp breaches?"
// Claude calls MCP tools:
> foodblock_query({
type: 'observe.alert',
state: { severity: 'temp_breach' },
since: '24h'
})
// → 3 alerts found
> foodblock_chain({
hash: alert.refs.shipment
})
// → Full shipment history for each
// Claude responds:
"3 shipments flagged:
- SH-441 (salmon, Edinburgh→London)
2 breaches in transit, max 8.2°C
Recommend inspection on arrival.
- SH-503 (dairy, Bristol→Birmingham)
1 breach, 6.1°C for 22 minutes.
Within tolerance but monitor.
- SH-612 (chicken, Norwich→London)
Sensor offline for 45 minutes.
Recommend manual temp check."
// Every answer backed by block hashes.
// Every claim verifiable.{
"type": "observe.alert",
"state": {
"severity": "temp_breach",
"metric": "temperature_c",
"value": 8.2,
"threshold": 5.0,
"duration_minutes": 34,
"sensor_id": "TH-441-02"
},
"refs": {
"shipment": "a1b2c3d4...",
"previous_reading": "f6a1b2c3...",
"sensor": "d4e5f6a1..."
}
}Agents are powerful but constrained. Every capability is scoped, capped, and auditable.
Register an agent in one API call. The MCP server gives any LLM food system superpowers. Start building autonomous food agents today.