To be consistent with logging level, use a named string type for icon
themes. This improves readability / discoverability, and is more
consistent.
Updates #552
For #725
Change CloseSSEStream from func(time.Duration) to
func(CloseSSEStreamArgs) for forward compatibility, allowing new fields
to be added without breaking existing callers.
This change adds support for RFC 9728 (OAuth 2.0 Protected Resource Metadata)
by introducing a `ProtectedResourceMetadataHandler`.
The handler includes built-in CORS support with `Access-Control-Allow-Origin: *`
by default, as OAuth metadata is public information meant for client discovery.
Documentation includes examples for using custom CORS policies with
popular middleware libraries (github.com/rs/cors and github.com/jub0bs/cors).
The implementation follows RFC 9728 §3.1 for OAuth 2.0 Authorization Server
Metadata discovery, enabling clients to discover protected resource capabilities
and authentication requirements.
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
mcp/protocol: Implement SEP-973
- Define Icon structure, which includes source, mimeType and sizes.
- sizes is any array of strings. refer
https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1531
- Support setting websiteUrl, icons for mcp.Implementation
- Support setting icons for mcp.Prompt
- Support setting icons for mcp.Tool
- Support setting icons for mcp.Resource
Fixes#552
In `examples/http`, previous HTTP-level logging middleware blocked SSE
streaming because `handler.ServeHTTP()` does not return until the
connection closes for GET requests (SSE streams).
This prevented response headers from being sent to the client.
Changes:
- Replace HTTP-level logging handler with MCP middleware pattern
- Implement logging at the MCP protocol layer using mcp.Middleware
- Add middleware to server using AddReceivingMiddleware()
- Simplify main.go by removing HTTP handler wrapping
This allows SSE streams to work properly while still providing detailed
logging for all MCP protocol-level method calls.
Fixes#632
Address longstanding TODOs to clean up stream metadata after streams are
complete:
- Interpret a missing stream as a complete stream.
- Remove the request->stream mapping when the request completes. Any
writes after that point will fail as there can be no recipient.
Tested using examples/client/loadtest, and updating
TestStreamableTransports to check in-band and out-of-band behavior.
- Fix typo in "TroubleShooting" heading, changing it to
"Troubleshooting"
- Improve CLI usage instructions by formatting commands as code blocks
and marking them with "bash"
- Change "Start the Server" to a third-level heading for clarity
- Add additional code examples for real-world client testing and
interaction steps
- Clarify and condense instructions for adding the tool to a popular MCP
client
---------
Signed-off-by: appleboy <appleboy.tw@gmail.com>
Co-authored-by: Robert Findley <rfindley@google.com>
Readme update and clarification
Targeting only the main.go doesn't add the logging file and causes
errors when finding additional functions.
```
mcp-server-testing main* ☸ prod-3-d 33s
❯ go run main.go server
# command-line-arguments
./main.go:127:24: undefined: LoggingHandler
mcp-server-testing main* ☸ prod-3-d
❯ go run . server
2025/10/09 11:33:13 MCP server listening on localhost:8000
2025/10/09 11:33:13 Available tool: cityTime (cities: nyc, sf, boston)
```
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
In practice, the streamable client transport was having trouble
connecting to various backends, because they are nonconformant in
various ways.
While it would be nice if all servers conformed to the spec, in practice
there are certain spec violations that are recoverable, and we can and
should recover them. Specifically:
- tolerate 404 instead of 405 for the hanging GET (#393)
- tolerate (=ignore) spurious response body for notifications and
responses, since we know none are expected
Additionally, fix a bug that we weren't parsing Content-Type correctly.
Fixes#521
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
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.
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
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
Our 'hello' example should be as simple as possible. On the other hand,
we should have an 'everything' example that exercises (almost)
everything we offer.
Using the everything example, I did some final testing using the
inspector. This turned up a couple rough edges related to JSON null that
I addressed by preferring empty slices.
For #33
Replace all occurrences of ServerRequest[*CallToolParams] and other
concrete instantiations with CallToolRequest and the like.
Make the XXXRequest types aliases, to preserve the convenience of
generics for the internal machinery (see shared.go, for example.)
I will expand the aliases in a followup PR.
Change the design of tool handlers by removing genericity from the common path.
- `ToolHandler` gets the args as a `json.RawMessage`. Using Server.AddTool does no unmarshaling or schema validation.
- `ToolHandlerFor`, installed with `AddTool`, are the only generic pieces.
TODO:
uncomment and fix some tests
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.
As described in #272, there is really no reason for transports to be
closed structs with constructors, since their state must be established
by a call to Connect. Making them open structs simplifies their APIs,
and means that all transports can be extended in the future: we don't
have to create empty Options structs just for the purpose of future
compatibility.
For now, the related constructors and options structs are simply
deprecated (with go:fix directives where possible). A future CL will
remove them prior to the v1.0.0 release.
For #272
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 client example that lists all features on a stdio server. Since
this is our first client example, organize examples by client / server
-- otherwise it is too difficult to find client examples.
For #33
Add example of implementing mcp on [sequentialthinking
server](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking),
from [Example Servers](https://modelcontextprotocol.io/examples).
The PR includes dynamic and reflective problem-solving through
structured thinking processes.
The server provides tools for:
- starting thinking sessions
- adding sequential thoughts with step tracking
- revising previous thoughts
- creating alternative reasoning branches
- reviewing complete processes.
Also, features include thread-safe session management, adaptive planning
that adjusts step counts dynamically.
Expose `jsonrpc2.MakeID`, `jsonrpc2.EncodeMessage` and
`jsonrpc2.DecodeMessage` functions to allow implementing custom
`mcp.Transport`.
Add an example that demonstrates a custom transport
implementation.
Fixes#110.