diff --git a/packages/markitdown-mcp/pyproject.toml b/packages/markitdown-mcp/pyproject.toml index b83f003..76e89b9 100644 --- a/packages/markitdown-mcp/pyproject.toml +++ b/packages/markitdown-mcp/pyproject.toml @@ -24,7 +24,8 @@ classifiers = [ "Programming Language :: Python :: Implementation :: PyPy", ] dependencies = [ - "markitdown~=0.1.0", + "mcp", + "markitdown[all]>=0.1.1,<0.2.0", ] [project.urls] @@ -35,6 +36,9 @@ Source = "https://github.com/microsoft/markitdown" [tool.hatch.version] path = "src/markitdown_mcp/__about__.py" +[project.scripts] +markitdown-mcp = "markitdown_mcp.__main__:main" + [tool.hatch.envs.types] extra-dependencies = [ "mypy>=1.0.0", diff --git a/packages/markitdown-mcp/src/markitdown_mcp/__main__.py b/packages/markitdown-mcp/src/markitdown_mcp/__main__.py new file mode 100644 index 0000000..99f6f97 --- /dev/null +++ b/packages/markitdown-mcp/src/markitdown_mcp/__main__.py @@ -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()