Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 3.8k
Feature/resource progress#800
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| @@ -956,7 +956,12 @@ def request_context(self) -> RequestContext[ServerSessionT, LifespanContextT]: | ||
| 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)] | ||
Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Local testing suggests it might be better to allow several resources to be reported as part of a single progress notification. e.g. context.report_progress(
progress=3,
total=10,
message='Reticulating splines',
resource_uris=['resource://spline1', 'resource://spline2', 'resource://spline3']
)I might refactor along these lines if this patch has a chance of making it into the protocol/sdk and it makes sense to others.
| ||
| | None = None, | ||
| ) -> None: | ||
| """Report progress for the current operation. | ||
| @@ -979,6 +984,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]: | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my interpretation of the spec, resources are owned and exposed by the "server". How the resource is created (say it's a file, media, API response) is not relevant. It may be that the same application can act as a client and a server (e.g. Claude Code can be a server but it is also a client, maybe the Claude Code application produces log files that the same application then exposes as a resource), but conceptually I don't think this fits the protocol, as currently framed. Nevertheless, it clearly states that both parties can request progress notifications about long-running processes (https://modelcontextprotocol.io/specification/2025-03-26/basic/utilities/progress#progress-flow), but IMO conceptually it is the server (or "the application when it's acting as a server") that creates resources. This is splitting hairs, but if Claude Code the server exposes a resource that Claude Code the application itself is producing, it's still inaccurate to say CC the client is creating the resource.
In any case, I'm curious what is the importance of this TODO? Is it to determine whether a client can send a resource/updated notification? If so, I would say no, IMO. But if the answer is "yes", like how would that affect the code/this PR?