|
4 | 4 | functionality through resources and tools, with special support for Iceberg tables. |
5 | 5 | """ |
6 | 6 |
|
| 7 | +import uvicorn |
| 8 | +from mcp.server import Server |
7 | 9 | from mcp.server.fastmcp import FastMCP |
8 | 10 | from mcp.server.fastmcp.prompts import base |
| 11 | +from mcp.server.sse import SseServerTransport |
9 | 12 | from pydantic import Field |
| 13 | +from starlette.applications import Starlette |
| 14 | +from starlette.requests import Request |
| 15 | +from starlette.routing import Mount, Route |
10 | 16 |
|
11 | 17 | from config import load_config |
12 | 18 | from trino_client import TrinoClient |
@@ -533,8 +539,46 @@ def maintain_iceberg(table: str, catalog: str, schema_name: str) -> list[base.Me |
533 | 539 | ] |
534 | 540 |
|
535 | 541 |
|
| 542 | +def create_starlette_app(mcp_server: Server, *, debug: bool = False) -> Starlette: |
| 543 | + """Create a Starlette application that can server the provied mcp server with SSE.""" |
| 544 | + sse = SseServerTransport("/messages/") |
| 545 | + |
| 546 | + async def handle_sse(request: Request) -> None: |
| 547 | + async with sse.connect_sse( |
| 548 | + request.scope, |
| 549 | + request.receive, |
| 550 | + request._send, # noqa: SLF001 |
| 551 | + ) as (read_stream, write_stream): |
| 552 | + await mcp_server.run( |
| 553 | + read_stream, |
| 554 | + write_stream, |
| 555 | + mcp_server.create_initialization_options(), |
| 556 | + ) |
| 557 | + |
| 558 | + return Starlette( |
| 559 | + debug=debug, |
| 560 | + routes=[ |
| 561 | + Route("/sse", endpoint=handle_sse), |
| 562 | + Mount("/messages/", app=sse.handle_post_message), |
| 563 | + ], |
| 564 | + ) |
| 565 | + |
| 566 | + |
536 | 567 | if __name__ == "__main__": |
| 568 | + import argparse |
| 569 | + |
537 | 570 | from loguru import logger |
538 | 571 |
|
539 | 572 | logger.info("Starting Trino MCP server...") |
540 | | - mcp.run(transport="stdio") |
| 573 | + mcp_server = mcp._mcp_server # noqa: SLF001 |
| 574 | + |
| 575 | + parser = argparse.ArgumentParser(description="Run MCP Trino Server as a SSE-based server") |
| 576 | + parser.add_argument("--host", default="127.0.0.1", help="Host to bind to") |
| 577 | + parser.add_argument("--port", type=int, default=8000, help="Port to listen on") |
| 578 | + args = parser.parse_args() |
| 579 | + |
| 580 | + # Bind SSE request handling to MCP server |
| 581 | + starlette_app = create_starlette_app(mcp_server, debug=True) |
| 582 | + # Run the server with Uvicorn |
| 583 | + uvicorn.run(starlette_app, host=args.host, port=args.port) |
| 584 | + logger.info("Trino MCP server is running.") |
0 commit comments