第 3 课

把 MarkItDown 交给 AI 智能体:MCP stdio 与 HTTP

安装 markitdown-mcp,用 MCP Python SDK 2.x 写客户端走 stdio 列出 convert_to_markdown 工具并转换本地 Excel,再开 HTTP 模式转换 data: URI 和网页,用 file:///etc/os-release 验证它没有身份验证、能读本机文件,最后按官方说明了解 Claude Desktop 的 Docker 配置和 MCP Inspector 调试。

图文20 分钟MarkItDown 官方文档 ↗

课程目录第 3 / 3 课

学习位置仅保存在当前浏览器,有效期 180 天。

01 / 图文教材

图文教材

本课对照的官方页面:markitdown-mcp 说明 、PyPI:markitdown-mcp 、MCP Python SDK 。测试环境:2026-11-05,Linux x86_64 云主机,Python 3.13.5,markitdown 0.1.9,markitdown-mcp 0.0.1a8,安装时自动带上的 MCP Python SDK 是 2.3.0。用 Python 客户端连接 stdio 和 HTTP 两种模式都实测过;Claude Desktop、Docker、MCP Inspector 三部分测试机没有对应环境,按官方说明整理,标注了「未实测」。

前两课是你自己调用 MarkItDown。这一课把它包装成一个 MCP 服务器,让 Claude Desktop 这类 AI 应用或你自己写的智能体在需要读文档时直接调用。官方的 markitdown-mcp 包只提供一个工具:convert_to_markdown(uri),参数 uri 可以是 http:、https:、file: 或 data: 开头的地址。

第 1 步:安装 markitdown-mcp

继续用前两课的虚拟环境:

cd ~/markitdown-lab && source .venv/bin/activate
pip install markitdown-mcp==0.0.1a8
pip show mcp | grep Version
mkdir -p l3 && cd l3

对照结果:

Version: 2.3.0

markitdown-mcp 依赖 mcp(MCP 官方 Python SDK),安装时会一起装上。下面的客户端脚本就用这个 SDK 来写。

第 2 步:用 stdio 模式调用

stdio 是默认模式:客户端启动 markitdown-mcp 进程,通过标准输入输出和它通信,不占端口。新建 mcp_stdio.py:

import asyncio
from pathlib import Path
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

server = StdioServerParameters(command="markitdown-mcp")
xlsx = Path("../files/test.xlsx").resolve().as_uri()

async def main():
    async with stdio_client(server) as (read, write):
        async with ClientSession(read, write) as s:
            info = await s.initialize()
            print("server:", info.server_info.name)
            for t in (await s.list_tools()).tools:
                print("tool:", t.name, list(t.input_schema["properties"]))
            r = await s.call_tool("convert_to_markdown", {"uri": xlsx})
            print("isError =", r.is_error)
            print("\n".join(r.content[0].text.splitlines()[:4]))

asyncio.run(main())

运行 python mcp_stdio.py,对照结果(终端里还会夹杂几行服务器日志,这里略去):

server: markitdown
tool: convert_to_markdown ['uri']
isError = False
## Sheet1
| Alpha | Beta | Gamma | Delta |
| --- | --- | --- | --- |
| 89 | 82 | 100 | 12 |

本地文件要写成 file:///绝对路径 的形式,脚本里用 Path(...).resolve().as_uri() 来生成。这里的属性名 server_info、input_schema、is_error 是 MCP Python SDK 2.x 的写法;如果你装的是 1.x,对应写法是 serverInfo、inputSchema、isError(1.x 写法未实测)。

第 3 步:用 HTTP 模式调用

有的客户端只能连接网络地址,这时用 Streamable HTTP 模式。开一个新终端(同样先激活虚拟环境)启动服务器:

markitdown-mcp --http --host 127.0.0.1 --port 3001

对照结果(节选):

StreamableHTTP session manager started
INFO:     Uvicorn running on http://127.0.0.1:3001 (Press CTRL+C to quit)

服务器的地址是 http://127.0.0.1:3001/mcp。回到原来的终端,先准备一个 data: URI。它把文件内容直接写在地址里,适合传小段数据:

printf '名称,价格\nA,1\nB,2\n' | base64

对照结果:

5ZCN56ewLOS7t+agvApBLDEKQiwyCg==

新建 mcp_http.py,分别转换这段 CSV 和一个网页:

import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client

URL = "http://127.0.0.1:3001/mcp"
DATA = "data:text/csv;base64,5ZCN56ewLOS7t+agvApBLDEKQiwyCg=="

async def main():
    async with streamable_http_client(URL) as (read, write, *_):
        async with ClientSession(read, write) as s:
            await s.initialize()
            for uri in [DATA, "https://example.com/"]:
                r = await s.call_tool("convert_to_markdown", {"uri": uri})
                print(f"== {uri[:30]} isError={r.is_error}")
                for line in r.content[0].text.splitlines()[:4]:
                    print(line[:60])

asyncio.run(main())

对照结果:

== data:text/csv;base64,5ZCN56ewL isError=False
| 名称 | 价格 |
| --- | --- |
| A | 1 |
| B | 2 |
== https://example.com/ isError=False
This domain is for use in documentation examples without nee

CSV 被转成了 Markdown 表格。streamable_http_client 也是 SDK 2.x 的名字;1.x 里叫 streamablehttp_client(未实测)。服务器同时提供 /sse 地址,供只支持旧 SSE 传输的客户端使用。

第 4 步:弄清楚安全边界

这个服务器没有任何身份验证,并且以启动它的用户的权限运行。官方说明特别提醒:convert_to_markdown 能读取这个用户能访问的任何文件,也能访问任何网址。新建 risk.py 验证一下:

import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client

async def main():
    url = "http://127.0.0.1:3001/mcp"
    async with streamable_http_client(url) as (read, write, *_):
        async with ClientSession(read, write) as s:
            await s.initialize()
            r = await s.call_tool("convert_to_markdown",
                                  {"uri": "file:///etc/os-release"})
            print(r.content[0].text.splitlines()[0])

asyncio.run(main())

对照结果(测试机是 Debian,你的系统会不同):

PRETTY_NAME="Debian GNU/Linux 13 (trixie)"

任何连上这个端口的程序都能这样读取文件。所以要注意三点:

  • HTTP 模式默认只监听 127.0.0.1,可以用 ss -ltn | grep 3001 确认。不要把 --host 改成 0.0.0.0 或其他网卡地址。
  • 只连接你信任的 AI 应用和智能体。
  • 需要更强的隔离时,按官方建议放进虚拟机或容器里运行,并只挂载需要的目录。

做完这一步,回到运行服务器的终端按 Ctrl+C 停止它。

第 5 步:接入 Claude Desktop(未实测)

官方推荐在 Claude Desktop 里用 Docker 运行这个服务器。测试机没有 Docker 和 Claude Desktop,以下按官方说明整理,没有实测。先在 markitdown 仓库的 packages/markitdown-mcp 目录里构建镜像:

git clone https://github.com/microsoft/markitdown.git
cd markitdown/packages/markitdown-mcp
docker build -t markitdown-mcp:latest .

然后打开 Claude Desktop 的 claude_desktop_config.json(官方给出的查找方法见 MCP 文档的 Claude Desktop 用户部分),加入下面这段。-v 把本机目录挂载到容器里的 /workdir,请换成你自己的目录:

{
  "mcpServers": {
    "markitdown": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "-v",
        "/home/user/data:/workdir",
        "markitdown-mcp:latest"
      ]
    }
  }
}

挂载之后,本机 /home/user/data/example.txt 在容器里的地址是 file:///workdir/example.txt。重启 Claude Desktop 后,可以在对话里说「把 /workdir/example.txt 转成 Markdown 并总结」。

如果不用 Docker,也可以把 command 写成虚拟环境里 markitdown-mcp 的绝对路径(例如 /home/你的用户名/markitdown-lab/.venv/bin/markitdown-mcp),args 留空。这种写法本课没有实测,而且服务器能读到你账号下的所有文件,安全上不如 Docker。

第 6 步:用 MCP Inspector 调试(未实测)

官方的调试方法是用 MCP Inspector 图形界面:

npx @modelcontextprotocol/inspector

打开它给出的本地地址后,传输类型选 STDIO,命令填 markitdown-mcp,点 Connect;如果服务器是 HTTP 模式,就选 Streamable HTTP,地址填 http://127.0.0.1:3001/mcp。连上之后在 Tools 页点 List Tools,选 convert_to_markdown,填一个 URI 运行。第 2、3 步的 Python 脚本做的是同样的检查,没有图形界面时用脚本就够了。

小结

  • pip install markitdown-mcp 后,直接运行 markitdown-mcp 就是 stdio 模式;加 --http --host 127.0.0.1 --port 3001 就是 HTTP 模式,地址是 /mcp。
  • 只有一个工具 convert_to_markdown(uri),支持 http:、https:、file:、data: 四种地址。
  • 服务器没有身份验证,能读取运行它的用户能读的所有文件,只能在本机给信任的客户端用。
  • Claude Desktop 官方推荐用 Docker 运行,并只挂载需要的目录。