feat: log the available MCP tools at debug level
With LOG_LEVEL=DEBUG, the generated tool list (name and first line of description) is logged at startup for both transports. The listing is skipped entirely at higher log levels.
This commit is contained in:
@@ -87,7 +87,8 @@ OPENAPI_SPEC_URL=https://petstore3.swagger.io/api/v3/openapi.json uv run xmcp
|
|||||||
|
|
||||||
Authentication examples: for a bearer token leave the defaults; for an API key
|
Authentication examples: for a bearer token leave the defaults; for an API key
|
||||||
header use `API_AUTH_HEADER=X-API-Key` with `API_AUTH_SCHEME` set to an empty
|
header use `API_AUTH_HEADER=X-API-Key` with `API_AUTH_SCHEME` set to an empty
|
||||||
string.
|
string. With `LOG_LEVEL=DEBUG`, the list of generated MCP tools (name and
|
||||||
|
description) is logged at startup.
|
||||||
|
|
||||||
### Per-client API keys (HTTP transport)
|
### Per-client API keys (HTTP transport)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -53,6 +54,19 @@ def build_server(config: Config) -> FastMCP:
|
|||||||
return server
|
return server
|
||||||
|
|
||||||
|
|
||||||
|
async def _log_available_tools(server: FastMCP) -> None:
|
||||||
|
"""Log the tools generated from the OpenAPI document (DEBUG level)."""
|
||||||
|
tools = await server.list_tools()
|
||||||
|
unique: dict[str, object] = {}
|
||||||
|
for tool in tools:
|
||||||
|
unique.setdefault(tool.name, tool)
|
||||||
|
logger.debug("Available MCP tools (%d):", len(unique))
|
||||||
|
for tool in unique.values():
|
||||||
|
description = (tool.description or "").strip().splitlines()
|
||||||
|
suffix = f" — {description[0]}" if description else ""
|
||||||
|
logger.debug(" - %s%s", tool.name, suffix)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
try:
|
try:
|
||||||
config = Config.from_env()
|
config = Config.from_env()
|
||||||
@@ -71,6 +85,9 @@ def main() -> None:
|
|||||||
except SpecError as exc:
|
except SpecError as exc:
|
||||||
raise SystemExit(f"Failed to load the OpenAPI document: {exc}") from exc
|
raise SystemExit(f"Failed to load the OpenAPI document: {exc}") from exc
|
||||||
|
|
||||||
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
|
asyncio.run(_log_available_tools(server))
|
||||||
|
|
||||||
# Logs go to stderr so the stdio transport's stdout stays protocol-clean.
|
# Logs go to stderr so the stdio transport's stdout stays protocol-clean.
|
||||||
if config.transport == "http":
|
if config.transport == "http":
|
||||||
logger.info("Serving MCP over streamable HTTP at http://%s:%d/mcp", config.host, config.port)
|
logger.info("Serving MCP over streamable HTTP at http://%s:%d/mcp", config.host, config.port)
|
||||||
|
|||||||
Reference in New Issue
Block a user