Skip to content

Commit acb45c6

Browse files
authored
Merge branch 'main' into main
2 parents a2f889b + 1a9ead0 commit acb45c6

File tree

18 files changed

+141
-75
lines changed

18 files changed

+141
-75
lines changed

examples/servers/simple-auth/mcp_simple_auth/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ async def exchange_authorization_code(
214214

215215
return OAuthToken(
216216
access_token=mcp_token,
217-
token_type="bearer",
217+
token_type="Bearer",
218218
expires_in=3600,
219219
scope=" ".join(authorization_code.scopes),
220220
)

examples/servers/simple-streamablehttp-stateless/mcp_simple_streamablehttp_stateless/server.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ def main(
4343
@app.call_tool()
4444
async def call_tool(
4545
name: str, arguments: dict
46-
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
46+
) -> list[
47+
types.TextContent
48+
| types.ImageContent
49+
| types.AudioContent
50+
| types.EmbeddedResource
51+
]:
4752
ctx = app.request_context
4853
interval = arguments.get("interval", 1.0)
4954
count = arguments.get("count", 5)

examples/servers/simple-streamablehttp/mcp_simple_streamablehttp/server.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ def main(
4747
@app.call_tool()
4848
async def call_tool(
4949
name: str, arguments: dict
50-
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
50+
) -> list[
51+
types.TextContent
52+
| types.ImageContent
53+
| types.AudioContent
54+
| types.EmbeddedResource
55+
]:
5156
ctx = app.request_context
5257
interval = arguments.get("interval", 1.0)
5358
count = arguments.get("count", 5)

examples/servers/simple-tool/mcp_simple_tool/server.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
async def fetch_website(
99
url: str,
10-
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
10+
) -> list[
11+
types.TextContent | types.ImageContent | types.AudioContent | types.EmbeddedResource
12+
]:
1113
headers = {
1214
"User-Agent": "MCP Test Server (github.com/modelcontextprotocol/python-sdk)"
1315
}
@@ -31,7 +33,12 @@ def main(port: int, transport: str) -> int:
3133
@app.call_tool()
3234
async def fetch_tool(
3335
name: str, arguments: dict
34-
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
36+
) -> list[
37+
types.TextContent
38+
| types.ImageContent
39+
| types.AudioContent
40+
| types.EmbeddedResource
41+
]:
3542
if name != "fetch":
3643
raise ValueError(f"Unknown tool: {name}")
3744
if "url" not in arguments:

src/mcp/client/streamable_http.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ async def handle_get_stream(
195195
self.url,
196196
headers=headers,
197197
timeout=httpx.Timeout(
198-
self.timeout.seconds, read=self.sse_read_timeout.seconds
198+
self.timeout.total_seconds(),
199+
read=self.sse_read_timeout.total_seconds(),
199200
),
200201
) as event_source:
201202
event_source.response.raise_for_status()
@@ -226,7 +227,7 @@ async def _handle_resumption_request(self, ctx: RequestContext) -> None:
226227
self.url,
227228
headers=headers,
228229
timeout=httpx.Timeout(
229-
self.timeout.seconds, read=ctx.sse_read_timeout.seconds
230+
self.timeout.total_seconds(), read=ctx.sse_read_timeout.total_seconds()
230231
),
231232
) as event_source:
232233
event_source.response.raise_for_status()
@@ -468,7 +469,8 @@ async def streamablehttp_client(
468469
async with httpx_client_factory(
469470
headers=transport.request_headers,
470471
timeout=httpx.Timeout(
471-
transport.timeout.seconds, read=transport.sse_read_timeout.seconds
472+
transport.timeout.total_seconds(),
473+
read=transport.sse_read_timeout.total_seconds(),
472474
),
473475
auth=transport.auth,
474476
) as client:

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from dataclasses import dataclass
33
from typing import Any, Literal
44

5-
from pydantic import AnyHttpUrl, AnyUrl, BaseModel, Field, RootModel, ValidationError
5+
from pydantic import AnyUrl, BaseModel, Field, RootModel, ValidationError
66
from starlette.datastructures import FormData, QueryParams
77
from starlette.requests import Request
88
from starlette.responses import RedirectResponse, Response
@@ -29,7 +29,7 @@
2929
class AuthorizationRequest(BaseModel):
3030
# See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1
3131
client_id: str = Field(..., description="The client ID")
32-
redirect_uri: AnyHttpUrl | None = Field(
32+
redirect_uri: AnyUrl | None = Field(
3333
None, description="URL to redirect to after authorization"
3434
)
3535

@@ -68,8 +68,8 @@ def best_effort_extract_string(
6868
return None
6969

7070

71-
class AnyHttpUrlModel(RootModel[AnyHttpUrl]):
72-
root: AnyHttpUrl
71+
class AnyUrlModel(RootModel[AnyUrl]):
72+
root: AnyUrl
7373

7474

7575
@dataclass
@@ -116,7 +116,7 @@ async def error_response(
116116
if params is not None and "redirect_uri" not in params:
117117
raw_redirect_uri = None
118118
else:
119-
raw_redirect_uri = AnyHttpUrlModel.model_validate(
119+
raw_redirect_uri = AnyUrlModel.model_validate(
120120
best_effort_extract_string("redirect_uri", params)
121121
).root
122122
redirect_uri = client.validate_redirect_uri(raw_redirect_uri)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from dataclasses import dataclass
55
from typing import Annotated, Any, Literal
66

7-
from pydantic import AnyHttpUrl, BaseModel, Field, RootModel, ValidationError
7+
from pydantic import AnyHttpUrl, AnyUrl, BaseModel, Field, RootModel, ValidationError
88
from starlette.requests import Request
99

1010
from mcp.server.auth.errors import (
@@ -27,7 +27,7 @@ class AuthorizationCodeRequest(BaseModel):
2727
# See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
2828
grant_type: Literal["authorization_code"]
2929
code: str = Field(..., description="The authorization code")
30-
redirect_uri: AnyHttpUrl | None = Field(
30+
redirect_uri: AnyUrl | None = Field(
3131
None, description="Must be the same as redirect URI provided in /authorize"
3232
)
3333
client_id: str

src/mcp/server/auth/provider.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import Generic, Literal, Protocol, TypeVar
33
from urllib.parse import parse_qs, urlencode, urlparse, urlunparse
44

5-
from pydantic import AnyHttpUrl, BaseModel
5+
from pydantic import AnyUrl, BaseModel
66

77
from mcp.shared.auth import (
88
OAuthClientInformationFull,
@@ -14,7 +14,7 @@ class AuthorizationParams(BaseModel):
1414
state: str | None
1515
scopes: list[str] | None
1616
code_challenge: str
17-
redirect_uri: AnyHttpUrl
17+
redirect_uri: AnyUrl
1818
redirect_uri_provided_explicitly: bool
1919

2020

@@ -24,7 +24,7 @@ class AuthorizationCode(BaseModel):
2424
expires_at: float
2525
client_id: str
2626
code_challenge: str
27-
redirect_uri: AnyHttpUrl
27+
redirect_uri: AnyUrl
2828
redirect_uri_provided_explicitly: bool
2929

3030

src/mcp/server/fastmcp/prompts/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
import pydantic_core
88
from pydantic import BaseModel, Field, TypeAdapter, validate_call
99

10-
from mcp.types import EmbeddedResource, ImageContent, TextContent
10+
from mcp.types import AudioContent, EmbeddedResource, ImageContent, TextContent
1111

12-
CONTENT_TYPES = TextContent | ImageContent | EmbeddedResource
12+
CONTENT_TYPES = TextContent | ImageContent | AudioContent | EmbeddedResource
1313

1414

1515
class Message(BaseModel):

src/mcp/server/fastmcp/server.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
from mcp.shared.context import LifespanContextT, RequestContext, RequestT
5353
from mcp.types import (
5454
AnyFunction,
55+
AudioContent,
5556
EmbeddedResource,
5657
GetPromptResult,
5758
ImageContent,
@@ -275,7 +276,7 @@ def get_context(self) -> Context[ServerSession, object, Request]:
275276

276277
async def call_tool(
277278
self, name: str, arguments: dict[str, Any]
278-
) -> Sequence[TextContent | ImageContent | EmbeddedResource]:
279+
) -> Sequence[TextContent | ImageContent | AudioContent | EmbeddedResource]:
279280
"""Call a tool by name with arguments."""
280281
context = self.get_context()
281282
result = await self._tool_manager.call_tool(name, arguments, context=context)
@@ -875,12 +876,12 @@ async def get_prompt(
875876

876877
def _convert_to_content(
877878
result: Any,
878-
) -> Sequence[TextContent | ImageContent | EmbeddedResource]:
879+
) -> Sequence[TextContent | ImageContent | AudioContent | EmbeddedResource]:
879880
"""Convert a result to a sequence of content objects."""
880881
if result is None:
881882
return []
882883

883-
if isinstance(result, TextContent | ImageContent | EmbeddedResource):
884+
if isinstance(result, TextContent | ImageContent | AudioContent | EmbeddedResource):
884885
return [result]
885886

886887
if isinstance(result, Image):

0 commit comments

Comments
 (0)