Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
229 lines (214 loc) · 10.5 KB
/
Copy pathindex.html
File metadata and controls
229 lines (214 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>graingraph: embedded graph database for Go</title>
<meta name="description" content="An embedded property graph database for Go: Cypher over SQLite, no CGO. Includes graingraph-query, an HTTP server compatible with Neo4j's Query API, with compact output and a built-in skill for AI agents.">
<link rel="canonical" href="https://graingraph.com/">
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<meta name="theme-color" content="#faf8f3" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#14130f" media="(prefers-color-scheme: dark)">
<meta property="og:type" content="website">
<meta property="og:title" content="graingraph: embedded graph database for Go">
<meta property="og:description" content="Cypher over SQLite for Go, plus an HTTP server compatible with Neo4j's Query API, with compact output and a built-in skill for AI agents.">
<meta property="og:url" content="https://graingraph.com/">
<meta name="twitter:card" content="summary">
<link rel="stylesheet" href="style.css">
<script src="script.js" defer></script>
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<header class="site-header">
<div class="wrap bar">
<a class="brand" href="./" aria-label="graingraph home">
<svg viewBox="0 0 32 32" aria-hidden="true">
<path class="e" d="M7 23 C 11 14, 14 11, 17 8 M17 8 C 19 13, 22 17, 26 21 M7 23 C 14 26, 20 25, 26 21" fill="none" stroke-width="2.2" stroke-linecap="round"/>
<circle class="n" cx="7" cy="23" r="3.6"/><circle class="n" cx="17" cy="8" r="3.6"/><circle class="n" cx="26" cy="21" r="3.6"/>
</svg>
graingraph
</a>
<nav aria-label="Main">
<ul>
<li><a href="#features">Features</a></li>
<li><a href="#quick-start">Quick start</a></li>
<li><a href="#agents">For agents</a></li>
<li><a class="btn secondary small" href="https://github.com/graingraph/graingraph">GitHub</a></li>
</ul>
</nav>
</div>
</header>
<main id="main">
<div class="wrap">
<div class="hero">
<p class="eyebrow">Open source · Apache 2.0 · v0.3.0</p>
<h1>A graph database you can embed, query with Cypher, and hand to an AI agent.</h1>
<p class="lede">graingraph is an embedded property graph database for Go. It stores data in SQLite, speaks Cypher, and needs no CGO and no server. It also ships <code>graingraph-query</code>, an HTTP server compatible with Neo4j’s Query API, a compact output format and a built-in skill, so an agent can learn to use it on its own.</p>
<div class="cta">
<a class="btn primary" href="#quick-start">Get started</a>
<a class="btn secondary" href="https://github.com/graingraph/graingraph">View on GitHub</a>
</div>
</div>
</div>
<section id="features">
<div class="wrap">
<h2>What you get</h2>
<p class="sub">One module, two ways to use it: import it as a Go package, or run the server and talk to it over HTTP.</p>
<div class="cards">
<article class="card">
<span class="tag">Embedded</span>
<h3>Pure Go, no CGO</h3>
<p>Open a file or <code>:memory:</code> and run Cypher from Go. Storage is SQLite through a pure-Go driver, so there is nothing to install and cross-compiling just works.</p>
</article>
<article class="card">
<span class="tag">Cypher</span>
<h3>Real Cypher 25</h3>
<p>Pattern matching, <code>MERGE</code>, subqueries, shortest paths, indexes and constraints, temporal types and vector search. It passes the openCypher TCK scenarios that apply to Cypher 25.</p>
</article>
<article class="card">
<span class="tag">Server</span>
<h3>HTTP when you need it</h3>
<p><code>graingraph-query</code> speaks the Neo4j Query API v2, so most clients written for Neo4j work with it and moving to Neo4j later stays straightforward.</p>
</article>
<article class="card">
<span class="tag">Agents</span>
<h3>Made to be used by agents</h3>
<p>Ask for <code>text/toon</code> and get a flat, compact table. Failures are real HTTP error statuses, and a skill document at <code>/skills</code> teaches any agent how to query it.</p>
</article>
</div>
</div>
</section>
<section id="quick-start">
<div class="wrap">
<h2>Quick start</h2>
<p class="sub">Pick the way that suits you. Both run the same engine.</p>
<div class="stack">
<div>
<p class="label">As a Go library</p>
<div class="code"><pre><code>go get github.com/graingraph/graingraph
import "github.com/graingraph/graingraph"
db, err := graingraph.Open(":memory:")
if err != nil { log.Fatal(err) }
defer db.Close(ctx)
_, err = db.RunQuery(ctx,
`CREATE (:Person {name: 'Ada'})-[:KNOWS]->(:Person {name: 'Grace'})`, nil)
result, err := db.RunQuery(ctx,
`MATCH (a:Person)-[:KNOWS]->(b:Person)
RETURN a.name AS from, b.name AS to`, nil)
for result.Next(ctx) {
fmt.Println(result.Record().Values()) // [Ada Grace]
}</code></pre></div>
</div>
<div>
<p class="label">As a server</p>
<div class="code"><pre><code>go install \
github.com/graingraph/graingraph/cmd/graingraph-query@latest
export GRAINGRAPH_QUERY_PASSWORD=change-me
graingraph-query --username admin --db graingraph.db
curl -u admin:change-me \
-H 'Content-Type: application/json' \
-H 'Accept: text/toon' \
localhost:7474/db/neo4j/query/v2 \
-d '{"statement":"MATCH (p:Person) RETURN p.name AS name, p.born AS born ORDER BY born"}'
# rows[2]{name,born}:
# Ada,1815
# Grace,1906</code></pre></div>
<p class="note">Prebuilt binaries for Linux, macOS and Windows are on the <a href="https://github.com/graingraph/graingraph/releases">releases page</a>.</p>
</div>
</div>
</div>
</section>
<section id="same-query">
<div class="wrap">
<h2>The same query, in two formats</h2>
<p class="sub">A statement that returns two nodes and the relationship between them, on a small movie graph. Real output from the server, on the left as the Query API JSON and on the right as TOON.</p>
<div class="two">
<div>
<p class="label">JSON <span class="pill">147 tokens</span></p>
<div class="code wrapcode"><pre><code>{
"data": {
"fields": ["p", "r", "m"],
"values": [
[
{
"elementId": "57",
"labels": ["Person"],
"properties": {
"born": 1956,
"name": "Tom Hanks"
}
},
{
"elementId": "97",
"startNodeElementId": "57",
"endNodeElementId": "165",
"type": "ACTED_IN",
"properties": {
"roles": ["Chuck Noland"]
}
},
{
"elementId": "165",
"labels": ["Movie"],
"properties": {
"released": 2000,
"tagline": "At the edge of the world, his journey begins.",
"title": "Cast Away"
}
}
]
]
},
"bookmarks": ["FB:AAAAAAAAAA8vsraGnMfqiQ=="],
"queryType": "r",
"resultAvailableAfter": 1,
"resultConsumedAfter": 1
}</code></pre></div>
</div>
<div>
<p class="label">TOON, <code>Accept: text/toon</code> <span class="pill teal">96 tokens</span></p>
<div class="code wrapcode"><pre><code>rows[1]{p._id,p._labels,p.born,p.name,r._id,r._type,r._start,r._end,r.roles,m._id,m._labels,m.released,m.tagline,m.title}:
"57",Person,1956,Tom Hanks,"97",ACTED_IN,"57","165","[\"Chuck Noland\"]","165",Movie,2000,"At the edge of the world, his journey begins.",Cast Away</code></pre></div>
</div>
</div>
<p class="note">Each node and relationship is spread over columns, the header is written once, and bookmarks and timings are left out. The JSON is reformatted here for reading; the server sends it on one line. Token counts are for this one row with a GPT tokenizer, so the saving grows with the number of rows.</p>
</div>
</section>
<section id="agents">
<div class="wrap">
<h2>For AI agents</h2>
<p class="sub">An agent that has never seen graingraph can find out how to use it from the server itself.</p>
<ol class="steps">
<li><strong>Discover.</strong> <code>GET /skills</code> lists the skills a server offers. It needs no credentials.</li>
<li><strong>Learn.</strong> <code>GET /skills/graingraph-query</code> returns a <code>SKILL.md</code> in the Agent Skills format, with that server's URL filled into the examples. The binary can print the same document with no server running.</li>
<li><strong>Query.</strong> Send Cypher with <code>Accept: text/toon</code>. Parameters go in the request, results come back as a compact table, and every failure is an error status.</li>
</ol>
<div class="code"><pre><code># any agent with HTTP access
curl https://your-server/skills
curl https://your-server/skills/graingraph-query
# or from the binary, with no server running
graingraph-query skill --url https://your-server > SKILL.md</code></pre></div>
<p class="note">This site also has an <a href="llms.txt">llms.txt</a>, and the repository has an <a href="https://github.com/graingraph/graingraph/blob/main/AGENTS.md">AGENTS.md</a> for agents that work on the code.</p>
</div>
</section>
<section id="status">
<div class="wrap">
<h2>Status</h2>
<p class="sub">graingraph is at v0.3.0 and young. The API may still change before 1.0. The server is single-user by design: one credential, and one transaction open at a time. If that fits what you are building, <a href="https://github.com/graingraph/graingraph">take a look at the code</a>, and open an issue if something is missing.</p>
</div>
</section>
</main>
<footer>
<div class="wrap">
<p>graingraph is open source under the <a href="https://github.com/graingraph/graingraph/blob/main/LICENSE">Apache License 2.0</a>.</p>
<ul>
<li><a href="https://github.com/graingraph/graingraph">GitHub</a></li>
<li><a href="https://github.com/graingraph/graingraph/releases">Releases</a></li>
<li><a href="https://github.com/graingraph/graingraph/issues">Issues</a></li>
<li><a href="llms.txt">llms.txt</a></li>
</ul>
<p class="legal">Neo4j is a registered trademark of Neo4j, Inc. graingraph is an independent project and is not affiliated with, endorsed by or sponsored by Neo4j, Inc. References to Neo4j describe compatibility.</p>
</div>
</footer>
</body>
</html>