3737import os
3838from urllib .parse import urlparse
3939
40+ from fastmcp_extensions import register_landing_page
41+
4042from airbyte .mcp .server import (
4143 DEFAULT_HTTP_HOST ,
4244 DEFAULT_HTTP_PORT ,
4749
4850logger = logging .getLogger (__name__ )
4951
52+ # Human-facing landing page shown when a browser GETs the MCP endpoint.
53+ MCP_LANDING_TITLE = "Airbyte MCP Server"
54+ MCP_LANDING_DOCS_URL = "https://docs.airbyte.com/ai-agents/"
55+
56+
57+ def _get_server_url () -> str :
58+ """Return the public base URL from `MCP_SERVER_URL`, defaulting to localhost."""
59+ return os .getenv (
60+ MCP_SERVER_URL_ENV ,
61+ f"http://localhost:{ DEFAULT_HTTP_PORT } " ,
62+ )
63+
5064
5165def main () -> None :
5266 """Start the Airbyte MCP server with HTTP transport."""
@@ -55,12 +69,24 @@ def main() -> None:
5569 # When deployed behind a path-stripping LB (MCP_SERVER_URL has a path
5670 # component like /cloud-mcp), serve the MCP endpoint at root so the
5771 # public URL is just the base path. Otherwise keep the FastMCP default.
58- server_url = os .getenv (
59- MCP_SERVER_URL_ENV ,
60- f"http://localhost:{ DEFAULT_HTTP_PORT } " ,
61- )
72+ server_url = _get_server_url ()
6273 mcp_path = "/" if urlparse (server_url ).path .strip ("/" ) else "/mcp"
6374
75+ # The advertised endpoint must match where the MCP route is actually mounted:
76+ # the bare server URL when mounted at root, otherwise the server URL + mcp_path.
77+ endpoint_url = server_url if mcp_path == "/" else server_url .rstrip ("/" ) + mcp_path
78+
79+ # Serve a browser-friendly landing page on GET at the MCP path. In stateless
80+ # mode FastMCP only binds POST/DELETE there, so this GET route does not
81+ # interfere with MCP traffic.
82+ register_landing_page (
83+ app ,
84+ path = mcp_path ,
85+ title = MCP_LANDING_TITLE ,
86+ endpoint_url = endpoint_url ,
87+ docs_url = MCP_LANDING_DOCS_URL ,
88+ )
89+
6490 if getattr (app , "auth" , None ) is None :
6591 logger .warning (
6692 "HTTP transport starting without authentication: no interactive "
0 commit comments