Expose a service¶
The smallest possible end-to-end. A single service callable plus a JSON-Schema- producing input serializer is all the MCP server needs.
from rest_framework import serializers
from rest_framework_services.types.service_spec import ServiceSpec
from rest_framework_mcp import MCPServer
def calculate_total(*, data: dict) -> dict:
"""Return the total of a list of line-item subtotals."""
return {"total": sum(item["amount"] for item in data["items"])}
class CalculateTotalInput(serializers.Serializer):
items = serializers.ListField(
child=serializers.DictField(child=serializers.IntegerField())
)
server = MCPServer(name="cart")
server.register_service_tool(
name="cart.calculate_total",
spec=ServiceSpec(service=calculate_total, input_serializer=CalculateTotalInput),
description="Sum the `amount` field across a list of line items.",
)
Mount in urls.py:
Validation, error mapping (ServiceValidationError → -32602), and JSON-Schema
publication on tools/list come for free. The service callable still works as
a plain Python function — call it directly from your tests or from elsewhere
in the codebase, no MCP awareness required.