Skip to content

@mrsf/mcp

Model Context Protocol (MCP) server for Sidemark — the Markdown Review Sidecar Format (MRSF).

License: MITMRSF v1.0 Draft@mrsf/mcp on npmnpm downloads (mcp)MCP Compatible

Exposes Sidemark and MRSF (Markdown Review Sidecar Format) operations as MCP tools and resources so that AI assistants (Claude Desktop, Cursor, VS Code Copilot, etc.) can review Markdown documents, inspect existing comment threads, add review feedback, resolve comments, validate sidecars, and re-anchor comments through the standard MCP protocol.

Installation

bash
npm install -g @mrsf/mcp

Or use directly:

bash
npx @mrsf/mcp

Quick Start — Claude Desktop

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):

json
{
  "mcpServers": {
    "mrsf": {
      "command": "npx",
      "args": ["-y", "@mrsf/mcp"]
    }
  }
}

Restart Claude Desktop — the MRSF tools will appear automatically.

Quick Start — VS Code / Cursor

Add to your project's .vscode/mcp.json:

json
{
  "servers": {
    "mrsf": {
      "command": "npx",
      "args": ["-y", "@mrsf/mcp"]
    }
  }
}

Transport Options

FlagDefaultDescription
--transport stdioStandard I/O (Claude Desktop, Cursor, VS Code)
--transport sseServer-Sent Events over HTTP
--port <n>3001Port for SSE transport
bash
# Default — stdio
mrsf-mcp

# SSE on custom port
mrsf-mcp --transport sse --port 8080

Tools

The server exposes the following MCP tools:

ToolDescription
mrsf_discoverFind the sidecar for a Markdown document
mrsf_validateValidate sidecars against the MRSF schema
mrsf_reanchorRe-anchor comments after a document has been edited
mrsf_addAdd a new review comment to a sidecar
mrsf_add_batchAdd multiple review comments in one atomic call
mrsf_updateUpdate fields of an existing comment by ID
mrsf_resolveResolve or unresolve comments by ID(s) or filters
mrsf_listList and filter comments (status, author, type, severity) with full or compact output
mrsf_statusCheck anchor health (fresh / stale / orphaned)
mrsf_renameUpdate a sidecar after its document has been renamed
mrsf_deleteDelete a comment by ID (with optional cascade)
mrsf_repairRepair or reset a corrupted sidecar
mrsf_helpList all tools and their parameter schemas

Working with live editor buffers

When an editor has unsaved Markdown changes, pass documentText to mrsf_add, mrsf_add_batch, mrsf_update, or mrsf_reanchor. The server uses that inline text for selected_text population and anchoring instead of reading the document from disk. For mrsf_reanchor, documentText requires exactly one target sidecar/document.

Mutating tools return a sidecar content hash as version. Pass the latest value back as expectedVersion on the next write to reject stale edits:

json
{
  "document": "guide.md",
  "id": "c-123",
  "text": "Updated comment",
  "expectedVersion": "last-observed-sha256"
}

If the sidecar changed, the tool returns isError: true with:

json
{
  "status": "conflict",
  "code": "version-mismatch",
  "currentVersion": "new-sha256",
  "expectedVersion": "last-observed-sha256"
}

Recommended client pattern: read or discover the sidecar to get version, make one mutation with expectedVersion, then re-read or use the returned version before any follow-up mutation.

Concurrency & write-conflict semantics

When an interactive editor and an agent (this MCP server) can both write the same sidecar, the following contract applies.

Within a single process (the @mrsf/cli library writeSidecar):

  • Writes to the same sidecar path are serialized through a per-file queue, so concurrent calls never interleave a read-modify-write cycle.
  • Every write is atomic (write to a temp file in the same directory, then rename), so readers never observe a half-written file.
  • The YAML writer round-trips at the CST level, preserving unrelated formatting/comments, but it persists the writer's full in-memory document — there is no field-level merge of concurrent edits. At this layer the effective semantics are last-write-wins for the document state held in memory.

Across processes (editor ⇄ MCP agent) — optimistic concurrency:

  • The library itself has no cross-process expectedVersion/etag guard; two separate processes doing read-modify-write can still race and lose comments.
  • The MCP tools add an optimistic-concurrency guard on top: every read/mutation returns a version (a SHA-256 hash of the sidecar contents). Pass the last-observed value back as expectedVersion on the next mutation. If the on-disk sidecar changed in the meantime, the tool returns isError: true with { "status": "conflict", "code": "version-mismatch", "currentVersion", "expectedVersion" } and performs no write.
  • The library does not merge concurrent comment additions; reconciliation is the caller's responsibility, driven by version.

Recommended pattern for a host that both watches and writes the sidecar:

  1. Track the latest version you have observed for each sidecar.
  2. Watch the sidecar file for external changes (e.g. the agent writing) and reload your in-memory document when it changes, adopting the new version.
  3. Always send expectedVersion on MCP mutations (mrsf_add, mrsf_add_batch, mrsf_update, mrsf_resolve, mrsf_rename, mrsf_delete, and single-target mrsf_reanchor).
  4. On a version-mismatch, reload the sidecar, re-apply your pending change against the fresh state, and retry with the new expectedVersion.
  5. Serialize your own writes (editor save vs. agent action) rather than firing both concurrently; the version guard turns an unavoidable race into a detectable conflict rather than silent data loss.

expectedVersion is honored only when a mutation targets exactly one sidecar. For batch/multi-target mrsf_reanchor it is ignored (the response notes this), so coordinate those per-file.

Tool Details

mrsf_discover

Find the Sidemark (MRSF) sidecar for a Markdown document.

ParameterTypeRequiredDescription
documentstringPath to the Markdown document
cwdstringWorking directory (defaults to process.cwd())

Returns version, the current sidecar content hash.

mrsf_validate

Validate one or more Sidemark (MRSF) sidecars.

ParameterTypeRequiredDescription
filesstring[]Sidecar or Markdown file paths. If omitted, discovers all sidecars in the workspace.
strictbooleanTreat warnings as errors
cwdstringWorking directory

mrsf_reanchor

Re-anchor comments after document edits.

ParameterTypeRequiredDescription
filesstring[]Sidecar or Markdown file paths. If omitted, discovers all sidecars.
dryRunbooleanReport without modifying files
thresholdnumberFuzzy match threshold 0.0–1.0 (default 0.6)
updateTextbooleanAlso replace selected_text with current document text
forcebooleanFirmly anchor high-confidence results: update commit to HEAD and clear audit fields
documentTextstringInline document content for unsaved editor buffers (single target only)
expectedVersionstringReject write if the current sidecar hash differs
cwdstringWorking directory

Returns version for each processed sidecar.

mrsf_add

Add a review comment to a Sidemark (MRSF) sidecar.

ParameterTypeRequiredDescription
documentstringPath to the Markdown document
textstringComment text
authorstringAuthor identifier (e.g. 'Name (handle)')
linenumberStarting line number (1-based)
end_linenumberEnding line number (inclusive)
start_columnnumberStarting column (0-based)
end_columnnumberEnding column
typestringComment type: suggestion, issue, question, accuracy, style, clarity
severity"low" | "medium" | "high"Severity level
reply_tostringParent comment ID for threading
extensionsobjectTool-specific x_* extension fields; keys must start with x_
documentTextstringInline document content for unsaved editor buffers
expectedVersionstringReject write if the current sidecar hash differs
cwdstringWorking directory

Returns version, the new sidecar content hash.

mrsf_add_batch

Add multiple review comments to a Sidemark (MRSF) sidecar in one atomic write.

ParameterTypeRequiredDescription
documentstringPath to the Markdown document
commentsobject[]Array of comments: each needs text and author, optional line, end_line, start_column, end_column, type, severity, reply_to, extensions
documentTextstringInline document content for unsaved editor buffers
expectedVersionstringReject write if the current sidecar hash differs
cwdstringWorking directory

Returns version, the new sidecar content hash.

mrsf_update

Update fields of an existing comment by ID (only provided fields are changed).

ParameterTypeRequiredDescription
documentstringPath to the Markdown document or its sidecar
idstringComment ID to update
textstringNew comment text
typestringNew type: suggestion, issue, question, accuracy, style, clarity
severity"low" | "medium" | "high"New severity level
linenumberNew starting line number (1-based)
end_linenumberNew ending line number (inclusive)
start_columnnumberNew starting column (0-based)
end_columnnumberNew ending column
extensionsobjectMerge tool-specific x_* fields into the comment
documentTextstringInline document content for unsaved editor buffers when line anchors change
expectedVersionstringReject write if the current sidecar hash differs
cwdstringWorking directory

extensions values are stored on disk as flat x_* fields on the comment, not as a nested object.

Returns version, the new sidecar content hash.

mrsf_resolve

Resolve or unresolve comments. Provide a single id, an array of ids, or filters.

ParameterTypeRequiredDescription
documentstringPath to the Markdown document or its sidecar
idstringSingle comment ID to resolve/unresolve
idsstring[]Array of comment IDs to resolve/unresolve
authorstringResolve all comments by this author
typestringResolve all comments of this type
severity"low" | "medium" | "high"Resolve all comments of this severity
unresolvebooleanSet to true to unresolve instead
expectedVersionstringReject write if the current sidecar hash differs
cwdstringWorking directory

Returns version, the current sidecar content hash.

mrsf_list

List and filter comments across Sidemark (MRSF) sidecars.

ParameterTypeRequiredDescription
filesstring[]Sidecar or Markdown file paths. If omitted, discovers all sidecars.
openbooleanOnly show unresolved comments
resolvedbooleanOnly show resolved comments
authorstringFilter by author
typestringFilter by type
severity"low" | "medium" | "high"Filter by severity
format"full" | "compact"Output format: full (JSON) or compact (text table)
summarybooleanReturn summary statistics instead of full comments
cwdstringWorking directory

Full and summary JSON outputs include each sidecar's version.

mrsf_status

Check anchor health of all comments in Sidemark (MRSF) sidecars.

ParameterTypeRequiredDescription
filesstring[]Sidecar or Markdown file paths. If omitted, discovers all sidecars.
cwdstringWorking directory

Returns sidecar version values in the files array.

mrsf_rename

Update sidecar after a document rename/move.

ParameterTypeRequiredDescription
oldDocumentstringOld path to the Markdown document
newDocumentstringNew path to the Markdown document
expectedVersionstringReject write if the current old sidecar hash differs
cwdstringWorking directory

Returns version, the new sidecar content hash.

mrsf_delete

Delete a comment by ID from a sidecar. By default, direct replies are promoted (they inherit the parent's anchor and their reply_to is re-pointed to the grandparent). Use cascade to delete direct replies along with the parent instead.

ParameterTypeRequiredDescription
documentstringPath to the Markdown document or its sidecar
idstringComment ID to delete
cascadebooleanWhen true, also remove direct replies instead of promoting them (default: false)
expectedVersionstringReject write if the current sidecar hash differs
cwdstringWorking directory

Returns version, the new sidecar content hash.

mrsf_repair

Repair or reset a corrupted sidecar. Use salvage strategy to attempt recovering parseable comments from a corrupted sidecar (rewrites it cleanly). Use reset strategy to delete the sidecar and start fresh with an empty comment list.

ParameterTypeRequiredDescription
documentstringPath to the Markdown document or its sidecar
strategy"salvage" | "reset"Repair strategy: salvage (default) attempts to recover comments; reset starts fresh
expectedVersionstringReject write if the current sidecar hash differs
cwdstringWorking directory

Returns version, the new sidecar content hash.

mrsf_help

List all available Sidemark (MRSF) MCP tools with their parameter schemas. Optionally filter to a specific tool for detailed parameter info.

ParameterTypeRequiredDescription
toolstringTool name to get detailed help for (e.g. mrsf_add). Omit to list all tools.

Resources

The server also exposes MCP resources for direct data access:

URI PatternDescription
mrsf://sidecar/{path}Full parsed Sidemark (MRSF) sidecar as JSON
mrsf://comment/{path}/{id}A single review comment from a sidecar
mrsf://anchors/{path}Anchor health status for all comments in a sidecar

Agent Skill Example

The repository includes a ready-to-use Agent Skill that teaches AI agents to review Markdown documents using the MCP server. See the skill on GitHub.

Copy it into your project:

bash
cp -r examples/mrsf-review .agent/skills/

The skill instructs the agent to discover sidecars, add anchored comments with type and severity, validate results, and summarize findings — all through the MCP tools above.

Requirements

  • Node.js ≥ 18
  • @mrsf/cli (installed automatically as a dependency)

License

MIT

Released under the MIT License.