Expose the jsonrpc.Error type to allow access to underlying JSON-RPC
error codes. Also, expose common JSON-RPC error codes in the jsonrpc
package, and MCP error codes in the mcp package.
Also, implement support for the MCP URL elicitation required error
(-32042), enabling servers to request out-of-band user authorization and
clients to automatically handle these requests with retry logic.
Server-side:
- Add CodeURLElicitationRequired constant
- Add URLElicitationRequiredError() constructor.
Client-side:
- Add urlElicitationMiddleware to intercept URLElicitationRequired
errors and retry calls.
- Update callElicitationCompleteHandler to signal waiting operations.
- Fix capability advertisement to support both form and URL modes.
Fixes#452Fixes#623
Add initial support for URL mode elicitation, by introducing the new
types, as well as both server and client-side validation.
A follow-up CL will add support for ErrURLElicitationRequired.
For #623
Add a timeout option for the streamable HTTP handler that automatically
cleans up idle sessions.
Also, fix a bug in the streamable client, where we hang on a request
even though the client can never get a response (because the HTTP
request terminated without a response or Last-Event-Id).
Fixes#499
As discussed at length in
https://github.com/modelcontextprotocol/go-sdk/issues/518, coupling our
schema fields to
jsonschema.Schema limits our user's ability to use a different schema
package, and makes it impossible for our client to talk to some
backends.
This CL relaxes the type of `*jsonschema.Schema` fields to be of type
`any`, which is a breaking change but is unlikely to affect most server
code. (It *is* a nontrivial change for clients).
Fixes https://github.com/modelcontextprotocol/go-sdk/issues/518
Add a framework for feature documentation, and start populating it with
our SDK documentation.
This framework is as follows:
- internal/docs/**.src.md is the markdown source for the docs/
directory.
- The x/example/internal/cmd/weave tool is used to compile these docs to
the top-level docs, supporting both linked code samples and generated
tables of contents.
- The readme-check workflow is updated to check these docs as well.
- The structure of these docs follows the MCP spec.
- Wherever possible, example code is linked from actual Go documentation
examples, so that it is testable.
Some minor modifications to the weave tool were made to support this
framework.
Additionally, partially fill out this documentation with content on
base protocol and client features, as well as troubleshooting help.
Along the way, a bug was encountered that our LoggingTransport was not
concurrency safe. This is fixed with a mutex.
Fixes https://github.com/modelcontextprotocol/go-sdk/issues/466
Fixes https://github.com/modelcontextprotocol/go-sdk/issues/409
Updates https://github.com/modelcontextprotocol/go-sdk/issues/442
An onClose function is passed to the ServerSession and ClientSession to
help cleanup resources from the caller.
The onClose function will be executed as part of the ServerSession and
ClientSession closure.
Fixes#258
This CL enables the server session to see what capabilities the client
has by introducing the InitializeParams() function.
This CL also adds a test to ensure ClientCapabilities is accurate.
Fixes#141
Implement the concurrency model described in #26: notifications are
synchronous, but calls are asynchronous (except for 'initialize'). To
achieve this, implement jsonrpc2.Async(ctx) to signal asynchronous
handling. This is simpler to use than returning ErrAsyncResponse and
calling Respond, and since this is an internal detail we don't need to
worry too much about whether it's idiomatic.
Add tests that verify both features, for both client and server.
Also:
- replace req.ID.IsValid with req.IsCall
- remove the methodHandler type as we can just use MethodHandler
Fixes#26
Export ServerCapabilities and related subtypes and update protocol,
server, and tests to use exported types. Add InitializeResult method on
ClientSession for accessing the initialize result from sessions.
Fixes: https://github.com/modelcontextprotocol/go-sdk/issues/166
Co-authored-by: Shashank Pachava <spachava753@gmail.com>
In #202, I added the checkRequest helper to validate incoming requests,
and invoked it in the stremable transports to preemptively reject
invalid HTTP requests, so that a jsonrpc error could be translated to an
HTTP error.
However, this introduced a bug: since cancellation was handled in the
jsonrpc2 layer, we never had to validate it in the mcp layer, and
therefore never added methodInfo. As a result, it was reported as an
invalid request in the http layer.
Add a test, and a fix. The simplest fix was to create stubs that are
placeholders for cancellation.
This was discovered in the course of investigating #285.
Handlers and client/server methods take a single request argument
combining the session and params. This slightly simplifies the signature
for handlers, since there is no longer an often-ignored session
argument.
But more importantly, it opens the door to adding more information in
requests, such as auth info and HTTP request headers.
For #243.
Support stateless streamable sessions by adding a GetSessionID function
to StreamableHTTPOptions. If GetSessionID returns "", the session is
stateless, and no validation is performed. This is implemented by
providing the session a trivial initialization state.
To implement this, some parts of #232 (distributed sessions) are copied
over, since they add an API for creating an already-initialized session.
In total, the following new API is added:
- StreamableHTTPOptions.GetSessionID
- ServerSessionOptions (a new parameter to Server.Connect)
- ServerSessionState
- ClientSessionOptions (a new parameter to Client.Connect, for symmetry)
For #10
Add a new (currently unexported) jsonResponse option to
StreamableServerTransportOptions, and use it to control the response
content type, serving application/json if set.
Additionally:
- A transportOptions field is added to the StreamableHTTPOptions.
- A messages iterator is added to encapsulate the iteration of stream
messages, since the handling of JSON and SSE responses are otherwise
very different.
- The serving flow is refactored to avoid returning (statusCode,
message), primarily because this seemed liable to lead to redundant
calls to WriteHeader, because only local logic knows whether or not
any data has been written to the response.
- The serving flow is refactored to delegate to responseJSON and
responseSSE, according to the currently unexported jsonResponse
option.
- A bug is fixed where all GET streams were considered persistent: the
terminal condition req.Method == http.MethodPost && nOutstanding == 0
was not right: GET requests may implement stream resumption.
Updates #211
Make several cleanups of the streamable client transport, encountered
during work on JSON support for the streamable server:
- The 'Close' condition is differentiated from asynchronous failures. A
failure should unblock Read with an error, at which point the JSON-RPC
connection will be broken and closed.
- Fields are reordered in streamableClientConn to make guards more
apparent.
- The handling of sessionID is simplified: we simply set the session ID
whenever we receive response headers. No need to have special handling
for the first request, as the serializeation of session initialization
is implemented in Client.Connect.
- Since the above bullet makes Write a trivial wrapper around
postMessage, the two methods are merged.
- A bug is fixed where JSON responses were handled synchronously in
Write. This lead to deadlock when a hanging client->server request is
waiting on a server->client request. Now JSON is handled symmetrically
to SSE: the Write returns once response headers are received.
asynchronous to Write.
- The httpConnection interface is renamed to clientConnection, and
receive the entire InitializeResult.
- streamableClientConn receivers are renamed to be consistently 'c'.
Audit all cases where params must not be null, and enforce this using
methodInfo via a new methodFlags bitfield that parameterizes method
requirements. Write extensive conformance tests catching all the
(server-side) crashes that were possible.
We should go further and validate schema against the spec, but that is
more indirect, more complicated, and potentially slower. For now we
adopt this more explicit approach.
Still TODO in a subsequent CL: verify the client side of this with
client conformance tests.
Additionally, improve some error messages that were redundant or leaked
internal implementation details.
Fixes#195
Add an isRequest field to methodInfo, used it to reject non-notification
requests that lack a valid ID. Furthermore, lift this validation to the
transport layer for HTTP server transports, so that we can preemptively
reject bad HTTP requests.
Fixes#194Fixes#197
Negotiate the protocol version properly, and set the header on HTTP
transports.
We follow the logic of the Typescript SDK.
- On initialization, the client sends the latest version it can support,
and accepts the version that the server returns if the client supports
it. If not, the connection fails.
- The server accepts the client's version unless it doesn't support it,
in which case it replies with its latest version.
Fixes#103.
This CL implements a completion handler for the server and a complete
method for the client.
Fixes: #12
<!-- Provide a brief summary of your changes -->
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
This adds support for completion.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
Added tests and an example.
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
N/A
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Use JSONRPCMessage, JSONRPCRequest, and JSONRPCResponse aliases
throughout the internal/mcp package, so that no jsonrpc2 names are
exposed in the public API.
Change-Id: Ibce794907538706448c694eafccf599a5892ab17
Reviewed-on: https://go-review.googlesource.com/c/tools/+/682796
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Add a test that checks for JSON null on the wire, and fix two categories
of bugs leading to null:
1. In many places, we could pass typed nil where we shouldn't have. Add
an orZero helper to avoid typed nills.
2. When listing roots, we should avoid nil.
Fixesgolang/go#74105
Change-Id: I061420487dbfcbf9016cb94b39bd72270e871c0e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/682675
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Update protocol versions to reflect that 2025-03-26 is supported, and
add server logic to negotiate the supported version with the client.
Update the client to set the protocol version, fixing what was probably
a spec violation.
+tests
Change-Id: I564b591b3daf018dd54f5c7e5d8f2d2b1e4ff502
Reviewed-on: https://go-review.googlesource.com/c/tools/+/682516
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
This CL adds a NotifyProgress function and a ProgressNotificationHandler
to enable progress sending and handling.
Subsequent CL's to follow to handle progress updates for other methods such as list or readresource.
Change-Id: Ifcc422e6f6231d7d773d5432c1cf64032d796709
Reviewed-on: https://go-review.googlesource.com/c/tools/+/681116
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Sam Thanawalla <samthanawalla@google.com>
Iterators return pointers instead of values, to be consistent.
Move tests out of example file.
Factor out iterator tests.
Change-Id: Icb14edf99d738de9d9dc08c1169057cb3dc5894b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/680295
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
CallToolParams.Arguments is any.
Clients can send whatever they want.
Tool authors who create their own ToolHandler (bypassing NewTool)
will receive the arguments as a map[string]any which has been
validated against the input schema.
Tool authors who call NewTool can choose the type that the arguments
unmarshal into.
There is no double-unmarshaling and no downcasting.
There is no way for tool authors to avoid the unmarshal, and no way to
avoid the validation unless the omit an input schema, which is probably
bad for LLMs. If tool authors want this optimization, we can provide
it later.
Change-Id: Ieb201e56c7fb8a23bb1a93b27e946630ec9e79ad
Reviewed-on: https://go-review.googlesource.com/c/tools/+/679595
TryBot-Bypass: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Add Client.ResourceTemplates
Test forthcoming.
Change-Id: I35e8ee8fabdf8fa216456ab3fcd0c8a7de9287c8
Reviewed-on: https://go-review.googlesource.com/c/tools/+/680255
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Provide support for resource templates on the client and server.
Adding, removing and listing resource templates looks just like those
operations on resources.
Although the spec provides no guidance on the unique ID for resource
templates, we follow most existing SDKs, as well as the parallel with
resources, and index on the URI template rather than the name.
As the spec recommends, the server verifies an incoming URI in a
ReadResource request against its list of resources and resource
templates, to make sure the URI came from one of them. The main
technical challenge here is the need to check that a URI template could
have produced a particular URI.
I wrote a very simplified version of this check. At some point
we should switch to github.com/yosida95/uritemplate/v3.
Change-Id: I1e34dd01c8f2171123c68c045ad62f5e85c05e7c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/680158
Auto-Submit: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
This CL simplifies the paginateList function in server.go to use a
generic helper for tools, resources, and prompts.
Change-Id: Ide0d2a90d715374280067e094d8870882e6bddfa
Reviewed-on: https://go-review.googlesource.com/c/tools/+/678055
Auto-Submit: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Implement sending middleware.
Sending middleware is useful for adding tracing, progress tokens,
and so on.
Change-Id: I0acab2550f0212d549c4adbcf1ebf425a9486df6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676355
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Write a separate constraint for ClientSession | ServerSession,
and change the pointerness of the type parameter.
There is still a dynamic cast, but overall I think this is a bit
simpler:
- The exported types have the more readable constraint "Session"
instead of "ClientSession | ServerSession".
- We can put the unexported methods in Session instead of needing a
separate interface (previously "session").
- This CL enables a simplified treatment of sending middleware, in
the next CL.
Change-Id: I41184fe93ea201d1da29dbfba26ac59f93771277
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676175
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Add a test to verify that the toWireParams helper maps all fields of
CallToolParams.
Change-Id: I81c28791734d60c793c76809c6b93d27e78c3c36
Reviewed-on: https://go-review.googlesource.com/c/tools/+/677975
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Make Tool APIs future-proof by pushing generics into CallToolParams, and
using CallToolParams throughout. This has several advantages:
- We no longer need the awkward CallToolOptions type, which is almost
but not quite like CallToolParams.
- NewTool no longer needs to define its own handler type: it accepts a
ToolHandler[TArgs]. This also means its signature is future-proof.
Additionally, provide a `CallTool` helper (the analog of NewTool) to
serve as a more strongly typed variant of `ClientSession.CallTool`.
+ design, protocol generation
Change-Id: I80172a25bc50734dae84a541aa4776ed9161694e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676495
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This CL streamlines the client side pagination logic by adding a generic
helper that handles pagination. This also simplifies the existing tools
iterator method.
Change-Id: If4304deda1ccd22d0c4580d76deaefc64e5dfeb9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/676975
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>