| Filename | Latest commit message | Latest commit date |
|---|---|---|
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>
|
||
| .. | ||
| src/main | ||
| pom.xml | ||
| README.md | ||
MCP Conformance Tests - Servlet Server
This module contains a comprehensive MCP (Model Context Protocol) server implementation for conformance testing using the servlet stack with an embedded Tomcat server and streamable HTTP transport.
Conformance Test Results
Status: 40 out of 40 tests passing (100%)
The server has been validated against the official MCP conformance test suite. See VALIDATION_RESULTS.md for detailed results.
What's Implemented
✅ Lifecycle & Utilities (4/4)
- Server initialization, ping, logging, completion
✅ Tools (11/11)
- Text, image, audio, embedded resources, mixed content
- Logging, error handling, sampling, elicitation
- Progress notifications
✅ Elicitation (10/10)
- SEP-1034: Default values for all primitive types
- SEP-1330: All enum schema variants
✅ Resources (6/6)
- List, read text/binary, templates, subscribe, unsubscribe
✅ Prompts (4/4)
- Simple, parameterized, embedded resources, images
✅ SSE Transport (2/2)
- Multiple streams support
✅ Security (2/2)
- ✅ DNS rebinding protection
Features
- Embedded Tomcat servlet container
- MCP server using HttpServletStreamableServerTransportProvider
- Comprehensive test coverage with 15+ tools
- Streamable HTTP transport with SSE on
/mcpendpoint - Support for all MCP content types (text, image, audio, resources)
- Advanced features: sampling, elicitation, progress (partial), completion
Running the Server
To run the conformance server:
cd conformance-tests/server-servlet
../../mvnw compile exec:java -Dexec.mainClass="io.modelcontextprotocol.conformance.server.ConformanceServlet"
Or from the root directory:
./mvnw compile exec:java -pl conformance-tests/server-servlet -Dexec.mainClass="io.modelcontextprotocol.conformance.server.ConformanceServlet"
The server will start on port 8080 with the MCP endpoint at /mcp.
Running Conformance Tests
Once the server is running, you can validate it against the official MCP conformance test suite using npx:
Run Full Active Test Suite
npx @modelcontextprotocol/conformance server --url http://localhost:8080/mcp --suite active
Run Specific Scenarios
# Test tools
npx @modelcontextprotocol/conformance server --url http://localhost:8080/mcp --scenario tools-list --verbose
# Test prompts
npx @modelcontextprotocol/conformance server --url http://localhost:8080/mcp --scenario prompts-list --verbose
# Test resources
npx @modelcontextprotocol/conformance server --url http://localhost:8080/mcp --scenario resources-read-text --verbose
# Test elicitation with defaults
npx @modelcontextprotocol/conformance server --url http://localhost:8080/mcp --scenario elicitation-sep1034-defaults --verbose
Available Test Suites
active(default) - All active/stable tests (30 scenarios)all- All tests including pending/experimentalpending- Only pending/experimental tests
Common Scenarios
Lifecycle & Utilities:
server-initialize- Server initializationping- Ping utilitylogging-set-level- Logging configurationcompletion-complete- Argument completion
Tools:
tools-list- List available toolstools-call-simple-text- Simple text responsetools-call-image- Image contenttools-call-audio- Audio contenttools-call-with-logging- Logging during executiontools-call-with-progress- Progress notificationstools-call-sampling- LLM samplingtools-call-elicitation- User input requests
Resources:
resources-list- List resourcesresources-read-text- Read text resourceresources-read-binary- Read binary resourceresources-templates-read- Resource templatesresources-subscribe- Subscribe to resource updatesresources-unsubscribe- Unsubscribe from updates
Prompts:
prompts-list- List promptsprompts-get-simple- Simple promptprompts-get-with-args- Parameterized promptprompts-get-embedded-resource- Prompt with resourceprompts-get-with-image- Prompt with image
Elicitation:
elicitation-sep1034-defaults- Default values (SEP-1034)elicitation-sep1330-enums- Enum schemas (SEP-1330)
Testing with curl
You can also test the endpoint manually:
# Check endpoint (will show SSE requirement)
curl -X GET http://localhost:8080/mcp
# Initialize session with proper headers
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-H "mcp-session-id: test-session-123" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}}}'
Architecture
- Transport: HttpServletStreamableServerTransportProvider (streamable HTTP with SSE)
- Container: Embedded Apache Tomcat
- Protocol: Streamable HTTP with Server-Sent Events
- Port: 8080 (default)
- Endpoint:
/mcp - Request Timeout: 30 seconds
Implemented Tools
Content Type Tools
test_simple_text- Returns simple text contenttest_image_content- Returns a minimal PNG image (1x1 red pixel)test_audio_content- Returns a minimal WAV audio filetest_embedded_resource- Returns embedded resource contenttest_multiple_content_types- Returns mixed text, image, and resource content
Behavior Tools
test_tool_with_logging- Sends log notifications during executiontest_error_handling- Intentionally returns an error for testingtest_tool_with_progress- Reports progress notifications (⚠️ SDK issue)
Interactive Tools
test_sampling- Requests LLM sampling from clienttest_elicitation- Requests user input from clienttest_elicitation_sep1034_defaults- Elicitation with default values (SEP-1034)test_elicitation_sep1330_enums- Elicitation with enum schemas (SEP-1330)
Implemented Prompts
test_simple_prompt- Simple prompt without argumentstest_prompt_with_arguments- Prompt with required arguments (arg1, arg2)test_prompt_with_embedded_resource- Prompt with embedded resource contenttest_prompt_with_image- Prompt with image content
Implemented Resources
test://static-text- Static text resourcetest://static-binary- Static binary resource (PNG image)test://watched-resource- Resource that can be subscribed totest://template/{id}/data- Resource template with parameter substitution
Known Limitations
See VALIDATION_RESULTS.md for details on remaining client-side limitations.