Handlers and Decorators

This module contains the MCP route controller and the decorator markers used to attach MCP metadata to handlers and standalone callables.

MCPController

class litestar_mcp.routes.MCPController[source]

Bases: Controller

MCP JSON-RPC 2.0 Streamable HTTP controller.

after_request: AfterRequestHookHandler | None

A sync or async function executed before a Request is passed to any route handler.

If this function returns a value, the request will not reach the route handler, and instead this value will be used.

after_response: AfterResponseHookHandler | None

A sync or async function called after the response has been awaited.

It receives the Request instance and should not return any values.

before_request: BeforeRequestHookHandler | None

A sync or async function called immediately before calling the route handler.

It receives the Request instance and any non-None return value is used for the response, bypassing the route handler.

cache_control: CacheControlHeader | None

A CacheControlHeader header to add to route handlers of this controller.

Can be overridden by route handlers.

dependencies: Dependencies | None

A string keyed dictionary of dependency Provider instances.

dto: type[AbstractDTO] | None | EmptyType

AbstractDTO to use for (de)serializing and validation of request data.

etag: ETag | None

An etag header of type ETag to add to route handlers of this controller.

Can be overridden by route handlers.

exception_handlers: ExceptionHandlersMap | None

A map of handler functions to status codes and/or exception types.

guards: Sequence[Guard] | None

A sequence of Guard callables.

include_in_schema: bool | EmptyType

A boolean flag dictating whether the route handler should be documented in the OpenAPI schema

middleware: Sequence[Middleware] | None

A sequence of Middleware.

opt: Mapping[str, Any] | None

A string key mapping of arbitrary values that can be accessed in Guards or wherever you have access to Request or ASGI Scope.

owner: Router

The Router or Litestar app that owns the controller.

This value is set internally by Litestar and it should not be set when subclassing the controller.

parameters: ParametersMap | None

A mapping of Parameter definitions available to all application paths.

path: str

A path fragment for the controller.

All route handlers under the controller will have the fragment appended to them. If not set it defaults to /.

request_class: type[Request] | None

A custom subclass of Request to be used as the default request for all route handlers under the controller.

request_max_body_size: int | None | EmptyType

Maximum allowed size of the request body in bytes. If this size is exceeded, a '413 - Request Entity Too Large' error response is returned.

response_class: type[Response] | None

A custom subclass of Response to be used as the default response for all route handlers under the controller.

response_cookies: ResponseCookies | None

A list of Cookie instances.

response_headers: ResponseHeaders | None

A string keyed dictionary mapping ResponseHeader instances.

return_dto: type[AbstractDTO] | None | EmptyType

AbstractDTO to use for serializing outbound response data.

security: Sequence[SecurityRequirement] | None

A sequence of dictionaries that to the schema of all route handlers under the controller.

signature_namespace: dict[str, Any]

A mapping of names to types for use in forward reference resolution during signature modelling.

signature_types: Sequence[Any]

A sequence of types for use in forward reference resolution during signature modelling.

These types will be added to the signature namespace using their __name__ attribute.

tags: Sequence[str] | None

A sequence of string tags that will be appended to the schema of all route handlers under the controller.

type_decoders: TypeDecodersSequence | None

A sequence of tuples, each composed of a predicate testing for type identity and a msgspec hook for deserialization.

type_encoders: TypeEncodersMap | None

A mapping of types to callables that transform them into types supported for serialization.

websocket_class: type[WebSocket] | None

A custom subclass of WebSocket to be used as the default websocket for all route handlers under the controller.

Markers

litestar_mcp.mcp_tool(name, *, description=None, agent_instructions=None, when_to_use=None, returns=None, output_schema=None, annotations=None, scopes=None, task_support=None)[source]

Decorator to mark a route handler as an MCP tool.

Parameters:
  • name -- The name of the MCP tool.

  • description -- LLM-facing description. Overrides fn.__doc__. Ignored when handler.opt["mcp_description"] is set (opt wins). Empty string is treated as absent so the docstring fallback still applies.

  • agent_instructions -- Mandatory-context block rendered in the ## Instructions section of the combined description.

  • when_to_use -- Optional structured hint for LLM clients — rendered as the ## When to use section.

  • returns -- Optional return-shape hint — rendered as the ## Returns section.

  • output_schema -- Optional JSON Schema for the tool's structured output.

  • annotations -- Optional metadata annotations (audience, priority, etc.).

  • scopes -- Optional list of OAuth scopes advertised as discovery metadata (surfaced under tools[].annotations.scopes in tools/list). Scopes are not enforced inline — attach a Litestar Guard to the route / router / controller for authorization.

  • task_support -- Optional task support mode. Must be one of optional, required, or forbidden.

Returns:

Decorator function that adds MCP metadata to the handler.

Example

Pass MCP metadata straight through to the route decorator — Litestar funnels unknown kwargs into handler.opt, so no double-decoration is required:

```python @get("/users", mcp_tool="user_manager", mcp_description="List every user.") async def get_users() -> list[dict]:

return [{"id": 1, "name": "Alice"}]

```

The decorator form is retained for parity; it carries the same metadata to the registry and is useful when you want to stamp output_schema, annotations, scopes, or task_support without mixing more keys into handler.opt.

litestar_mcp.mcp_resource(name, *, uri_template=None, description=None, agent_instructions=None, when_to_use=None, returns=None)[source]

Decorator to mark a route handler as an MCP resource.

Parameters:
  • name -- The name of the MCP resource.

  • uri_template -- Optional RFC 6570 Level 1 URI template (e.g. "app://workspaces/{workspace_id}/files/{file_id}"). Concrete URIs matching the template dispatch to this handler with extracted variables passed as kwargs.

  • description -- LLM-facing description. Overrides fn.__doc__.

  • agent_instructions -- Mandatory-context block rendered in the ## Instructions section.

  • when_to_use -- Optional structured hint rendered as the ## When to use section.

  • returns -- Optional return-shape hint rendered as the ## Returns section.

Returns:

Decorator function that adds MCP metadata to the handler.

Example

Pass MCP metadata straight through to the route decorator — Litestar funnels unknown kwargs into handler.opt:

```python @get("/config", mcp_resource="app_config") async def get_config() -> dict:

return {"debug": True}

@get(

"/workspaces/{workspace_id:str}/files/{file_id:str}", mcp_resource="workspace_file", mcp_resource_template="app://workspaces/{workspace_id}/files/{file_id}",

) async def read_workspace_file(workspace_id: str, file_id: str) -> dict:

...

```

The decorator form is retained for parity; it carries the same metadata to the registry.

litestar_mcp.mcp_prompt(name, *, title=None, description=None, arguments=None, icons=None)[source]

Decorator to mark a callable as an MCP prompt template.

Prompt functions take keyword arguments matching the declared prompt arguments and return prompt messages. The return value is normalised to a list of PromptMessage dicts:

  • str → single {"role": "user", "content": {"type": "text", "text": ...}}

  • dict → treated as a single message and wrapped in a list

  • list[dict] → used directly

  • Any other type → str(result) wrapped as a single user text message

Both sync and async callables are supported.

Parameters:
  • name -- Unique identifier for the prompt (used in prompts/get).

  • title -- Optional human-readable display name for UI clients.

  • description -- LLM-facing description. When omitted, fn.__doc__ is used as the fallback during registration.

  • arguments -- Optional explicit argument definitions — each entry is a dict with name (required), and optional title, description, and required keys. title is the human-readable display name from the MCP BaseMetadata mixin (a hint for UI clients; not used for matching). When omitted, the argument list is derived automatically from the decorated function's signature and Google-style docstring — note that signature introspection cannot infer title, so set it explicitly when needed.

  • icons -- Optional list of icon objects for UI display. Each entry is a dict with src (URL), mimeType, and optionally sizes per the MCP spec.

Returns:

Decorator function that adds MCP metadata to the callable.

Example

Standalone prompt function registered via LitestarMCP(prompts=[summarize_text]):

```python @mcp_prompt(name="summarize", description="Summarise a document.") async def summarize_text(text: str, style: str = "concise") -> str:

return f"Please summarise the following in a {style} style:\n\n{text}"

```