FoodEx2 Encoder

org.foodnotesPublished by foodnotes.orgOfficial publisherv1.0.0Updated Oct 30, 2026

Turn an English food description into an EFSA FoodEx2 code.

VerifiedStreamable HTTPWeb executableData & AnalyticsAI & ML

Overview

AI-generated overview

Remote MCP server that turns an English food description into an EFSA FoodEx2 code with base term, facets and free text.

What you can do
  • Encode a food description into a FoodEx2 code, returning the code, base term, facets, free text, fit, method and a short explanation.
  • Look up catalogue terms lexically and by embedding, then walk the MTX catalogue to select a base term.
  • Record what the code cannot express as labelled free text, such as group names the catalogue splits into separate terms.
When to use it
Use it when you need FoodEx2 codes for food descriptions, for example preparing dietary exposure or food classification data for EFSA-style reporting. It suits quick single-description coding rather than bulk catalogue browsing, decoding or validation.
Requirements
A remote endpoint reached over streamable HTTP with OAuth sign-in; no local install or environment variables are declared for the hosted version. The self-hosted core needs Node.js 20+, Python 3 for a one-time catalogue build, and an OpenAI-compatible model endpoint with an API key such as FOODEX2_LLM_API_KEY.
Before you install
Codes are approximate: the README says to check every code before use, and some descriptions are coded broader than stated, with the remainder left as free text. Input must be English. The self-hosted version sends descriptions to a third-party model endpoint, which is billed separately from your chat client.

Installation

In SourceWeft

  1. Open FoodEx2 Encoder in the dashboard and add it to a workspace.
  2. Connect the required credentials. They are stored privately and never shown on public pages.
  3. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/org.foodnotes%2Ffoodex2-encoder/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config. The client completes OAuth sign-in on first connect.

{
  "mcpServers": {
    "foodex2-encoder": {
      "type": "http",
      "url": "https://foodex2-encoder.foodnotes.org/mcp"
    }
  }
}

README

foodex2-encoder

Library and stdio MCP server that turns an English food description into an EFSA FoodEx2 code (MTX catalogue): base term, facet descriptors, and labelled free text for what the code cannot express.

This repository is the core. A hosted version is available at https://foodex2-encoder.foodnotes.org/ .

Limitations

Check every code before you use it. In particular:

  • English input only, including foreign food names commonly used in English.
  • Group names the catalogue splits are kept as free text. When a description uses a name that the catalogue only has as several separate terms, that part goes to free text instead of the code. For example, canned shellfish is coded as Canned seafood with source-commodity=shellfish in free text, rather than Canned seafood made from crustaceans and molluscs. The code is not wrong, but it is broader than the description: Canned seafood also covers other marine animals, such as sea urchins.

What you need

  • Node.js 20+
  • Python 3 (one-time catalogue build from the vendored EFSA .ecf)
  • An OpenAI-compatible model endpoint and API key (OpenRouter is the default)

Install

bash
git clone https://github.com/FoodNotes-org/foodex2-encoder.gitcd foodex2-encodergit submodule update --initnpm installnpm run build:cataloguenpm run build:embeddings

data/ is generated locally (~25 MB) and is gitignored. Rebuild after updating the vendor/efsa-catalogues submodule.

The coding rules in src/rules/ (EFSA business rules, facet cardinality, our own checks) are shared with the FoodEx2 Atlas validator. Their data comes from rules/cardinality.yaml, rules/conflicts.yaml and vendor/efsa-business-rules/; after editing those, regenerate the committed src/rules/rules-data.json with npm run build:rules. Sources, licence and limits are in rules/efsa-business-rules.md.

Model endpoint

Copy .env (or export the same variables). OpenRouter needs only a key:

bash
FOODEX2_LLM_API_KEY=sk-or-…          # or OPENROUTER_API_KEY# optional:# FOODEX2_LLM_BASE_URL=https://openrouter.ai/api/v1# FOODEX2_MODEL=openai/gpt-6.1-sol

Any other OpenAI-compatible endpoint works the same way (FOODEX2_LLM_BASE_URL, FOODEX2_LLM_API_KEY, FOODEX2_MODEL). The server calls that endpoint for classify / select / residual steps; your chat client’s subscription is separate.

Try it (CLI)

bash
npm run cli -- encode "orange juice"npm run cli -- encode "fried rice with chicken"npm run cli -- traverse "eggplant"    # walk only (debug)

Lexical hits return in about a second. Descriptions that need a catalogue walk typically take 15–25 seconds.

Try it (MCP stdio)

bash
npm run server

Point a client at that process. Cursor example (mcp.json):

json
{  "mcpServers": {    "foodex2-encoder": {      "command": "npx",      "args": ["tsx", "/ABS/PATH/TO/foodex2-encoder/src/server.ts"],      "env": {        "FOODEX2_LLM_API_KEY": "sk-or-…"      }    }  }}

Tool: encode. It returns the code, base term, facets, free text, fit, method, and a short explanation. Catalogue lookups, decoding, validation and EFSA guidance are in the free FoodEx2 Atlas MCP.

Tests and eval

bash
npm test                 # unit tests (no model)npm run lexical-eval     # lexical base-term cases (no model)npm run encode-eval      # end-to-end gold set (needs a model key)

eval/encode-base-term.yaml is a small, focused regression set: one realistic case per capability (catalogue synonym, model synonym, named dish, restraint, and so on). Gold rules can require or forbid facets and free-text fragments; expected may list several acceptable base codes (any-of).

npm run encode-eval records the model and MTX version, and on a complete run writes eval/results/encode-base-term.json for publishing or sharing with the public core repo. Always cite the model named in that file’s _provenance.

Layout

src/encode/     lexical → traverse → select → residualssrc/search/     lexical + embedding retrievalsrc/server.ts   stdio MCPsrc/tools.ts    tool handlers (shared surface for a future Worker wrapper)data/           generated catalogue + embeddings (local)eval/           gold cases + results artifactvendor/         EFSA catalogues (submodule)

Licence

MIT — see LICENSE. Copyright (c) 2026 e-accent BV.

That grant covers this software. EFSA catalogue files under vendor/efsa-catalogues/ (and generated data/ derived from them) remain subject to EFSA’s terms.

Attribution (eval inputs)

Some food names used as evaluation cases under eval/ were drawn from national food composition databases. We use food names only (not nutrient values). Those databases remain under their publishers’ terms:

Source: README.md at commit 1bf05fe

Tools

0
This server asks you to sign in, so SourceWeft could not read its tools without an account and has not indexed them. What a connected account sees can depend on that account and its permissions.

Version history

1
  1. v1.0.0LatestOct 16, 2026

Score

85% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts