dsh-plugin
DayuanJiang/next-ai-draw-iodsh 的 draw.io 绘图插件:通过 next-ai-drawio MCP 服务器作图,点回复里的链接在右侧栏打开实时预览,可以手动修改图,AI 的每次修改都是可以恢复的版本。需 Node.js 18+,首次使用由 npx 下载 MCP 服务器。
提供 markitdown 工具,把 PDF、Word、Excel、PowerPoint、HTML、CSV、EPUB 与网址转成 Markdown:能找到真实的 Microsoft MarkItDown 时驱动它,否则使用内置的零依赖转换器。
Microsoft MarkItDown as a DeepSeek Harness tool.
One tool, markitdown, turns a document into Markdown the model can actually read.
The model calls it before reading any non-text file:
markitdown({ input: "reports/q3.pdf" })
markitdown({ input: "data/forecast.xlsx", output: "notes/forecast.md" })
markitdown({ input: "https://example.com/spec.html" })
A text-only model cannot open a PDF, a spreadsheet, or a slide deck. MarkItDown solves that well — but it is a Python package, and a harness plugin needs to reach it without assuming a specific Python environment, a specific install layout, or that anything is installed at all.
So this plugin does not reimplement MarkItDown and does not vendor it. It looks for a real installation, drives it, and falls back to a built-in converter when there is none:
| Order | Engine | What it is | Needs |
|---|---|---|---|
| 1 | markitdown | Microsoft's own CLI | pip install "markitdown[all]" |
| 2 | uvx markitdown | the real package, run without installing it | uv |
| 3 | python -m markitdown | a Python that already has the package | Python 3.10+ with MarkItDown |
| 4 | built-in | a dependency-free converter shipped in this plugin | nothing |
Order 2 is usually the best deal: if uv is on the machine, the real MarkItDown runs
with no permanent install. It defaults to the markitdown[all] spec so Office and PDF
formats actually work — plain markitdown has no format converters at all.
Order 4 keeps the tool useful on a bare machine. It is honest about its limits rather than guessing.
| Format | Real MarkItDown | Built-in fallback |
|---|---|---|
| full layout extraction | not supported — says so, names the fix | |
Word .docx | full | headings, paragraphs, lists, tables |
Excel .xlsx | full | sheets, shared strings, numbers, tables |
PowerPoint .pptx | full | slide-by-slide text |
HTML / .epub | full | headings, lists, links, tables, code |
| CSV / TSV / JSON / XML | full | tables / fenced JSON / flattened text |
Jupyter .ipynb | full | markdown and code cells |
| Images, audio, YouTube | OCR and transcription | not supported |
| Plain text and code | passthrough | passthrough |
The built-in converter is a safety net, not a replacement. When it is used, the result says so and names the command that unlocks full fidelity.
DeepSeek Harness 0.1.5-rc.1 or newer on either release line — 0.1.x and 0.2.x are both
supported:
"engines": { "dsh": ">=0.1.5-rc.1 <0.3.0-0" }
Verified against harness 0.1.5-rc.2 and 0.2.0-rc.2. The 0.2 line moved @deepseek-ai/dsh-tools
to ~3.18.4 and cordis to ~4.0.4; neither affected this plugin's code, which is why the runtime
is identical across both lines.
Node ^22.19.0 || >=24.0.0.
dsh plugin --profile web add github:jiekesu967/dsh-markitdown
The compiled lib/ is committed, so this path needs no build step.
Download dsh-markitdown-<version>.tgz from
Releases, then:
dsh plugin --profile web add ./dsh-markitdown-<version>.tgz
dsh plugin --profile web add dsh-markitdown
The package is published from this repository: https://www.npmjs.com/package/dsh-markitdown.
Then restart dsh web. The markitdown tool appears in the next session.
Nothing else is required. For PDF, OCR, audio, and full-fidelity Office conversion, install one of:
pip install "markitdown[all]" # or
winget install astral-sh.uv # then `uvx markitdown` works with no install
Every field is optional; defaults are shown.
- id: markitdown
name: dsh-markitdown
config:
engine: auto # auto | markitdown | uvx | python | builtin
uvxPackage: "markitdown[all]" # slim it to "markitdown[pdf,docx,pptx,xlsx]"
command: "" # explicit markitdown executable, overrides PATH
timeoutMs: 120000 # per-conversion deadline
maxChars: 120000 # inline result cap; longer output is truncated
maxBytes: 67108864 # bytes the built-in engine will read
allowUrls: true # accept http(s) inputs
extraArgs: [] # extra CLI arguments for the external engine
engine: auto probes the chain once per plugin instance and caches the winner. Setting an
engine explicitly disables the fallback: if you ask for uvx and there is no uv, the call
fails with the reason and the fix, rather than quietly converting with something else.
A first uvx run downloads MarkItDown and its dependencies (about a minute). Package-manager
progress lines are filtered out of the tool result; only real diagnostics are reported.
output writes through the filesystem seam, so the per-session sandbox policy and the
read-before-write observation rule both apply. Writing to an existing file re-reads it first.maxChars and no output path was
given, the result says it was truncated and how to get the rest.shell: false. A filename or URL containing shell
metacharacters is one argv element and can never become a command. Only real executables are
accepted; .cmd/.bat shims are rejected because running them would require a shell.Converting untrusted documents means the input decides how much work the converter does, so every cap is enforced while reading rather than after:
maxBytes, both through the filesystem seam and on the
fallback path that runs without it. The size comes from stat first, so a small file never
reserves the whole cap.content-length over the cap is
refused without downloading anything, and a streamed body is cancelled mid-transfer once it
passes the cap.unzip(buffer, maxEntryBytes)
and convertBuiltin(bytes, name, { maxEntryBytes }).XFD) are dropped rather than
used to size a row array.npm run build # compile src/ → lib/
npm test # built-in converter + plugin surface tests
npm run typecheck # type check only
The build links the DSH packages from $DSH_CHECKOUT (a source checkout) or $DSH_RUNTIME (an
installed runtime), then compiles with the TypeScript compiler API in a single Node process — no
shell, so it also runs on Windows. Rebuilding an unchanged tree leaves lib/ byte-identical.
Tests need no network, no Python, and no MarkItDown install: the fallback engine is exercised
against synthetic OOXML fixtures built in-process. If your environment forbids spawning child
processes, npm run test:inline runs them all in one.
src/index.ts plugin wiring: config, tool definition, execute path
src/engine.ts engine chain: probe, cache, launch
src/builtin.ts dependency-free converters
src/text.ts entity decoding, HTML→Markdown, delimited parsing
src/zip.ts minimal ZIP reader for OOXML/EPUB containers
src/exec.ts subprocess plumbing with honest failure reporting
MarkItDown is Microsoft's work, MIT licensed: https://github.com/microsoft/markitdown. This plugin only drives it. Trademarks belong to their owners; this project is not affiliated with or endorsed by Microsoft.
MIT — see LICENSE.