Commit graph

570 commits

Author SHA1 Message Date
Daniel Garnier-Moiroux
e7b389f846 Update CONTRIBUTING.md with an AI agent policy
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-26 15:44:50 +02:00
Daniel Garnier-Moiroux
fb029c8c76 Revert "Clean up AbstractMcpClientServerIntegrationTests"
This reverts commit 439dc90d25.
Spring AI still uses the old API from these tests because they have
muliple clients.

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-24 16:44:08 +02:00
Daniel Garnier-Moiroux
c4dd4715ca Implement AbstractStatelessIntegrationTests with Servlet
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-24 16:35:01 +02:00
Daniel Garnier-Moiroux
305e4cbd03 Update VERSIONING and CHANGELOG
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-19 16:00:42 +02:00
Daniel Garnier-Moiroux
cceba3f695 Next development version
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-19 15:27:57 +02:00
Daniel Garnier-Moiroux
c7e1cfe90e Release version 2.0.1 v2.0.1
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-19 15:25:35 +02:00
Daniel Garnier-Moiroux
3477fcd0cd Bound STDIO client reads
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-19 14:53:08 +02:00
Daniel Garnier-Moiroux
3b72eec0b8 Bound STDIO server reads
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-19 14:53:08 +02:00
Daniel Garnier-Moiroux
ef037dae7b Bound HTTP client reads
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-19 14:41:20 +02:00
Daniel Garnier-Moiroux
6a41dedaa0 Bound HTTP server reads
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-19 14:41:20 +02:00
Daniel Garnier-Moiroux
1fcb40430c Clarify supported lines 2.0.x, 1.1.x, 0.18.x
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-19 11:34:18 +02:00
Daniel Garnier-Moiroux
e75a8ee651 ignore .envrc
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-19 11:27:37 +02:00
Christian Tzolov
2fd159a79a Prepare SDK Tier 2 assessment submission
- Add CHANGELOG.md with release lines and history
- Refresh ROADMAP.md: 2.x stable line, 3.0.x for 2026-07-28 spec (first
  milestones Sep 2026), Tier 2 commitment, 1.x/0.x security-patches-only
- Refresh VALIDATION_RESULTS.md: 2026-08-17 run on conformance suite
  0.2.0-alpha.11 (server 73/73, auth 193/193, client 3/4 w/ sse-retry baselined)
- Bump conformance CI action pins v0.1.11 -> v0.1.16
- Update docs with missing features

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
2026-08-19 11:16:44 +02:00
Iuliia Sobolevska
8ee8ccbc17
Make McpTransportContext.metadata immutable (#1076)
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-08-07 18:36:22 +02:00
nanookclaw
27b91521c0
fix: stop pagination on empty cursors (#954)
Signed-off-by: Nanook <nanookclaw@users.noreply.github.com>
Co-authored-by: Nanook <nanookclaw@users.noreply.github.com>
2026-08-07 18:25:39 +02:00
jiajingda
f5aab36a2f
Fix SSE event classification to follow spec for missing event field (#913)
Per the SSE specification (WHATWG HTML Living Standard 9.2.6), an event with no explicit event field MUST be dispatched as a message event. HttpClientStreamableHttpTransport previously used strict equality and silently dropped such frames in the reconnect/GET stream path, causing server-initiated notifications to never reach the handler. Extract classification into a package-private isMessageEvent helper and cover with parameterized unit tests.

Closes gh-885
2026-08-07 17:48:03 +02:00
Minsung Son
fd004989b9
refactor: add notification handler to stateless servers. (#835)
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
Co-authored-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-07-10 17:51:38 +02:00
Daniel Garnier-Moiroux
0557b87603
Introduce AGENTS.md (#1059)
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-07-08 15:16:28 +02:00
Mathias Geat
5d3decebd6
Fix error behavior on unregistered handlers in stateless server handler (#800)
Instead of throwing an McpError, it now returns with a JSON-RPC method not found error (-32601), aligned with the stateful implementation.

Closes #784
2026-07-08 14:42:06 +02:00
João Dinis Ferreira
dea53fd14c
Bump json-schema-validator to 2.0.4 / 3.0.6 (#1058)
Fixes #992
2026-07-08 12:06:32 +02:00
Ana-Maria Mihalceanu
30f1adf613
Update README.md (#1044) 2026-06-30 17:53:14 +02:00
Daniel Garnier-Moiroux
ff78191ebd
Close response after sending error in McpStreamableServerSession#responseStream (#1041)
Closes #1040

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-06-26 16:06:36 +02:00
Daniel Garnier-Moiroux
f7d9a64b3c Change @ParameterizedTest -> @Test in HttpServletStatelessServerTransport
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-06-24 16:41:21 +02:00
Daniel Garnier-Moiroux
d015b4e97c Add tests for completion requests targeting missing prompt or resource
Polish gh-996

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-06-24 16:41:10 +02:00
King Star
301f8b06c7 fix(server): return empty completion when handler is absent 2026-06-24 14:27:24 +02:00
Daniel Garnier-Moiroux
492c859eb8 Conformance: introduce @ConditionalOnScenario
- Useful for incoming auth scenarios in Conformance v2 / 2026-07-28 spec

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-06-24 12:24:20 +02:00
Daniel Garnier-Moiroux
b1a7d5fe88 Upgrade conformance suite to 0.1.16, Spring AI conformance to 2.0.0 GA
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-06-23 15:49:21 +02:00
Daniel Garnier-Moiroux
439dc90d25 Clean up AbstractMcpClientServerIntegrationTests
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-06-23 10:34:54 +02:00
Dariusz Jędrzejczyk
d1ef187c9c Next development version
Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-06-11 13:41:15 +02:00
Dariusz Jędrzejczyk
f56d038409 Release version 2.0.0 v2.0.0
Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-06-11 13:37:50 +02:00
Dariusz Jędrzejczyk
d20af91512
Add 2025-11-25 spec version to all transports (#1025)
Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-06-11 12:17:46 +02:00
Christian Tzolov
c42d313975
Return void from McpStatelessSyncServer#closeGracefully instead of Mono (#1019)
Co-authored-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
2026-06-11 12:02:44 +02:00
Dariusz Jędrzejczyk
275633775c
Update documentation and migration notes for v2 (#1024)
Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-06-11 11:38:19 +02:00
Daniel Garnier-Moiroux
fe82ad508a
Add schemas for form-based elicitation (#1020)
* Add StringSchema, BooleanSchema and NumberSchema
* Add enum schemas for form-based elicitation matching SEP-1330

Closes #691

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-06-11 11:16:47 +02:00
Christian Tzolov
99faac65f7
Clarify tool validation error messages (#1023)
- DefaultJsonSchemaValidator now emits a neutral message;
- Call sites in ToolInputValidator and the server output handlers
  prepend their own context prefix,
- Integration test assertions strengthened accordingly.

Closes #986

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>

* address review comments

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>

* address review comments

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>

---------

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
2026-06-11 09:45:28 +02:00
Dariusz Jędrzejczyk
df75857fb1
fix: avoid dropped errors when transport is closed or uninitialized (#995)
Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-06-04 14:11:32 +02:00
Daniel Garnier-Moiroux
dbb9bdad51
Add URL elicitation support (SEP-1036) (#993)
Add URL-type elicitation schema support allowing servers to request URL
input from users during tool execution. This enables out-of-band
interactions like payment processing or API key entry.

Breaking changes:

- `ElicitRequest` changed from a `record` to an `interface`.
- The original `ElicitRequest` record was renamed to `ElicitFormRequest`.
- `McpClient` builder `elicitation()` methods now accept `ElicitFormRequest` instead of `ElicitRequest`.

New APIs:

- `ElicitUrlRequest` record for URL-mode elicitation.
- `urlElicitation()` builder methods in `McpClient`.
- `elicitationCompleteConsumer()` and `elicitationCompleteConsumers()` builder methods in `McpClient`.
- `sendElicitationComplete()` methods in `McpAsyncServer` and `McpSyncServer`.
- `McpError.URL_ELICITATION_REQUIRED` and `McpSchema.ErrorCodes.URL_ELICITATION_REQUIRED`.
- `ElicitationCompleteNotification` record and `METHOD_NOTIFICATION_ELICITATION_COMPLETE` constant.

Co-authored-by: Daniel Garnier-Moiroux <git@garnier.wf>
Co-authored-by: Sainath Reddy Bobbala <bsnr@amazon.com>
2026-06-03 16:24:29 +02:00
Joao Ferreira
c49a994463 Add missing Export-Package to mcp-json-jackson2 and mcp-json-jackson3
Use explicit package names instead of a wildcard glob to avoid
embedding mcp-core classes into the jackson module JARs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-28 11:02:08 +02:00
Dariusz Jędrzejczyk
c8ab3411b9
feat: Refine logging levels (#985)
The logging is sometimes too verbose and uses inappropriate level. With this
change there should be less disturbing logs and less duplication.

Notable changes:

* `LifeCycleInitializer#handleException` - duplicated log, already handled in
  transports that use the initializer.
* `McpClientSession#sendRequest` - an MCP protocol level error in JSON-RPC is
  not really a reason for ERROR level log. Using INFO with more details.
* `DefaultJsonSchemaValidator` - ERROR logs in `validate` are always logged by
  the users of this method. `validateSchema` surfaces as
  `IllegalArgumentException` and can be logged at higher levels by the user.

Also: remove DEBUG logs from mcp-test module.

Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-05-27 11:50:48 +02:00
Dariusz Jędrzejczyk
c6d365c418
Unify logging config (#984)
Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-05-27 11:15:53 +02:00
Daniel Garnier-Moiroux
4f3f7d9fa4 Expose request URI in McpHttpClientAuthorizationErrorHandler
Breaking change

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-05-26 11:00:49 +02:00
Dariusz Jędrzejczyk
accba74c8f
feat: client-side application of elicitation schema defaults (SEP-1034) (#976)
Adds an opt-in McpClient builder option `applyElicitationDefaults(boolean)`
that, when enabled, fills missing keys of an accepted ElicitResult.content
with `default` values declared in the requestedSchema before returning the
result to the server. Mirrors the TypeScript SDK's applyElicitationDefaults
behavior, but exposed as a local client config rather than a wire capability.

Co-authored-by: Sainath Reddy Bobbala <bsnr@amazon.com>
Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-05-22 19:51:54 +02:00
Daniel Garnier-Moiroux
6b71136224
Release to maven central: do not run the tests twice (#977) 2026-05-21 17:14:51 +02:00
Daniel Garnier-Moiroux
fc330a5885 conformance-tests: upgrade to MCP-security 0.1.11, implement CIMD
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-05-21 14:41:14 +02:00
sAInath
d81430a532
feat: Add SEP-973 icons and metadata support (#912)
Add Icon record and icons field to Implementation, Resource,
ResourceTemplate, Prompt, and Tool records per SEP-973. Add
websiteUrl and description fields to Implementation.

All fields are optional and backward compatible. Existing
constructors and builders continue to work unchanged.
Icon.src is validated as required per the spec.
Icon.theme field supports light/dark theme variants.

Includes serialization, deserialization, round-trip, and backward
compatibility tests for all modified records.

Closes modelcontextprotocol#694

Co-authored-by: Sainath Reddy Bobbala <bsnr@amazon.com>
2026-05-19 12:40:26 +02:00
Daniel Garnier-Moiroux
c09ee67f60 Deprecate SSE transports
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-05-13 17:52:17 +02:00
Dariusz Jędrzejczyk
87e2c7d4de
feat: validate embedded JSON Schema documents against 2020-12 meta-schema (SEP-1613) (#949)
MCP embeds JSON Schema documents in three places — Tool.inputSchema,
Tool.outputSchema, and ElicitRequest.requestedSchema — and SEP-1613
mandates that these documents conform to JSON Schema 2020-12 by default.

Servers now reject malformed schemas at both build time (McpServer.build())
and runtime (McpAsyncServer/McpStatelessAsyncServer.addTool()), returning
an IllegalArgumentException that identifies the offending field and
references SEP-1613.  Elicitation requests whose requestedSchema violates
the meta-schema are rejected before being sent to the client.

Schemas that explicitly declare a different dialect via $schema are accepted
without meta-schema validation, since 2020-12 is the default, not the only
permitted dialect.

Refine meta-schema loading and deprecate orphan JsonSchemaValidator

Resolves #700

Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-05-07 14:14:53 +02:00
Dariusz Jędrzejczyk
5d4a1cce42
Revert removed builders for Resource and ResourceTemplate (#947)
Instead of fully breaking the API, this is a step
which depreactes the existing non-argument builder.

It allows the users to gradually migrate while preserving
the necessary checks.

Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
Co-authored-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-05-05 11:22:48 +02:00
Dariusz Jędrzejczyk
22a0efa577 feat!: enforce required MCP spec fields in McpSchema; lenient wire deserialization (#928)
Every wire-serialized record in McpSchema now validates spec-required
fields at construction time. Wire deserialization is intentionally
lenient: a missing required field is replaced with a documented default
and a WARN is logged, instead of failing the parse. A required-first
builder convention is introduced across the schema so it is no longer
possible to obtain a builder that is missing required state.

Required-field guards
---------------------
Every wire record's compact constructor asserts non-null (and non-empty
for String identifiers like name, uri, uriTemplate, version) on its
spec-required components. Passing null now throws
IllegalArgumentException at construction time instead of silently
producing invalid JSON via @JsonInclude(NON_ABSENT). This applies to
the JSON-RPC envelopes, lifecycle types, resource/prompt/tool requests
and results, sampling and elicitation, content records, root, complete,
logging and progress notifications, and the two CompleteReference
implementations. See MIGRATION-2.0.md for the full list.

Lenient wire deserialization
----------------------------
For each of those records (except JSONRPCResponse.JSONRPCError, which
still fails fast) a @JsonCreator static `fromJson` factory substitutes
a documented default for any absent required field — "" for strings,
[] for collections, {} for maps, 0 / 0.0 for numerics, INFO for
LoggingLevel, USER for SamplingMessage.role, ASSISTANT for
CreateMessageResult.role, CANCEL for ElicitResult.action, {values=[]}
for CompleteResult.completion — and logs a WARN naming the field and
the value used. Application code can still observe a malformed message
and react, but the SDK no longer halts the conversation.

Builder convention
------------------
Records that have a builder gain a required-first factory method
`builder(req1, req2, …)`; setters for required fields are removed from
the builder so it cannot be left in an invalid state. Existing no-arg
`builder()` factories and required-field setters are kept where source
compatibility demands it but are marked @Deprecated. New builders are
also added for several records that previously had none (ProgressNotification,
JSONRPCError, CompleteRequest, list/result types, content records, ...).

JSON-RPC envelope ergonomics
----------------------------
Previously every JSON-RPC envelope had to be constructed via the
canonical record constructor and the literal "2.0" string had to be
threaded through every call site, e.g.

    new JSONRPCRequest("2.0", "tools/call", id, params)
    new JSONRPCResponse("2.0", id, result, null)
    new JSONRPCResponse("2.0", id, null, new JSONRPCError(code, message, null))

Now:

    new JSONRPCRequest("tools/call", id, params)              // jsonrpc defaulted
    new JSONRPCNotification("notifications/initialized")       // params optional
    JSONRPCResponse.result(id, result)                        // factory
    JSONRPCResponse.error(id, new JSONRPCError(code, message)) // 2-arg error

JSONRPCResponse's compact constructor additionally enforces the
JSON-RPC invariant that exactly one of `result` / `error` is set —
previously the SDK could build envelopes that violated the protocol.

CompleteReference changes
-------------------------
- PromptReference.equals/hashCode now key on `name` only (previously
  derived from identifier()+type()). Two refs with the same name but
  different titles now compare equal — code using PromptReference as a
  map/set key should be audited.
- PromptReference's compact constructor pins `type` to "ref/prompt"
  and logs a WARN if the caller supplies a different non-null value.
  The legacy two-arg `PromptReference(String type, String name)`
  constructor remains @Deprecated.
- ResourceReference's record components are reduced from (type, uri)
  to (uri) — positional construction breaks. The legacy
  `ResourceReference(String type, String uri)` constructor stays
  @Deprecated and ignores `type`.
- CompleteReference.identifier() is @Deprecated and now returns null
  via a default method on the interface.

Tests / refactor
----------------
Conformance harness, integration tests, sample apps, and internal
callers were migrated to the new builder factories and convenience
constructors. No semantic changes to client/server runtime behaviour
beyond the McpSchema changes above.

Docs
----
- MIGRATION-2.0.md: required-field section now covers the broader
  record set and the lenient-deserialization behaviour; PromptReference
  WARN behaviour and ResourceReference component reduction are
  documented; the JSON-RPC envelope section is rewritten to compare the
  pre-2.0 surface with the new one.
- CONTRIBUTING.md: the "Evolving wire-serialized records" recipe is
  split into two cases — adding a new optional field (existing rules)
  and adding/maintaining a spec-required field (new rules covering
  Assert in compact constructor, @JsonCreator fromJson with defaults
  and WARN, required-first builder factory).

Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-05-04 21:01:46 +02:00
Daniel Garnier-Moiroux
599b43cac4 Fix assertions in HttpClientSseClientTransportTests 2026-05-04 15:35:48 +02:00