Repository navigation
Commit c531bb8
authored
Add a modern client for MCP 2026-07-28 (#1325)
The latest protocol revision introduced a stateless incarnation of the
protocol. It requires no initialization handshake or session
management, and it doesn't allow server-to-client requests.
An instance of the modern client is meant to stand for one user. It
does no I/O when built and can share its transport with other clients,
so an application that handles authorization creates one per user over
a single HTTP transport. Identity isn't passed to client methods; the
caller's McpTransportContext reaches the transport's request
customizers and authorization error handler, on every attempt.
Clients are built with McpClient.async(transport) or
McpClient.sync(transport), and each operation goes through an immutable
request spec, e.g. client.tool("create_issue").arguments(args).call().
Timeouts, progress, _meta and elicitation handlers are set on the
builder and can be overridden per call on the spec.
The client takes care of what the revision requires:
- the _meta block with version and capabilities on every request
- version renegotiation
- the multi round-trip loop for input_required results (with callOnce()
for callers that run it themselves)
- the Mcp-* and Mcp-Param-* headers, with one retry on -32020
- subscriptions/listen streams that report which parts of the filter
the server doesn't honour
The client keeps its tool listing for the listing's ttlMs, as that
user's view of the server, and uses it for x-mcp-header mirroring.
listTools().list() serves the kept listing while it's fresh, and
skipCache() always asks the server. A listen stream that reports tool
changes drops the kept listing.
A round timeout bounds each exchange but not the time a user spends
answering; a call timeout is optional. The sync client runs the loop
and its handlers on the caller's thread.
The client's own failures (missing input handler, too many input
rounds, invalid result, lost response, timeout, lost listen stream,
HTTP error status) extend McpClientException. Errors the server
answered remain McpException, so catching the two covers every failure
of a call.
Transports: Streamable HTTP on the JDK HttpClient, and stdio. Sampling,
roots, logging and extensions are left out for now. Synchronous HTTP
hooks (fromSync) run on boundedElastic, so they may block, for example
to fetch a token. McpHttpRequest and McpHttpResponseInfo can be created
outside the SDK, so a custom HTTP transport can call the request
customizers and the authorization error handler.
On the server side, the HTTP and stdio wire constants are shared with
the client, input requests are typed by method and mode, and the listen
filter is open so features can honour extension fields.
InputResponses.get and RequestStateCodec.open return null instead of an
empty Optional.
A conformance client in conformance-tests/client-modern passes the
non-auth 2026-07-28 client scenarios.
Part of #1011
Signed-off-by: Dariusz Jedrzejczyk <2554306+chemicL@users.noreply.github.com>1 parent 33e1581 commit c531bb8
100 files changed
Lines changed: 15492 additions & 227 deletions
File tree
- .github/workflows
- conformance-tests
- client-modern
- src/main
- java/io/modelcontextprotocol/conformance/client/modern
- resources
- server-servlet-modern/src/main/java/io/modelcontextprotocol/conformance/server/modern
- docs
- mcp-core/src
- main/java/io/modelcontextprotocol
- client/transport
- modern
- client
- transport
- server
- feature
- transport
- test/java/io/modelcontextprotocol/modern
- client
- transport
- mcp-test/src/test/java/io/modelcontextprotocol/modern
- client
- server
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
110 | 149 | | |
111 | 150 | | |
112 | 151 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
44 | 45 | | |
45 | 46 | | |
46 | 47 | | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
47 | 73 | | |
48 | 74 | | |
49 | 75 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
0 commit comments