open_nodes
Expand entities to retrieve full details, observations, and relations from Memento's offline memory storage.
Instructions
Expand specified entities: return their full details including observations and relations.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| names | Yes | Names of entities to expand. |
Implementation Reference
- src/server.js:202-219 (registration)MCP tool registration for 'open_nodes', including input schema using Zod, description, and handler function that calls knowledgeGraphManager.openNodes and returns JSON response.// Tool: open_nodes this.tool( 'open_nodes', 'Expand specified entities: return their full details including observations and relations.', { names: z.array(z.string()).describe('Names of entities to expand.') }, async ({ names }) => ({ content: [{ type: 'text', text: JSON.stringify( await this.#knowledgeGraphManager.openNodes(names), null, 2 ) }] }) );
- src/server.js:207-208 (schema)Zod input schema for the open_nodes tool: array of entity names.names: z.array(z.string()).describe('Names of entities to expand.') },
- Knowledge graph manager method that delegates openNodes call to the underlying repository implementation.async openNodes(names) { return this.#repository.openNodes(names); }
- src/postgres/graph-repo.js:349-407 (helper)PostgreSQL repository implementation of openNodes: queries entities by names, their observations, and relations between them, formats into {entities, relations} structure.async openNodes(names) { if (!names.length) { return { entities: [], relations: [] }; } /** * @type {[{entitytype, id, name}]} */ const entities = await this.#query( `SELECT * FROM entities WHERE name = ANY ($1)`, [ names ] ); if (!entities.length) { return { entities: [], relations: [] }; } const ids = entities.map(e => e.id); const observations = await this.#query( `SELECT entity_id, content FROM observations WHERE entity_id = ANY ($1)`, [ ids ] ); /** * @type {[{name, from_name, to_name, relationtype}]} */ const relations = await this.#query( `SELECT r.from_id, r.to_id, r.relationtype, ef.name AS from_name, et.name AS to_name FROM relations r JOIN entities ef ON ef.id = r.from_id JOIN entities et ON et.id = r.to_id WHERE r.from_id = ANY ($1) AND r.to_id = ANY ($1)`, [ ids ] ); return { entities: entities.map(e => ({ name: e.name, entityType: e.entitytype, observations: observations .filter(o => o.entity_id === e.id) .map(o => o.content) })), relations: relations.map(rel => ({ from: rel.from_name, to: rel.to_name, relationType: rel.relationtype })) };
- src/sqlite/graph-repo.js:305-352 (helper)SQLite repository implementation of openNodes: similar to Postgres, queries entities by names, observations, and mutual relations using parameterized queries.async openNodes(names) { if (!names.length) { return { entities: [], relations: [] }; } const placeholders = names.map(() => '?').join(','); const entities = await this.db.all( `SELECT * FROM entities WHERE name IN (${placeholders})`, names ); if (!entities.length) { return { entities: [], relations: [] }; } const ids = entities.map(e => e.id); const idPlaceholders = ids.map(() => '?').join(','); const observations = await this.db.all( `SELECT entity_id, content FROM observations WHERE entity_id IN (${idPlaceholders})`, ids ); /** * * @type {[{from_name, to_name, relationType}]} */ const relations = await this.db.all( `SELECT r.from_id, r.to_id, r.relationType, ef.name AS from_name, et.name AS to_name FROM relations r JOIN entities ef ON ef.id = r.from_id JOIN entities et ON et.id = r.to_id WHERE r.from_id IN (${idPlaceholders}) AND r.to_id IN (${idPlaceholders})`, [...ids, ...ids] ); return { entities: entities.map(entity => ({ name: entity.name, entityType: entity.entityType, observations: observations .filter(obs => obs.entity_id === entity.id) .map(obs => obs.content) })), relations: relations.map(relation => ({ from: relation.from_name, to: relation.to_name, relationType: relation.relationType })) };
- src/graph-repository.js:34-34 (schema)JSDoc type definition specifying the input (string[] names) and output structure for the openNodes method.* @property {(names: string[]) => Promise<{ entities: Array<{ name: string, entityType: string, observations: string[] }>, relations: Array<{ from: string, to: string, relationType: string }> }>} openNodes