Libraries & tools
Get the ICF Editor desktop app, or add ICF to your stack with the official, zero-dependency libraries — each one parses, validates, builds in memory, writes, and generates the companion ICX index. Source on GitHub.
ICF Editor
A cross-platform desktop editor for ICF & ICX, built on Monaco and the icf.js engine: live parse & validation with click-to-jump problems, a virtualized outline that scales to 100k+ records, structured record editing, Merge / Split, ICX generation & compare, and import/export across JSON, CSV, XML and YAML.
ICF Editor
Pick your platform. Builds are unsigned, so the OS shows a one-time trust prompt on first launch — Windows: More info → Run anyway; macOS: right-click → Open. Verify a download against SHA256SUMS.txt.
Embed ICF in your stack
Official, zero-dependency reference implementations. Each one parses, validates, builds in memory, writes, and generates the companion ICX index.
icfj
<dependency>
<groupId>org.icformat</groupId>
<artifactId>icfj</artifactId>
<version>1.2.0</version>
</dependency>implementation 'org.icformat:icfj:1.2.0'Direct download of the compiled library (Java 11 bytecode).
icfj-1.2.0.jaricfpy
pip install icfpygit clone https://github.com/icformat/icfpy
cd icfpy
pip install -e .import icfpy
doc = icfpy.parse(open("invoice.icf", encoding="utf-8").read())
print(doc.to_pretty_string())icf.js
npm install icf.js<!-- ES module via jsDelivr -->
<script type="module">
import { parse } from 'https://cdn.jsdelivr.net/npm/icf.js@1/+esm';
</script>
<!-- …or the global build (window.ICF) -->
<script src="https://cdn.jsdelivr.net/npm/icf.js@1"></script>import { parse } from 'icf.js';
const doc = parse(icfText);
console.log(doc.toPrettyString());icfmcp
Exposes ICF knowledge bases to Claude Code, Claude Desktop and other MCP clients: tag search, summaries, record access and validation over ICX v1.2 indexes (generated on the fly when absent).
git clone https://github.com/icformat/icfmcp
cd icfmcp && npm install && npm run build
claude mcp add icf -- node dist/index.js /path/to/knowledgeParse, navigate, build, write
The same lifecycle in all three libraries: read a document, walk the data tree, build a node from scratch, and write it back.
IcfDocument doc = Icf.parse(Paths.get("invoice.icf"));
IcfNode data = doc.toIcfNode();
String city = data.path("Project").path("Location").asText();
// validate
ValidationResult r = Icf.validate(icfText);
if (!r.isValid()) r.getErrors().forEach(System.out::println);
// build & write
IcfObject root = IcfNode.object();
root.putObject("vendor").put("id", "V001");
String icf = Icf.write(root);
// companion index
IcfDocument icx = Icf.generateIcx(doc, "invoice.icf", icfText);import icfpy
doc = icfpy.parse(open("invoice.icf", encoding="utf-8").read())
data = doc.to_icf_node()
city = data.path("Project").path("Location").as_text()
# validate
r = icfpy.validate(icf_text)
if not r.is_valid:
for e in r.errors: print(e)
# build & write
root = icfpy.IcfNode.object()
root.put_object("vendor").put("id", "V001")
icf = icfpy.write(root)
# companion index
icx = icfpy.generate_icx(doc, "invoice.icf", icf_text)import { parse, validate, write,
generateIcx, IcfNode } from 'icf.js';
const doc = parse(icfText);
const city = doc.toIcfNode()
.path("Project").path("Location").asText();
// validate
const r = validate(icfText);
if (!r.isValid()) r.getErrors().forEach(e => console.warn(e.toString()));
// build & write
const root = IcfNode.object();
root.putObject("vendor").put("id", "V001");
const icf = write(root);
// companion index
const icx = generateIcx(doc, "invoice.icf");DOCUMENTATION.md — the canonical, hand-maintained record of every public type and method.