ad4m_recall
Query semantic links in a Perspective using optional filters for source, predicate, or target to find specific relationships.
Instructions
Query links from a Perspective by source, predicate, or target. Omit any field to match all.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| perspective_uuid | Yes | Perspective UUID to query | |
| source | No | Filter by source URI | |
| predicate | No | Filter by predicate URI | |
| target | No | Filter by target URI |
Implementation Reference
- src/index.ts:326-350 (registration)Tool registration for 'ad4m_recall' on the MCP server. Defines schema with optional source/predicate/target filters and delegates to an inline async handler.
// 5. ad4m_recall server.tool("ad4m_recall", "Query links from a Perspective by source, predicate, or target. Omit any field to match all.", { perspective_uuid: z.string().describe("Perspective UUID to query"), source: z.string().optional().describe("Filter by source URI"), predicate: z.string().optional().describe("Filter by predicate URI"), target: z.string().optional().describe("Filter by target URI"), }, async ({ perspective_uuid, source, predicate, target }) => { const query: Record<string, string> = {}; if (source) query.source = source; if (predicate) query.predicate = predicate; if (target) query.target = target; const data = await gql( `query Q($uuid: String!, $q: LinkQuery!) { perspectiveQueryLinks(uuid: $uuid, query: $q) { author timestamp data { source predicate target } } }`, { uuid: perspective_uuid, q: query } ); return ok(data.perspectiveQueryLinks); } ); - src/index.ts:335-349 (handler)Inline async handler for ad4m_recall: builds a LinkQuery from optional filter params, executes a GraphQL perspectiveQueryLinks query against the AD4M executor, and returns the matching links.
async ({ perspective_uuid, source, predicate, target }) => { const query: Record<string, string> = {}; if (source) query.source = source; if (predicate) query.predicate = predicate; if (target) query.target = target; const data = await gql( `query Q($uuid: String!, $q: LinkQuery!) { perspectiveQueryLinks(uuid: $uuid, query: $q) { author timestamp data { source predicate target } } }`, { uuid: perspective_uuid, q: query } ); return ok(data.perspectiveQueryLinks); } - src/index.ts:329-334 (schema)Zod schema for ad4m_recall: requires perspective_uuid (string), optional source/predicate/target (strings).
{ perspective_uuid: z.string().describe("Perspective UUID to query"), source: z.string().optional().describe("Filter by source URI"), predicate: z.string().optional().describe("Filter by predicate URI"), target: z.string().optional().describe("Filter by target URI"), }, - src/index.ts:132-152 (helper)Generic GraphQL helper used by ad4m_recall to execute the perspectiveQueryLinks query against the AD4M executor.
async function gql(query: string, variables: Record<string, unknown> = {}): Promise<GqlResult> { const resp = await fetch(AD4M_GQL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query, variables }), signal: AbortSignal.timeout(10_000), }); if (!resp.ok) throw new Error(`AD4M HTTP ${resp.status}: ${await resp.text()}`); const json = await resp.json() as { data?: GqlResult; errors?: { message: string }[] }; if (json.errors?.length) { const msg = json.errors[0].message; if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) { throw new Error("AD4M executor not reachable. Start it with: ad4m serve --port 4000"); } if (msg.includes("Unauthorized") || msg.includes("not unlocked")) { throw new Error(`Agent is locked. Unlock with:\ncurl -X POST ${AD4M_GQL} -H 'Content-Type: application/json' -d '{"query":"mutation { agentUnlock(passphrase: \\"YOUR_PASSPHRASE\\") { isUnlocked } }"}'`); } throw new Error(msg); } return json.data ?? {}; } - src/index.ts:154-156 (helper)Helper function that wraps results in the MCP content response format used by ad4m_recall to return data.
function ok(data: unknown) { return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] }; }