main.py lifespan now enumerates every MCP tool with its description at startup so operators can see at a glance what the server exposes. The auto-generated '### Responses:' suffix that fastapi-mcp appends to each tool description is truncated before logging to keep the startup log scannable. Docstrings added to all 12 route handlers in server.py so the MCP tool descriptions are meaningful (without them, fastapi-mcp would emit empty descriptions). Each route now carries a summary + description used by the auto-generated OpenAPI schema.
50 lines
1.6 KiB
Python
50 lines
1.6 KiB
Python
# coding=utf-8
|
|
"""
|
|
@Time :2026/6/24
|
|
@Author :tao.chen
|
|
"""
|
|
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI
|
|
|
|
from common.factory import init_mcp_server
|
|
from common.logging import logger
|
|
from spark_executor import app as spark_executor_app
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: "FastAPI"):
|
|
logger.info(f"Startup {app.title}")
|
|
spark_executor_mcp = init_mcp_server(spark_executor_app)
|
|
spark_executor_mcp.mount_http(app, mount_path="/spark-executor-mcp")
|
|
logger.info(
|
|
f"MCP server mounted at /spark-executor-mcp "
|
|
f"(source: {spark_executor_app.title} v{spark_executor_app.version})"
|
|
)
|
|
|
|
# Enumerate every MCP tool + its description so operators can see at a
|
|
# glance what the server exposes (useful for debugging / change review).
|
|
tools = spark_executor_mcp.tools
|
|
logger.info(f"MCP tools registered ({len(tools)}):")
|
|
for i, tool in enumerate(tools, 1):
|
|
desc = (tool.description or "").strip()
|
|
# fastapi-mcp appends an auto-generated "### Responses: ..." block to
|
|
# every tool description; drop it so the startup log stays scannable.
|
|
if "### Responses" in desc:
|
|
desc = desc.split("### Responses", 1)[0].rstrip()
|
|
# Collapse internal newlines / extra spaces into one line.
|
|
desc = " ".join(desc.split())
|
|
logger.info(f" {i:>2}. {tool.name} - {desc}")
|
|
|
|
yield
|
|
logger.info(f"Shutdown {app.title}")
|
|
|
|
|
|
app = FastAPI(title="Main App", lifespan=lifespan)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
|
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|