Files
mcp-server/main.py
T
Claude ff9dea0ba7 feat: log MCP tool list + descriptions on startup
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.
2026-06-24 17:50:30 +08:00

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)