|
5 | 5 | import inspect |
6 | 6 | import json |
7 | 7 | import re |
| 8 | +import secrets |
8 | 9 | import warnings |
9 | 10 | from collections.abc import AsyncIterator, Awaitable, Callable |
10 | 11 | from contextlib import ( |
@@ -197,8 +198,9 @@ def __init__( |
197 | 198 | lifespan = default_lifespan |
198 | 199 | else: |
199 | 200 | self._has_lifespan = True |
| 201 | + # Generate random ID if no name provided |
200 | 202 | self._mcp_server = LowLevelServer[LifespanResultT]( |
201 | | - name=name or "FastMCP", |
| 203 | + name=name or self.generate_name(), |
202 | 204 | version=version, |
203 | 205 | instructions=instructions, |
204 | 206 | lifespan=_lifespan_wrapper(self, lifespan), |
@@ -519,7 +521,7 @@ def _get_additional_http_routes(self) -> list[BaseRoute]: |
519 | 521 | return routes |
520 | 522 |
|
521 | 523 | async def _mcp_list_tools(self) -> list[MCPTool]: |
522 | | - logger.debug("Handler called: list_tools") |
| 524 | + logger.debug(f"[{self.name}] Handler called: list_tools") |
523 | 525 |
|
524 | 526 | async with fastmcp.server.context.Context(fastmcp=self): |
525 | 527 | tools = await self._list_tools() |
@@ -563,7 +565,7 @@ async def _handler( |
563 | 565 | return await self._apply_middleware(mw_context, _handler) |
564 | 566 |
|
565 | 567 | async def _mcp_list_resources(self) -> list[MCPResource]: |
566 | | - logger.debug("Handler called: list_resources") |
| 568 | + logger.debug(f"[{self.name}] Handler called: list_resources") |
567 | 569 |
|
568 | 570 | async with fastmcp.server.context.Context(fastmcp=self): |
569 | 571 | resources = await self._list_resources() |
@@ -608,7 +610,7 @@ async def _handler( |
608 | 610 | return await self._apply_middleware(mw_context, _handler) |
609 | 611 |
|
610 | 612 | async def _mcp_list_resource_templates(self) -> list[MCPResourceTemplate]: |
611 | | - logger.debug("Handler called: list_resource_templates") |
| 613 | + logger.debug(f"[{self.name}] Handler called: list_resource_templates") |
612 | 614 |
|
613 | 615 | async with fastmcp.server.context.Context(fastmcp=self): |
614 | 616 | templates = await self._list_resource_templates() |
@@ -653,7 +655,7 @@ async def _handler( |
653 | 655 | return await self._apply_middleware(mw_context, _handler) |
654 | 656 |
|
655 | 657 | async def _mcp_list_prompts(self) -> list[MCPPrompt]: |
656 | | - logger.debug("Handler called: list_prompts") |
| 658 | + logger.debug(f"[{self.name}] Handler called: list_prompts") |
657 | 659 |
|
658 | 660 | async with fastmcp.server.context.Context(fastmcp=self): |
659 | 661 | prompts = await self._list_prompts() |
@@ -712,7 +714,9 @@ async def _mcp_call_tool( |
712 | 714 | Returns: |
713 | 715 | List of MCP Content objects containing the tool results |
714 | 716 | """ |
715 | | - logger.debug("Handler called: call_tool %s with %s", key, arguments) |
| 717 | + logger.debug( |
| 718 | + f"[{self.name}] Handler called: call_tool %s with %s", key, arguments |
| 719 | + ) |
716 | 720 |
|
717 | 721 | async with fastmcp.server.context.Context(fastmcp=self): |
718 | 722 | try: |
@@ -754,7 +758,7 @@ async def _mcp_read_resource(self, uri: AnyUrl | str) -> list[ReadResourceConten |
754 | 758 |
|
755 | 759 | Delegates to _read_resource, which should be overridden by FastMCP subclasses. |
756 | 760 | """ |
757 | | - logger.debug("Handler called: read_resource %s", uri) |
| 761 | + logger.debug(f"[{self.name}] Handler called: read_resource %s", uri) |
758 | 762 |
|
759 | 763 | async with fastmcp.server.context.Context(fastmcp=self): |
760 | 764 | try: |
@@ -809,7 +813,9 @@ async def _mcp_get_prompt( |
809 | 813 |
|
810 | 814 | Delegates to _get_prompt, which should be overridden by FastMCP subclasses. |
811 | 815 | """ |
812 | | - logger.debug("Handler called: get_prompt %s with %s", name, arguments) |
| 816 | + logger.debug( |
| 817 | + f"[{self.name}] Handler called: get_prompt %s with %s", name, arguments |
| 818 | + ) |
813 | 819 |
|
814 | 820 | async with fastmcp.server.context.Context(fastmcp=self): |
815 | 821 | try: |
@@ -1966,9 +1972,11 @@ async def import_server( |
1966 | 1972 | self._prompt_manager.add_prompt(prompt) |
1967 | 1973 |
|
1968 | 1974 | if prefix: |
1969 | | - logger.debug(f"Imported server {server.name} with prefix '{prefix}'") |
| 1975 | + logger.debug( |
| 1976 | + f"[{self.name}] Imported server {server.name} with prefix '{prefix}'" |
| 1977 | + ) |
1970 | 1978 | else: |
1971 | | - logger.debug(f"Imported server {server.name}") |
| 1979 | + logger.debug(f"[{self.name}] Imported server {server.name}") |
1972 | 1980 |
|
1973 | 1981 | @classmethod |
1974 | 1982 | def from_openapi( |
@@ -2195,6 +2203,15 @@ def _should_enable_component( |
2195 | 2203 |
|
2196 | 2204 | return True |
2197 | 2205 |
|
| 2206 | + @classmethod |
| 2207 | + def generate_name(cls, name: str | None = None) -> str: |
| 2208 | + class_name = cls.__name__ |
| 2209 | + |
| 2210 | + if name is None: |
| 2211 | + return f"{class_name}-{secrets.token_hex(2)}" |
| 2212 | + else: |
| 2213 | + return f"{class_name}-{name}-{secrets.token_hex(2)}" |
| 2214 | + |
2198 | 2215 |
|
2199 | 2216 | @dataclass |
2200 | 2217 | class MountedServer: |
|
0 commit comments