Skip to content

Commit 0284c5f

Browse files
committed
Merge remote-tracking branch 'origin/main' into create-the-types-subpackage
# Conflicts: # src/mcp/types/_types.py
2 parents f763dc3 + ae7793e commit 0284c5f

File tree

2 files changed

+17
-20
lines changed

2 files changed

+17
-20
lines changed

src/mcp/server/auth/handlers/register.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,8 @@ class RegistrationHandler:
3232
async def handle(self, request: Request) -> Response:
3333
# Implements dynamic client registration as defined in https://datatracker.ietf.org/doc/html/rfc7591#section-3.1
3434
try:
35-
# Parse request body as JSON
36-
# TODO(Marcelo): This is unnecessary. We should use `request.body()`.
37-
body = await request.json()
38-
client_metadata = OAuthClientMetadata.model_validate(body)
35+
body = await request.body()
36+
client_metadata = OAuthClientMetadata.model_validate_json(body)
3937

4038
# Scope validation is handled below
4139
except ValidationError as validation_error:

src/mcp/server/fastmcp/server.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import re
77
from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence
88
from contextlib import AbstractAsyncContextManager, asynccontextmanager
9-
from typing import Any, Generic, Literal, overload
9+
from typing import Any, Generic, Literal, TypeVar, overload
1010

1111
import anyio
1212
import pydantic_core
@@ -44,7 +44,7 @@
4444
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
4545
from mcp.server.transport_security import TransportSecuritySettings
4646
from mcp.shared.context import LifespanContextT, RequestContext, RequestT
47-
from mcp.types import Annotations, AnyFunction, ContentBlock, GetPromptResult, Icon, ToolAnnotations
47+
from mcp.types import Annotations, ContentBlock, GetPromptResult, Icon, ToolAnnotations
4848
from mcp.types import Prompt as MCPPrompt
4949
from mcp.types import PromptArgument as MCPPromptArgument
5050
from mcp.types import Resource as MCPResource
@@ -53,6 +53,8 @@
5353

5454
logger = get_logger(__name__)
5555

56+
_CallableT = TypeVar("_CallableT", bound=Callable[..., Any])
57+
5658

5759
class Settings(BaseSettings, Generic[LifespanResultT]):
5860
"""FastMCP server settings.
@@ -112,7 +114,7 @@ def __init__(
112114
website_url: str | None = None,
113115
icons: list[Icon] | None = None,
114116
version: str | None = None,
115-
auth_server_provider: (OAuthAuthorizationServerProvider[Any, Any, Any] | None) = None,
117+
auth_server_provider: OAuthAuthorizationServerProvider[Any, Any, Any] | None = None,
116118
token_verifier: TokenVerifier | None = None,
117119
*,
118120
tools: list[Tool] | None = None,
@@ -121,7 +123,7 @@ def __init__(
121123
warn_on_duplicate_resources: bool = True,
122124
warn_on_duplicate_tools: bool = True,
123125
warn_on_duplicate_prompts: bool = True,
124-
lifespan: (Callable[[FastMCP[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]] | None) = None,
126+
lifespan: Callable[[FastMCP[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]] | None = None,
125127
auth: AuthSettings | None = None,
126128
):
127129
self.settings = Settings(
@@ -361,7 +363,7 @@ async def read_resource(self, uri: AnyUrl | str) -> Iterable[ReadResourceContent
361363

362364
def add_tool(
363365
self,
364-
fn: AnyFunction,
366+
fn: Callable[..., Any],
365367
name: str | None = None,
366368
title: str | None = None,
367369
description: str | None = None,
@@ -417,7 +419,7 @@ def tool(
417419
icons: list[Icon] | None = None,
418420
meta: dict[str, Any] | None = None,
419421
structured_output: bool | None = None,
420-
) -> Callable[[AnyFunction], AnyFunction]:
422+
) -> Callable[[_CallableT], _CallableT]:
421423
"""Decorator to register a tool.
422424
423425
Tools can optionally request a Context object by adding a parameter with the
@@ -455,7 +457,7 @@ async def async_tool(x: int, context: Context) -> str:
455457
"The @tool decorator was used incorrectly. Did you forget to call it? Use @tool() instead of @tool"
456458
)
457459

458-
def decorator(fn: AnyFunction) -> AnyFunction:
460+
def decorator(fn: _CallableT) -> _CallableT:
459461
self.add_tool(
460462
fn,
461463
name=name,
@@ -507,7 +509,7 @@ def resource(
507509
icons: list[Icon] | None = None,
508510
annotations: Annotations | None = None,
509511
meta: dict[str, Any] | None = None,
510-
) -> Callable[[AnyFunction], AnyFunction]:
512+
) -> Callable[[_CallableT], _CallableT]:
511513
"""Decorator to register a function as a resource.
512514
513515
The function will be called when the resource is read to generate its content.
@@ -553,7 +555,7 @@ async def get_weather(city: str) -> str:
553555
"Did you forget to call it? Use @resource('uri') instead of @resource"
554556
)
555557

556-
def decorator(fn: AnyFunction) -> AnyFunction:
558+
def decorator(fn: _CallableT) -> _CallableT:
557559
# Check if this should be a template
558560
sig = inspect.signature(fn)
559561
has_uri_params = "{" in uri and "}" in uri
@@ -618,7 +620,7 @@ def prompt(
618620
title: str | None = None,
619621
description: str | None = None,
620622
icons: list[Icon] | None = None,
621-
) -> Callable[[AnyFunction], AnyFunction]:
623+
) -> Callable[[_CallableT], _CallableT]:
622624
"""Decorator to register a prompt.
623625
624626
Args:
@@ -660,7 +662,7 @@ async def analyze_file(path: str) -> list[Message]:
660662
"Did you forget to call it? Use @prompt() instead of @prompt"
661663
)
662664

663-
def decorator(func: AnyFunction) -> AnyFunction:
665+
def decorator(func: _CallableT) -> _CallableT:
664666
prompt = Prompt.from_function(func, name=name, title=title, description=description, icons=icons)
665667
self.add_prompt(prompt)
666668
return func
@@ -1086,7 +1088,7 @@ async def elicit(
10861088
10871089
Args:
10881090
schema: A Pydantic model class defining the expected response structure, according to the specification,
1089-
only primive types are allowed.
1091+
only primitive types are allowed.
10901092
message: Optional message to present to the user. If not provided, will use
10911093
a default message based on the schema
10921094
@@ -1158,10 +1160,7 @@ async def log(
11581160
"""
11591161

11601162
if extra:
1161-
log_data = {
1162-
"message": message,
1163-
**extra,
1164-
}
1163+
log_data = {"message": message, **extra}
11651164
else:
11661165
log_data = message
11671166

0 commit comments

Comments
 (0)