This PR fixes goroutine leaks in all unit tests.
To find the leaks I integrated https://github.com/uber-go/goleak and I
suggest to keep using it to catch any future regressions.
I used the folowing script to more easily find individual tests which
were leaking goroutines:
```
for t in $(go test -run=Nothing -list=. ./mcp | grep -v ok); do go test ./mcp -run="$t" > /dev/null && echo -n . || echo -e "\nDetected leak: $t"; done
```
- 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)
```
GetProtectedResourceMetadataFromHeader was validating the resource field
against the metadata endpoint URL instead of the original server URL.
Per RFC 9728 section 3.3, the resource field must match the URL that the
client used to make the request to the resource server.
Fixes: #560
PR 501 added logging to the streamable server, but didn't pass a non-nil
logger to the streamable transport (an oversight). However, tests still
passed due to net/http's panic recovery.
Update test servers to enforce that handlers do not panic, and fix the
panic by:
1. Passing along the configured logger to the session transport.
2. Using ensureLogger in Connect, since we technically allow
StreamableServerTransports to be constructed by the user.
Fixes#556
mcp/server.go: implement server‑side logging
- Thread a *slog.Logger through server paths to improve debuggability
- Introduce no‑op discard handler + ensureLogger so loggers are never
nil
- Use ensured loggers in Server
- address todo comments related to adding logging support
All tests are passing and no functionality should change with this PR
Fixes https://github.com/modelcontextprotocol/go-sdk/issues/170
This commit adds ability to create a mcp.Transport with specific
io.ReadCloser and io.WriteCloser.
Ii is needed when you need create an mcp.Client for mcp.Server launched
in separate process and you need to communicate with it with it's own
stdin/stdout.
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>
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
## Problem
Context propagation was broken in `StreamableClientTransport` because:
1. `Connect()` used `context.Background()` instead of the parent context
2. `Close()` created a race condition where DELETE requests were
cancelled before completion
## Solution
- Use parent context when creating the connection context in `Connect()`
- Reorder `Close()` operations to perform cleanup DELETE before
cancelling context
## Impact
- Request-scoped values (auth tokens, trace IDs) now propagate correctly
to background HTTP operations
- Eliminates race condition in cleanup operations
- Maintains proper Go context semantics
Fixes#513
This change adjusts the code example in readme so if you view it in
github it won't show a horizontal scroll bar in code example.
It's trivial change, but I believe it's still an improvement.
Also significantly lessen our warnings, and note that this is a release
candidate, rewrite Acknowledgements to be Acknowledgements /
Alternatives, since other MCP SDKs continue to be actively developed.