Skip to main content
ClaudeWave

MCP server that saves your Claude Code, Cursor, and Codex sessions as versioned Markdown reports — with human-in-the-loop review and Apple Pencil / S Pen annotation.

MCP ServersRegistry oficial3 estrellas0 forks● TypeScriptMITActualizado today
ClaudeWave Trust Score
95/100
✓ Verified
Passed
  • ✓Open-source license (MIT)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Last scanned: 10/5/2026
Install in Claude Code / Claude Desktop
Method: NPX · md-log-mcp
Claude Code CLI
claude mcp add md-log-mcp -- npx -y md-log-mcp
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "md-log-mcp": {
      "command": "npx",
      "args": ["-y", "md-log-mcp"],
      "env": {
        "MDLOG_API_BASE_URL": "<mdlog_api_base_url>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Detected environment variables
MDLOG_API_BASE_URL
Casos de uso

Resumen de MCP Servers

# md-log-mcp

[![npm version](https://img.shields.io/npm/v/md-log-mcp)](https://www.npmjs.com/package/md-log-mcp)
[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-com.md--log%2Fmd--log--mcp-1f6feb)](https://registry.modelcontextprotocol.io/v0/servers?search=md-log)
[![License: MIT](https://img.shields.io/npm/l/md-log-mcp)](./LICENSE)
[![Node](https://img.shields.io/node/v/md-log-mcp)](https://nodejs.org)

> **Review the report, not the diff.** An MCP server that lets your AI coding agent — **Claude Code, Claude Desktop, Codex, Cursor** — save its work and analysis as immutable, versioned **Markdown reports** into [**md-log**](https://md-log.com), a human-in-the-loop review & archive layer for **"vibe coding."** You then read and **stylus-annotate** (S-Pen / Apple Pencil) those reports on web, phone, and tablet — every save a new immutable version.

A [Model Context Protocol](https://modelcontextprotocol.io) server — **two transports, one tool set** —
that lets **Claude Code** (and other agents) save `.md` files — text **and** embedded screenshots
together — straight into **md-log**, a human-in-the-loop review & archive layer for vibe coding. The
**recommended** way to connect is the **hosted remote endpoint** (`https://mcp.md-log.com/mcp`, a URL +
your key — no install); a local **stdio** (`npx -y md-log-mcp`) transport is the alternative. The agent writes a report
**by path** (`my-project/2026-07-07-error-report.md`); missing folders are auto-created, images are
uploaded and their references rewritten to `asset://` links, and every save becomes an immutable new
version. The same report is then readable, editable, and stylus-annotatable (S-Pen / Apple Pencil
where supported) on a phone or tablet, and on the web.

md-log is a **hosted service** at **https://app.md-log.com** — you don't run any server yourself.
This package is just the connector: a **thin authenticated HTTP client** that validates POSIX paths,
orchestrates asset uploads, maps errors to stable agent codes, and forwards everything to the hosted
md-log service — the single authority for auth, storage, versioning and quota. All you need is a
Personal Access Token from the web app.

## Stack

- **@modelcontextprotocol/sdk** (TypeScript) — one `McpServer` (17 tools), two transports.
- **stdio transport** (`md-log-mcp`) — JSON-RPC over stdin/stdout; the default local mode (so stdout
  is reserved for the protocol; logs go to stderr). PAT from env.
- **Streamable HTTP transport** (`md-log-mcp-http`) — the remote mode: agents connect by URL with no
  local install; the PAT is taken **per request** from the `Authorization` header. See
  [Remote (Streamable HTTP) mode](#remote-streamable-http-mode).
- **TypeScript**, bundled with **tsup** to ESM `dist/server.js` (stdio) + `dist/http.js` (HTTP).
  Runtime deps: the MCP SDK and **zod** (input schemas). Node's built-in `fetch`/`http` are the only
  network layers — no web framework.
- **PAT auth** — a md-log Personal Access Token sent to the backend as `Authorization: Bearer`.

## Requirements

- Node **22+**
- A **Personal Access Token** (PAT) minted in the md-log web app (**Settings → Tokens**; shown once)

That's it — the md-log service itself is hosted at `https://app.md-log.com`; there is nothing to
install or self-host.

## Tools (17)

Every tool returns dual output — a human-readable `content[].text` and a machine-readable
`structuredContent` — and validates the POSIX path (NFC-normalize; reject `..`/`.`, control chars,
empty/whitespace segments, backslashes, reserved names; enforce 255-byte name / 1024-byte path
limits; require `.md` for files) **before** any backend call. All requests hit the base URL in
`MDLOG_API_BASE_URL` (which already includes `/api/v1`).

| Tool | What it does |
| ---- | ------------ |
| **`save_markdown`** ⭐ | The headline tool. Create or overwrite a `.md` by path (force last-writer-wins); missing folders auto-created. Optionally uploads embedded images first (each given as `data_base64` **or** a local `file_path`) and rewrites each `placeholder` in the content to an `asset://<key>` link. Accepts `commit_message` — a recommended 1-2 line change summary shown in the version history. |
| `upload_asset` | Upload one image (reserve → presigned PUT → complete) and return an `asset://<key>` reference to embed as `![alt](asset://<key>)`. Provide the image as **either** `data_base64` (inline base64) **or** `file_path` (a local file the server reads) — exactly one; with `file_path`, `filename` defaults to the basename and `content_type` is inferred from the extension (png/jpg/jpeg/gif/webp/avif). |
| `append_to_markdown` | Append to an existing file with optimistic concurrency (GET current → concat → conditional PUT with `base_version_no`). Auto-retries once on conflict, then surfaces `CONFLICT`. Accepts `commit_message` — a recommended 1-2 line change summary shown in the version history. |
| **`edit_markdown`** | Change PART of a file by exact literal replacement (read → apply → conditional PUT with `base_version_no`; auto-retries once on conflict, re-applying every edit). Pass several changes at once as **`edits: [{old_string, new_string, replace_all?}, …]`** (max 50, applied in order) — they land as **one write = one version = one notification**; for a single change the `old_string`/`new_string` shorthand still works (never both). Each `old_string` must match **exactly once**, counting overlapping positions too (`"\n\n"` inside `"\n\n\n"` is ambiguous → `detail.overlapping: true`) — 0 matches or an ambiguous >1 rejects the **whole call** with `VALIDATION` (`detail.reason` = `NO_MATCH` / `AMBIGUOUS_MATCH`, `detail.edit_index` = the failing edit) and **nothing is written**; set `replace_all:true` to change every occurrence on purpose. Other `detail.reason`s: input shape — `MIXED_INPUT`, `MISSING_EDIT`, `EMPTY_EDITS`, `TOO_MANY_EDITS`, `EMPTY_OLD_STRING`, `IDENTICAL_STRINGS` (rejected before any read); result — `NO_CHANGE` (edits cancel out), `DOCUMENT_TOO_LARGE` (a step would pass the 25 MiB cap), `TOO_MANY_REPLACEMENTS` (more occurrences replaced in one call than the document cap allows), `BATCH_TOO_SLOW` (edits after the first stopped once the call has run 2 s — split them across calls). A match failure on the conflict retry carries `detail.after_concurrent_write: true`. Never creates a file (missing path → `NOT_FOUND`) and has no force mode — prefer it over `update_markdown` for any partial change. |
| `update_markdown` | Replace a file's ENTIRE content. Pass `expected_version` for optimistic concurrency (mismatch → `CONFLICT`); omit it to force LWW. Passing `expected_version` for a path that does **not** exist now returns `CONFLICT` (`detail.server_version_no` = `0`), not a silent create. For a partial change use `edit_markdown` instead. Accepts `commit_message` — a recommended 1-2 line change summary shown in the version history. |
| `restore_version` | Roll a file back to an earlier `version_no` (from `list_versions`): that version's content becomes a NEW current version — history is immutable, so the rollback is itself undoable. Restoring the version the file is already on is an accepted no-op. Accepts `commit_message`. |
| `get_markdown` | Read a file's content by path (materializes inline content or a presigned content URL for large docs). Pass `version` (a `version_no` from `list_versions`) to read an old immutable version. |
| `list_versions` | List a file's immutable version history, newest first (`version_no`, `commit_message`, author, `registered_at`, size). |
| `delete_markdown` | Soft-delete a file. Requires `confirm:true` (otherwise `VALIDATION`); resolves the path to a document key first. |
| `create_folder` | `mkdir -p` — create every missing segment; already-existing folders count as success. |
| `list_folders` | Return the full folder tree. |
| `list_files` | List the documents and immediate subfolders inside a folder path. |
| `search_markdown` | Search by TITLE (substring) + BODY full-text (current versions; whole-word match, ranked, body hits include a snippet). |
| `move_markdown` | Move and/or rename a `.md` by path (`from_path` → `to_path`); destination folders auto-created; the document KEEPS its key, so version history and reviewers' annotations survive. |
| `move_folder` | Move a folder (whole subtree) under a new parent (`new_parent_path` empty/omitted = root); parent auto-created; cyclic moves rejected server-side. |
| `rename_folder` | Rename a folder in place (descendant paths rewritten server-side). |
| `delete_folder` | Delete a folder. Requires `confirm:true`; by default only an EMPTY folder is deleted — pass `cascade:true` to soft-delete the whole subtree (`rm -r`). |

### Error codes surfaced to the agent

Backend failures return `{ isError: true, content:[{type:"text", ...}] }` with a mapped code in
`structuredContent.error.code`:

`NOT_FOUND` · `CONFLICT` (carries the server head `{server_version_no, server_checksum, …}` in
`detail`) · `UNAUTHORIZED` · `RATE_LIMITED` · `QUOTA_EXCEEDED` · `BACKEND_UNAVAILABLE` ·
`VALIDATION` · `FOLDER_EXISTS` (swallowed as success by `create_folder`) · `ERROR`.

## Authentication

The MCP/PC lane authenticates with a **Personal Access Token** (`mdlog_pat_…`) — minted once in the
web app's **Settings** and supplied via env. The client attaches it as `Authorization: Bearer <PAT>`
(plus `X-API-Token` for compatibility) on every request. The backend is the single source of truth
for auth and quota.

| Variable | Required | Example | Notes |
| -------- | -------- | ------- | ----- |
| `MDLOG_API_BASE_URL` | yes | `https://app.md-log.com/api/v1` | The hosted service base, **including** `/api/v1`. No version suffix is appended; a trailing slash is stripped. |
| `MDLOG_PAT` | yes | `mdlog_pat_xxxxxxxxxxxxxxxxxxxxxxxx` | Bearer PAT. **Store it securely (OS keychain) — never commit it.** |
| `MDLOG_MAX_DOCUMENT_BYTES` | no | `26214400` (25 MiB) | Client-side pre-flight for the backend's per-document body cap
aiannotationclaudeclaude-codecode-reviewcodexcursordeveloper-toolsdocumentationhuman-in-the-loopllmmarkdownmcpmodel-context-protocolvibe-coding

Lo que la gente pregunta sobre md-log-mcp

¿Qué es md-log/md-log-mcp?

+

md-log/md-log-mcp es mcp servers para el ecosistema de Claude AI. MCP server that saves your Claude Code, Cursor, and Codex sessions as versioned Markdown reports — with human-in-the-loop review and Apple Pencil / S Pen annotation. Tiene 3 estrellas en GitHub y su última actualización registrada es del 2026-10-04.

¿Cómo se instala md-log-mcp?

+

Puedes instalar md-log-mcp clonando el repositorio (https://github.com/md-log/md-log-mcp) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar md-log/md-log-mcp?

+

Nuestro agente de seguridad ha analizado md-log/md-log-mcp y le ha asignado un Trust Score de 95/100 (tier: Verified). Revisa el desglose completo de comprobaciones superadas y flags en esta página.

¿Quién mantiene md-log/md-log-mcp?

+

md-log/md-log-mcp es mantenido por md-log. La última actividad registrada en GitHub es del 2026-10-04, con 0 issues abiertos.

¿Hay alternativas a md-log-mcp?

+

Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.

Despliega md-log-mcp en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: md-log/md-log-mcp
[![Featured on ClaudeWave](https://claudewave.com/api/badge/md-log-md-log-mcp)](https://claudewave.com/repo/md-log-md-log-mcp)
<a href="https://claudewave.com/repo/md-log-md-log-mcp"><img src="https://claudewave.com/api/badge/md-log-md-log-mcp" alt="Featured on ClaudeWave: md-log/md-log-mcp" width="320" height="64" /></a>

Más MCP Servers

Alternativas a md-log-mcp