feat: log available MCP tools with tags at info level
CI / Build and push docker image (push) Successful in 49s
CI / Build and push docker image (push) Successful in 49s
The generated tool list is now logged at INFO (default) and each line includes the tool's OpenAPI tags alongside its name. The list is only skipped when LOG_LEVEL is above INFO.
This commit is contained in:
@@ -99,8 +99,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. With `LOG_LEVEL=DEBUG`, the list of generated MCP tools (name and
|
string. At startup the generated tool list (name, tags and description) is
|
||||||
description) is logged at startup.
|
logged at INFO; set `LOG_LEVEL=WARNING` to suppress it.
|
||||||
|
|
||||||
### Per-client API keys (HTTP transport)
|
### Per-client API keys (HTTP transport)
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -108,15 +108,16 @@ async def _prepare_tools(
|
|||||||
f": {', '.join(sorted(tool.name for tool in tools))}" if tools else "",
|
f": {', '.join(sorted(tool.name for tool in tools))}" if tools else "",
|
||||||
)
|
)
|
||||||
|
|
||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.INFO):
|
||||||
unique: dict[str, object] = {}
|
unique: dict[str, object] = {}
|
||||||
for tool in tools:
|
for tool in tools:
|
||||||
unique.setdefault(tool.name, tool)
|
unique.setdefault(tool.name, tool)
|
||||||
logger.debug("Available MCP tools (%d):", len(unique))
|
logger.info("Available MCP tools (%d):", len(unique))
|
||||||
for tool in unique.values():
|
for tool in unique.values():
|
||||||
|
tags = f" [{', '.join(sorted(tool.tags))}]" if tool.tags else ""
|
||||||
description = (tool.description or "").strip().splitlines()
|
description = (tool.description or "").strip().splitlines()
|
||||||
suffix = f" — {description[0]}" if description else ""
|
suffix = f" — {description[0]}" if description else ""
|
||||||
logger.debug(" - %s%s", tool.name, suffix)
|
logger.info(" - %s%s%s", tool.name, tags, suffix)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
@@ -140,7 +141,7 @@ def main() -> None:
|
|||||||
if (
|
if (
|
||||||
config.tools_included is not None
|
config.tools_included is not None
|
||||||
or config.tools_tags_included is not None
|
or config.tools_tags_included is not None
|
||||||
or logger.isEnabledFor(logging.DEBUG)
|
or logger.isEnabledFor(logging.INFO)
|
||||||
):
|
):
|
||||||
asyncio.run(
|
asyncio.run(
|
||||||
_prepare_tools(
|
_prepare_tools(
|
||||||
|
|||||||
Reference in New Issue
Block a user