The KF server exposes its knowledge graph over the
Model Context Protocol at /mcp. Any MCP client
— Claude Desktop, VS Code, a custom agent — can connect and read the database:
search it, walk the relations between items, and pull complete failure analyses,
risk models and compliance registers.
This is the difference between an assistant that can write the form of an FMEA and one that knows your products, your failures and your quality history.
Streamable HTTP transport (MCP spec §4.2).
{
"mcpServers": {
"kf": { "url": "https://kf.example.com/mcp" }
}
}
Authentication is the same gate as the REST API: a bearer token
in licensed mode, sent as Authorization: Bearer …. In evaluation mode every
request is served as the evaluation user and no token is needed — which is what makes
it worth ten minutes of your time before you decide anything.
A token carries exactly the access of the user who created it. The client sees precisely the items that user would see in a browser, no more; see access control.
Every tool is read-only, and that is a decision rather than an omission. Reads are complete: there is no part of the model the tools cannot reach. What a model may change in an organisation's quality record is a separate question with a separate answer, and the answer today is the REST API, where the caller is a program somebody wrote on purpose.
One consequence worth knowing: KF's audit trail is an append-only journal kept beside the database rather than inside it, precisely so that a read tool never writes a row into the record it is reading.
Four kinds of thing, and the edges between them.
| Class | y | What it is |
|---|---|---|
| Object | m | A component, product or container |
| Action | a | Work to be done. Only actions carry a schedule |
| Event | e | A failure, issue or risk |
| Document | i | A Markdown page |
| Type | t | Something other items conform to |
Types are the point. An item typed against another inherits its requirements: whatever the type owes and the instance lacks appears on the instance's checklist as
missing. The inheritance is live — add a requirement to the type and every instance
owes it from that moment, retroactively, including instances created long before
the lesson existed.
A task is an edge, not a class. What makes something a task is the task relation
it hangs off, not what it is: a task may be an action (do this), an object (deliver
this) or a document (write this). Only actions carry a schedule, so only actions can
appear on a Gantt.
Status is a tag — done, resolved, not_applicable, or absent, which means
pending. missing is computed and never stored: it is what a type requires and an
instance has not got. On a type, resolved closes the obligation for every instance
present and future; done speaks only for the type itself.
All read-only. Every tool acting on one item takes an id.
| Tool | Answers |
|---|---|
search | Find items. Full text by default; by=code looks one up by its code, by=tag lists everything carrying a tag. |
get_item | Everything about one item: title, class, code, tags, status, when it was created and last changed, its breadcrumb path, its risk level, its types, and any other field it carries. |
get_related | What is connected to this item, over every kind of edge at once. |
get_checklist | What this item still owes: every task it or its types require, with the status of each. |
get_inverted_checklist | Lessons learned that have not been generalized. |
get_failure_analysis | The FMEA view: for the item and everything beneath it, the failure events, their causes and effects, and the actions taken against each — with the risk of every event. |
get_failure_tree | The fault tree above an event: what could have caused it, and what caused that, as indented text. |
get_risk_model | The ruler behind every risk level: the scales, what each value means, the rules that turn them into a level, and what the levels are called. |
get_history | When this item was written, by whom, and what the author said changed — every revision, newest first. |
get_exports | Where to download this item's reports as files. |
list | Enumerate a set — everything of a class, carrying a tag, under a subtree, or modified in a date range — with a TOTAL. |
The tool list is generated from the server's own table and checked by a test, so it cannot drift from what the server actually publishes.
get_related replaces what used to be six near-identical tools. Each row says which
relation it came by and which way it runs, so no prior knowledge of the model is
needed to read the answer. Narrow with kind and direction once you know what you
want.
| kind | glyph | downward | upward |
|---|---|---|---|
| cause | → | effects | causes |
| component | ∋ | components | part_of |
| failure | [ | failure_modes | failure_mode_of |
| link | - | links_to | linked_from |
| precedes | ≺ | followed_by | preceded_by |
| task | * | tasks | task_of |
| type | ⊃ | instances | types |
The glyphs are how the store spells the edges. No caller ever needs to use one.
as_of — on get_item and get_history. Reads the item as it stood at a given
time: RFC 3339, a plain date (meaning the end of that day), or Unix milliseconds. The
database is live and may be written to while you are reading it. Pin the read to the
opening meeting and two identical questions hours apart give the same answer.
reconcile=true — on get_checklist. Returns the register's own arithmetic,
already checked: rows, headings, requirements, and whether the row list and the
summary agree. Use it before quoting any number off a register.
total is counted after access filtering — on list. It is what you may see,
not what exists. A list of nine with no denominator is indistinguishable from the
first nine of three hundred.
status_note — on every checklist row. It says what the status word actually
means, because all five mean something other than what they appear to say. done is
not conformity; missing is not "no evidence exists".
get_exportsThe chat is not the place to read a 79-row register. get_exports returns the URLs
for the item's reports as files — FMEA as CSV or Excel, the compliance register as
either, subtree as JSON, fault tree and Gantt as SVG, Gantt as MS Project XML, tasks
as iCalendar. Every export carries a provenance header naming the database it came
from.
"What do we know about this failure mode?"
search("seal failure") → get_item(id) → get_related(id) for causes, effects and
the actions taken → get_failure_tree(id) for the causal chain.
"Is this project ready to ship?"
search("Model B", by=code) → get_checklist(id, reconcile=true) for the arithmetic,
then get_checklist(id) for the rows — reading status_note rather than the status
word.
"We changed component Y — what do we need to re-check?"
get_related(y, kind=type, direction=up) for what Y learns from → get_checklist(y)
for what that obliges → get_related(y, kind=component, direction=up) for what Y sits
inside and therefore affects.
"Justify this risk rating."
get_item(id) for the level → get_risk_model(id) for the ruler it was measured
with. A database may hold more than one matrix — an ISO 26262 HARA and a conventional
FMEA side by side — and this says which one scored this item, and why.
"What did this look like at the opening meeting?"
get_item(id, as_of="2026-07-26") → get_history(id, as_of="2026-07-26"). Same
question tomorrow, same answer.