Skip to content

MCP

Fontana Knowledge Graph exposes agent retrieval as a first-party Model Context Protocol server on your tenant origin at /_kg-engine/mcp (Streamable HTTP). Agents explore through an evidence loop: search or open a chunk, read its position, section, entities and neighbours in the same payload, then hop to more chunks. Every answer contains only what the caller may read (Permissions). Enable the seeded Knowledge Graph connection on agents you assign namespaces to.

Tool What it does
kg_search Hybrid search (full-text, vector, graph expansion) fused with RRF; several namespaces fuse by rank. Returns capped chunk packages. Disabled and unreadable content is excluded.
kg_open Open packages by exactly one of chunkKey, outlineKey (that section’s chunks), entityKey (chunks mentioning it), or fileId (the file’s chunks in order).
kg_hop Typed hop onto related packages: next_chunk, prev_chunk, similar (from a chunkKey); mentions, rel, same_type (from an entityKey); outline_child, outline_parent, outline_siblings (from an outlineKey).
kg_outline A file’s page index: sections in document order with outlineKey, title, depth, parent and pages. Paged with cursor / nextCursor; limit maxDepth for large files.
kg_ontology Published TBox for a namespace (entity types, relation types, PATTERN endpoints).
kg_entity_search Named-entity entry by text and/or vector similarity; returns type labels and mention evidence packages.
kg_file_entities File-scoped entity inventory: all entities mentioned by the file’s chunks plus published entity types used in that file. Paginate with afterEntityKey when truncated.
kg_file_triples File-scoped instance REL triples where both subject and object are mentioned in the file.
kg_namespaces List Knowledge Graph namespaces the caller may read.
kg_files Find files in one namespace. folderPrefix, name (a path glob), and pattern (a content regex) combine. Omit pattern to list a page (cursor / nextCursor). Each file includes namespace, path, and fileId. Hidden files stay out of the page.
kg_file Read or query one file: namespace plus path or fileId. Omit format for size, mime, and status. A csv or tsv also returns columns. sql is one SELECT against table data. See Query a file.
kg_cypher One read-only OpenCypher statement for an exact word, a figure, or a known path (at most 50 rows, 2 second limit). Return the file path and the chunk text. An entity name alone is not a citation. A misspelling is entity search, then a walk from the resolved name.

Enable these tools on an agent with the Knowledge capability tile on the agent card.

Every search, open, hop, and entity-search hit is a chunk package. Lists carry truncated and total when clipped at the requested cap.

Field Contents
text The chunk text, plus contextHeader (the “Document › Heading › Subheading” trail) and citation (namespace/path › sections (pp.))
position chunkIndex, charStart / charEnd in the parsed text, page and line span, tokenCount, prevChunkKey, nextChunkKey
outline The chunk’s page-index section: outlineKey, title, depth, order, and its ancestors, siblings and children
mentions Entities the chunk mentions: key, name, type id and label, how it was found (method), and the quoted text
relNeighbors Typed relations of those entities, when a file you may read states them
dates The file’s documentDate, effective window and collections
similarFiles Readable files similar to the chunk’s file, best first
Cap Default Hard max
topK 8 32
mentions 8 24
rel 8 24
ancestors 6 12
siblings 8 24
children 8 24
similar 4 16

Pass caps on the tool call to override defaults. Values over the hard max fail closed with an error. Optional tokenBudget omits or truncates chunk text. Files ingested before character offsets existed report trace.missingOffsets until they are reprocessed.

kg_search runs one or more retrieval lanes and fuses results with reciprocal rank fusion (RRF):

Parameter Default Purpose
query (required) Search text
namespaces All allowed Subset of the caller’s namespace allow-list
lanes fulltext, vector, graph_expand Which lanes to run. co_annotation is opt-in and is not in the default. A failed lane soft-fails empty without aborting the whole search
tokenBudget none Estimated token cap on returned chunk text
filters none Collection, folder, temporal, and relation filters
ranking.rrfK 60 RRF constant k
ranking.laneWeights 1 each Per-lane multipliers on RRF contributions
ranking.minScore none Drop hits below this display score (0–1 scale)

Across several namespaces, results interleave by rank within each namespace, not by raw score — scores from different corpora are not comparable. Multi-namespace search keeps per-namespace and per-lane soft-fail: empty the failed lane or namespace, continue others, never abort the agent turn.

When permissions or filters hide most of a namespace, the vector lane widens its candidate pool in rounds instead of returning fewer hits; trace.vectorWidening reports the final pool and whether its cap was reached.

The assistant includes co_annotation in lanes when it wants chunks that mention two entities named in the question. That lane stays off unless the search asks for it. Studio search has no switch for it. People asking in chat do not set this argument.

The span linker runs only when co-annotation is on. It attaches a phrase in the question to a nearby entity when the published ontology did not already name it.

Grounding roles on the response label those entities from how often they are mentioned. The pipeline diagram stays the ingest stages in Processing lanes.

How the assistant answers from the Knowledge GraphYou ask a question. The assistant calls Knowledge Graph search. Full text, embeddings, and a Cypher graph hop run every time and fuse into one ranked list. Co-annotation finds chunks that name two entities in the question. The span linker attaches a phrase the ontology did not name. The response labels entities bridge, filter, or ignore from how often each appears.ASKSALWAYSFUSELISTOPTROLESEVERY SEARCHYOUYouask in chatAIAssistantcalls search over MCPTXTFull textkeywords in the chunksVECEmbeddingsvectors of the chunksCYPCypherone graph hopRRFRank fusionone ranked listOUTSearch responsebridge · filter · ignorefrom how often each appearsOPTCo-annotationtwo entities in the questionchunks naming two entitiesspan linker if a phrase is unnamedLEGENDEvery searchWhen the question names two entitiesExtra lane

When the lane runs, the response includes grounding, one entry per namespace. Each entry lists the grounded entities with their roles, the chosen pair, directCount (chunks that mention both entities), and bridgeCount (chunks one relation away). When the lane cannot form that evidence, the entry carries a reason such as too_few_bridges.

  • kg_open: Resolve one key to packages when you already have a chunk, outline, entity, or file id.
  • kg_hop: Expand from fromKey with a typed kind. similar moves to the first chunks of files similar to the chunk’s file.
  • kg_outline: Read a file’s table of contents, then open a section with kg_open {outlineKey}.
  • kg_ontology: Fetch the published type box when you need TBox without stuffing it onto every search hit.
  • kg_entity_search: Start from a name; results still land on mention packages so answers stay citation-backed. Each hit carries degree (how many chunks mention the entity) and role: bridge (specific enough to connect the question to evidence), filter (common enough to narrow the question, not to connect chunks), or ignore (too common to connect the question to evidence).
  • kg_file_entities: List entities and entity types already extracted for one file before you edit them or re-run an ontology review. Use afterEntityKey when the response is truncated.
  • kg_file_triples: List typed REL instance triples for one file when both endpoints are mentioned in that file. When truncated is true, pass continueAfter back as afterSourceEntityKey, afterRelationTypeId, and afterTargetEntityKey.

kg_files finds a file. kg_file reads or queries that one file. Pass namespace and exactly one of path or fileId. Chat @kg:<namespace>/<path> maps to that namespace and path.

Omit format for size, mime type, and status. A csv or tsv also returns columns, the header names.

format files query
sql csv, tsv One read-only SELECT or WITH against the table data. Quote a header that is not a bare name: "Market Value (AUD)".
text text, including csv, tsv, markdown, and JSON as text An in-file regular expression, or omit query and pass startLine and endLine for a line window.
jsonpath, jsonata, jinja JSON A query over the document. Jinja receives the parsed JSON as data.

A file larger than 10 MiB returns its size. Read it with text and a line window.

kg_cypher runs one read-only OpenCypher statement against a single namespace. Label every node, follow one relationship at a time, project a property such as f.vfsPath, and end with a literal LIMIT from 1 to 50. The platform stops each query after 2 seconds. Parallel calls wait in line, and Falkor still runs one of these statements at a time.

List the namespaces you may read with kg_namespaces, and read a namespace’s published type box with kg_ontology, before you write a statement. The namespace argument selects the graph. Node labels are Chunk, FileRef, Entity, and EntityType. To read the next page, add WHERE ID(n) > $afterId. SKIP is rejected.

The graph stores:

  • FileRef, a file (vfsPath, name, fileId). A Folder (folderPath) connects with Folder -[:HAS_CHILD]-> FileRef.
  • Chunk, one text window (text, path, chunkIndex). Chunk -[:PART_OF]-> FileRef and Chunk -[:NEXT_CHUNK]-> Chunk.
  • OutlineNode, a heading (title). OutlineNode -[:COVERS]-> Chunk.
  • Entity, a mention (name, typeId). Only Chunk -[:MENTIONS]-> Entity.
  • EntityType, the published schema (typeId, label, side = "published").
  • REL, a typed link between entities (relationTypeId), when the namespace has any. Start from a chunk mention and alias the edge.

An entity, heading, or folder has to share the pattern with an aliased Chunk or FileRef. An exact word in a known path:

MATCH (c:Chunk)-[:PART_OF]->(f:FileRef)
WHERE toLower(c.text) CONTAINS "dkim"
AND f.vfsPath CONTAINS "reports"
RETURN f.vfsPath AS path, c.text AS text
LIMIT 10

An answer cites the file path and the chunk text it came from. An entity name on its own is not a source. Cypher matches the text it is given: a misspelling such as “remed” for “Resmed” is an entity search, then a Cypher walk from that name back to the mentioning chunk. To connect two files, follow Chunk -[:MENTIONS]-> Entity <-[:MENTIONS]- Chunk and return each file path.

kg_search answers by meaning when you do not know the words or the path. Cypher answers an exact word, a figure, or a known path. The platform adds the enabled-file check and your folder and file permissions to each Chunk and FileRef before the query runs.

Every KG tool call is permission-enforced. Fontana resolves the caller’s readable namespaces and their namespace, folder and file permissions on each call. Nothing from a file the caller may not read, or from a disabled file, reaches the answer — not its chunks, not the entities only it mentions, not relations only it states, not its similar-file links. If the caller context is missing or cannot be resolved, the call fails closed: an explicit auth error, never a silent empty result or a cross-namespace answer.

In-app agents and external PAT clients both execute tools under your identity. An in-app agent reads only what both it and you may read.

  • Agents: enable the seeded Knowledge Graph MCP connection from AI → Tools and assign namespaces on the agent (Knowledge capability tile).
  • Chat: when the Knowledge Graph toggle is on, qualifying search evidence may be injected into the turn automatically. An answer that uses a file shows a bookmark for that file. Hover the bookmark to see the namespace and path. Click it to open the file in Knowledge Graph.
  • KG Studio: graph layout, ontology editing, and search debugging use the product UI against the same tenant data plane.

Agent Memory writes use the separate Agent Memory tile (knowledge_addMemory / knowledge_forgetMemory), not MCP.

On your tenant Flow origin:

  • Health: https://<tenant>.<baseDomain>/_kg-engine/health (no auth)
  • MCP (Streamable HTTP): https://<tenant>.<baseDomain>/_kg-engine/mcp

In Flow: enable the seeded Knowledge Graph connection on an agent from AI → Tools. Flow runs tool calls as the signed-in user.

Use a personal access token (PAT) to connect external MCP clients to your tenant’s public /_kg-engine/mcp endpoint. PATs authenticate as you; knowledge-graph:read and your permissions apply exactly as for in-app agents.

On AI → Tools, select the seeded Knowledge Graph MCP. Flow shows copyable URL, Authorization header, and Cursor JSON for ChatGPT, Claude, Cursor, and other Streamable HTTP clients. Create a PAT under Admin → Personal access tokens and paste the full fnt_pat_… value into your client config.

  1. Sign in to your tenant Flow origin (the same HTTPS hostname you use for workflows, for example https://acme.example.com).
  2. Open Admin → Personal access tokens (/admin/access-tokens).
  3. Select Create PAT, then copy the full token (fnt_pat_…). It is shown once; store it in a password manager.
  4. Rotate or revoke at the same page if the token is exposed.

The PAT must be minted on the same tenant origin you configure in your MCP client. A token from one hostname does not work on another.

Add a Streamable HTTP server in your Cursor MCP configuration (~/.cursor/mcp.json or a project-level .cursor/mcp.json):

{
"mcpServers": {
"knowledge-graph": {
"url": "https://<tenant>.<baseDomain>/_kg-engine/mcp",
"headers": {
"Authorization": "Bearer fnt_pat_…"
}
}
}
}

After editing MCP config, run Developer: Reload Window in Cursor (or fully quit and reopen).

ChatGPT connects to remote HTTPS MCP servers only (Streamable HTTP). You need a paid plan with Developer mode enabled (Settings → Security and login).

  1. Open Settings → Apps & Connectors (or ChatGPT Plugins → + in newer UI).
  2. Create a custom connector (Developer mode):
    • Connector URL: https://<tenant>.<baseDomain>/_kg-engine/mcp
    • Authentication: Token (not OAuth), or a single Authorization header (see below).
  3. Paste your full fnt_pat_… value. ChatGPT sends Authorization: Bearer fnt_pat_… to your tenant MCP endpoint.

Header-only setup (works in Cursor and ChatGPT):

Field Value
URL https://<tenant>.<baseDomain>/_kg-engine/mcp
Bearer token env var (leave empty unless you set the env var on the host)
Header name Authorization
Header value Bearer fnt_pat_… (full token, including the Bearer prefix)

Env-var setup (ChatGPT desktop / Codex): set bearer_token_env_var to a name such as MCP_PAT, export that variable to the raw token (no Bearer prefix), and do not also send a conflicting Authorization header.

Health checks do not use auth. Confirm the PAT on the MCP path:

Terminal window
export MCP_PAT='fnt_pat_…' # full token from /admin/access-tokens
curl -fsS "https://<tenant>.<baseDomain>/_kg-engine/health"
# {"ok":true}
curl -sS -w "\nHTTP %{http_code}\n" -X POST \
-H "Authorization: Bearer $MCP_PAT" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' \
"https://<tenant>.<baseDomain>/_kg-engine/mcp"

Replace <tenant>.<baseDomain> with your tenant origin. 401 means the token is missing, truncated, revoked, or minted on a different origin. 200 with a JSON-RPC body means auth succeeded.

Symptom Likely cause Fix
Health OK, MCP 401 Bad or missing Authorization Use Authorization: Bearer fnt_pat_… only; pick one auth method (header or env var, not both)
Intermittent 401 Bearer env var and header both set Pick one auth method; clear the other
Always 401 Truncated token in the UI Re-copy the full PAT (~50+ characters after fnt_pat_)
Always 401 PAT from another tenant origin Create the PAT on the same hostname as your MCP client URL
Always 401 Revoked or rotated PAT Create a new PAT at /admin/access-tokens