Commit graph go-sdk/docs/protocol.md
Author SHA1 Message Date
Yaroslav
12cbafe54d
oauthex: oauth discovery checks (#1220)
add extra checks for the default oauth discovery client:
* disallow redirects which downgrade to http
* disallow redirects to localhost or private ip
* disallow the initial call to a private ip
* proxy configuration opts out of dial time checking
2026-09-02 21:07:19 +02:00
Guglielmo Colombo
21c18c6229
mcp: allow restricting the protocol versions a server supports (#1199)
Fixes #945
2026-08-28 16:06:10 +02:00
Anton Dziatkovskii
810e6cb751
docs: make the protocol.md table of contents resolve (#1196)
Hi — I am an AI agent (Claude), working as Anton Dzyatkovsky's synthetic
co-founder. Same author as #1159 (dead MRTR links in `client.md`), same
genre, but this one has a cause worth naming rather than five links
worth patching.

**AI disclosure** (per
[AI_POLICY.md](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/AI_POLICY.md)):
this contribution — the investigation, the diff, the test and this
description — was written by Claude Code running autonomously; Anton is
the accountable human and reachable on this thread. Every measurement
quoted below was produced by running the thing, not inferred: the id
tables are scraped from the two rendered surfaces, the test's slug
function was checked against 31 of GitHub's real ids, and the failure
output is a real run against the pre-fix tree. Any reply from this
account is written the same way unless it says otherwise. I edited only
`internal/docs/**` and regenerated, per `AGENTS.md`.

## What is broken

Five table-of-contents entries in `docs/protocol.md` point at anchors
that no heading produces. They are dead on **both** surfaces — GitHub's
render of the file, and the published site.

| ToC entry links to | heading actually gets |
|---|---|
| `#discovery-(server/discover)` | `discovery-serverdiscover` |
| `#per-request-meta-keys` | `per-request-_meta-keys` |
| `#per-response-meta-keys` | `per-response-_meta-keys` |
| `#subscriptions-(subscriptions/listen)` |
`subscriptions-subscriptionslisten` |
| `#sse-transport-(legacy)` | `sse-transport-legacy` |

Right-hand column is scraped, not derived: `user-content-*` ids from
GitHub's rendered `docs/protocol.md`, and `<h* id=...>` from
`https://go.sdk.modelcontextprotocol.io/protocol`. Four of the five are
dead on the live site too; `sse-transport-legacy` is not in the
currently deployed build, so I could only confirm that one on GitHub.

## Why

`%toc` and the renderer slug the same heading by different rules, and
they disagree on exactly the punctuation these headings use:

* **weave** keeps `(`, `)` and `/`, and drops `_`
* **GitHub and python-markdown's `toc`** drop `(`, `)` and `/`, and keep
`_`

So the two agree on plain words and part ways the moment a heading
carries a method name in parentheses or a `_meta` field. This is a
class, not five typos: any future heading with those characters gets a
dead ToC entry, silently — the docs regenerate fine, `docs-check`
passes, and only a reader clicking the ToC finds out.

Someone already hit this, by hand: `internal/docs/server.src.md` links
to `protocol.md#subscriptions-subscriptionslisten`, i.e. the real
renderer id, not the one the ToC uses. That cross-link is the odd one
out today; the ToC is what is wrong.

## The fix

The characters have to leave the headings, because weave computes the
ToC and it is not in this repo. Each of the five sections already names
its RPC or field in its first sentence, so the heading loses nothing:

| was | becomes | the name is still in the first sentence |
|---|---|---|
| Discovery (``server/discover``) | **Discovery** | "the
`server/discover` RPC lets a client discover…" |
| Per-request ``_meta`` keys | **Per-request metadata keys** | "carries
these keys inside its `_meta` map" |
| Per-response ``_meta`` keys | **Per-response metadata keys** |
"servers SHOULD identify themselves on every response" |
| Subscriptions (``subscriptions/listen``) | **Subscriptions** |
"`subscriptions/listen` replaces the legacy…" |
| SSE Transport (legacy) | **Legacy SSE Transport** | "Before the
streamable transport, the 2024-11-05 spec…" |

Plus the one hand-written cross-link in `server.src.md`, updated to
`protocol.md#subscriptions`.

**The cost, stated plainly:** renaming a heading changes its id, so any
external deep link to `#discovery-serverdiscover` or
`#per-request-_meta-keys` breaks. Those ids are only reachable today by
someone who scrolled and copied the permalink — the ToC never produced
them — so I think the trade is worth it, but it is your call. **The
alternative is to fix the slug in weave**
(`golang.org/x/example/internal/cmd/weave`) and leave the headings
alone. I am happy to take it there instead if you would rather keep the
ids; say the word and I will close this.

## The guard

`internal/docs/toc_test.go` — reads the generated docs and checks every
`%toc` entry against the id its heading will actually get. No network,
no new dependency.

The slug function in it is validated, not asserted: run over all 31
headings of the current `docs/protocol.md`, it reproduces **31 of 31**
of the ids GitHub actually emitted for that file (and 30 of 31 on the
live site — the miss is the not-yet-deployed SSE section above).

Behaviour on the pre-fix tree, which is the point of it:

```
--- FAIL: TestTOCAnchorsResolve
    protocol.md: table-of-contents entry "Discovery (`server/discover`)" points at #discovery-(server/discover),
      which no heading produces (want #discovery-serverdiscover); drop (, ), / and _ from the heading
    ... and the other four, each named
```

All five, by name, with the id they should have had. On this branch it
passes.

## Runs

`go generate ./...` → no diff (idempotent, so `docs-check` stays green)
· `go vet ./...` clean · `go build ./...` clean · `go test ./...` → 14
packages ok, 0 failures, 26 without tests.

Docs and one new test only; no SDK code touched.

Co-authored-by: Anton Dziatkovskii <194927794+tonydzi@users.noreply.github.com>
2026-08-25 09:26:21 +02:00
Guglielmo Colombo
b8c53fedd6
mcp: add docs for tier 1 assessment (#1195)
Closes open points in
[comment](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/3220#issuecomment-5373089321)
2026-08-24 12:00:59 +02:00
Anton Dziatkovskii
725694100a
docs: fix the streamable client snippet to use (*Client).Connect (#1142)
### What was broken

`docs/protocol.md` → *Streamable Transport* → client side shows:

```go
client, err := mcp.Connect(ctx, transport, &mcp.ClientOptions{...})
```

There is no top-level `mcp.Connect`. The package has
`(*Client).Connect`, whose
third parameter is `*ClientSessionOptions`, not `*ClientOptions`. So the
one
snippet a reader reaches for when wiring up the client side of
streamable HTTP
does not build.

It is also the only outlier in the docs: `quick_start.md`, `client.md`,
`server.md`, `troubleshooting.md` and `protocol.md` itself (lines 470,
538) all
already use `client.Connect(ctx, transport, nil)`.

### How I checked

Pasted the snippet verbatim into a fresh module requiring the released
SDK
(`github.com/modelcontextprotocol/go-sdk v1.7.0`):

```
$ go build ./...
./broken.go:15:21: undefined: mcp.Connect
```

Then ran the proposed replacement end to end against a real streamable
server
(`mcp.NewStreamableHTTPHandler` behind `httptest.NewServer`), connecting
and
calling a tool over the session:

```
BUILD OK
tool result: {"greeting":"Hi you"}
```

### What it is now

```go
transport := &mcp.StreamableClientTransport{
	Endpoint: "http://localhost:8080/mcp",
}
client := mcp.NewClient(&mcp.Implementation{Name: "client", Version: "v1.0.0"}, nil)
session, err := client.Connect(ctx, transport, nil)
```

Change is in `internal/docs/protocol.src.md`; `docs/protocol.md`
regenerated with
`go generate ./internal/docs`, both committed together. Docs-only, no
code paths
touched.

---
Assisted-by: Claude Opus 5 — this PR was drafted and verified by Anton's
AI
cofounder running on his account; the commands and outputs above are
from real
runs, not reconstructions.

Co-authored-by: Anton Dzyatkovsky <dzyatkovskiy.a@gmail.com>
2026-08-04 14:39:05 +02:00
Guglielmo Colombo
5cb8339210
mcp: update return meta in DiscoverResult (SEP-2575) (#1097)
This PR implements the latest changes introduced by
https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3002
2026-07-16 16:10:12 +02:00
Guglielmo Colombo
fa548d7401
docs: update docs (#1089) 2026-07-16 11:11:22 +02:00
Guglielmo Colombo
a817f61412
mcp: add Cacheable fields to DiscoverResult (#1022)
This PR add the Cacheable fields to the DiscoverResult, as it was added
later
(8e4c2322ca)
2026-06-24 14:08:43 +02:00
Guglielmo Colombo
b9e6fc5a66
mcp: add documentation for new protocol version (#1019)
Add documentation for new protocol version in the `internal/docs`
2026-06-23 17:07:38 +02:00
Max Gerber
2d47cc9664
auth: issuer mix-up mitigation (#859)
This PR functions as a Reference implementation of
[SEP-2468](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2468)
/ [RFC9207](https://datatracker.ietf.org/doc/rfc9207/).

This PR hardens the MCP OAuth Client functionality against Mix-Up
attacks:
>   Mix-up attacks aim to steal an authorization code or access token by
>   tricking the client into sending the authorization code or access
> token to the attacker instead of the honest authorization or resource
>   server

This PR hardens the client by adding support for a new `iss` parameter
in authorization responses:
- Authorization Servers broadcast support for the `iss` parameter via
the `authorization_response_iss_parameter_supported` metadata parameter
- If the parameter is supported, clients expect to receive the `iss`
parameter in the authorization response
- Clients compare the `iss` parameter in the authorization response to
the `Issuer` parameter in the authorization metadata. The two must match
exactly for the response to be processed.

Fixes #941
2026-05-27 11:39:08 +02:00
Dinesh
1209861858
Add documentation backed by mkdocs (#883)
Affects /docs - (Refined Documentation for deployment and added Some
Supporting documentation)
Added a github action for deployment

Fixes #835  

Added Support for mkdocs
Example -  https://dinesht04.github.io/go-sdk/

Requires Configuration of Github pages as follows:-

1. Enable Github Pages
2. Select gh-pages branch for deployment

<img width="1237" height="817" alt="gh-pages"
src="https://github.com/user-attachments/assets/01f0b012-d5f3-4011-9af9-7269e657ae6a"
/>

## Sources
# For mkdocs.yaml
1.
https://github.com/modelcontextprotocol/python-sdk/blob/main/mkdocs.yml
2. https://github.com/modelcontextprotocol/java-sdk/blob/main/mkdocs.yml
  3. MKDocs official documentation
# For Github Action
1.
https://github.com/modelcontextprotocol/python-sdk/blob/main/.github/workflows/publish-docs-manually.yml
2.
https://github.com/modelcontextprotocol/java-sdk/blob/main/.github/workflows/docs.yml
3.
https://github.com/james-willett/material-mkdocs-youtube-2024/blob/main/.github/workflows/ci.yml
- From Youtube Tutorial
2026-04-09 14:25:43 +02:00
Maciej Kisiel
638d404e0d
all: stabilize client OAuth support (#861)
Also fix lint errors that were hidden because of the build tag.
2026-03-31 12:36:31 +02:00
Oleksandr Redko
b71a8391a6
all: fix typos (#869)
Grammar issues in docs, comments, and error messages.
2026-03-30 18:43:01 +02:00
Pranav RK
2d43865b97
Enterprise managed authorization (#770)
`auth`, `oauthex`: implement Enterprise Managed Authorization (SEP-990)
This PR implements Enterprise Managed Authorization (SEP-990) for the Go
MCP SDK, enabling MCP Clients and Servers to leverage enterprise
Identity Providers for seamless authorization without requiring users to
authenticate separately to each MCP Server.
 Overview
Enterprise Managed Authorization follows the Identity Assertion
Authorization Grant specification
(draft-ietf-oauth-identity-assertion-authz-grant), implementing a
three-step flow:
1. **Single Sign-On (SSO)**: User authenticates to the MCP Client via
enterprise IdP (Okta, Auth0, Azure AD, etc.)
2. **Token Exchange (RFC 8693)**: Client exchanges ID Token for Identity
Assertion JWT Authorization Grant (ID-JAG) at the IdP
3. **JWT Bearer Grant (RFC 7523)**: Client exchanges ID-JAG for Access
Token at the MCP Server
This enables:
- **For end users**: Single sign-on across MCP Clients and Servers—no
manual connection/authorization per server
- **For enterprise admins**: Centralized visibility and control over
which MCP Servers can be used within the organization
- **For MCP clients**: Automatic token acquisition without user
interaction for each server

Closes:
[#628](https://github.com/modelcontextprotocol/go-sdk/issues/628)

---------

Co-authored-by: Maciej Kisiel <mkisiel@google.com>
2026-03-30 16:29:30 +02:00
Maciej Kisiel
ea161959d7
all: clean up Go 1.24 specific code. (#850) 2026-03-20 12:28:56 +01:00
Maciej Kisiel
a433a831d6
mcp: verify 'Origin' and 'Content-Type' headers (#842)
This PR introduces protection against cross-origin requests by
installing `http.CrossOriginProtection`.
By default, the zero value is used which does not contain any trusted
origins or bypass patterns.
The protection can be customized by providing a custom
`http.CrossOriginProtection` in `mcp.StreamableHTTPOptions`. Currently,
the deny handler set on the protection is ignored.
This default has an MCPGODEBUG option (`disableoriginverification`) to
disable the default protection.
It will be available until `v1.6.0` of the SDK.
We also increase the Go version required by the SDK to 1.25, since this
is the version that introduced `http.CrossOriginProtection`. This is in
line with the SDK's policy of supporting two newest Go versions (1.26
was released in February 2026).

Additionally, we start validating if the `Content-Type` header for
`POST` requests is set to `application/json` to avoid accepting
CORS-safelisted requests.
2026-03-13 11:36:41 +01:00
Maciej Kisiel
d836ceb87d
auth: allow passing custom http.Client to AuthorizationCodeHandler (#840) 2026-03-13 10:06:58 +01:00
Robert Findley
4e1c3a34b5
mcp: update latestProtocolVersion to 2025-11-25 (#724)
Update the SDK to use protocol version 2025-11-25 as the latest
supported version. Fix tests and examples that had hardcoded
expectations for the previous version (2025-06-18).

---------

Co-authored-by: Maciej Kisiel <mkisiel@google.com>
2026-03-03 10:30:11 +01:00
Maciej Kisiel
c9317fb5b7
all: client side OAuth support (#785)
This PR introduces client-side OAuth support.

# Overall design philosophy

The main new interface introduced to support client-side OAuth is the
`OAuthHandler`. Contrary to its counter-parts in some other SDKs, it is
intentionally small and generic so that it can support most of the OAuth
authorization flow variants. The main `mcp` package purposefully
delegates almost all auth handling to `OAuthHandler` implementations.
This way, the `mcp` package continues to be largely OAuth agnostic.

The `auth` package comes with a default `OAuthHandler` implementation –
`AuthorizationCodeHandler`, which implements the authorization flow
for the `authorization_code` grant type, as defined in the [MCP
specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization).
It is expected that the `OAuthHandler` implementation granularity will
be roughly per grant type, as this parameter influences the
authorization flow the most.

# Detailed design

## `OAuthHandler` (auth/client.go)

The main interface for the integration consists of two methods:

```go
type OAuthHandler interface {
	// TokenSource returns a token source to be used for outgoing requests.
	// Returned token source might be nil. In that case, the transport will not
	// add any authorization headers to the request.
	TokenSource(context.Context) (oauth2.TokenSource, error)

	// Authorize is called when an HTTP request results in an error that may
	// be addressed by the authorization flow (currently 401 Unauthorized and 403 Forbidden).
	// It is responsible for performing the OAuth flow to obtain an access token.
	// The arguments are the request that failed and the response that was received for it.
	// The headers of the request are available, but the body will have already been consumed
	// when Authorize is called.
	// If the returned error is nil, TokenSource is expected to return a non-nil token source.
	// After a successful call to Authorize, the HTTP request will be retried by the transport.
	// The function is responsible for closing the response body.
	Authorize(context.Context, *http.Request, *http.Response) error
}
```

`StreamableClientTransport` accepts this interface as a field and uses
the `TokenSource` method to add an `Authorization: Bearer` header to
outgoing requests to the MCP server. If the request fails with `401:
Unauthorized` or `403: Forbidden`, the transport calls `Authorize` to
perform the authorization flow. If `Authorize` returns a non-nil error,
the request is retried once. `Authorize` errors do not result in
termination of the client session (unless they happen during
connection initialization), as some OAuth flows are multi-legged and it should be
acceptable to retry for example when the authorization grant was
received.

*Note:* There was already an `OAuthHandler` type defined as part of a
previous iteration of OAuth support. It was renamed to
`OAuthHandlerLegacy`. This is the only backwards incompatible API change
in the experimental client `auth` part (protected by the
`mcp_go_client_oauth` Go build tag). The cost of replacing previous
usages is deemed worthwhile to maintain clear naming, under the
assumption that the experimental client `auth` part was not widely used.

## `AuthorizationCodeHandler` (auth/authorization_code.go)

This is the `OAuthHandler` implementation that fulfills the [MCP
specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization).
In particular, in supports:

- Protected Resource Metadata discovery and fetching
- Authorization Server Metadata discovery and fetching
- Client registration
  - OpenID Connect metadata document
  - Pre-registration
  - Dynamic Client Registration
- PKCE
- `client_secret_post`, `client_secret_basic` token endpoint
auth methods
- Automatic refresh of tokens

### Authorization Server redirect

As part of the flow for the `authorization_code` grant type, the client
needs to point the user to the authorization URL, so that they confirm
the access request. This design proposes that it will be supported via a
pluggable dependency that will initiate this process in an
application-specific way:

```go
type AuthorizationCodeHandler struct {
	...

	// AuthorizationCodeFetcher is a required function called to initiate the authorization flow.
	// It is responsible for opening the URL in a browser for the user to start the authorization process.
	// It should return the authorization code and state once the Authorization Server
	// redirects back to the RedirectURL.
	AuthorizationCodeFetcher func(ctx context.Context, args *AuthorizationArgs) (*AuthorizationResult, error)

	...
}
```

The function is supposed perform any application specific logic to handle the redirect
from the Authorization Server and return the resulting code and state.

## `oauthex` changes

Some additional/adjusted building blocks that may be useful when
creating `OAuthHandler` implementations are present in the `oauthex`
package:

- `auth_meta.go`: Authorization Server Metadata utilities:
  - `GetAuthServerMeta`: get Authorization Server Metadata from a URL
- `dcr.go`: Dynamic Client Registration utilities (unchanged)
- `resource_meta.go`: Protected Resource Metadata utilities:
- `GetProtectedResourceMetadata`: get Protected Resource Metadata from a
URL
  - `ParseWWWAuthenticate` – as per name (unchanged)
- [deprecated] `GetProtectedResourceMetadataFromID` and
`GetProtectedResourceMetadataFromHeader` in favor of more generic
`GetProtectedResourceMetadata`. They will be kept under the Go build tag
and removed one version of the SDK in the future.
2026-02-27 15:30:13 +01:00
Robert Findley
d1c06cb748
internal/docs: document UserID for session hijacking prevention (#697)
Update our Session Hijacking mitigation documentation to describe the
new TokenInfo.UserID field and how the streamable transport uses it to
bind sessions to users.

Fixes #571
2025-12-08 15:25:34 -05:00
Eliya Sadan
d6d6edd6d4
auth: add OAuth 2.0 Protected Resource Metadata handler
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.
2025-12-08 14:54:52 -05:00
Robert Findley
80abbe6171
docs: document support for resumability and redelivery (#606)
Add missing documentation on resumability and redelivery in the
streamable transport.

Indirectly, also update stale transcluded examples. Example changes
weren't causing CI failure as we only trigger the docs check on changes
to the raw docs.
2025-10-27 14:00:58 -04:00
Robert Findley
1c3f38f777
all: more minor cleanup (#547)
Fix broken / missing links.
2025-09-30 16:07:07 -04:00
Jonathan Amsterdam
8b6391b173
docs: explain how to get TokenInfo (#502) 2025-09-19 11:50:42 -04:00
Jonathan Amsterdam
ff81f2f35a
docs: add auth and security sections (#492)
For #442.
2025-09-18 14:25:35 -04:00
Robert Findley
f5cee0aa32
docs: document stateless mode and custom transports (#485) 2025-09-18 11:22:40 -04:00
Robert Findley
ac2f175214
docs: add feature and troubleshooting documentation (#463)
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
2025-09-16 11:13:40 -04:00