Skip to content

Commit 7bb8a48

Browse files
[recipes] Add OB-Graph knowledge graph layer (NateBJones-Projects#158)
* [recipes] Add OB-Graph knowledge graph layer Adds graph database functionality for Open Brain using PostgreSQL nodes + edges with recursive CTE traversal. Includes schema, MCP server with 10 tools, and setup documentation. https://claude.ai/code/session_015Z8wCeokTMTdrVMthqzGKJ * [recipes] Clarify OB-Graph deployment setup --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent b0b07da commit 7bb8a48

6 files changed

Lines changed: 1013 additions & 0 deletions

File tree

recipes/ob-graph/.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SUPABASE_URL=https://YOUR_PROJECT_REF.supabase.co
2+
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
3+
MCP_ACCESS_KEY=your-mcp-access-key
4+
DEFAULT_USER_ID=your-uuid-here

recipes/ob-graph/README.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# OB-Graph: Knowledge Graph Layer for Open Brain
2+
3+
A knowledge graph you can build and query through your AI — powered by PostgreSQL, deployed as a Supabase Edge Function, and accessed via MCP.
4+
5+
## Why This Matters
6+
7+
Your Open Brain stores thoughts, but thoughts don't exist in isolation. Projects depend on tools. People work at companies. Concepts connect to other concepts. Without explicit relationships, your AI has to re-derive connections every time you ask "how is X related to Y?" OB-Graph gives your thoughts a relationship layer — nodes for entities, edges for connections, and graph traversal to surface paths you didn't know existed.
8+
9+
## What It Does
10+
11+
Adds two tables (`graph_nodes`, `graph_edges`) and an MCP server with 10 tools for:
12+
13+
- **Building** a knowledge graph — create nodes (people, projects, concepts, tools) and connect them with typed edges (works_on, depends_on, related_to)
14+
- **Querying** relationships — get direct neighbors, multi-hop traversal, and shortest-path between any two nodes
15+
- **Linking** to existing thoughts — nodes can optionally reference a thought via `thought_id`
16+
17+
All graph traversal runs in PostgreSQL using recursive CTEs — no external graph database needed.
18+
19+
## Prerequisites
20+
21+
- Working Open Brain setup ([Getting Started guide](../../docs/01-getting-started.md))
22+
- Supabase project configured
23+
- Supabase CLI installed and linked to your project
24+
25+
## Credential Tracker
26+
27+
```text
28+
OB-GRAPH -- CREDENTIAL TRACKER
29+
--------------------------------------
30+
31+
SUPABASE (from your Open Brain setup)
32+
Project URL: ____________
33+
Secret key: ____________
34+
Project ref: ____________
35+
36+
GENERATED DURING SETUP
37+
Default User ID: ____________
38+
MCP Access Key: ____________
39+
MCP Server URL: ____________
40+
MCP Connection URL: ____________
41+
42+
--------------------------------------
43+
```
44+
45+
## Setup Instructions
46+
47+
![Step 1](https://img.shields.io/badge/Step_1-Create_Database_Schema-2E86AB?style=for-the-badge)
48+
49+
<details>
50+
<summary><strong>SQL: Create tables, indexes, RLS, and graph functions</strong> (click to expand)</summary>
51+
52+
Run the contents of `schema.sql` in your Supabase SQL Editor (Dashboard → SQL Editor → New Query → paste → Run).
53+
54+
The schema creates:
55+
56+
| Object | Purpose |
57+
|--------|---------|
58+
| `graph_nodes` | Entities in your knowledge graph |
59+
| `graph_edges` | Directed relationships between nodes |
60+
| `traverse_graph()` | Recursive CTE function for multi-hop traversal |
61+
| `find_shortest_path()` | BFS shortest path between two nodes |
62+
| RLS policies | User-scoped data isolation on both tables |
63+
| Indexes | Fast lookups by user, type, label, source/target |
64+
65+
</details>
66+
67+
> [!IMPORTANT]
68+
> The schema includes `GRANT` statements for `service_role`. These are required on newer Supabase projects — don't skip them.
69+
70+
Done when: You can see `graph_nodes` and `graph_edges` in the Supabase Table Editor, and both functions appear under Database → Functions.
71+
72+
---
73+
74+
![Step 2](https://img.shields.io/badge/Step_2-Deploy_the_MCP_Server-2E86AB?style=for-the-badge)
75+
76+
Follow the [Deploy an Edge Function](../../primitives/deploy-edge-function/) guide using these values:
77+
78+
| Setting | Value |
79+
|---------|-------|
80+
| Function name | `ob-graph-mcp` |
81+
| Download path | `recipes/ob-graph` |
82+
83+
Before you deploy, generate an MCP access key and decide which Open Brain user this graph belongs to. Then set the function secrets from `.env.example`:
84+
85+
```bash
86+
openssl rand -hex 32
87+
supabase secrets set \
88+
MCP_ACCESS_KEY=your-generated-key \
89+
DEFAULT_USER_ID=your-user-uuid
90+
```
91+
92+
`SUPABASE_URL` and `SUPABASE_SERVICE_ROLE_KEY` are provided automatically by Supabase for Edge Functions. You only need to set `MCP_ACCESS_KEY` and `DEFAULT_USER_ID` manually.
93+
94+
Done when: The `ob-graph-mcp` function is deployed successfully and its secrets include `MCP_ACCESS_KEY` and `DEFAULT_USER_ID`.
95+
96+
---
97+
98+
![Step 3](https://img.shields.io/badge/Step_3-Connect_to_Your_AI-2E86AB?style=for-the-badge)
99+
100+
Follow the [Remote MCP Connection](../../primitives/remote-mcp/) guide to connect this recipe to Claude Desktop, ChatGPT, Claude Code, or any other MCP client.
101+
102+
| Setting | Value |
103+
|---------|-------|
104+
| Connector name | `OB-Graph` |
105+
| URL | Your **MCP Connection URL** from the credential tracker |
106+
107+
Done when: Your AI client can connect to the OB-Graph MCP server without authentication errors and the tools appear in its MCP tool list.
108+
109+
---
110+
111+
![Step 4](https://img.shields.io/badge/Step_4-Test_the_Graph-2E86AB?style=for-the-badge)
112+
113+
Try these commands with your AI:
114+
115+
**Build a small graph:**
116+
```
117+
Create these graph nodes:
118+
- "Supabase" (type: tool)
119+
- "Open Brain" (type: project)
120+
- "PostgreSQL" (type: tool)
121+
122+
Then connect them:
123+
- Open Brain --depends_on--> Supabase
124+
- Open Brain --depends_on--> PostgreSQL
125+
- Supabase --built_with--> PostgreSQL
126+
```
127+
128+
**Query relationships:**
129+
```
130+
What are all the neighbors of "Open Brain" in my graph?
131+
```
132+
133+
```
134+
Traverse my graph starting from "Supabase" up to 3 hops deep
135+
```
136+
137+
```
138+
Find the shortest path between "PostgreSQL" and "Open Brain"
139+
```
140+
141+
Done when: Your AI can create nodes, connect them with edges, and traverse the graph to answer relationship questions.
142+
143+
## MCP Tools Reference
144+
145+
| Tool | Description |
146+
|------|-------------|
147+
| `create_node` | Add an entity node (person, project, concept, tool, place) |
148+
| `create_edge` | Create a directed relationship between two nodes |
149+
| `search_nodes` | Find nodes by label or type |
150+
| `get_neighbors` | Get direct connections (incoming, outgoing, or both) |
151+
| `traverse_graph` | Multi-hop walk from a starting node (recursive CTE) |
152+
| `find_path` | Shortest path between two nodes (bidirectional BFS) |
153+
| `update_node` | Update label, type, or merge new properties |
154+
| `delete_node` | Remove a node and all its edges (CASCADE) |
155+
| `delete_edge` | Remove a specific relationship |
156+
| `list_edge_types` | List all relationship types in use with counts |
157+
158+
> [!TIP]
159+
> As your graph grows, see the [MCP Tool Audit & Optimization Guide](../../docs/05-tool-audit.md) for strategies on managing tool context.
160+
161+
## How the Graph Traversal Works
162+
163+
OB-Graph uses PostgreSQL recursive CTEs instead of a dedicated graph database. Here's the pattern:
164+
165+
```sql
166+
WITH RECURSIVE graph_walk AS (
167+
-- Base case: start node
168+
SELECT id, label, 0 AS depth, ARRAY[id] AS path
169+
FROM graph_nodes WHERE id = start_id
170+
171+
UNION ALL
172+
173+
-- Recursive case: follow edges, prevent cycles via path check
174+
SELECT n.id, n.label, gw.depth + 1, gw.path || n.id
175+
FROM graph_walk gw
176+
JOIN graph_edges e ON e.source_node_id = gw.id
177+
JOIN graph_nodes n ON n.id = e.target_node_id
178+
WHERE gw.depth < max_depth
179+
AND NOT n.id = ANY(gw.path) -- cycle prevention
180+
)
181+
SELECT * FROM graph_walk;
182+
```
183+
184+
This approach works well for knowledge graphs with thousands of nodes. It stays within Supabase's free tier limits (no extra services or extensions required) and gives you traversal, pathfinding, and neighbor queries — the core operations you need for relationship exploration.
185+
186+
> [!NOTE]
187+
> Recursive CTEs are bounded by `max_depth` and cycle prevention. For very large graphs (100k+ edges), consider adding a `weight` threshold filter to prune low-confidence edges during traversal.
188+
189+
## Expected Outcome
190+
191+
After setup, your AI can:
192+
193+
1. Build a knowledge graph of entities and relationships as you talk about them
194+
2. Answer "how is X related to Y?" with concrete graph paths
195+
3. Explore multi-hop connections ("what's 3 degrees from this project?")
196+
4. List all relationship types to understand your graph's structure
197+
5. Link graph nodes back to existing thoughts for full context
198+
199+
## Troubleshooting
200+
201+
### "relation 'graph_nodes' does not exist"
202+
203+
You haven't run the SQL from Step 1 yet. Copy `schema.sql` into your Supabase SQL Editor and run it.
204+
205+
### "function traverse_graph does not exist"
206+
207+
The SQL functions at the bottom of `schema.sql` didn't run. Make sure you execute the **entire** file, not just the `CREATE TABLE` statements. The functions (`traverse_graph`, `find_shortest_path`) are defined after the tables.
208+
209+
> [!WARNING]
210+
> If you ran only part of the SQL, run the full file again — all statements use `IF NOT EXISTS` or `CREATE OR REPLACE`, so re-running is safe.
211+
212+
### "duplicate key value violates constraint unique_edge"
213+
214+
You're trying to create an edge that already exists (same source, target, and relationship type). This is by design — the `unique_edge` constraint prevents duplicate relationships. If you want to update an existing edge's weight or properties, delete the old edge first and create a new one.

recipes/ob-graph/deno.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"imports": {
3+
"@hono/mcp": "npm:@hono/mcp@0.1.1",
4+
"@modelcontextprotocol/sdk": "npm:@modelcontextprotocol/sdk@1.24.3",
5+
"hono": "npm:hono@4.9.2",
6+
"zod": "npm:zod@4.1.13",
7+
"@supabase/supabase-js": "npm:@supabase/supabase-js@2.47.10"
8+
}
9+
}

0 commit comments

Comments
 (0)