Skip to main content
Glama

mindyard

Your personal LLM wiki: a git-versioned Markdown vault, served over MCP to Claude.ai, Claude Desktop, Claude Code or any MCP client.

The model reads, searches and edits your wiki through six tools. The server does the bookkeeping that keeps the wiki trustworthy, and no model runs on it:

  • every write is a git commit, applied atomically: a batch of edits lands whole or not at all;

  • no lost updates: editing a page requires the version you read, and a stale one is rejected (optimistic concurrency);

  • write zones: sources in raw/ are create-only, the index, log and schema cannot be deleted, and wiki.yaml (the rules) is read-only for the model;

  • the protocol travels with the server: clients without any skill still get the method through the MCP instructions and tool descriptions;

  • a deterministic linter checks links, orphans, frontmatter and the rules your wiki.yaml declares (required fields, closed status lists, statuses implied by dates).

Status: early release (0.1). Website: mindyard.dev.

Quickstart

uv tool install mindyard        # or prefix each command with `uvx`, or `pip install mindyard`
mindyard init ./data/vaults/garden --demo
mindyard lint ./data/vaults/garden
claude mcp add mindyard -e MINDYARD_DATA_ROOT=$PWD/data -- mindyard serve --stdio

--stdio lets a local client launch the server itself: no port, no token, the vaults of the user who runs it. Claude Desktop takes the same command in claude_desktop_config.json:

{
  "mcpServers": {
    "mindyard": {
      "command": "uvx",
      "args": ["mindyard", "serve", "--stdio"],
      "env": { "MINDYARD_DATA_ROOT": "/home/you/data" }
    }
  }
}

Over HTTP instead, MINDYARD_DATA_ROOT=./data mindyard serve listens on http://127.0.0.1:8787/mcp, without auth and on loopback only; authentication below opens it to Claude.ai and remote clients.

mindyard init DIR without --demo creates an empty vault. Every directory under <data root>/vaults/ holding a wiki.yaml is served as one wiki.

Related MCP server: wiki-helper

A vault

garden/
  wiki.yaml    # enforced: layout, entity kinds, lint rules (read-only for the model)
  schema.md    # advisory: what the wiki is about, conventions, for the model
  index.md     # one line per page
  log.md       # one entry per operation
  raw/         # sources, verbatim, create-only
  wiki/        # distilled pages, linked with [[wikilinks]] (Obsidian-compatible)

Authentication

Set MINDYARD_AUTH:

Value

For

Notes

none

local use

refuses to listen beyond loopback

bearer

remote Claude Code or Desktop, scripts

mindyard token new laptop prints a token once; only its SHA-256 is stored

google

Claude.ai (OAuth)

needs MINDYARD_BASE_URL, MINDYARD_GOOGLE_CLIENT_ID, MINDYARD_GOOGLE_CLIENT_SECRET, MINDYARD_ALLOWED_EMAILS; an account off the list is refused at sign-in

Claude Code against a remote server, with a bearer token:

claude mcp add --transport http mindyard https://wiki.example.org/mcp \
  --header "Authorization: Bearer $MINDYARD_TOKEN"

Claude.ai custom connectors accept static headers for some accounts only; OAuth (google) is the route that works everywhere.

Configuration

Variable

Default

MINDYARD_DATA_ROOT

(required)

holds vaults/, tokens.yaml, state/

MINDYARD_AUTH

none

none, bearer, google

MINDYARD_TENANCY

single

mapped: several tenants, see below

MINDYARD_HOST, MINDYARD_PORT, MINDYARD_PATH

127.0.0.1, 8787, /mcp

MINDYARD_BASE_URL

public URL, for OAuth

MINDYARD_ALLOWED_EMAILS

comma-separated, verified emails only

MINDYARD_TELEMETRY

1

one log line per tool call; argument values are never logged

state/ holds the OAuth proxy's client registrations and tokens. It is not a cache: deleting it signs every client out.

Several tenants. With MINDYARD_TENANCY=mapped, tenants.yaml maps identities (issuer and subject, never the email) to tenants, whose vaults live under tenants/<tenant>/. A caller only ever sees its own tenant's wikis; no tool takes a tenant argument.

Docker

cp compose.example.yaml compose.yaml   # adjust user, auth, volume
docker compose up -d

Put a TLS reverse proxy in front; the server itself enforces authentication.

Development

uv sync
uv run ruff check && uv run ruff format --check && uv run mypy && uv run pytest

A client skill carrying the editorial method is in skills/mindyard/.

Contributions are welcome: see CONTRIBUTING.md. Contributors sign a license agreement (CLA.md). Security issues: SECURITY.md.

License

AGPL-3.0-or-later. See LICENSE.

Available Tools

6 tools
get_lint_reportLint reportA
Read-only

Return the wiki's latest lint report, as Markdown.

The report lists broken links, orphan pages, frontmatter problems and breaches of the rules the wiki declares. It is written by the 'mindyard lint' command, not recomputed by this call, so it may predate recent edits. Use it to review a wiki's health or before a clean-up batch; when no report exists yet, a message says so.

Inputs: wiki (required). Returns: result

list_pagesList pagesA
Read-only

List the Markdown files of a zone, to browse a wiki by its structure.

To find pages by their content, use search_wiki instead; to open one, pass its path to read_page. Returns {pages, truncated, total}: paths relative to the wiki root, sorted and capped at limit; total counts every match and truncated says the list was cut.

Inputs: wiki (required), limit, scope, prefix. Returns: object

list_wikisList wikisA
Read-only

List the caller's wikis as [{id, label, description}].

Call it first in a session: every other tool takes one of these ids as 'wiki'. An empty list means no wiki is set up for this account.

Inputs: no named parameters. Returns: result

read_pageRead pageA
Read-only

Read one file of the target wiki (confined to its root).

Use it to open a page found with list_pages or search_wiki, and the index, log and schema files at the wiki root. A missing path or one outside the wiki is refused with an error.

Default: rendered for display, Obsidian wikilinks stripped, so never show '[[...]]' to the user. Pass raw=True to get the verbatim bytes before editing a page, so write_batch keeps the '[[...]]' syntax on disk.

offset is 1-based and limit caps the lines returned. Returns {content, version, total_lines, start_line, end_line, truncated}. Pass 'version' back as 'expected_version' when modifying this page.

Inputs: path (required), wiki (required), raw, limit, +1 more. Returns: object

search_wikiSearch wikiA
Read-only

Find the lines of a wiki that contain a text, to locate pages by content.

Returns [{page, line, text}], one entry per matching line. Read the full page with read_page (offset=line jumps to the match); to browse by path, use list_pages. An invalid regular expression is refused with an error.

Inputs: wiki (required), query (required), regex, scope, +1 more. Returns: result

write_batchWrite batch (commits changes)A
Destructive

Transactionally apply typed edit operations in one git commit.

Call it only after the user agreed to the plan (target wiki, every operation, any split into several batches). Keep each call under about 30 kB of arguments: split up front, with index and log in the last batch.

Each edit is one {op, ...}, applied in order (chained on the same path):

  • create: {op, path, content}; fails if the path exists.

  • overwrite: {op, path, content, expected_version}; full rewrite.

  • replace: {op, path, old, new, expected_version, replace_all?}; surgical edit, 'old' must be unique unless replace_all=true. Read the page with raw=True first so 'old' matches the bytes on disk.

  • delete: {op, path, expected_version}.

  • rename: {op, path, new_path, expected_version}; wikilinks to the old name are not rewritten, fix them with replace ops in the same batch.

expected_version is the token from read_page; required to modify, delete or rename an existing file, ignored for a path created earlier in this batch. Writes stay under the wiki and raw zones or the index/log/schema files; raw/ is create-only; the log, index and schema cannot be deleted or renamed. Everything is validated first: on any failure nothing is written or committed. Returns {commit, applied}.

Inputs: wiki (required), edits (required), message (required). Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.4/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose: listing wikis, reading a page, browsing pages by path, searching content, retrieving a lint report, and applying transactional edits. Descriptions explicitly cross-reference each other (e.g., 'to find pages by content, use search_wiki instead'), leaving no ambiguity about when to use which tool.

    Naming Consistency5/5

    All six tool names follow a consistent snake_case verb_noun pattern: list_wikis, read_page, list_pages, search_wiki, get_lint_report, write_batch. There are no mixed conventions or vague verbs.

    Tool Count5/5

    Six tools is a well-scoped set for a wiki server, covering discovery (list_wikis, list_pages), retrieval (read_page, search_wiki), health checking (get_lint_report), and mutation (write_batch). No tool feels redundant or missing at this level.

    Completeness4/5

    The page lifecycle is fully covered: read, list, search, and a transactional write_batch that supports create, overwrite, replace, delete, and rename. The only minor gaps are wiki-level operations (e.g., creating or deleting a wiki), which appear intentionally out of scope since wikis are set up externally.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Provides structured search, schema-validated writes, and linting for a markdown knowledge base, enabling agents to operate the wiki over a single streamable-HTTP MCP endpoint.
      1
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables MCP clients to maintain a persistent Markdown knowledge base by ingesting sources, searching and reading notes, and creating or updating wiki pages with optimistic locking.
      12
      AGPL 3.0
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables MCP clients to read, search, list, create, and update Markdown wiki articles with tags, knowledge-graph links, backlinks, and version history under a shared permission model. All access is scoped by per-article read/write permissions and requires MFA-authenticated logins.
      1
      Apache 2.0