docs

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2026 License: MIT Imports: 6 Imported by: 0

README

memgraph-docs

Build human-readable documents on top of memgraph, an agentic knowledge substrate. Exposed as an MCP server so agents can write — and reconstruct — structured documents (headings, paragraphs, lists, code, quotes, media refs) as a tree of memgraph nodes.

Status: Alpha (v0.1.0). See DESIGN.md for the model.

What it does

memgraph stores facts as atomic nodes with first-class edges. memgraph-docs adds a vocabulary on top: a doc.document node holds a tree of typed content children connected by doc.contains edges. An agent can:

  • create a document, append headings/paragraphs/lists/code/quotes/media/dividers,
  • nest content under headings (or under other nodes — sections become subtrees),
  • edit a node (new memgraph version) or move it around,
  • reconstruct the whole tree as a CommonMark markdown string.

Because everything lives in memgraph, you also get versioning, lineage, freshness, and graph-shaped queries for free. memgraph-docs doesn't reimplement any of that.

Install

One-line install (macOS, Linux)
curl -fsSL https://raw.githubusercontent.com/camggould/memgraph-docs/main/install.sh | sh

Downloads the latest release from GitHub, verifies SHA-256 against checksums.txt, and installs memgraph-docs to /usr/local/bin (falling back to $HOME/.local/bin if /usr/local/bin isn't writable and sudo isn't available).

Override defaults via env vars:

# Pin to a specific version
curl -fsSL https://raw.githubusercontent.com/camggould/memgraph-docs/main/install.sh | MEMGRAPH_DOCS_VERSION=v0.1.0 sh

# Install somewhere else
curl -fsSL https://raw.githubusercontent.com/camggould/memgraph-docs/main/install.sh | MEMGRAPH_DOCS_INSTALL_DIR=$HOME/bin sh
Pre-built binaries (manual)

Tarballs and a checksums.txt are on the Releases page for darwin/linux on amd64+arm64 and windows/amd64.

go install
go install github.com/camggould/memgraph-docs/cmd/memgraph-docs@latest

Requires Go 1.25+. Binary lands in $(go env GOBIN) (or $GOPATH/bin).

Build from source
git clone https://github.com/camggould/memgraph-docs.git
cd memgraph-docs
go build -o memgraph-docs ./cmd/memgraph-docs

Pure-Go build, no cgo. Cross-compile for any supported target:

GOOS=linux GOARCH=amd64 go build -o memgraph-docs-linux-amd64 ./cmd/memgraph-docs
Cutting a new release (maintainers)

The repo ships a .goreleaser.yaml. After tagging a new version on main:

git tag -a vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.Z
GITHUB_TOKEN=$(gh auth token) goreleaser release --clean

Quickstart

memgraph-docs runs as an MCP server over stdio. It opens a memgraph SQLite store and exposes docs_* tools.

memgraph-docs serve --sqlite ~/.memgraph/store.db

The store file is the same one memgraph uses. You can run both servers against the same file (just not at the same time — SQLite is single-writer).

Wire it into an MCP client
{
  "mcpServers": {
    "memgraph-docs": {
      "command": "memgraph-docs",
      "args": ["serve", "--sqlite", "/Users/you/.memgraph/store.db"]
    }
  }
}

For Claude Code:

claude mcp add memgraph-docs -- memgraph-docs serve --sqlite ~/.memgraph/store.db
Sample agent flow
> Write a short doc in my notes graph about today's outage.

[agent calls docs_create_document(graph_id="...", title="Outage 2026-05-16")]
[agent calls docs_append_heading(level=1, text="Summary")]
[agent calls docs_append_paragraph(text="...")]
[agent calls docs_append_heading(level=1, text="Timeline")]
[agent calls docs_append_list(ordered=true, items=["09:42 — pager"...])]
[agent calls docs_render_markdown(...)]

The render output is a CommonMark string ready to paste into a wiki, doc tool, or email.

MCP tools

Read:

Tool Purpose
docs_list_documents All root document nodes in a graph
docs_get_outline Structural tree (headings + containers, no bodies)
docs_render_markdown Full document as a markdown string

Write — content:

Tool Purpose
docs_create_document New document root with title / author / abstract
docs_append_heading Heading 1-6
docs_append_paragraph Paragraph
docs_append_list Ordered or unordered list with items in one call
docs_append_code Fenced code block with language
docs_append_quote Blockquote
docs_append_media Image / video / audio / file by URL
docs_append_divider Horizontal rule

Write — edits:

Tool Purpose
docs_update_text New version of an existing node's text
docs_move Reparent and/or reorder a node

All append tools accept an optional parent_id. If omitted, the new node is added under the document root. To build a section, append a heading and then append its content with that heading's lineage_id as the parent.

Node kinds

All kinds are namespaced with doc.:

Kind Notes
doc.document Root
doc.heading metadata.level = 1..6
doc.paragraph
doc.list metadata.ordered = bool; children are list_items
doc.list_item Can have nested lists as children
doc.code_block metadata.language
doc.quote
doc.media metadata.kind ∈ {image, video, audio, file}, metadata.src, metadata.alt
doc.divider

Edges: one kind, doc.contains, parent → child. Sibling order is the edge's ordinal.

Clients can introduce custom kinds; the renderer falls back to a best-effort plain-paragraph rendering.

Library use

The same builder API is available as a Go package:

import (
    docs "github.com/camggould/memgraph-docs"
    memgraph "github.com/camggould/memgraph"
    "github.com/camggould/memgraph/store/sqlite"
)

store, _ := sqlite.Open("store.db")
defer store.Close()

b := docs.NewBuilder(store)
doc, _ := b.CreateDocument(ctx, docs.CreateDocumentInput{
    GraphID: graphID,
    Title:   "My Doc",
})

heading, _ := b.AppendHeading(ctx, docs.AppendHeadingInput{
    DocumentID: doc.LineageID,
    Level:      1,
    Text:       "Hello",
})

b.AppendParagraph(ctx, docs.AppendParagraphInput{
    DocumentID: doc.LineageID,
    ParentID:   heading.LineageID,
    Text:       "Content under the heading.",
})

md, _ := b.RenderMarkdown(ctx, doc.LineageID)

Development

git clone https://github.com/camggould/memgraph-docs.git
cd memgraph-docs
go test -race ./...

Relationship to memgraph

memgraph-docs is the L2 reference client described in memgraph's PRD §10. The substrate (graph, lineage, conflicts, MCP transport, storage backends) lives in memgraph; memgraph-docs is a thin layer that adds vocabulary, structural conventions, and a renderer.

If you want raw memgraph tools (search, traverse, create_graph, etc.), run memgraph alongside this server.

License

MIT. See LICENSE.

Documentation

Overview

Package docs is a thin layer over memgraph that models documents as trees of typed nodes (headings, paragraphs, lists, media, etc.) connected by ordered doc.contains edges. The package provides a Builder for writing document trees into a memgraph.Store and a renderer for emitting them as markdown. See DESIGN.md for the conceptual model.

Index

Constants

View Source
const (
	KindDocument  = "doc.document"
	KindHeading   = "doc.heading"
	KindParagraph = "doc.paragraph"
	KindList      = "doc.list"
	KindListItem  = "doc.list_item"
	KindCodeBlock = "doc.code_block"
	KindQuote     = "doc.quote"
	KindMedia     = "doc.media"
	KindDivider   = "doc.divider"
)

Node kinds used by memgraph-docs. All are namespaced with `doc.` so they don't collide with kinds from other clients sharing the same memgraph deployment.

View Source
const (
	MediaImage = "image"
	MediaVideo = "video"
	MediaAudio = "audio"
	MediaFile  = "file"
)

Media kinds used by docs.media nodes' metadata.kind field.

View Source
const EdgeContains = "doc.contains"

Edge kind connecting parents to children in a document tree.

View Source
const MaxHeadingLevel = 6

MaxHeadingLevel is the deepest CommonMark heading level we accept.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppendCodeInput

type AppendCodeInput struct {
	DocumentID memgraph.LineageID
	ParentID   memgraph.LineageID
	Code       string
	Language   string
	CreatedBy  string
}

type AppendDividerInput

type AppendDividerInput struct {
	DocumentID memgraph.LineageID
	ParentID   memgraph.LineageID
	CreatedBy  string
}

type AppendHeadingInput

type AppendHeadingInput struct {
	DocumentID memgraph.LineageID
	ParentID   memgraph.LineageID // empty = document root
	Level      int                // 1-6
	Text       string
	CreatedBy  string
}

type AppendListInput

type AppendListInput struct {
	DocumentID memgraph.LineageID
	ParentID   memgraph.LineageID
	Ordered    bool
	Items      []string
	CreatedBy  string
}

type AppendMediaInput

type AppendMediaInput struct {
	DocumentID memgraph.LineageID
	ParentID   memgraph.LineageID
	MediaKind  string // image, video, audio, file
	Src        string
	Alt        string
	Caption    string
	Width      int
	Height     int
	CreatedBy  string
}

type AppendParagraphInput

type AppendParagraphInput struct {
	DocumentID memgraph.LineageID
	ParentID   memgraph.LineageID
	Text       string
	CreatedBy  string
}

type AppendQuoteInput

type AppendQuoteInput struct {
	DocumentID memgraph.LineageID
	ParentID   memgraph.LineageID
	Text       string
	CreatedBy  string
}

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder is the high-level write/read API for documents stored in a memgraph.Store. All operations are safe for concurrent use as long as the underlying Store is.

func NewBuilder

func NewBuilder(store memgraph.Store) *Builder

NewBuilder returns a Builder bound to the given Store. The Builder does not own the Store; callers are responsible for closing it.

func (*Builder) AppendCode

func (b *Builder) AppendCode(ctx context.Context, in AppendCodeInput) (NodeRef, error)

func (*Builder) AppendDivider

func (b *Builder) AppendDivider(ctx context.Context, in AppendDividerInput) (NodeRef, error)

func (*Builder) AppendHeading

func (b *Builder) AppendHeading(ctx context.Context, in AppendHeadingInput) (NodeRef, error)

func (*Builder) AppendList

func (b *Builder) AppendList(ctx context.Context, in AppendListInput) (NodeRef, error)

AppendList creates a list node and its item children in sequence. If item creation fails partway through, earlier writes are NOT rolled back — memgraph doesn't expose multi-write transactions at the Store level. For v0.1 this is acceptable; clients can detect partial failure via the count in the returned NodeRef metadata.

func (*Builder) AppendMedia

func (b *Builder) AppendMedia(ctx context.Context, in AppendMediaInput) (NodeRef, error)

func (*Builder) AppendParagraph

func (b *Builder) AppendParagraph(ctx context.Context, in AppendParagraphInput) (NodeRef, error)

func (*Builder) AppendQuote

func (b *Builder) AppendQuote(ctx context.Context, in AppendQuoteInput) (NodeRef, error)

func (*Builder) CreateDocument

func (b *Builder) CreateDocument(ctx context.Context, in CreateDocumentInput) (DocumentRef, error)

func (*Builder) GetOutline

func (b *Builder) GetOutline(ctx context.Context, docID memgraph.LineageID, maxDepth int) (Outline, error)

GetOutline returns the document's structural tree. maxDepth limits how deep the traversal goes; 0 means unlimited.

func (*Builder) ListDocuments

func (b *Builder) ListDocuments(ctx context.Context, graphID memgraph.GraphID) ([]DocumentRef, error)

func (*Builder) Move

func (b *Builder) Move(ctx context.Context, in MoveInput) error

Move reparents a node and/or reorders it among its siblings. It rewrites the single inbound doc.contains edge for the node (deletes and recreates it), and compacts sibling ordinals to 1..N at both the old and new parents so numbers stay small.

func (*Builder) RenderMarkdown

func (b *Builder) RenderMarkdown(ctx context.Context, docID memgraph.LineageID) (string, error)

RenderMarkdown walks the document tree and emits a CommonMark string. Unknown kinds render as plain paragraphs.

func (*Builder) UpdateText

func (b *Builder) UpdateText(ctx context.Context, in UpdateTextInput) (NodeRef, error)

type CreateDocumentInput

type CreateDocumentInput struct {
	GraphID   memgraph.GraphID
	Title     string
	Author    string
	Abstract  string
	CreatedBy string
}

type DocumentRef

type DocumentRef struct {
	LineageID memgraph.LineageID
	GraphID   memgraph.GraphID
	Title     string
	Author    string
	Abstract  string
	CreatedAt time.Time
}

DocumentRef summarizes a document for listing.

type MoveInput

type MoveInput struct {
	NodeID      memgraph.LineageID
	NewParentID memgraph.LineageID
	Position    *int // 0-indexed; nil = append
	CreatedBy   string
}

type NodeRef

type NodeRef struct {
	LineageID memgraph.LineageID
	GraphID   memgraph.GraphID
	Kind      string
	Ordinal   int
}

NodeRef is the public ID + minimal metadata returned from write operations.

type Outline

type Outline struct {
	Node     OutlineNode `json:"node"`
	Children []Outline   `json:"children,omitempty"`
}

Outline summarizes the structural skeleton of a document — headings and container nodes, without paragraph or code bodies. Used by docs_get_outline.

type OutlineNode

type OutlineNode struct {
	LineageID memgraph.LineageID `json:"lineage_id"`
	Kind      string             `json:"kind"`
	Title     string             `json:"title,omitempty"`
	Level     int                `json:"level,omitempty"`
}

OutlineNode is the minimal per-node payload returned in an outline.

type UpdateTextInput

type UpdateTextInput struct {
	NodeID    memgraph.LineageID
	Text      string
	CreatedBy string
}

Directories

Path Synopsis
cmd
memgraph-docs command
Command memgraph-docs is the CLI entrypoint for the memgraph-docs MCP server.
Command memgraph-docs is the CLI entrypoint for the memgraph-docs MCP server.
Package mcp exposes a memgraph-docs Builder as a Model Context Protocol server.
Package mcp exposes a memgraph-docs Builder as a Model Context Protocol server.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL