Skip to content

Architecture Overview

markymark is a Rust workspace of seven crates that produce a single binary. That binary can run as an LSP server (for editors) or an MCP server (for AI agents), sharing the same core indexing engine.

CrateRole
markymark-kernelsZig FFI layer — md4c parser and SIMD-accelerated operations
markymark-coreShared types, traits, error handling, scanner interface
markymark-parserTree-sitter-based markdown and structured format parsing
markymark-indexDocument indexing, cross-reference resolution, diagnostics
markymark-lspLSP server (tower-lsp)
markymark-mcpMCP server (rmcp)
markymark-cliCLI entry point and argument parsing
markymark-cli
/ \
markymark-lsp markymark-mcp
\ /
markymark-index
|
markymark-parser
|
markymark-core
|
markymark-kernels

The dependency graph is strictly layered — no circular dependencies. markymark-kernels requires a Zig 0.15.2+ toolchain — the Zig layer is statically linked into the final binary.

Both the LSP and MCP servers share the same indexing infrastructure. The CLI binary (markymark-cli) selects the server mode at startup:

  • --lsp starts the LSP server on stdin/stdout for editor integration
  • --mcp (with workspace roots) starts the MCP server on stdin/stdout for AI agent access

Both modes use CoreEngine — a trait defined in markymark-core — as the interface between protocol handlers and the indexing layer. CoreOperation enumerates every supported operation, and CoreOperationResult wraps the response. Adding a new capability requires changes in one place, and both servers can expose it.

markymark-kernels contains Zig source code compiled via build.rs into a static library linked at build time. The Zig code provides:

  • md4c parser bindings — a fast markdown parser (ported from Bun’s Zig md4c implementation) used as the primary parsing path for LSP operations
  • Document Engine — a stateful per-document Zig engine that parses markdown, extracts symbols, and serializes results into a binary blob consumed by Rust via DocumentIndex::from_blob()
  • SIMD-accelerated operations — vectorized search and text processing routines
  • FFI bindings — Rust calls into Zig via C ABI exports; the Rust side uses repr(C) mirror structs at the boundary

Good starting points for new contributors:

  • markymark-cli/src/main.rs — how the binary selects LSP vs MCP mode
  • markymark-core/src/engine.rsCoreEngine trait and CoreOperation enum
  • markymark-core/src/scanner.rsScanBackend trait with Md4cScanBackend and ZigScanBackend implementations
  • markymark-index/src/document/mod.rsDocumentIndex per-document storage
  • markymark-index/src/realm/mod.rsRealmIndex cross-document lookups
  • markymark-parser/src/lib.rs — tree-sitter parser entry point