Commit graph

550 commits

Author SHA1 Message Date
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
Daniel Garnier-Moiroux
bf30e21f0d DefaultSseMessageEndpointValidator allows same-origin message endpoints
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-05-04 13:54:03 +02:00
Daniel Garnier-Moiroux
563b1551a3 Validate message endpoint in SSE client transport
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-30 17:30:22 +02:00
Dariusz Jędrzejczyk
5895b2edd2
fix: Return empty prompt completion result when prompt has no arguments (#934)
Recent changes don't coerce null completion arguments to empty lists so we have
to check for null when handling prompt completions.

Resolves #932

Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-04-24 14:05:12 +02:00
Dariusz Jędrzejczyk
4c8596306d feat!: consistent JSON forward/backward compatibility - 2.0 foundation (#972)
The MCP specification evolves continuously; domain types must absorb
new fields and subtypes without breaking existing clients or servers.
On the 1.x line this is structurally prevented by sealed interfaces,
which make it impossible to add a permitted subtype without breaking
exhaustive pattern-match switch expressions in caller code. This
commit opens the 2.0 release line, where those constraints are lifted
and serialization is made self-contained — independent of any global
ObjectMapper configuration.

Breaking changes for users migrating from 1.x

- Sealed interfaces removed from JSONRPCMessage, Request, Result,
  Notification, ResourceContents, CompleteReference and Content.
  Exhaustive switch expressions over these types must add a default
  branch.
- Prompt(name, description, null) no longer silently coerces null
  arguments to an empty list. Use Prompt.withDefaults() to preserve
  the previous behaviour.
- CompleteCompletion.total and .hasMore are now absent from the wire
  when not set, rather than being emitted as null.
- ServerParameters no longer carries Jackson annotations; it is an
  internal configuration class, not a wire type.

What now works that did not before

- CompleteReference polymorphic dispatch (PromptReference vs
  ResourceReference) works through a plain readValue or convertValue
  call — no hand-rolled map inspection required.
- LoggingLevel deserialization is lenient: unknown level strings
  produce null instead of throwing.
- All domain records now tolerate unknown JSON fields, so a client
  built against an older SDK version will not fail when a newer server
  sends fields it does not yet recognise.
- Null optional fields are consistently absent from serialized output
  regardless of ObjectMapper configuration.

Documentation

- CONTRIBUTING adds an "Evolving wire-serialized records" section: a
  9-rule recipe and example for adding a field safely.
- MIGRATION-2.0 documents all breaking changes listed above.

Follow-up coming next

Several spec-required fields (e.g. JSONRPCError.code/message,
ProgressNotification.progress, CreateMessageRequest.maxTokens,
CallToolResult.content) are stored as nullable Java types without a
null guard. If constructed with null, the NON_ABSENT rule silently
omits them, producing invalid wire JSON without throwing. Fix: compact
canonical constructors with Assert.notNull, following the pattern
already in JSONRPCRequest.

Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
2026-04-23 17:34:55 +03:00
ashakirin
d1823389a9
feat!: add tool input arguments validation (#873)
added tool input arguments validation causes tool execution error. Breaking change, because validation is activated by default

closes #697

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-13 16:58:04 +02:00
Bilal Oumehdi
95203233c8
fix: Remove JsonSchema and use a Map for inputSchema to support json schemas dialect (#749)
* feat: remove JsonSchema an use a Map for inputSchema

- Fixes #886

Co-authored-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-10 11:32:22 +02:00
Daniel Garnier-Moiroux
fcdc0d4c14 Polish gh-906 2026-04-09 11:11:07 +02:00
smohite04
eaa0c691f0
feat: add support for meta parameter in client paginated list queries (#906)
* feat: add support for meta parameter in client paginated list queries#

- resources/list
- resources/templates/list
- prompts/list
- tools/list

paginated list operations extended in this review:
- listResources(String cursor, Map<String, Object> meta)
- listResourceTemplates(String cursor, Map<String, Object> meta)
- listPrompts(String cursor, Map<String, Object> meta)

Closes #907

Co-authored-by: SHEETAL MOHITE <mohishee@amazon.com>
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-09 10:40:35 +02:00
RameshReddy Adutla
8fd9903e62 Fix UTF-8 encoding for non-ASCII tool names in HTTP client transports
Both HttpClientSseClientTransport and HttpClientStreamableHttpTransport
set Content-Type to 'application/json' without specifying the charset.
While Java's BodyPublishers.ofString() uses UTF-8 by default, the
missing charset in the header can cause the server to interpret the
request body using a different encoding (e.g., ISO-8859-1), corrupting
non-ASCII characters such as Chinese tool names.

Explicitly set Content-Type to 'application/json; charset=utf-8' in
POST requests on both client transports.

Fixes #260

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Daniel Garnier-Moiroux <git@garnier.wf>
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-08 15:02:23 +02:00
Daniel Garnier-Moiroux
5e77762eeb HttpClientStreamableHttpTransport: handle HTTP 405
- Forward-port of #900

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-02 17:26:53 +02:00
Daniel Garnier-Moiroux
8c7774ad5f Server transports: remove deprecated methods from builder
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-02 15:50:57 +02:00
300:29:1
301dbe46ce
Deprecate Builder.customizeRequest() in favor of httpRequestCustomizer() (#791)
Deprecate Builder.customizeRequest() in HttpClientSseClientTransport and HttpClientStreamableHttpTransport

customizeRequest() executes its consumer once at build time, freezing
headers into the shared requestBuilder. This silently breaks OAuth
token refresh scenarios where the Authorization header needs to be
updated after the transport is built.

Add @Deprecated and update Javadoc to clarify the build-time-only
semantics and guide users toward httpRequestCustomizer() or
asyncHttpRequestCustomizer() which run on every request.

Closes #788

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-02 11:38:53 +02:00
Radesh Govind
cd2c21c1c8
docs: document best practice for handling argument errors in MCP tools (#891)
Resolves #356

Clarify the two-tier error model:
- Recoverable tool errors: use CallToolResult with isError(true)
- Protocol-level errors: throw McpError / let exceptions propagate as JSON-RPC errors

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-02 11:07:04 +02:00
Daniel Garnier-Moiroux
22e7bd4b56 conformance: update to mcp-security 0.1.5, pass scope-step-up
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-02 10:55:43 +02:00
matteoroxis
b6eb672c19 docs: add conformance summary to README
Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-04-02 10:54:27 +02:00
Sergei Semenov
3a7818201e
Fixed URL links from README.md to 'Java Dependencies', 'Java MCP Client', 'Java MCP Server' pages (#874) 2026-04-01 17:55:33 +02:00
Daniel Garnier-Moiroux
685b1899f9
Merge commit from fork 2026-03-27 18:19:47 +00:00
Christian Tzolov
cbb235fd32 Next development version
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
2026-03-13 13:31:03 +01:00
Christian Tzolov
c4b585795e
fix: prepare POMs for Maven Central release readiness (#863)
- Fix malformed SCM developerConnection URL (slash → colon) across all modules
- Add mcp-json-jackson3 to mcp-bom dependency management
- Update license URL to HTTPS
- Fix POM's scm definitions

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



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

---------

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
2026-03-13 12:41:49 +01:00
Daniel Garnier-Moiroux
abcd19c0c2
HttpClientStreamHttpTransport: add authorization error handler (#861)
HttpClientStreamHttpTransport: add authorization error handler

- Closes #240

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
2026-03-13 10:12:57 +01:00