Added an initial minimal SSE MCP server for MarkItDown

This commit is contained in:
Adam Fourney 2025-03-24 23:19:26 -07:00
parent b41a03f10b
commit 397ed06695
2 changed files with 70 additions and 1 deletions

View file

@ -24,7 +24,8 @@ classifiers = [
"Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: PyPy",
] ]
dependencies = [ dependencies = [
"markitdown~=0.1.0", "mcp",
"markitdown[all]>=0.1.1,<0.2.0",
] ]
[project.urls] [project.urls]
@ -35,6 +36,9 @@ Source = "https://github.com/microsoft/markitdown"
[tool.hatch.version] [tool.hatch.version]
path = "src/markitdown_mcp/__about__.py" path = "src/markitdown_mcp/__about__.py"
[project.scripts]
markitdown-mcp = "markitdown_mcp.__main__:main"
[tool.hatch.envs.types] [tool.hatch.envs.types]
extra-dependencies = [ extra-dependencies = [
"mypy>=1.0.0", "mypy>=1.0.0",

View file

@ -0,0 +1,65 @@
from typing import Any
from mcp.server.fastmcp import FastMCP
from starlette.applications import Starlette
from mcp.server.sse import SseServerTransport
from starlette.requests import Request
from starlette.routing import Mount, Route
from mcp.server import Server
from markitdown import MarkItDown
import uvicorn
# Initialize FastMCP server for MarkItDown (SSE)
mcp = FastMCP("markitdown")
@mcp.tool()
async def convert_to_markdown(uri: str) -> str:
"""Convert a resource described by an http:, https:, file: or data: URI to markdown"""
return MarkItDown().convert_uri(uri).markdown
def create_starlette_app(mcp_server: Server, *, debug: bool = False) -> Starlette:
sse = SseServerTransport("/messages/")
async def handle_sse(request: Request) -> None:
async with sse.connect_sse(
request.scope,
request.receive,
request._send,
) as (read_stream, write_stream):
await mcp_server.run(
read_stream,
write_stream,
mcp_server.create_initialization_options(),
)
return Starlette(
debug=debug,
routes=[
Route("/sse", endpoint=handle_sse),
Mount("/messages/", app=sse.handle_post_message),
],
)
# Main entry point
def main():
import argparse
mcp_server = mcp._mcp_server
parser = argparse.ArgumentParser(description="Run MCP SSE-based MarkItDown server")
parser.add_argument(
"--host", default="127.0.0.1", help="Host to bind to (default: 127.0.0.1)"
)
parser.add_argument(
"--port", type=int, default=3001, help="Port to listen on (default: 3001)"
)
args = parser.parse_args()
starlette_app = create_starlette_app(mcp_server, debug=True)
uvicorn.run(starlette_app, host=args.host, port=args.port)
if __name__ == "__main__":
main()