Skip to content

Feature/617 async call tools #866

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 33 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c3ef7de
tinkering with resource progress
davemssavage May 24, 2025
b72bbc4
ruff check and format fixes
davemssavage May 24, 2025
202e922
use len of parameters to check progress variant, can't rely on client…
davemssavage May 24, 2025
d634e6a
clarify TODO message
davemssavage May 25, 2025
6169282
Merge branch 'feature/resource_progress' into feature/617-async-call-…
davemssavage May 31, 2025
22bd2eb
implement types as per 617 proposal
davemssavage May 31, 2025
9d3dfb2
ruff format/check fixes
davemssavage May 31, 2025
ffdb950
fixed updated field name
davemssavage May 31, 2025
a2c0ade
ignore type error
davemssavage May 31, 2025
9b1fd81
work in progress towards async protocol - simple call and get work
davemssavage Jun 1, 2025
5c03c55
remove TODO
davemssavage Jun 1, 2025
3e933e4
add notes on TODO items for result cache
davemssavage Jun 1, 2025
4316bec
More TODO notes
davemssavage Jun 1, 2025
58fc239
format fixes
davemssavage Jun 1, 2025
93b3c66
Add trivial authorisation check - confirms if user is the same
davemssavage Jun 1, 2025
fc6ee15
sort TODOs in terms of relative priority
davemssavage Jun 1, 2025
646dd63
ruff check/format
davemssavage Jun 1, 2025
ea0048c
Updates to support join
davemssavage Jun 2, 2025
bef1d72
Further updates, create lowlevel test for result caching and improve …
davemssavage Jun 3, 2025
9802041
Merge remote-tracking branch 'upstream/main' into feature/617-async-c…
davemssavage Jun 3, 2025
ba0f9ee
formatting and other misc tidy up highlighted by ruff check
davemssavage Jun 3, 2025
ff58c07
add comment to discuss uuid generation
davemssavage Jun 3, 2025
234ed4c
various minor tidy up
davemssavage Jun 3, 2025
fed9e70
add test for keep_alive expiry
davemssavage Jun 3, 2025
f8d9e04
fix assertion order and tidyup code for readability
davemssavage Jun 4, 2025
f926235
remove received, serves no purpose in spec, update protocol merge req…
davemssavage Jun 4, 2025
f667b63
Add tests for cancellation behaviour and implement
davemssavage Jun 4, 2025
6ded316
add todo note
davemssavage Jun 4, 2025
36c80a1
updated doc comment
davemssavage Jun 4, 2025
ef7944c
add TODO on user auth context propagation
davemssavage Jun 4, 2025
0e2437d
Add initial test for auth context propagation in async context
davemssavage Jun 4, 2025
f1d1116
remove cache tools, didn't turn out to be that useful in this context…
davemssavage Jun 4, 2025
d0e463e
rename result_cache class and allow other implementations for enterpr…
davemssavage Jun 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions src/mcp/client/session.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
from datetime import timedelta
from typing import Any, Protocol
from typing import Annotated, Any, Protocol

import anyio.lowlevel
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
from pydantic import AnyUrl, TypeAdapter
from pydantic import TypeAdapter
from pydantic.networks import AnyUrl, UrlConstraints

import mcp.types as types
from mcp.shared.context import RequestContext
from mcp.shared.message import SessionMessage
from mcp.shared.session import BaseSession, ProgressFnT, RequestResponder
from mcp.shared.session import (
BaseSession,
ProgressFnT,
RequestResponder,
ResourceProgressFnT,
)
from mcp.shared.version import SUPPORTED_PROTOCOL_VERSIONS

DEFAULT_CLIENT_INFO = types.Implementation(name="mcp", version="0.1.0")
Expand Down Expand Up @@ -208,7 +214,10 @@ async def set_logging_level(self, level: types.LoggingLevel) -> types.EmptyResul
)

async def list_resources(
self, cursor: str | None = None
self,
cursor: str | None = None,
# TODO suggest in progress resources should be excluded by default?
# possibly add an optional flag to include?
) -> types.ListResourcesResult:
"""Send a resources/list request."""
return await self.send_request(
Expand Down Expand Up @@ -239,7 +248,9 @@ async def list_resource_templates(
types.ListResourceTemplatesResult,
)

async def read_resource(self, uri: AnyUrl) -> types.ReadResourceResult:
async def read_resource(
self, uri: Annotated[AnyUrl, UrlConstraints(host_required=False)]
) -> types.ReadResourceResult:
"""Send a resources/read request."""
return await self.send_request(
types.ClientRequest(
Expand All @@ -251,7 +262,9 @@ async def read_resource(self, uri: AnyUrl) -> types.ReadResourceResult:
types.ReadResourceResult,
)

async def subscribe_resource(self, uri: AnyUrl) -> types.EmptyResult:
async def subscribe_resource(
self, uri: Annotated[AnyUrl, UrlConstraints(host_required=False)]
) -> types.EmptyResult:
"""Send a resources/subscribe request."""
return await self.send_request(
types.ClientRequest(
Expand All @@ -263,7 +276,9 @@ async def subscribe_resource(self, uri: AnyUrl) -> types.EmptyResult:
types.EmptyResult,
)

async def unsubscribe_resource(self, uri: AnyUrl) -> types.EmptyResult:
async def unsubscribe_resource(
self, uri: Annotated[AnyUrl, UrlConstraints(host_required=False)]
) -> types.EmptyResult:
"""Send a resources/unsubscribe request."""
return await self.send_request(
types.ClientRequest(
Expand All @@ -280,7 +295,7 @@ async def call_tool(
name: str,
arguments: dict[str, Any] | None = None,
read_timeout_seconds: timedelta | None = None,
progress_callback: ProgressFnT | None = None,
progress_callback: ProgressFnT | ResourceProgressFnT | None = None,
) -> types.CallToolResult:
"""Send a tools/call request with optional progress callback support."""

Expand Down
14 changes: 10 additions & 4 deletions src/mcp/server/fastmcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
asynccontextmanager,
)
from itertools import chain
from typing import Any, Generic, Literal
from typing import Annotated, Any, Generic, Literal

import anyio
import pydantic_core
from pydantic import BaseModel, Field
from pydantic.networks import AnyUrl
from pydantic.networks import AnyUrl, UrlConstraints
from pydantic_settings import BaseSettings, SettingsConfigDict
from starlette.applications import Starlette
from starlette.middleware import Middleware
Expand Down Expand Up @@ -147,7 +147,7 @@ def __init__(
tools: list[Tool] | None = None,
**settings: Any,
):
self.settings = Settings(**settings)
self.settings = Settings(**settings) # type: ignore

self._mcp_server = MCPServer(
name=name or "FastMCP",
Expand Down Expand Up @@ -962,7 +962,12 @@ def request_context(
return self._request_context

async def report_progress(
self, progress: float, total: float | None = None, message: str | None = None
self,
progress: float,
total: float | None = None,
message: str | None = None,
resource_uri: Annotated[AnyUrl, UrlConstraints(host_required=False)]
| None = None,
) -> None:
"""Report progress for the current operation.

Expand All @@ -985,6 +990,7 @@ async def report_progress(
progress=progress,
total=total,
message=message,
resource_uri=resource_uri,
)

async def read_resource(self, uri: str | AnyUrl) -> Iterable[ReadResourceContents]:
Expand Down
Loading
Loading