chore: add D212 lint rule to enforce Google-style docstrings (#1892)

This commit is contained in:
Felix Weinberger 2026-01-16 16:10:52 +00:00 • committed by GitHub
commit d41d0c0128
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 452 additions and 925 deletions

View file

@ -1,5 +1,4 @@
"""
Server-side experimental features.
"""Server-side experimental features.
WARNING: These APIs are experimental and may change without notice.

View file

@ -1,5 +1,4 @@
"""
Experimental request context features.
"""Experimental request context features.
This module provides the Experimental class which gives access to experimental
features within a request context, such as task-augmented request handling.
@ -32,8 +31,7 @@ from mcp.types import (
@dataclass
class Experimental:
"""
Experimental features context for task-augmented requests.
"""Experimental features context for task-augmented requests.
Provides helpers for validating task execution compatibility and
running tasks with automatic lifecycle management.
@ -64,8 +62,7 @@ class Experimental:
*,
raise_error: bool = True,
) -> ErrorData | None:
"""
Validate that the request is compatible with the tool's task execution mode.
"""Validate that the request is compatible with the tool's task execution mode.
Per MCP spec:
- "required": Clients MUST invoke as task. Server returns -32601 if not.
@ -110,8 +107,7 @@ class Experimental:
*,
raise_error: bool = True,
) -> ErrorData | None:
"""
Validate that the request is compatible with the given tool.
"""Validate that the request is compatible with the given tool.
Convenience wrapper around validate_task_mode that extracts the mode from a Tool.
@ -126,8 +122,7 @@ class Experimental:
return self.validate_task_mode(mode, raise_error=raise_error)
def can_use_tool(self, tool_task_mode: TaskExecutionMode | None) -> bool:
"""
Check if this client can use a tool with the given task mode.
"""Check if this client can use a tool with the given task mode.
Useful for filtering tool lists or providing warnings.
Returns False if tool requires "required" but client doesn't support tasks.
@ -150,8 +145,7 @@ class Experimental:
task_id: str | None = None,
model_immediate_response: str | None = None,
) -> CreateTaskResult:
"""
Create a task, spawn background work, and return CreateTaskResult immediately.
"""Create a task, spawn background work, and return CreateTaskResult immediately.
This is the recommended way to handle task-augmented tool calls. It:
1. Creates a task in the store

View file

@ -1,5 +1,4 @@
"""
Experimental server session features for server→client task operations.
"""Experimental server session features for server→client task operations.
This module provides the server-side equivalent of ExperimentalClientFeatures,
allowing the server to send task-augmented requests to the client and poll for results.
@ -25,8 +24,7 @@ ResultT = TypeVar("ResultT", bound=types.Result)
class ExperimentalServerSessionFeatures:
"""
Experimental server session features for server→client task operations.
"""Experimental server session features for server→client task operations.
This provides the server-side equivalent of ExperimentalClientFeatures,
allowing the server to send task-augmented requests to the client and
@ -42,8 +40,7 @@ class ExperimentalServerSessionFeatures:
self._session = session
async def get_task(self, task_id: str) -> types.GetTaskResult:
"""
Send tasks/get to the client to get task status.
"""Send tasks/get to the client to get task status.
Args:
task_id: The task identifier
@ -61,8 +58,7 @@ class ExperimentalServerSessionFeatures:
task_id: str,
result_type: type[ResultT],
) -> ResultT:
"""
Send tasks/result to the client to retrieve the final result.
"""Send tasks/result to the client to retrieve the final result.
Args:
task_id: The task identifier
@ -77,8 +73,7 @@ class ExperimentalServerSessionFeatures:
)
async def poll_task(self, task_id: str) -> AsyncIterator[types.GetTaskResult]:
"""
Poll a client task until it reaches terminal status.
"""Poll a client task until it reaches terminal status.
Yields GetTaskResult for each poll, allowing the caller to react to
status changes. Exits when task reaches a terminal status.
@ -101,8 +96,7 @@ class ExperimentalServerSessionFeatures:
*,
ttl: int = 60000,
) -> types.ElicitResult:
"""
Send a task-augmented elicitation to the client and poll until complete.
"""Send a task-augmented elicitation to the client and poll until complete.
The client will create a local task, process the elicitation asynchronously,
and return the result when ready. This method handles the full flow:
@ -160,8 +154,7 @@ class ExperimentalServerSessionFeatures:
tools: list[types.Tool] | None = None,
tool_choice: types.ToolChoice | None = None,
) -> types.CreateMessageResult:
"""
Send a task-augmented sampling request and poll until complete.
"""Send a task-augmented sampling request and poll until complete.
The client will create a local task, process the sampling request
asynchronously, and return the result when ready.

View file

@ -1,5 +1,4 @@
"""
ServerTaskContext - Server-integrated task context with elicitation and sampling.
"""ServerTaskContext - Server-integrated task context with elicitation and sampling.
This wraps the pure TaskContext and adds server-specific functionality:
- Elicitation (task.elicit())
@ -51,8 +50,7 @@ from mcp.types import (
class ServerTaskContext:
"""
Server-integrated task context with elicitation and sampling.
"""Server-integrated task context with elicitation and sampling.
This wraps a pure TaskContext and adds server-specific functionality:
- elicit() for sending elicitation requests to the client
@ -83,8 +81,7 @@ class ServerTaskContext:
queue: TaskMessageQueue,
handler: TaskResultHandler | None = None,
):
"""
Create a ServerTaskContext.
"""Create a ServerTaskContext.
Args:
task: The Task object
@ -123,8 +120,7 @@ class ServerTaskContext:
# Enhanced methods with notifications
async def update_status(self, message: str, *, notify: bool = True) -> None:
"""
Update the task's status message.
"""Update the task's status message.
Args:
message: The new status message
@ -135,8 +131,7 @@ class ServerTaskContext:
await self._send_notification()
async def complete(self, result: Result, *, notify: bool = True) -> None:
"""
Mark the task as completed with the given result.
"""Mark the task as completed with the given result.
Args:
result: The task result
@ -147,8 +142,7 @@ class ServerTaskContext:
await self._send_notification()
async def fail(self, error: str, *, notify: bool = True) -> None:
"""
Mark the task as failed with an error message.
"""Mark the task as failed with an error message.
Args:
error: The error message
@ -204,8 +198,7 @@ class ServerTaskContext:
message: str,
requested_schema: ElicitRequestedSchema,
) -> ElicitResult:
"""
Send an elicitation request via the task message queue.
"""Send an elicitation request via the task message queue.
This method:
1. Checks client capability
@ -270,8 +263,7 @@ class ServerTaskContext:
url: str,
elicitation_id: str,
) -> ElicitResult:
"""
Send a URL mode elicitation request via the task message queue.
"""Send a URL mode elicitation request via the task message queue.
This directs the user to an external URL for out-of-band interactions
like OAuth flows, credential collection, or payment processing.
@ -347,8 +339,7 @@ class ServerTaskContext:
tools: list[Tool] | None = None,
tool_choice: ToolChoice | None = None,
) -> CreateMessageResult:
"""
Send a sampling request via the task message queue.
"""Send a sampling request via the task message queue.
This method:
1. Checks client capability
@ -434,8 +425,7 @@ class ServerTaskContext:
*,
ttl: int = 60000,
) -> ElicitResult:
"""
Send a task-augmented elicitation via the queue, then poll client.
"""Send a task-augmented elicitation via the queue, then poll client.
This is for use inside a task-augmented tool call when you want the client
to handle the elicitation as its own task. The elicitation request is queued
@ -520,8 +510,7 @@ class ServerTaskContext:
tools: list[Tool] | None = None,
tool_choice: ToolChoice | None = None,
) -> CreateMessageResult:
"""
Send a task-augmented sampling request via the queue, then poll client.
"""Send a task-augmented sampling request via the queue, then poll client.
This is for use inside a task-augmented tool call when you want the client
to handle the sampling as its own task. The request is queued and delivered

View file

@ -1,5 +1,4 @@
"""
TaskResultHandler - Integrated handler for tasks/result endpoint.
"""TaskResultHandler - Integrated handler for tasks/result endpoint.
This implements the dequeue-send-wait pattern from the MCP Tasks spec:
1. Dequeue all pending messages for the task
@ -36,8 +35,7 @@ logger = logging.getLogger(__name__)
class TaskResultHandler:
"""
Handler for tasks/result that implements the message queue pattern.
"""Handler for tasks/result that implements the message queue pattern.
This handler:
1. Dequeues pending messages (elicitations, notifications) for the task
@ -75,8 +73,7 @@ class TaskResultHandler:
session: ServerSession,
message: SessionMessage,
) -> None:
"""
Send a message via the session.
"""Send a message via the session.
This is a helper for delivering queued task messages.
"""
@ -88,8 +85,7 @@ class TaskResultHandler:
session: ServerSession,
request_id: RequestId,
) -> GetTaskPayloadResult:
"""
Handle a tasks/result request.
"""Handle a tasks/result request.
This implements the dequeue-send-wait loop:
1. Dequeue all pending messages
@ -144,8 +140,7 @@ class TaskResultHandler:
session: ServerSession,
request_id: RequestId,
) -> None:
"""
Dequeue and send all pending messages for a task.
"""Dequeue and send all pending messages for a task.
Each message is sent via the session's write stream with
relatedRequestId set so responses route back to this stream.
@ -172,8 +167,7 @@ class TaskResultHandler:
await self.send_message(session, session_message)
async def _wait_for_task_update(self, task_id: str) -> None:
"""
Wait for task to be updated (status change or new message).
"""Wait for task to be updated (status change or new message).
Races between store update and queue message - first one wins.
"""
@ -199,8 +193,7 @@ class TaskResultHandler:
tg.start_soon(wait_for_queue)
def route_response(self, request_id: RequestId, response: dict[str, Any]) -> bool:
"""
Route a response back to the waiting resolver.
"""Route a response back to the waiting resolver.
This is called when a response arrives for a queued request.
@ -218,8 +211,7 @@ class TaskResultHandler:
return False
def route_error(self, request_id: RequestId, error: ErrorData) -> bool:
"""
Route an error back to the waiting resolver.
"""Route an error back to the waiting resolver.
Args:
request_id: The request ID from the error response

View file

@ -1,5 +1,4 @@
"""
TaskSupport - Configuration for experimental task support.
"""TaskSupport - Configuration for experimental task support.
This module provides the TaskSupport class which encapsulates all the
infrastructure needed for task-augmented requests: store, queue, and handler.
@ -21,8 +20,7 @@ from mcp.shared.experimental.tasks.store import TaskStore
@dataclass
class TaskSupport:
"""
Configuration for experimental task support.
"""Configuration for experimental task support.
Encapsulates the task store, message queue, result handler, and task group
for spawning background work.
@ -65,8 +63,7 @@ class TaskSupport:
@asynccontextmanager
async def run(self) -> AsyncIterator[None]:
"""
Run the task support lifecycle.
"""Run the task support lifecycle.
This creates a task group for spawning background task work.
Called automatically by Server.run().
@ -84,8 +81,7 @@ class TaskSupport:
self._task_group = None
def configure_session(self, session: ServerSession) -> None:
"""
Configure a session for task support.
"""Configure a session for task support.
This registers the result handler as a response router so that
responses to queued requests (elicitation, sampling) are routed
@ -100,8 +96,7 @@ class TaskSupport:
@classmethod
def in_memory(cls) -> "TaskSupport":
"""
Create in-memory task support.
"""Create in-memory task support.
Suitable for development, testing, and single-process servers.
For distributed systems, provide custom store and queue implementations.