Graph Contradictions
graph_contradictionsDetect pairs of facts connected by a CONTRADICTS edge in your knowledge graph. Use to review unresolved contradictions before consolidation or to audit historical resolutions.
Instructions
Find facts that contradict each other in the memory graph — pairs connected by a CONTRADICTS edge. Use during reviews, before a graph_decay run, or when the user asks about conflicting information. Returns {contradictions: [{node_a, node_b, description, detected_date, resolved}], count} ordered by most-recently detected. By default only unresolved pairs are surfaced; set include_resolved=true to audit historical resolutions. Resolve a contradiction by graph_weaken on the wrong edge or by graph_relate with relation=SUPERSEDES on the new fact.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| include_resolved | No | Include resolved contradictions (default: false) |
Implementation Reference
- src/mcp-server/index.ts:431-446 (registration)Registration of the 'graph_contradictions' tool with the MCP server, including schema definition (include_resolved flag), description, and readOnlyHint annotation.
server.registerTool("graph_contradictions", { title: "Graph Contradictions", description: "Find facts that contradict each other in the memory graph — pairs connected by a CONTRADICTS edge. Use during reviews, before a graph_decay run, or when the user asks about conflicting information. Returns `{contradictions: [{node_a, node_b, description, detected_date, resolved}], count}` ordered by most-recently detected. By default only unresolved pairs are surfaced; set include_resolved=true to audit historical resolutions. Resolve a contradiction by graph_weaken on the wrong edge or by graph_relate with relation=SUPERSEDES on the new fact.", inputSchema: { include_resolved: z.boolean().optional().default(false).describe("Include resolved contradictions (default: false)"), }, annotations: { readOnlyHint: true }, }, async (args) => { try { const result = await client.findContradictions(currentTenant(), args.include_resolved ?? false); return toolResult(result); } catch (err) { return toolError(`graph_contradictions failed: ${err instanceof Error ? err.message : String(err)}`); } }); - src/mcp-server/index.ts:439-446 (handler)Handler function for graph_contradictions — calls client.findContradictions(currentTenant(), includeResolved) and returns the result.
}, async (args) => { try { const result = await client.findContradictions(currentTenant(), args.include_resolved ?? false); return toolResult(result); } catch (err) { return toolError(`graph_contradictions failed: ${err instanceof Error ? err.message : String(err)}`); } }); - src/shared/neo4j-client.ts:824-865 (helper)The Neo4jClient.findContradictions() method — queries the Neo4j graph for CONTRADICTS edges, optionally filtering to unresolved only, returning node_a, node_b, description, detected_date, and resolved status.
async findContradictions(tenantId: string, includeResolved = false): Promise<{ contradictions: Array<{ node_a: { id: string; type: string; name: string }; node_b: { id: string; type: string; name: string }; description: string; detected_date: string; resolved: boolean; }>; count: number; }> { const resolvedFilter = includeResolved ? "" : "AND r.resolved = false"; const rows = await this.run( ` MATCH (a:Entity {tenant_id: $tenantId})-[r:CONTRADICTS]->(b:Entity {tenant_id: $tenantId}) WHERE 1=1 ${resolvedFilter} RETURN a.id AS aId, labels(a) AS aLabels, a.name AS aName, b.id AS bId, labels(b) AS bLabels, b.name AS bName, r.description AS description, r.detected_date AS detected_date, r.resolved AS resolved ORDER BY r.detected_date DESC `, { tenantId }, ); const contradictions = rows.map((row) => ({ node_a: { id: String(row["aId"]), type: (row["aLabels"] as string[]).find((l) => l !== "Entity") ?? "Entity", name: String(row["aName"]), }, node_b: { id: String(row["bId"]), type: (row["bLabels"] as string[]).find((l) => l !== "Entity") ?? "Entity", name: String(row["bName"]), }, description: String(row["description"] ?? ""), detected_date: toISOString(row["detected_date"]), resolved: Boolean(row["resolved"]), })); return { contradictions, count: contradictions.length }; } - src/shared/types.ts:23-23 (schema)CONTRADICTS is defined as a relationship type constant in the RELATIONSHIP_TYPES array.
"CONTRADICTS",