Foodblock MCP README

The full upstream README, mirrored for reference. Install config, tool schemas, adoption signals and our own overview live on the Foodblock MCP listing page.

FoodBlock

OpenSSF Best Practices IETF Internet-Draft DOI OpenSSF Scorecard

The smallest language strangers in food need to agree on, with no boss. Everything else is data.

A block is three fields, signed by its author on their own device:

config.json
{
  "type": "promise",
  "state": {
    "terms": { "price": { "minor": 450, "currency": "GBP" }, "quantity": { "value": "30", "unit": "{egg}" } },
    "at": "2026-10-15T09:00:00.000Z",
    "audience": "public",
    "seq": 4
  },
  "refs": { "author": "a1b2…", "prev": "c3d4…", "from": "a1b2…", "what": "e5f6…" }
}

This is an offer: it is signed by its from side. Its id is the hash of its canonical form (one exact way of writing it as text: RFC 8785). The author signs the same bytes with Ed25519 (the suite std; p256 and sm are two more). Nobody's clock decides who has authority. The other side can check that authority. Without the author's key no one can make a block that counts as theirs, or change one without changing its id, and a key that signs two versions of its history leaves the proof. What the protocol cannot do (keep a lost key safe, stop a custodian who holds your key, see inside a sealed block it was not sent) is in the threat model (a draft).

The language

Seven types, in three moods:

TypeMeaning
What existsactorA person, an autonomous system or machine, a circle, or a contact
thingAnything held, found or written: food, tools, places, recipes, shares, schemas
IsobserveA claim that something is so
transformA thing changes: inputs become outputs, or a thing is kept and stays itself
transferA thing changes owner, holder or place
MustpromiseA commitment, offered or asked
MaygrantAuthority given to someone

Seven verbs, the refs that link blocks: updates, answers (the only way to consent), confirms, defeats, for, derives_from, same_as. prev and after say what came before.

Strict. Only four types carry authority and are closed (actor, promise, transfer, grant); any other word is an open type that a node stores and passes on. A node writes and reads only the current version's shapes: no nulls, no floats (money is { minor, currency }, an amount { value, unit } with a decimal string), exact UTC times, sets written sorted, every block in its key's chain (state.seq, refs.prev). It never repairs a block: it refuses it, and the author signs a new one.

Three sizes of peer

Every peer speaks the protocol itself: a phone, a robot kitchen, a van, a sensor. Machines are peers like people. There are three sizes (protocol.json peers, and spec/protocol.md): micro (a device that measures and signs), edge (the local operator, works offline) and node (the lasting level, serves pull and push to anyone). Only people and machines hold nodes. A business, a household or a community is a circle of them, never a node of its own.

What is here

FolderWhat it is
spec/The protocol, its lists, the canonical form, transport, profiles, vectors, the oracle and the paper
sdk/javascriptThe reference SDK
sdk/rustThe one core: every rule, as a Rust crate, a C library and WebAssembly
sdk/python, sdk/go, sdk/swift, sdk/kotlinThe same protocol in other languages, thin layers over the core; each runs every vector section
server/A node: Postgres for the blocks, HTTP for signed pull, push and .well-known/foodblock
mcp/An MCP server, so any autonomous system can write and read signed blocks
cli/fb: make an identity and device keys, write blocks in its key chain, check, validate, verify, and convert old data once
sql/schema.sqlThe node's store: append-only, each block kept exactly as it arrived
test/Cross-language canonical vectors, and the script that copies the spec into each SDK

Each SDK's README says which profile it covers.

For autonomous systems

FoodBlock is built for people, autonomous systems and machines to use together. An autonomous system can read and write it directly:

Quick start

server.ts
const fb = require('@foodxdev/foodblock') // in this repository: require('./sdk/javascript/src/index.cjs')
const keys = fb.generateKeypair()                  // one key is the whole ceremony
const me = fb.identity.genesis(keys, { kind: 'person', at: '2026-10-15T09:00:00.000Z', audience: 'public' })  // who you are: its hash is your id; kind, at and audience are yours to state
const eggs = fb.write('thing', { kind: 'eggs', name: 'Free-range eggs' }, {}, { author: me.hash, key: keys, held: [me], at: '2026-10-15T09:01:00.000Z', audience: 'public' })
fb.valid(eggs, [me])                               // [] : sound, signed by a key of its author, in its chain

From a terminal:

bash
cd cli && npm install
node bin/fb.js init me.json --kind person --audience public --reach P30D
node bin/fb.js create thing eggs --state '{"name":"Free-range eggs"}' --identity me.json

Between nodes

Anyone can leave a node with everything they signed. Peers swap blocks with two messages, pull and push, and every answer is signed by a key of the node's holder (spec/modules/nodes.md). .well-known/foodblock says who the node is, what it holds and its admission rule.

Run one with docker compose -f server/docker-compose.yml up, or cd server && npm install && npm start with a Postgres at DATABASE_URL and a key file from fb key at NODE_KEY.

Tests

WhatCommand
Conformance vectorsnode spec/run-vectors.cjs
The SDKs carry the spec exactlynode test/sync-spec.cjs --check
JS SDKcd sdk/javascript && npm test
Python SDKcd sdk/python && python3 -m unittest discover -s tests
Go SDKcd sdk/go && CGO_ENABLED=0 go test ./...
Swift SDKsdk/swift/scripts/build-xcframework.sh --macos && swift test (at the root)
Rust corecd sdk/rust && cargo test
Kotlin SDKcd sdk/kotlin && ./gradlew :foodblock:test (needs a JDK 17); the bundled-library check: scripts/build-natives.sh jvm && ./gradlew :foodblock:testBundled
The oracle (written from the spec text alone)node spec/oracle/run.cjs
Every fold, core against oraclenode test/audit/run.cjs
No listed thing is dead or untestednode test/necessity.cjs (the full measurement, ten minutes: node tools/necessity.cjs)
Stored blocks against the current corenode tools/replay-check.cjs <export> (counts and reason codes only; see DISTRIBUTION.md)
Nodecd server && npm test (in-memory Postgres; set TEST_DATABASE_URL for a real one)
MCP servercd mcp && npm test
CLIcd cli && npm test

Licence

Public domain (CC0 1.0; decided 2026-10-29, replacing MIT). FOODX WORLD LIMITED (England and Wales, company 16406719), which wrote it and runs this repository, waived its copyright: the protocol needs no one's permission to implement, copy or change.

How a change is proposed and how versions work: GOVERNANCE.md. How we treat each other, and what content is not allowed: CODE_OF_CONDUCT.md. Reporting a weakness: SECURITY.md.

To cite FoodBlock, see CITATION.cff.