ai-station/.venv/lib/python3.12/site-packages/mcp/server/fastmcp/resources/base.py

50 lines
1.7 KiB
Python

"""Base classes and interfaces for FastMCP resources."""
import abc
from typing import Annotated
from pydantic import (
AnyUrl,
BaseModel,
ConfigDict,
Field,
UrlConstraints,
ValidationInfo,
field_validator,
)
from mcp.types import Annotations, Icon
class Resource(BaseModel, abc.ABC):
"""Base class for all resources."""
model_config = ConfigDict(validate_default=True)
uri: Annotated[AnyUrl, UrlConstraints(host_required=False)] = Field(default=..., description="URI of the resource")
name: str | None = Field(description="Name of the resource", default=None)
title: str | None = Field(description="Human-readable title of the resource", default=None)
description: str | None = Field(description="Description of the resource", default=None)
mime_type: str = Field(
default="text/plain",
description="MIME type of the resource content",
pattern=r"^[a-zA-Z0-9]+/[a-zA-Z0-9\-+.]+(;\s*[a-zA-Z0-9\-_.]+=[a-zA-Z0-9\-_.]+)*$",
)
icons: list[Icon] | None = Field(default=None, description="Optional list of icons for this resource")
annotations: Annotations | None = Field(default=None, description="Optional annotations for the resource")
@field_validator("name", mode="before")
@classmethod
def set_default_name(cls, name: str | None, info: ValidationInfo) -> str:
"""Set default name from URI if not provided."""
if name:
return name
if uri := info.data.get("uri"):
return str(uri)
raise ValueError("Either name or uri must be provided")
@abc.abstractmethod
async def read(self) -> str | bytes:
"""Read the resource content."""
pass # pragma: no cover