At 7s, this test was 70% of our test execution time on my computer.
Speed it up by mutating the defaultTerminateDuration for the purposes of
the test.
Also update our test workflow to use go1.25, now that it's out.
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
Simplify the readme generation to just use go:generate, no longer
depending on Make or bash.
Subsequent CLs will generate more documentation in a similar manner.
For #442
Previously, the error message received from ClientSession.Wait would
only report the closeErr, which would often be nil even if the client
transport was broken. Wait should return the reason the session
terminated, if abnormal.
I'm not sure of the exact semantics of this, but surely returning nil is
less useful than returning a meaningful non-nil error. We can refine our
handling of errors once we have more feedback.
Also add a test for client termination on HTTP server shutdown,
described in #265. This should work as long as (1) the session is
stateful (with a hanging GET), or (2) the session is stateless but the
client has a keepalive ping.
Also: don't send DELETE if the session was terminated with 404; +test.
Fixes#265
In #272, we made transports open structs and deprecated their
constructors. However, we left the constructors in place to allow go:fix
directives to facilitate migration.
Now let's remove the constructors before cutting the release.
Fixes#305
The files in the oauthex package used the default Go license header,
rather than the MCP SDK license header (an accident of tooling). We
should fix this while jba@google.com is the only author of this code.
A subsequent PR will add a lint check to prevent this in the future.
Make the process termination timeout configurable instead of using a
hardcoded 5-second delay. This allows applications to customize the
termination behavior based on their specific needs.
Fixes#322.
Add example/server/toolschemas, which demonstrates various ways to
customize tool schemas, and illustrates the differences between
ToolHandler and ToolHandlerFor.
Fixes#385Fixes#386
For #368
Upon a closer reading of the spec, it is OK for the server to response
to client requests before it has received notifications/initialized (as
long as it has received initialize). This effectively rolls back the fix
from #225.
Some hooks are left for enforcing strictness around server->client
requests prior to initialized. These will be revisited in subsequent
CLs.
For #395
Update examples/server/rate-limiting to use the same replace directive
strategy as the auth-middleware example, and fix the breakages.
Also remove the unneeded type parameters in examples/client/middleware.
The streamable client connection can break for a variety of reasons,
asynchronously to the client's request. Decorate these failures with
additional context to clarify why they occurred.
Add a test for the failure message of #393.
Fixes#393
Use a fake streamable server to facilitate testing client behavior.
For this commit, just update the existing test (moved to a new file for
isolation). Subsequent CLs will add more tests.
Improve one client error message that occurred while debuging tests.
For #393
toolForErr was ignoring the output schema if the output type was any.
That neglected the case where the user provided their own output schema.
Fixes#371.
During initialization, the default logging level is set to info allowing
servers to emit logs immediately without waiting for a client to set a
log level.
The updated example shows how to send a notification in the context of
the request.
Fixes#387
The condition sessionID == "" was not quite right for disallowing GET
requests. Since we decided to differentiate "stateless" vs "sessionless"
servers, we need to disallow GET requests for both.
For #393
Add ErrOAuth error type and handling to match TypeScript SDK behavior.
OAuth protocol errors now return HTTP 400 instead of 500, providing
better error classification for authentication issues.
Changes
- Add ErrOAuth variable for OAuth-specific protocol errors
- Update verify function to return 400 for OAuth errors
- Add test case for OAuth error handling
Fixes compatibility with TypeScript SDK error handling patterns.
Exporting StreamableHTTPOptions.JSONResponse is helpful for some users behind proxies that don't work well with text/event-stream.
For #211
Co-authored-by: ccpro10 <co1797249167@gmail.com>
Log the result of a tool call in the middleware.
This example now fully demonstrates that receiving middleware can
effectively wrap a ToolHandler. That means that one reason for ToolFor
is moot: you don't need to get your hands on the returned ToolHandler in
order to wrap it.
This commit introduces a new example demonstrating the integration of
authentication middleware with an MCP server. The server supports both
JWT token and API key authentication, along with scope-based access
control for various MCP tools. Key features include token generation
endpoints, in-memory API key storage, and a health check endpoint.
New files added:
- `main.go`: Implements the MCP server and authentication logic.
- `go.mod` and `go.sum`: Manage dependencies for the project.
- `README.md`: Provides setup instructions, available endpoints, and
example usage.
This example serves as a reference for implementing secure access to MCP
tools.
Fixes#330
This CL utilizes the event store to write outgoing messages and removes
the unbounded outgoing data structure.
It also adds a new interface [EventStore.Open]
For #190