etim-json
Provides read-only MCP tools to query the ETIM classification model, enabling AI agents to search classes, retrieve feature/unit definitions, and look up ETIM codes.
README
etim-json
The ETIM classification model as clean JSON — convert, validate, generate TypeScript types, search, and serve to AI agents over MCP.
ETIM is the open classification standard for technical products — the shared language of electrical wholesale, HVAC, building products and industrial supply across much of Europe and North America. It is published as API responses and exchange files aimed at PIM systems. This tool turns a release into one canonical, validated, diffable JSON file, and then makes that file useful: typed for your compiler, searchable from your terminal, and queryable by any MCP-capable AI assistant.
This package ships no ETIM data. The model belongs to ETIM International and its community, published under ODC-BY 1.0 — free to use with attribution. You convert the model you are licensed to download; the attribution travels inside every file this tool writes.
Try it in ten seconds
No credentials, no data, no config — a bundled synthetic demo model:
npx etim-json mcp --demo
Or in Claude Code:
claude mcp add etim-demo -- npx -y etim-json mcp --demo
Then ask: "What features does an installation cable have in the ETIM demo
model?" Every response is stamped SYNTHETIC DEMO DATA — the demo shows the
tool's shape, deliberately not the real classification.
The real model
Request API credentials from ETIM International (free for members; ETIM says non-members can ask their local country office), then:
export ETIM_CLIENT_ID=… ETIM_CLIENT_SECRET=…
npx etim-json fetch -o etim.json --release ETIM-10.0 --languages EN,DE
npx etim-json validate etim.json
npx etim-json stats etim.json
And serve it to your assistant:
{
"mcpServers": {
"etim": {
"command": "npx",
"args": ["-y", "etim-json", "mcp", "--model", "/path/to/etim.json"]
}
}
}
That config works as-is in Claude Desktop, Claude Code (claude mcp add etim -- npx -y etim-json mcp --model /path/to/etim.json), Cursor, and anything
else that speaks MCP over stdio.
What the MCP server exposes
Five read-only tools over the loaded model — the server writes nothing, reaches nothing over the network, and no tool accepts a filesystem path:
| Tool | Answers |
|---|---|
etim_model_info |
Which release am I querying, how big is it, whose data is it? |
etim_search_classes |
"Find the class for a residual current breaker" — by name, synonym, translation or code |
etim_get_class |
The full definition: features, types, units, permitted values |
etim_lookup |
Any code — EC…, EG…, EF…, EV…, EU… — identified and described |
etim_list_groups |
The top-level map of what the model covers |
Every tool declares readOnlyHint and returns structured content alongside
prose, so agents can consume results as data rather than re-parsing text.
CLI
etim-json demo -o demo.json synthetic demo model
etim-json fetch -o etim.json [options] convert via the ETIM API
etim-json validate <model> [--strict] exit 1 on errors (--strict: also warnings)
etim-json stats <model> counts, languages, provenance
etim-json search <model> <query> find classes
etim-json class <model> EC003024 one class in full
etim-json lookup <model> EU570448 identify any code
etim-json types <model> -o etim.d.ts TypeScript declarations
etim-json mcp --model <file> | --demo serve over MCP (stdio)
Every command is quiet, composes with pipes, exits non-zero on failure, and
takes --json for machine-readable output.
Generated types
npx etim-json types etim.json -o etim.d.ts
gives your compiler literal unions of the codes actually present in your release:
import type { EtimClassCode, EtimClassMap } from "./etim.d.ts";
const cable: EtimClassCode = "EC000034"; // typo → compile error
Unions over 4,000 members widen to string with the cap noted in the emitted
comment — visible, not silent.
The format
One JSON object per release. Vocabularies are global dictionaries; classes bind features to class-specific units and value lists — the same shape ETIM itself has:
{
"formatVersion": 1,
"kind": "etim-model",
"release": "ETIM-10.0",
"languages": ["DE"],
"source": { "type": "etim-api", "apiVersion": "ETIM API 2.0", "retrievedAt": "…" },
"attribution": { "licence": "ODC-BY 1.0", "statement": "Contains information from the ETIM classification model…" },
"groups": { "EG000017": { "description": "…" } },
"features": { "EF000008": { "type": "N", "description": "…" } },
"values": { "EV000123": { "description": "…" } },
"units": { "EU570448": { "description": "…", "abbreviation": "mm" } },
"classes": {
"EC000034": {
"version": 9,
"groupCode": "EG000017",
"features": [{ "code": "EF000008", "orderNumber": 1, "unitCode": "EU570448" }]
}
}
}
Serialisation is canonical — sorted keys, stable arrays — so two conversions of the same release diff clean, and a re-fetch shows you exactly what changed.
The validator enforces referential integrity (every unitCode resolves, no
class binds a feature twice) as errors, and flags surprises (an
alphanumeric feature with no value list) as warnings — because the
published model has legitimate exceptions, and a validator that cries wolf
teaches people to skip it.
Library
Everything the CLI does is importable:
import { parseModelJson, assertModel, searchClasses, getClass } from "etim-json";
import { readFileSync } from "node:fs";
const model = assertModel(parseModelJson(readFileSync("etim.json", "utf8")));
const [hit] = searchClasses(model, "Leitungsschutzschalter", { language: "DE" });
const mcb = getClass(model, hit.code);
What is verified, and what is not
Honesty section, in the spirit of the tool:
- Verified: the transform is built and tested against the public ETIM API 2.0 contract (fetched 2026-08-12), with fixtures shaped exactly by that contract. The MCP server is tested through a real client handshake and a real stdio child-process session, including hostile frames. 54 tests, including a dedicated adversarial suite (prototype-pollution smuggling, dangling references, regex injection, oversized inputs).
- Not yet verified live: an end-to-end
fetchagainst the production API needs credentials we don't put in CI. If a page shape ever disagrees with the published contract,validatewill catch the damage — please open an issue with the (redacted) response. - Not yet supported: the IXF file format (ETIM's XML release format) and CMT CSV exports. Both are planned; both will be built against their format descriptions, not guesses.
Security posture
- The MCP server holds one read-only dataset chosen by the operator at startup. No tool takes a path, URL or credential.
- Model files are parsed with a prototype-pollution guard, a size ceiling and BOM tolerance; hostile keys are rejected at the door.
- The API fetcher paces itself: sequential pages, a delay between them, one backoff retry. Tools that get their users rate-banned are worse than slow tools.
- Two runtime dependencies: the official MCP SDK and zod. No transitive surprises to audit.
Licensing
- This software: MIT.
- The ETIM model: © ETIM International and its community, licensed ODC-BY 1.0. Attribution is required for public use, and notices must stay intact — which is why every file this tool writes carries the attribution inside it. This project is not affiliated with or endorsed by ETIM International.
- The bundled demo model: synthetic, invented for this tool, and useless as classification. It exists so you can try the interface without touching licensed data.
Documentation
docs/TOOLS.md— the complete MCP tool reference: schemas, annotations, worked request/response pairs, example prompts, error behaviourdocs/FORMAT.md— the normative etim-json format specificationSECURITY.md— threat model and how to reportCONTRIBUTING.md·CODE_OF_CONDUCT.md·CHANGELOG.md
Why this exists
Built by Partsgraph — we make manufacturer and distributor catalogues readable to AI agents, and ETIM is the backbone vocabulary of that work. We benchmarked 984 industrial catalogues on AI-readability (the data is public); zero of them exposed a machine-readable classification interface. This is a small tool against a large gap.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.