content: from __future__ import annotations as _annotations
  
  from collections.abc import Callable
  from typing import TYPE_CHECKING, Any
  
  from mcp.server.fastmcp.exceptions import ToolError
  from mcp.server.fastmcp.tools.base import Tool
  from mcp.server.fastmcp.utilities.logging import get_logger
  from mcp.shared.context import LifespanContextT, RequestT
  from mcp.types import Icon, ToolAnnotations
  
  if TYPE_CHECKING:
      from mcp.server.fastmcp.server import Context
      from mcp.server.session import ServerSessionT
  
  logger = get_logger(__name__)
  
  
  class ToolManager:
      """Manages FastMCP tools."""
  
      def __init__(
          self,
          warn_on_duplicate_tools: bool = True,
          *,
          tools: list[Tool] | None = None,
      ):
          self._tools: dict[str, Tool] = {}
          if tools is not None:
              for tool in tools:
                  if warn_on_duplicate_tools and tool.name in self._tools:
                      logger.warning(f"Tool already exists: {tool.name}")
                  self._tools[tool.name] = tool
  
          self.warn_on_duplicate_tools = warn_on_duplicate_tools
  
      def get_tool(self, name: str) -> Tool | None:
          """Get tool by name."""
          return self._tools.get(name)
  
      def list_tools(self) -> list[Tool]:
          """List all registered tools."""
          return list(self._tools.values())
  
      def add_tool(
          self,
          fn: Callable[..., Any],
          name: str | None = None,
          title: str | None = None,
          description: str | None = None,
          annotations: ToolAnnotations | None = None,
          icons: list[Icon] | None = None,
          meta: dict[str, Any] | None = None,
          structured_output: bool | None = None,
      ) -> Tool:
          """Add a tool to the server."""
          tool = Tool.from_function(
              fn,
              name=name,
              title=title,
              description=description,
              annotations=annotations,
              icons=icons,
              meta=meta,
              structured_output=structured_output,
          )
          existing = self._tools.get(tool.name)
          if existing:
              if self.warn_on_duplicate_tools:
                  logger.warning(f"Tool already exists: {tool.name}")
              return existing
          self._tools[tool.name] = tool
          return tool
  
      def remove_tool(self, name: str) -> None:
          """Remove a tool by name."""
          if name not in self._tools:
              raise ToolError(f"Unknown tool: {name}")
          del self._tools[name]
  
      async def call_tool(
          self,
          name: str,
          arguments: dict[str, Any],
          context: Context[ServerSessionT, LifespanContextT, RequestT] | None = None,
          convert_result: bool = False,
      ) -> Any:
          """Call a tool by name with arguments."""
          tool = self.get_tool(name)
          if not tool:
              raise ToolError(f"Unknown tool: {name}")
  
          return await tool.run(arguments, context=context, convert_result=convert_result)
  