Knowledge graph MCP server that gives AI full access to your knowledge graph. Supports Logseq and Obsidian — both with full read-write support. Navigate pages, search blocks, analyze link structure, track decisions, manage flashcards, compile knowledge, curate knowledge stores, and write content — all through the Model Context Protocol.
Hard fork of graphthulhu by Max Skridlevsky, extended with persistent SQLite storage, vector-based semantic search via Ollama, pluggable LLM providers (Ollama, Vertex AI), pluggable content sources (disk, GitHub, web crawl, code), knowledge compilation with temporal intelligence, curated knowledge stores, and trust tiers for the Unbound Force AI agent swarm ecosystem.
Built in Go with the official MCP Go SDK.
Your knowledge graph stores interconnected pages, blocks, and links. But AI assistants can't see any of it — they're blind to your second brain.
Dewey fixes that. It exposes your entire knowledge graph through MCP, so any MCP client can:
- Read any page with its full block tree, parsed links, tags, and properties
- Search across all blocks with contextual results (parent chain + siblings)
- Traverse the link graph to discover how concepts connect
- Find knowledge gaps — orphan pages, dead ends, weakly-linked areas
- Discover topic clusters through connected component analysis
- Create pages, write blocks, build hierarchies, link pages bidirectionally
- Query with raw DataScript/Datalog for anything the built-in tools don't cover (Logseq)
- Review flashcards with spaced repetition statistics (Logseq)
- Explore whiteboards and their spatial connections (Logseq)
It turns "tell me about X" into an AI that actually understands your knowledge graph's structure.
50 tools across 15 categories. Most work with both backends; some are Logseq-only (DataScript queries, flashcards, whiteboards).
| Tool | Backend | Description |
|---|---|---|
get_page |
Both | Full recursive block tree with parsed links, tags, properties |
get_block |
Both | Block by UUID with ancestor chain, children, siblings |
list_pages |
Both | Filter by namespace, property, or tag; sort by name/modified/created |
get_links |
Both | Forward and backward links with the blocks that contain them |
get_references |
Logseq | All blocks referencing a specific block via ((uuid)) |
traverse |
Both | BFS path-finding between two pages through the link graph |
| Tool | Backend | Description |
|---|---|---|
search |
Both | Full-text search with parent chain + sibling context |
query_properties |
Both | Find by property values with operators (eq, contains, gt, lt) |
query_datalog |
Logseq | Raw DataScript/Datalog queries against the Logseq database |
find_by_tag |
Both | Tag search with child tag hierarchy support |
| Tool | Backend | Description |
|---|---|---|
graph_overview |
Both | Global stats: pages, blocks, links, most connected, namespaces |
find_connections |
Both | Direct links, shortest paths, shared connections between pages |
knowledge_gaps |
Both | Orphan pages, dead ends, weakly-linked areas |
list_orphans |
Both | List orphan page names with block counts and property status |
topic_clusters |
Both | Connected components with hub identification |
health |
Both | Check server status: version, backend, read-only mode, page count, embedding status, sources |
| Tool | Backend | Description |
|---|---|---|
create_page |
Both | New page with properties and initial blocks |
append_blocks |
Both | Append plain-text blocks (simpler than upsert_blocks) |
upsert_blocks |
Both | Batch create with nested children for deep hierarchies |
update_block |
Both | Replace block content by UUID |
delete_block |
Both | Remove block and all children |
move_block |
Both | Reposition before, after, or as child of another block (cross-page supported) |
link_pages |
Both | Bidirectional link with optional relationship context |
delete_page |
Both | Remove a page and all its blocks |
rename_page |
Both | Rename page and update all [[links]] across the graph |
bulk_update_properties |
Both | Set a property on multiple pages in one call |
| Tool | Backend | Description |
|---|---|---|
decision_check |
Both | Surface open, overdue, and resolved decisions with deadline status |
decision_create |
Both | Create a DECIDE block with #decision tag, deadline, options, context |
decision_resolve |
Both | Mark a decision as DONE with resolution date and outcome |
decision_defer |
Both | Push deadline with reason, tracks deferral count, warns after 3+ |
analysis_health |
Both | Audit analysis/strategy pages for graph connectivity (3+ links or has decision) |
| Tool | Backend | Description |
|---|---|---|
journal_range |
Both | Entries across a date range with full block trees |
journal_search |
Both | Search within journals, optionally filtered by date |
| Tool | Backend | Description |
|---|---|---|
flashcard_overview |
Logseq | SRS stats: total, due, new vs reviewed, average repeats |
flashcard_due |
Logseq | Cards due for review with ease factor and interval |
flashcard_create |
Logseq | Create front/back card with #card tag |
| Tool | Backend | Description |
|---|---|---|
list_whiteboards |
Logseq | All whiteboards in the graph |
get_whiteboard |
Logseq | Embedded pages, block references, visual connections |
| Tool | Backend | Description |
|---|---|---|
semantic_search |
Both | Find documents semantically similar to a natural language query |
similar |
Both | Find the most similar documents to a given page or block |
semantic_search_filtered |
Both | Semantic search with metadata filters (source, properties, tier) |
| Tool | Backend | Description |
|---|---|---|
compile |
Both | Synthesize stored learnings into compiled knowledge articles |
store_compiled |
Both | Persist a compiled article synthesized by the calling agent |
| Tool | Backend | Description |
|---|---|---|
lint |
Both | Scan knowledge base for quality issues (stale decisions, embedding gaps, knowledge store quality) |
| Tool | Backend | Description |
|---|---|---|
promote |
Both | Promote draft content to validated after human review |
| Tool | Backend | Description |
|---|---|---|
index |
Both | Fetch and index configured content sources |
reindex |
Both | Delete and rebuild all external source content |
reload |
Obsidian | Force a full vault re-index from disk |
| Tool | Backend | Description |
|---|---|---|
store_learning |
Both | Store a learning with tag, category, and temporal identity |
| Tool | Backend | Description |
|---|---|---|
curate |
Both | Run the curation pipeline to extract structured knowledge from indexed sources into knowledge stores |
brew install --cask unbound-force/tap/deweyThe cask includes a signed and notarized binary. Ollama is installed automatically as a dependency.
go install github.com/unbound-force/dewey/v3@latestRequires Go 1.25+. Works on macOS, Linux, and any platform with a Go toolchain.
git clone https://github.com/unbound-force/dewey.git
cd dewey
go build -o dewey .- In Logseq, go to Settings → Features and enable HTTP APIs server
- Click the API icon that appears in the top toolbar
- Click Start Server
- Click Create Token and copy the generated token — you'll need it for configuration
The API runs on http://127.0.0.1:12315 by default.
No plugins or server required. Dewey reads your vault's .md files directly.
You need to provide the path to your vault:
dewey serve --backend obsidian --vault /path/to/your/vaultOr via environment variables:
export DEWEY_BACKEND=obsidian
export OBSIDIAN_VAULT_PATH=/path/to/your/vault
deweyThe Obsidian backend supports full read-write operations. It parses YAML frontmatter into properties, builds a block tree from headings, and indexes [[wikilinks]] for backlink resolution. Writes use atomic temp-file renames, and the in-memory index is rebuilt after every mutation. File watching (fsnotify) keeps the index in sync with external edits. Daily notes are detected from a configurable subfolder (default: daily notes).
Add to your opencode.json:
{
"mcp": {
"dewey": {
"type": "local",
"command": ["dewey"],
"env": {
"LOGSEQ_API_URL": "http://127.0.0.1:12315",
"LOGSEQ_API_TOKEN": "your-token-here"
}
}
}
}{
"mcp": {
"dewey": {
"type": "local",
"command": ["dewey", "--backend", "obsidian", "--vault", "/path/to/your/vault"]
}
}
}To disable all write operations (Obsidian backend, the default):
{
"mcp": {
"dewey": {
"type": "local",
"command": ["dewey", "--read-only", "--backend", "obsidian", "--vault", "/path/to/your/vault"]
}
}
}For the Logseq backend (requires Logseq running with API enabled):
{
"mcp": {
"dewey": {
"type": "local",
"command": ["dewey", "--read-only", "--backend", "logseq"],
"env": {
"LOGSEQ_API_URL": "http://127.0.0.1:12315",
"LOGSEQ_API_TOKEN": "your-token-here"
}
}
}
}On startup with the Logseq backend, Dewey checks if your graph directory is git-controlled. If not, it prints a warning to stderr suggesting you initialize version control. Write operations cannot be undone without it.
Dewey stores its index in .uf/dewey/graph.db (SQLite). The database holds pages, blocks, links, vector embeddings, and source metadata. After the first full index, subsequent sessions load from the persistent index and only reprocess changed files — startup is near-instant.
Run dewey init to create the .uf/dewey/ directory with default configuration:
dewey initThis creates:
.uf/dewey/config.yaml— embedding model and endpoint settings.uf/dewey/sources.yaml— content source configuration (empty by default).uf/dewey/graph.db— created automatically on firstdewey serveordewey index.uf/dewey/dewey.log— created automatically bydewey servefor MCP server diagnostics (truncated at 10 MB on startup)
Add .uf/dewey/ to your .gitignore. The index is machine-local and rebuilt from source files.
| Variable | Default | Description |
|---|---|---|
LOGSEQ_API_URL |
http://127.0.0.1:12315 |
Logseq HTTP API endpoint |
LOGSEQ_API_TOKEN |
(required for Logseq) | Bearer token from Logseq settings |
DEWEY_BACKEND |
obsidian |
Backend type: obsidian (default) or logseq |
OBSIDIAN_VAULT_PATH |
— | Path to Obsidian vault root |
DEWEY_EMBEDDING_MODEL |
granite-embedding:30m |
Ollama embedding model name |
DEWEY_EMBEDDING_ENDPOINT |
http://localhost:11434 |
Ollama API endpoint |
DEWEY_AUTHOR |
— | Override author identity for store_learning (useful in CI or shared environments) |
GITHUB_TOKEN / GH_TOKEN |
— | GitHub API token for content sources |
| Flag | Short | Description |
|---|---|---|
--verbose |
-v |
Enable debug logging (shows UUID seeds, block insertions, lock detection) |
--log-file PATH |
Write logs to file in addition to stderr | |
--no-embeddings |
Skip embedding generation (on serve, index, reindex) | |
--vault PATH |
Path to vault (on serve, index, reindex, status, search, doctor, manifest) |
When running as an MCP server (dewey serve), Dewey automatically logs to .uf/dewey/dewey.log for diagnostics. The log file is truncated when it exceeds 10 MB.
Initialize a Dewey configuration in the current directory. Creates .uf/dewey/ with default config.yaml and sources.yaml.
dewey init [--vault PATH]Build or update the knowledge graph and embedding indexes from all configured sources. Uses content hashing for incremental updates — only re-indexes changed files.
dewey index [--vault PATH] [--source NAME] [--force] [--no-embeddings]--force— Re-fetch all sources, even if within their refresh interval--no-embeddings— Skip embedding generation (keyword search still works)
Delete the existing index and rebuild from scratch. Use when upgrading Dewey, recovering from corruption, or after fixing UUID collision issues.
dewey reindex [--vault PATH] [--no-embeddings]This removes graph.db, WAL/SHM files, and the lock file before rebuilding. Requires stopping dewey serve first (the lock file prevents concurrent access).
Report index health: page count, block count, embedding coverage, source status.
dewey status [--vault PATH] [--json]Run diagnostic checks for Dewey dependencies and report pass/fail with fix instructions. Checks: workspace initialization, database health (per-source page counts), Ollama availability, embedding model status, MCP server process, and opencode.json configuration.
dewey doctor [--vault PATH]Full-text search across the knowledge graph (local files and external sources from graph.db).
dewey search [--vault PATH] [--limit N] QUERYAdd a content source (GitHub or web) to the configuration.
dewey source add github --org ORG --repos REPO1,REPO2 [--refresh INTERVAL]
dewey source add web --url URL [--name NAME] [--depth N] [--refresh INTERVAL]Generate .uf/dewey/manifest.md — a structured summary of CLI commands, MCP tools, and exported packages discovered via AST parsing of Go source files.
dewey manifest [--vault PATH]Append a block to a Logseq journal page.
dewey journal [--vault PATH] CONTENTAppend a block to a named Logseq page.
dewey add [--vault PATH] PAGE CONTENTSynthesize stored learnings into compiled knowledge articles. Reads all learnings, clusters them by topic tag, and produces current-state articles that resolve temporal contradictions — newer facts replace older ones.
dewey compile [--vault PATH]Scan the knowledge base for quality issues: stale decisions, embedding gaps, contradictions, and orphaned content.
dewey lint [--vault PATH] [--fix]Promote a page from draft tier to validated after human review. Only draft-tier pages (agent-generated content) can be promoted.
dewey promote [--vault PATH] PAGE_NAMERun the curation pipeline to extract structured knowledge from indexed sources into knowledge stores. Uses an LLM (via Ollama) to analyze indexed content and produce curated markdown files with confidence scoring and quality flags.
dewey curate [--vault PATH] [--store NAME] [--force] [--no-embeddings]--store— Curate a specific named store (default: all configured stores)--force— Run full curation instead of incremental (re-process all documents)--no-embeddings— Skip embedding generation for curated files
Dewey indexes content from four pluggable source types. Configure them in .uf/dewey/sources.yaml:
sources:
- name: local-vault
type: disk
config:
path: .
- name: org-repos
type: github
config:
org: your-org
repos:
- repo-one
- repo-two
content_types:
- issues
- pulls
- readmes
refresh: daily
- name: go-docs
type: web
config:
urls:
- https://pkg.go.dev/github.com/spf13/cobra
depth: 2
refresh: weeklyYou can also add sources via the CLI instead of editing YAML directly:
dewey source add github --org your-org --repos repo-one,repo-two
dewey source add web --url https://pkg.go.dev/github.com/spf13/cobra --depth 2After adding sources, build the index:
dewey index # incremental — only fetches sources past their refresh interval
dewey index --force # full rebuild — re-fetches everythingThe code source type indexes source code files using language-aware AST chunking. Currently supports Go, with a pluggable architecture for additional languages.
- name: project-code
type: code
config:
path: "../replicator"
languages:
- goThe Go chunker extracts: package doc comments, exported function/method signatures, type declarations, Cobra CLI commands, and MCP tool registrations. Test files are excluded by default.
Dewey respects .gitignore files at the root of each source directory. Additionally, disk and code sources support ignore and recursive fields in sources.yaml:
- name: disk-website
type: disk
config:
path: "../website"
ignore: [drafts, temp] # additional patterns beyond .gitignore
recursive: true # set false for top-level files onlySemantic search requires an embedding provider. Dewey defaults to Ollama running locally, but also supports Google Vertex AI. All keyword-based tools work without an embedding provider — only the 3 semantic search tools (semantic_search, similar, semantic_search_filtered) require one.
Dewey auto-starts Ollama if it's installed but not running. No manual ollama serve needed — Dewey detects Ollama's state (External/Managed/Unavailable) and starts a subprocess if necessary. The subprocess is detached so it outlives Dewey.
brew install --cask ollama-app # macOS — or download from https://ollama.ai
ollama pull granite-embedding:30m # IBM Granite, 63 MB, Apache 2.0dewey statusThe output shows embedding coverage. If Ollama is running and the model is pulled, you'll see embedding stats. If the provider is unavailable, Dewey logs a warning at startup and disables semantic search — all other tools continue to work normally.
Embedding and synthesis providers are configurable via .uf/dewey/config.yaml:
# Ollama (default — no config needed if defaults are fine)
embedding:
provider: ollama
model: granite-embedding:30m
endpoint: http://localhost:11434
# Vertex AI — for cloud-powered embeddings or synthesis
embedding:
provider: vertex
model: text-embedding-005
project: my-gcp-project
region: us-central1
synthesis:
provider: vertex
model: claude-sonnet-4-6
project: my-gcp-project
region: us-east5You can mix providers — e.g., Ollama for embeddings (fast, local) and Vertex AI for synthesis (high quality):
embedding:
provider: ollama
model: granite-embedding:30m
synthesis:
provider: vertex
model: claude-sonnet-4-6
project: my-gcp-project
region: us-east5Vertex AI requires Google Cloud application-default credentials:
gcloud auth application-default login --scopes=https://www.googleapis.com/auth/cloud-platformSet project and region in your config to match your GCP setup. Vertex AI embedding models (e.g., text-embedding-005) and Claude synthesis models (e.g., claude-sonnet-4-6) must be enabled in your GCP project.
Note: Switching embedding providers changes vector dimensions. Run dewey reindex after changing the embedding model.
Rate limiting: Vertex AI providers automatically retry on HTTP 429 (Too Many Requests) with exponential backoff and jitter — base delay 1 second, maximum 60 seconds, up to 5 attempts. The Retry-After header is respected when present. If retries are exhausted, the error is returned to the caller.
Create ~/.config/dewey/config.yaml (or $XDG_CONFIG_HOME/dewey/config.yaml) to set defaults for all vaults. Per-vault config overrides global.
Environment variables override config file values for embedding. For synthesis, they serve as fallbacks when no config exists.
| Variable | Default | Description |
|---|---|---|
DEWEY_EMBEDDING_MODEL |
granite-embedding:30m |
Embedding model (overrides config) |
DEWEY_EMBEDDING_ENDPOINT |
http://localhost:11434 |
Embedding API endpoint (overrides config) |
DEWEY_GENERATION_MODEL |
(none) | Synthesis model (fallback when no config) |
Dewey can synthesize stored learnings into compiled knowledge articles using an LLM. The compile tool reads all learnings, clusters them by topic tag, and produces current-state articles that resolve temporal contradictions — newer facts replace older ones, while non-contradicted information carries forward.
Agents can also compile knowledge directly: call compile to receive synthesis prompts, perform synthesis with any model, then call store_compiled to persist the result with provenance tracking. This enables agent-driven compilation without requiring a local LLM.
All content in Dewey's index has a trust tier:
| Tier | Source | Description |
|---|---|---|
authored |
Disk, GitHub, web, code sources | Human-written content. Highest trust. |
curated |
curate, knowledge stores |
Machine-extracted knowledge. LLM-curated with quality flags. |
validated |
promote |
Agent content promoted by human review. |
draft |
store_learning, compile |
Agent-generated. Unreviewed. |
untrusted |
Source config | Content from sources marked as lower trust. |
Filter search by tier: semantic_search_filtered(query: "auth", tier: "authored")
Filter curated content: semantic_search_filtered(query: "auth", tier: "curated")
Knowledge stores are named collections of curated knowledge extracted from indexed sources. Configure them in .uf/dewey/knowledge-stores.yaml:
stores:
- name: team-knowledge
sources:
- disk-meetings
- github-org
curation_interval: "10m"Run dewey curate to extract knowledge, or let background curation handle it automatically during dewey serve. Curated files are written to .uf/dewey/knowledge/{store-name}/ and automatically indexed with tier: "curated" for immediate searchability.
Each curated knowledge item includes:
- Confidence scoring:
high,medium,low, orflagged - Quality flags:
missing_rationale,implied_assumption,incongruent,unsupported_claim - Source traceability: Every fact traces back to its source document
Learnings stored via store_learning are also dual-written to .uf/dewey/learnings/ as markdown files, ensuring they survive database deletion.
Dewey scans indexed content for security threats and structural anomalies through five defense layers:
- Injection pattern scanning — Detects prompt injection attempts (instruction overrides, role reassignment, delimiter injection) using compiled regex patterns with severity calibration (critical/high/medium)
- Content hash drift detection — Tracks content changes between index cycles via SHA-256 hash comparison
- Markdown structure validation — Identifies invisible Unicode characters, embedded data URIs, invalid heading depth, and suspicious HTML tags (
<script>,<iframe>, event handlers) - Content size anomaly detection — Statistical outlier detection using 3-sigma threshold across source documents (requires 5+ documents per source)
- Trust tier assignment — Sources can be marked with explicit trust levels, with
untrustedtier for lower-trust external content
Configure sanitization per-source in .uf/dewey/sources.yaml:
sources:
- name: external-wiki
type: web
config:
urls:
- https://wiki.example.com
trust_tier: untrusted # authored (default), curated, validated, draft, untrusted
sanitize_mode: strict # warn (default for web/github), strict, off (default for disk/code)sanitize_mode: warn— Scan content and merge findings into page properties. Content is still indexed. Default forwebandgithubsources.sanitize_mode: strict— Reject documents withcriticalorhighseverity findings. Documents are skipped during indexing.sanitize_mode: off— Skip sanitization entirely. Default fordiskandcodesources (user-authored content).
Use dewey doctor to see an aggregated summary of sanitization findings by source and severity:
dewey doctor --vault /path/to/vaultUse dewey lint to see per-page findings with severity and pattern version:
dewey lint --vault /path/to/vaultWhen patterns are updated in a new Dewey release, dewey lint flags stale findings and recommends dewey reindex to re-scan with updated patterns.
When dewey serve starts, the MCP server is ready within 1 second. Vault indexing runs in the background — tools serve from the persistent store (previous session's data) while indexing completes. The health tool reports indexing status.
main.go Entry point — backend routing, MCP server startup
cli.go CLI subcommands: journal, add, search, init, index, reindex, status,
source, doctor, manifest, compile, lint, promote, curate
server.go MCP server setup — 50 tool registrations
backend/backend.go Backend interface + optional capability interfaces
client/logseq.go Logseq HTTP API client with retry/backoff
vault/
vault.go Obsidian vault client — reads .md files into Backend interface
markdown.go Markdown → block tree parser (heading-based sectioning)
frontmatter.go YAML frontmatter parser
index.go Backlink index builder from [[wikilinks]]
parse_export.go Exported parsing and persistence functions
tools/
navigate.go Page, block, links, references, BFS traversal
search.go Full-text, property, DataScript/frontmatter, tag search
analyze.go Graph overview, connections, gaps, clusters
write.go Create, update, delete, move, link operations
decision.go Decision protocol: check, create, resolve, defer, analysis health
journal.go Date range and search within journals
flashcard.go SRS overview, due cards, card creation
whiteboard.go List and inspect whiteboards
semantic.go Semantic search, similar, filtered search, store_learning
compile.go Knowledge compilation, linting, promotion
curate.go Knowledge store curation pipeline handler
helpers.go Result formatting utilities
graph/
builder.go In-memory graph construction from any backend
algorithms.go Overview, connections, gaps, clusters, BFS
parser/content.go Regex extraction of [[links]], ((refs)), #tags, properties
types/
logseq.go Shared types with custom JSON unmarshaling
tools.go Input types for all 50 tools
semantic.go Semantic search types
llm/ LLM synthesis interface (Synthesizer, OllamaSynthesizer, VertexSynthesizer, NoopSynthesizer)
store/
store.go SQLite persistence (pages, blocks, links, sources)
embeddings.go Vector embedding storage and cosine similarity search
migrate.go Schema migration management
embed/
embed.go Embedder interface + Ollama implementation
vertex.go Vertex AI embedding implementation
provider.go Provider factory + config
chunker.go Block-to-chunk preparation with heading context
source/
source.go Source interface definition
config.go Source configuration parsing (YAML)
disk.go Local disk source (file scanning)
github.go GitHub API source (issues, PRs, READMEs)
web.go Web crawl source (HTML-to-text, robots.txt)
manager.go Source orchestration (refresh, failures)
chunker/ Language-aware source code parsing (Go chunker, registry)
curate/ Knowledge store config parsing + curation pipeline
sanitize/ Content sanitization pipeline (injection scanning, structure validation,
drift detection, size anomaly detection)
Dewey is a hard fork of graphthulhu, originally created by Max Skridlevsky. All graphthulhu functionality is preserved; Dewey extends it with additional capabilities for the Unbound Force ecosystem.
go build -o dewey . # Build
go test ./... # Test
go vet ./... # Vet