High-performance Markdown & structured document LSP + MCP server in Rust and Zig.
Pre-release Software: markymark is in active development. APIs, configuration, and behavior may change between minor versions.
markymark is a Language Server Protocol (LSP) and Model Context Protocol (MCP) server for Markdown and structured data files, built in Rust with Zig SIMD kernels for performance-critical operations:
- Multi-format support — Markdown, JSON, JSONC, JSON5, JSONL, YAML, TOML, .env, INI/CFG
- Zig SIMD kernels — Vectorized heading/link/tag/block scanning, similarity search, entity hashing, and token estimation via
@Vectorintrinsics with scalar reference fallbacks - Multi-tenant realm isolation (shared vs isolated workspaces)
- Full Obsidian and Logseq flavor support (wiki links, callouts, block IDs, page properties)
- Anchor link rename support (updates heading references across workspace)
- Cross-format references — wiki links resolve to structured document key paths
- Incremental indexing — Byte-range selective merge for fast re-indexing on edit
- Dual-transport architecture (LSP + MCP over stdio)
cargo install --git https://github.com/sethyanow/markymark markymark-clicargo install markymark-cliPre-built binaries for macOS (ARM64/x86_64), Linux (x86_64/ARM64), and Windows (x86_64) are available from Releases.
Install markymark from the VS Code Marketplace or search "markymark" in the Extensions panel. The extension discovers the markymark binary on $PATH and starts the LSP client automatically.
See markymark-plugin/README.md for plugin installation.
As LSP server (stdio):
markymark --lspAs MCP server (stdio):
markymark --mcp /path/to/workspaceWhen running as an MCP server, markymark exposes these tools:
| Tool | Description |
|---|---|
create-realm |
Create an isolated workspace realm |
add-root |
Add a directory root to a realm for indexing |
search-symbols |
Fuzzy symbol search across indexed documents |
get-outline |
Heading/key outline for a single document |
export-index |
Full index export (headings, tags, links) for a document |
find-references |
All references to a heading or XML tag |
rename |
Rename a heading or tag, updating all references |
search-workspace |
Full-text search with frontmatter/property/tag filtering |
search-for-pattern |
Regex search with glob filtering and context lines |
graph-analysis |
Link graph intelligence (orphans, hubs, broken links, clusters, DOT export) |
When using markymark with Claude Code, AI agents can save significant tokens by querying the LSP for structure and diagnostics before reading files.
For a 260-line file, an LSP documentSymbol query uses ~100 tokens vs ~2000+ for a full Read — roughly 95% savings. This works for Markdown, JSON, YAML, TOML, and all supported formats:
- Get structure first —
LSP documentSymbolreturns the heading/key hierarchy - Check diagnostics — Broken links, duplicate slugs, and unclosed tags are reported automatically
- Hover for details —
LSP hoveron headings shows backlinks; on structured keys shows path/type info - Read only when needed — Use
Readonly if you need full content
Document outline (works for Markdown headings AND JSON/YAML/TOML keys):
LSP documentSymbol file.md
LSP documentSymbol config.jsonHover on a heading or structured key:
LSP hover file.md <line> <col>
LSP hover config.yaml <line> <col>Find all references (cross-format: wiki links resolve to structured keys):
LSP findReferences file.md <line> <col>Jump to definition of a wiki link target:
LSP goToDefinition file.md <line> <col>Search symbols across workspace:
LSP workspaceSymbol "query"Add this to your project's CLAUDE.md to encourage LSP-first reading:
## Document Intelligence
This project uses markymark LSP. ALWAYS prefer LSP over reading raw files:
- `LSP documentSymbol <file>` for structure/outline before Read
- `LSP hover <file> <line> <col>` for heading backlinks and key path info
- Diagnostics (broken links, duplicate headings) are reported automatically
- Works for Markdown, JSON, YAML, TOML, .env, INI, and more
- Only use the Read tool when you need full prose content| Crate | Description |
|---|---|
markymark-core |
Core types and abstractions |
markymark-parser |
Tree-sitter based parser (Markdown, JSON, YAML, TOML, JSON5, JSONL, flat) |
markymark-index |
Document indexing and symbol resolution |
markymark-kernels |
Zig SIMD kernel FFI wrappers (scan, embed, similarity, hash, tokens) |
markymark-lsp |
LSP server (tower-lsp-server) |
markymark-mcp |
MCP server (rmcp) |
markymark-cli |
CLI entry point |
- Rust stable (Edition 2021)
- Zig 0.15.2+ (for SIMD kernels in
markymark-kernels)
cargo build --release
# Binary at target/release/markymarkThe markymark-kernels crate's build.rs invokes zig build lib automatically — Zig just needs to be on $PATH.
# Run all tests
cargo test
# Run tests for a specific crate
cargo test -p markymark-core
# Run with insta snapshot review
cargo insta test --reviewcargo clippy --workspace --all-targetsInstall lefthook and local security tools:
# macOS (Homebrew)
brew install lefthook gitleaks
# Linux (install lefthook binary from upstream release if needed)
# https://github.com/evilmartians/lefthook#install
# Rust tooling
cargo install --locked cargo-auditInstall git hooks for this repository:
lefthook installRun the full pre-commit pipeline manually:
lefthook run pre-commit- CommonMark: Standard markdown with heading anchors
- Obsidian: Wiki links
[[page]], callouts, block IDs^id, embeds![[file]] - Logseq: Nested lists, block UUIDs, page properties
All structured formats get byte-accurate source positions, LSP document symbols, hover info, and cross-format reference resolution.
| Format | Extensions | Parser |
|---|---|---|
| JSON | .json |
tree-sitter-json |
| JSONC | .jsonc |
tree-sitter-json (comment-tolerant) |
| JSON5 | .json5 |
json5 crate + custom scanner |
| JSONL | .jsonl |
per-line JSON via tree-sitter |
| YAML | .yaml, .yml |
tree-sitter-yaml |
| TOML | .toml |
tree-sitter-toml-ng |
| .env | .env |
line-based key=value |
| INI/CFG | .ini, .cfg |
section + key=value/key:value |