“Which query optimization candidates came out of last week’s investigation?”
When an agent gets that question, search finds the discovery. The answer lives in a connected insight, grounded by a memory that preserves the workload baseline. Search can return all three as separate matches. The agent still needs the routes between them.
In a codebase, search finds a matching token. Navigation follows the symbol through its definition, implementations, and callers. An agent needs the same path through the dashboards, insights, discoveries, and memories available through a shared context store.
Product code publishes an ontology: a type map that defines which entity types can connect. Each organization and environment supplies the live entities and connections that form its entity graph. A search hit stops being the answer.
The opening animation shows the full handoff before we unpack each piece: Map, Search, Traverse, Read.
Product code publishes the ontology
Each entity type publishes a compact ontology contract: its handle prefix, description, and whether its instances are indexed. The route list is declared in product code. One entry defines the routes out of a discovery:
{from: NodeType::Kind::Discovery,to: [NodeType::Kind::Insight,NodeType::Kind::Dashboard,NodeType::Kind::Segment,NodeType::Kind::SemanticModel,NodeType::Kind::Memory]}
Those declarations produce the ontology. The entity graph is materialized separately: when an entity changes, Altertable stores a compact searchable copy of it and its outgoing edges. Traversal reads that copy instead of joining product tables on every request.
Relationships come from explicit product references, including references supplied when agents create objects. We do not infer them from text.
Deploy an ontology node type or update the declared route list, and the next call to the Model Context Protocol (MCP) tool initialize returns the updated ontology. Product code remains the source, so agents receive the current ontology instead of a static inventory embedded in the prompt. They can later re-read it from the read-only MCP resource altertable://ontology without another initialize call.
Routes become live edges
The ontology declares routes between entity types. Search and traversal read the indexed entities and edges available to the current MCP session.
The graph below comes from a real search followed by one-hop traversal. We shortened titles, removed dates, and replaced object slugs, while preserving their prefixes, entity types, edge directions, and relationships. Inside the platform, the UI and the agent point at the same original objects.
Search finds the handle
With the ontology, organization, and environment already supplied by the Altertable MCP tool initialize, the agent needs a starting point.
The MCP tool search_entities combines a PostgreSQL full-text lexical branch and a pgvector semantic branch into one ranked candidate list with reciprocal rank fusion.
The response gives the agent each candidate's type, title, snippet, and rank. The agent compares those fields with the user's question. In the top result, DSC-104 is the handle and DSC is its type-carrying prefix.
Ranked candidates
DSC-104, discovery. Weekly query workload: 6 optimization candidates.DSC-87, discovery. Query latency follow-up.MEM-41, memory. Optimization review notes.
Selected starting point: discovery DSC-104. It ranks first, its title and snippet match the optimization question, and its type can connect to insights and memories.
One hop to the evidence
We could have exposed an open-ended graph query. We did not. The MCP tool get_neighbors expands one hop, so the agent chooses each next edge explicitly. The agent gets the analyses and baseline directly connected to the finding instead of running another broad search.
That boundary makes each expansion explicit in the tool trace, prevents a high-degree node from flooding the context window, and requires an explicit resource read before full entity content enters context. get_neighbors returns 25 neighbors by default, allows at most 100, and sets truncated when more exist.
One-hop neighbors of DSC-104
Outgoing
INS-208, insight. Optimization candidates by performance impact.INS-209, insight. Slowest production queries.
Incoming
MEM-72, memory. Query workload baseline.
Direction is part of the result. Expanding DSC-104 finds MEM-72 as an incoming neighbor (direction: "in") because the memory points to the discovery. The agent reaches the workload baseline behind the finding without running another text search. The two outgoing edges lead to its analyses.
This animation focuses on the handoff from search to traversal. The ranked discovery supplies the slug to get_neighbors, which returns compact references to its neighbors.
The animation stops after get_neighbors returns compact references. It does not read the entity bodies. To ground the answer, the agent selects INS-208 and MEM-72. The client reads their full entity content from the MCP resources altertable://ontology/entities/INS-208 and altertable://ontology/entities/MEM-72.
That division is intentional: MCP tools let the model search and traverse; MCP resources give the client URI-addressed content to read after the model chooses which entities to inspect.
With both entities in context, the agent can report the 6 optimization candidates from INS-208 and evaluate them against the workload baseline in MEM-72.
A map is not access
Every session receives the same ontology: type-level routes with no live entities or edges. The map grants no access by itself.
Live entities remain scoped to the caller's organization and environment at every step. search_entities, get_neighbors, and entity resources each apply entity policy before returning candidates, neighbors, or content. A denied entity appears in none of those responses.
Entity policy is not a separate rulebook for agents. It delegates to each type's product policy, the same rules that gate dashboards and memories in the UI, so a session reads exactly what its caller could open. A denied slug also behaves like a missing one: traversal and entity reads return the same not-found result, with no hint that something was withheld.
Put the map in the protocol
The model does not need every related entity loaded into its context window. It needs a reliable path from the search result to the evidence required for the answer.
The protocol should expose choices, not make them. Search finds a starting point. The ontology shows valid routes. The entity graph connects those routes to live evidence. The agent decides where to go next.
The map is not more context.
It is how the agent chooses what context to read.






