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.
The engine resolves the caller's namespace allow-list from Convex on every call and fails closed: missing or unresolvable caller context returns an empty result with an explicit auth error, never a cross-namespace answer.
Tool catalog
Section titled “Tool catalog”| 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_list |
VFS file listing, paged with cursor / nextCursor; optional folderPrefix (e.g. observability) lists files in that folder. Effectively disabled files are omitted. |
kg_files_info |
File metadata by VFS path or fileId. |
kg_files_read |
Read UTF-8 file text by namespace + path or fileId (bounded bytes/lines). Chat @kg:<namespace>/<path> maps to the same namespace and path (no leading slash). Effectively disabled files are omitted. |
kg_files_grep |
Regex grep across text files; use to find files by name (e.g. compliance\\.md) or content. Effectively disabled files are omitted. |
Enable these tools on an agent with the Knowledge capability tile on the agent card.
Chunk packages
Section titled “Chunk packages”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.
Hybrid search (kg_search)
Section titled “Hybrid search (kg_search)”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; 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.
Open, hop, ontology, entities
Section titled “Open, hop, ontology, entities”kg_open: Resolve one key to packages when you already have a chunk, outline, entity, or file id.kg_hop: Expand fromfromKeywith a typedkind.similarmoves 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 withkg_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.kg_file_entities: List entities and entity types already extracted for one file before you edit them or re-run an ontology review. UseafterEntityKeywhen the response istruncated.kg_file_triples: List typed REL instance triples for one file when both endpoints are mentioned in that file.
Permissions, fail closed
Section titled “Permissions, fail closed”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.
Using Knowledge Graph MCP in Flow
Section titled “Using Knowledge Graph MCP in Flow”- 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.
- 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.
Tenant endpoints
Section titled “Tenant endpoints”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.
External MCP clients (Cursor, ChatGPT)
Section titled “External MCP clients (Cursor, ChatGPT)”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.
Issue a PAT
Section titled “Issue a PAT”- Sign in to your tenant Flow origin (the same HTTPS hostname you use for workflows, for example
https://acme.example.com). - Open Admin → Personal access tokens (
/admin/access-tokens). - Select Create PAT, then copy the full token (
fnt_pat_…). It is shown once; store it in a password manager. - 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.
Cursor
Section titled “Cursor”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 (Developer mode)
Section titled “ChatGPT (Developer mode)”ChatGPT connects to remote HTTPS MCP servers only (Streamable HTTP). You need a paid plan with Developer mode enabled (Settings → Security and login).
- Open Settings → Apps & Connectors (or ChatGPT Plugins → + in newer UI).
- Create a custom connector (Developer mode):
- Connector URL:
https://<tenant>.<baseDomain>/_kg-engine/mcp - Authentication: Token (not OAuth), or a single
Authorizationheader (see below).
- Connector URL:
- Paste your full
fnt_pat_…value. ChatGPT sendsAuthorization: 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.
Verify PAT auth
Section titled “Verify PAT auth”Health checks do not use auth. Confirm the PAT on the MCP path:
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.
Troubleshooting 401
Section titled “Troubleshooting 401”| 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 |