from django.db.models import QuerySet # For more advanced low level usage, you can use the mcp_server directly from mcp_server import mcp_server as mcp from mcp_server.djangomcp import DjangoMCP from mcp_server import ( MCPToolset, drf_serialize_output, drf_publish_create_mcp_tool, drf_publish_update_mcp_tool, drf_publish_destroy_mcp_tool, drf_publish_list_mcp_tool, ) from mcp_server import ModelQueryToolset from .models import Bird, Location, City from .serializers import BirdSerializer from .views import ( LocationAPIView, LocationAPIUpdateView, LocationAPIListView, LocationAPIListViewSet, LocationAPIUpdateViewSet, ) class BirdQuery(ModelQueryToolset): model = Bird output_format = "csv" # output_as_resource = True # as of today milage with this may vary, claude supports it if it is not tool long, ADK fails to process the response ... def get_queryset(self): """self.request can be used to filter the queryset""" return super().get_queryset().filter(location__isnull=False) class LocationTool(ModelQueryToolset): model = Location class CityTool(ModelQueryToolset): model = City class LocationQuery(ModelQueryToolset): model = Location class CityQuery(ModelQueryToolset): model = City class SpeciesCount(MCPToolset): def _search_birds(self, search_string: str | None = None) -> QuerySet: """Get the queryset for birds, methods starting with _ are not registered as tools""" return Bird.objects.all() if search_string is None else Bird.objects.filter(species__icontains=search_string) @drf_serialize_output(BirdSerializer) def increment_species(self, name: str, amount: int = 1): """ Increment the count of a bird species by a specified amount and returns tehe new count. The first argument is the species name, the second is the amount to increment with (1) by default. """ ret = self._search_birds(name).first() if ret is None: ret = Bird.objects.create(species=name) ret.count += amount ret.save() return ret # To create a secondary MCP endpoint with its own isolated toolset, you can use the DjangoMCP constructor second_mcp = DjangoMCP(name="altserver") @mcp.tool() async def get_species_count(name : str): """ Find the ID of a bird species by its name or part of name. Returns the count""" ret = await Bird.objects.filter(species__icontains=name).afirst() if ret is None: ret = await Bird.objects.acreate(species=name) return ret.count @second_mcp.tool() async def get_bird_news(): """ Get the latest bird news """ return "Scientists have discovered a new bird species!" drf_publish_create_mcp_tool(LocationAPIView) drf_publish_update_mcp_tool(LocationAPIUpdateView) drf_publish_destroy_mcp_tool(LocationAPIUpdateView, instructions="A tool to delete a location") drf_publish_destroy_mcp_tool( LocationAPIUpdateViewSet, instructions="Another tool to delete a location", actions={"delete": "destroy"}, ) drf_publish_list_mcp_tool(LocationAPIListView, instructions="A tool to list all locations") drf_publish_list_mcp_tool( LocationAPIListViewSet, instructions="Another tool to list all locations", actions={"get": "list"}, )