### Context
Design (`design/mrtr.md`) and implementation proposal for Multi
Round-Trip Requests (MRTR) per
[SEP-2322](de6d76fba3/seps/2322-MRTR.md).
### Changes
- Introduce `InputRequest` and `InputResponse` sealed interfaces with
corresponding `InputRequestMap` and `InputResponseMap` types for custom
map JSON codec implementation.
- Extend `CallToolParams`, `GetPromptParams`, and `ReadResourceParams`
with `InputResponses`, `RequestState` and an unexported `resultType`
("complete" or "input_required") for retry round-trips. The type is set
by the SDK based on input requests presence.
- Add client-side MRTR middleware enabled by default that automatically
fulfills input requests and retries.
- Added MRTROptions on ClientOptions to allow disabling the middleware
and configuring the number of retries.
- Add server-side MRTR middleware for backward compatibility:
transparently bridges input requests to direct
Elicit/CreateMessage/ListRoots calls for older clients
Replaces the simple time-interval check in `LoggingHandler` with a
standard `rate.Limiter` from `golang.org/x/time/rate`, as suggested by
the existing TODO comment.
This provides a well-tested implementation and removes the need for
manual `lastMessageSent` tracking. The rate (`1/MinInterval`) and burst
(1) match the previous behavior exactly.
/cc @jba
Closes#924
---------
Signed-off-by: wucm667 <stevenwucongmin@gmail.com>
Co-authored-by: Jonathan Amsterdam <jba@users.noreply.github.com>
Co-authored-by: Maciej Kisiel <mkisiel@google.com>
A fix was submitted to our dependency, tests added to validate the
problematic scenario.
We also added some fuzz tests to check for additional issues, none were
found.
As reported in
https://github.com/modelcontextprotocol/go-sdk/issues/805, case
insensitive unmarshaling can pose security issues. This change adjusts
all non-test and non-example unmarshaling to use a case sensitive mode.
This introduces a new external dependency
`github.com/segmentio/encoding`.
This is a preliminary implementation of OAuth 2.1 for the client.
When a StreamableClientTransport encounters a 401 Unauthorized response
from the server, it initiates the OAuth flow described in thec
authorization section of the MCP spec
(https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization).
On success, the transport obtains an access token which it passes
to all subsequent requests.
Much remains to be done here:
* Resource Indicators, as described in section 2.5.1 of the MCP spec.
* All of this is unexported, so it is available only to our own
StreamingClientTransport. We should add API so people can use it
with their own transports.
* And, of course, tests. We should test against fake implementations
but also, if we can find any, real reference implementations.
For #19
Co-authored-by: Jonathan Amsterdam <jba@google.com>
---------
Co-authored-by: Jonathan Amsterdam <jba@google.com>
Our validation logic was avoiding double-unmarshalling as much as
possible, by parsing before validation and validating the Go type.
This only works if the Go type has the same structure as its JSON
representation, which may not be the case in the presence of types with
custom MarshalJSON or UnmarshalJSON methods (such as time.Time).
But even if the Go type doesn't use any custom marshalling, validation
is broken, because we can't differentiate zero values from missing
values.
Bite the bullet and use double-unmarshalling for both input and output
schemas. Coincidentally, this fixes three bugs:
- We were accepting case-insensitive JSON keys, since we parsed first,
even though they should have been rejected. A number of tests were
wrong.
- Defaults were overriding present-yet-zero values, as noted in an
incorrect test case.
- When "arguments" was missing, validation wasn't performed, no defaults
were applied, and unmarshalling failed even if all properties were
optional.
First unmarshalling to map[string]any allows us to fix all these bugs.
Unfortunately, it means a 3x increase in the number of reflection
operations (we need to unmarshal, apply defaults and validate,
re-marshal with the defaults, and then unmarshal into the Go type).
However, this is not likely to be a significant overhead, and we can
always optimize in the future.
Update github.com/google/jsonschema-go to pick up necessary improvements
supporting this change.
Additionally, fix the error codes for invalid tool parameters, to be
consistent with other SDKs (Invalid Params: -32602).
Fixes#447Fixes#449
Updates #450
1. Replaced the `uriTemplateToRegexp` function with the use of
[yosida95/uritemplate](https://github.com/yosida95/uritemplate) to
handle URI template matching as per the request.
2. Updated the relevant test cases to verify the new implementation and
fixed an invalid URI template (`"file:///{}/{a}/{b}"`) that doesn't
conform to RFC 6570 due to an empty `{}` expression.
3. Updated `go.mod` and `go.sum` to reflect the new dependency.
Fixes#11.