Md Log Mcp

com.md-log由 md-log.com 發布v1.3.1更新於 Nov 7, 2026

md-log MCP: save/update/fetch markdown by path (stdio + remote HTTP, PAT auth).

概覽

AI 產生的概覽

讓 AI 程式助理連接 md-log 託管服務,依路徑儲存、編輯、搜尋並版本化 Markdown 報告,供人工審閱。

可以做什麼
  • 依路徑儲存與讀取 Markdown,自動建立缺少的資料夾,每次儲存都成為不可變版本。
  • 以精確文字取代局部修改檔案、附加內容,或整份內容替換並做衝突檢查。
  • 上傳圖片並把佔位符改寫為資源連結,也可單獨上傳資源。
  • 瀏覽與檢索:列出資料夾和檔案、依標題與內文全文搜尋、查看檔案的版本歷史。
  • 還原舊版本,移動或重新命名檔案與資料夾,並在確認後軟刪除檔案或資料夾。
適用情境
適合讓 AI 程式助理把工作成果與分析以可讀的 Markdown 報告交付,供人審閱、註記和歸檔,並保留完整版本歷史。也適合希望把助理產生的文件存放在可搜尋的託管位置而非本機檔案的團隊。
執行需求
需要 md-log 託管帳號,以及在網頁應用程式設定中產生、僅顯示一次的 Personal Access Token,透過環境變數 MDLOG_PAT 提供;還需在 MDLOG_API_BASE_URL 填入含 /api/v1 的 API 基礎位址。本機套件需要 Node.js 22 或更新版本;使用託管遠端端點則無需安裝。
安裝前請注意
PAT 是隨每次請求傳送的持有者憑證且只顯示一次,請勿提交到版本控制,外洩後應立即撤銷。此伺服器會寫入、覆寫、移動和軟刪除文件與資料夾,刪除資料夾時可連帶刪除整個子樹。報告內容和圖片會傳送到 md-log 託管服務。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Md Log Mcp,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

md-log-mcp

[npm version] [MCP Registry] [License: MIT] [Node]

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, 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 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.
  • 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).

ToolWhat 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_assetUpload 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_markdownAppend 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_markdownChange 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.reasons: 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_markdownReplace 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_versionRoll 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_markdownRead 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_versionsList a file's immutable version history, newest first (version_no, commit_message, author, registered_at, size).
delete_markdownSoft-delete a file. Requires confirm:true (otherwise VALIDATION); resolves the path to a document key first.
create_foldermkdir -p — create every missing segment; already-existing folders count as success.
list_foldersReturn the full folder tree.
list_filesList the documents and immediate subfolders inside a folder path.
search_markdownSearch by TITLE (substring) + BODY full-text (current versions; whole-word match, ranked, body hits include a snippet).
move_markdownMove 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_folderMove a folder (whole subtree) under a new parent (new_parent_path empty/omitted = root); parent auto-created; cyclic moves rejected server-side.
rename_folderRename a folder in place (descendant paths rewritten server-side).
delete_folderDelete 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.

VariableRequiredExampleNotes
MDLOG_API_BASE_URLyeshttps://app.md-log.com/api/v1The hosted service base, including /api/v1. No version suffix is appended; a trailing slash is stripped.
MDLOG_PATyesmdlog_pat_xxxxxxxxxxxxxxxxxxxxxxxxBearer PAT. Store it securely (OS keychain) — never commit it.
MDLOG_MAX_DOCUMENT_BYTESno26214400 (25 MiB)Client-side pre-flight for the backend's per-document body cap, in UTF-8 bytes (Korean is 3 bytes/char). An over-cap save fails immediately with a VALIDATION error naming the actual size, instead of an opaque backend 400. Applies to both transports. Change only against a self-hosted backend with a different cap.

The server fails fast at startup with a clear message if either var is missing or the base URL is malformed.

Build

bash
npm installnpm run build      # tsup → dist/server.js (ESM, Node 22)npm run typecheck  # tsc --noEmit (optional)

Smoke test

scripts/smoke.mjs spawns the built server over stdio (MCP SDK Client + StdioClientTransport), then runs initialize → tools/list → save_markdown (a small report embedding a tiny data: PNG) → get_markdown (reads it back, checks the marker) → search_markdown — printing PASS/FAIL per step and exiting non-zero on any failure. Run it against a live backend with a real PAT:

bash
npm run buildMDLOG_API_BASE_URL="http://localhost:8080/api/v1" \MDLOG_PAT="mdlog_pat_xxxx" \node scripts/smoke.mjs        # or: npm run smoke

Connect a client

Mint the PAT in the web app's Settings → Tokens, store it securely, then add md-log to your MCP client. Never commit a PAT.

📄 연결 가이드 (HTML) — md-log.com/guides/customer-guide.html: 웹 앱에서 발급받은 MCP 키(PAT) 로 URL 연결(권장) 또는 npx 로컬 연결 (Claude Code · Desktop · Codex · Cursor).

Recommended — remote (URL), no install

Point your client at the hosted endpoint and pass the PAT as a Bearer header. Nothing to install — no Node.js, no npx. (You don't even need this package for the hosted connection.)

bash
# Claude Codeclaude mcp add --transport http md-log https://mcp.md-log.com/mcp \  --header "Authorization: Bearer mdlog_pat_xxxxxxxxxxxxxxxxxxxxxxxx"
jsonc
// Cursor / Claude Desktop / any client that takes JSON — the `type` field MUST be "http"{  "mcpServers": {    "md-log": {      "type": "http",      "url": "https://mcp.md-log.com/mcp",      "headers": { "Authorization": "Bearer mdlog_pat_xxxxxxxxxxxxxxxxxxxxxxxx" }    }  }}

Over the remote endpoint, embed images inline (base64); uploading a local image by path (file_path) works only with the local method below.

Alternative — local (stdio via npx)

Runs this connector as a local subprocess (needs Node 22+; npx fetches the published package, nothing to build). Use it if you prefer a local process, need local-file (file_path) image uploads, or self-host md-log without a hosted MCP endpoint.

jsonc
{  "mcpServers": {    "md-log": {      "command": "npx",      "args": ["-y", "md-log-mcp"],      "env": {        "MDLOG_API_BASE_URL": "https://app.md-log.com/api/v1",        "MDLOG_PAT": "mdlog_pat_xxxxxxxxxxxxxxxxxxxxxxxx"      }    }  }}

Mint & secure the PAT. Create it in the web Settings → Tokens (it is shown only once) and keep it out of version control — prefer the OS keychain. On macOS, for example:

bash
security add-generic-password -a "$USER" -s md-log-pat -w "mdlog_pat_xxxx"export MDLOG_PAT="$(security find-generic-password -a "$USER" -s md-log-pat -w)"

If a PAT leaks, revoke it in the web app and mint a new one.

Remote (Streamable HTTP) mode

The second bin, md-log-mcp-http, serves the same 17 tools over MCP's Streamable HTTP transport — a single POST /mcp endpoint — so agents connect by URL with no local install. Use it when you want to host the connector centrally (a container / small VM behind a TLS reverse proxy) instead of every user running npx.

How it differs from stdio:

  • PAT per request. The token is not read from env; each request carries its own Authorization: Bearer <mdlog_pat_…> header, so one endpoint serves many users — each with their own md-log token. (MDLOG_PAT is ignored in this mode.)
  • Stateless. A fresh client + server per request; no session store (replica / autoscale friendly).
  • No local files. The file_path image source is refused (it would read the server's disk); send images inline as data_base64. Everything else is identical.

Run it

bash
npm run buildMDLOG_API_BASE_URL="https://app.md-log.com/api/v1" \node dist/http.js            # or: npm run start:http# → md-log-mcp-http ready — POST http://127.0.0.1:8787/mcp

Configuration (env)

VariableRequiredDefaultNotes
MDLOG_API_BASE_URLyes—Hosted md-log base, including /api/v1.
MDLOG_HTTP_HOSTno127.0.0.1Bind interface. Localhost-only by default; set 0.0.0.0 only behind a TLS reverse proxy.
MDLOG_HTTP_PORTno8787TCP port.
MDLOG_HTTP_PATHno/mcpThe MCP endpoint path.
MDLOG_HTTP_ALLOWED_ORIGINSno(none)Comma-separated browser Origin allowlist (DNS-rebinding defense). A request that carries an Origin not on the list is 403d; non-browser clients (no Origin) are always allowed.
MDLOG_HTTP_ALLOWED_HOSTSno(none)Optional comma-separated Host allowlist (extra DNS-rebinding defense).
MDLOG_HTTP_MAX_BODY_BYTESno33554432 (32 MiB)Max request body (base64 images inflate ~33%).

Security posture (per the MCP spec): binds to 127.0.0.1 by default, requires a Bearer token on every MCP request, validates Origin against the allowlist to defeat DNS-rebinding, and caps the body size. A GET /health liveness probe (no auth) returns {"status":"ok"}. GET/DELETE on the MCP endpoint return 405 (stateless: no standalone SSE stream, no session to terminate).

Connect an agent by URL

jsonc
{  "mcpServers": {    "md-log": {      "type": "http",      "url": "https://your-host.example/mcp",      "headers": { "Authorization": "Bearer mdlog_pat_xxxxxxxxxxxxxxxxxxxxxxxx" }    }  }}

Client config shape varies (Claude Code / Cursor / etc.) — the essentials are the endpoint URL and an Authorization: Bearer <PAT> header. Always terminate TLS in front of a public deployment; the PAT rides on every request.

Scripts

  • npm run build — bundle to dist/server.js (stdio) + dist/http.js (Streamable HTTP) (tsup, ESM, Node 22).
  • npm run dev — rebuild on change (tsup --watch).
  • npm run typecheck — tsc --noEmit.
  • npm run smoke — stdio smoke test against a live backend (needs env + a build).
  • npm run smoke:http — backend-free HTTP-transport smoke test (handshake + auth/origin/file_path guards).
  • npm start — run the built stdio server (node dist/server.js).
  • npm run start:http — run the built HTTP server (node dist/http.js).

來源:README.md,提交 579b5e0

工具

0
SourceWeft 曾在隔離沙箱中以無憑證方式啟動該軟體包一次,以列出其工具,但未能完成:伺服器未能啟動。

版本歷史

4
  1. v1.3.1最新Nov 7, 2026
  2. v1.3.0Oct 4, 2026
  3. v1.2.0Oct 2, 2026
  4. v1.1.4Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分