About foodblock-mcp
foodblock-mcp is an MCP server for AI agents that read and write signed FoodBlock records. It connects food-related information to a structured protocol with validation and author-controlled signatures.
Key features
- 01Read and write signed blocks
- 02Represent food and related records
- 03Validate block structure and signatures
- 04Work with FoodBlock identity chains
Use cases
- 01Record a food offer or commitment
- 02Read structured food information
- 03Check authorship and validity of records
MCP support
The MCP server lets MCP-compatible systems read and write signed FoodBlock blocks.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
npx -y foodblock-mcpFOODBLOCK_URLOptional FoodBlock server URL. Leave empty for standalone mode.Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.
Tools
17Saved tool list · updated 2w ago
| Parameter | Type | Required | Description |
|---|---|---|---|
| refs | object | No | References to other blocks by hash. Example: { seller: 'abc123...' } |
| type | string | Yes | Block type. Base types: actor, place, substance, transform, transfer, observe. Use dot notation for subtypes, e.g. actor.producer, substance.product, transfer.order |
| state | object | No | The block's properties as a JSON object. Example: { name: 'Sourdough', price: 4.50 } |
Details
From the project READMEFoodBlock
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:
{
"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 default suite; p256 and sm are two more). Nobody's clock decides who has authority. The
other side can check that authority. Nothing can be lost or forged without it showing.
- The spec:
spec/protocol.md, FoodBlock 1.6 (revised 2026-10-19). It is normative: where anything else here disagrees, it governs. Beside it:protocol.json(every list, for code to load), the canonical form, transport (email is the envelope, FoodBlock the letter) and the conformance vectors. There is no earlier version in the protocol: 1.6 is year zero. Old data enters once, through a converter that is not part of the protocol.NECESSITY.mdshows, for every field, term, verb, closed type, reference key and invariant, which vectors fail without it;EXPERIMENTS.mdrecords the compressions tried. - The paper: the FoodBlock whitepaper v1.6 (PDF) (DOI 10.5281/zenodo.23457910): why the protocol exists. Where it and the spec differ, the spec is current.
The language
Seven types, in three moods:
| Type | Meaning | |
|---|---|---|
| What exists | actor | A person, an autonomous system or machine, a circle, or a contact |
thing | Anything held, found or written: food, tools, places, recipes, shares, schemas | |
| Is | observe | A claim that something is so |
transform | A thing changes: inputs become outputs, or a thing is kept and stays itself | |
transfer | A thing changes owner, holder or place | |
| Must | promise | A commitment, offered or asked |
| May | grant | Authority 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 1.6 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 delivery van, a drone, a smart fridge, a
sensor. Machines are peers like people. Any food machine can take an SDK, make its own identity, and act within the
grants it holds. Each peer is one of three sizes (protocol.json peers):
- Micro, a device: a soil or fridge sensor, a scale, an oven, a robot's body. It needs the canonical form, SHA-256, Ed25519, the write check, its own chain, and the vectors for these. One that acts in the world also checks its grants and stops the moment a stop arrives.
- Edge, the local operator: the computer at a farm, in a kitchen, in a van or a shop. It adds local discovery, pull and push with the peers near it, the promise fold for its own deals, and it keeps working offline.
- Node, the lasting level: adds sealed envelopes and commitments, serving pull and push to anyone, signed answers, internet discovery, and the folds for every record it holds.
Only people and machines hold nodes. A business, a household or a community is a circle of them: it has an id and a record, kept by its members' nodes, never a node of its own.
What is here
| Folder | What it is |
|---|---|
spec/ | The protocol, its lists, the canonical form, transport, profiles, vectors, the oracle and the paper |
sdk/javascript | The reference SDK |
sdk/rust | The one core: every rule, as a Rust crate, a C library and WebAssembly |
sdk/python, sdk/go, sdk/swift, sdk/kotlin | The 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.sql | The 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:
- MCP server:
mcp/, for Claude, Cursor, Windsurf, Gemini CLI and any MCP-compatible autonomous system - The spec in one file:
spec/protocol.md, with every list machine-readable inspec/protocol.json - LLM quick reference: https://foodx.network/llms.txt
- About FoodX: https://foodx.network
Quick start
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) // who you are: its hash is your id
const eggs = fb.write('thing', { kind: 'eggs', name: 'Free-range eggs' }, {}, { author: me.hash, key: keys, held: [me] })
fb.valid(eggs, [me]) // [] : sound, signed by a key of its author, in its chain
From a terminal:
cd cli && npm install
node bin/fb.js init me.json
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 (spec/modules/nodes.md):
- Pull
{ since, limit, filter, heads }: every match since an arrival number, oldest first, never ranked.heads: truegives only the latest blocks. A signed pull also proves who is asking, so it gets the copies sealed to them. - Push
{ messages, for }: the node keeps what its authors signed and what the owner's admission rule lets in. A block whose previous block is missing waits. Two blocks of one key naming oneprevprove a lie. - A signed request carries a
counteror achallenge(GET /challenge) and no time. - Every answer is signed by a key of the node's holder (a person or a machine).
- Discovery:
.well-known/foodblocksays who the node is, what it holds, who it speaks for and its admission rule. On a local network it can be announced in a shorter form.
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
| What | Command |
|---|---|
| Conformance vectors | node spec/run-vectors.cjs |
| The SDKs carry the spec exactly | node test/sync-spec.cjs --check |
| JS SDK | cd sdk/javascript && npm test |
| Python SDK | cd sdk/python && python3 -m unittest discover -s tests |
| Go SDK | cd sdk/go && CGO_ENABLED=0 go test ./... |
| Swift SDK | sdk/swift/scripts/build-xcframework.sh --macos && swift test (at the root) |
| Rust core | cd sdk/rust && cargo test |
| Kotlin SDK | cd 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 oracle | node test/audit/run.cjs |
| No listed thing is dead or untested | node test/necessity.cjs (the full measurement, ten minutes: node tools/necessity.cjs) |
| Stored blocks against the current core | node tools/replay-check.cjs <export> (counts and reason codes only; see DISTRIBUTION.md) |
| Node | cd server && npm test (in-memory Postgres; set TEST_DATABASE_URL for a real one) |
| MCP server | cd mcp && npm test |
| CLI | cd cli && npm test |
Licence
MIT. Copyright FOODX WORLD LIMITED (England and Wales, company 16406719), which owns this repository. The protocol needs no one's permission to implement.
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.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.