Java MCP server with Streamable HTTP, Netty transports, and stateless deployment Tachyon MCP, a Java 21 Model Context Protocol server built on Netty 4.2, has been released with full support for the MCP 2025-11-25 spec including Streamable HTTP transport, session lifecycle, native I/O transports, and a stateless mode for serverless deployments. The server implements JSON-RPC 2.0, pagination, CORS, DNS rebinding protection, and features like tools, resources, prompts, tasks, and logging with extensible handlers. Tachyon MCP — A Java 21 Model Context Protocol https://modelcontextprotocol.io MCP server built on Netty 4.2 https://netty.io . Fully implements MCP spec 2025-11-25 Streamable HTTP transport, session lifecycle, native I/O transports, and a stateless mode for serverless deployments. TL;DR python import dev.tachyonmcp.server.TachyonMcpServer; import dev.tachyonmcp.server.features.tools.AbstractSyncToolHandler; import dev.tachyonmcp.server.features.tools.ToolDescriptor; import dev.tachyonmcp.server.features.tools.ToolResult; import dev.tachyonmcp.server.session.McpContext; import tools.jackson.databind.node.JsonNodeFactory; void main { var schema = JsonNodeFactory.instance.objectNode ; schema.put "type", "object" ; schema.putObject "properties" .putObject "city" .put "type", "string" ; TachyonMcpServer.builder .name "weather-mcp" .tool new AbstractSyncToolHandler ToolDescriptor.builder "get forecast" .description "Get weather forecast" .inputSchema schema .build { @Override public Object handle McpContext ctx, Object args { return ToolResult.text "☀️ 22°C" ; } } .stateless true .port 8080 .bind ; } - JSON-RPC 2.0 — request/response/error/notification - Streamable HTTP — POST, GET SSE , DELETE, OPTIONS - Lifecycle — initialize → initialized → ACTIVE - Pagination — cursor-based across all list methods - Session state machine — INITIALIZING → ACTIVE → CLOSED - CORS & origin validation - DNS rebinding protection - Accept header strict validation 406 - Pending request timeout 60s - SSE resumability via Last-Event-ID tools/list — paginated with nextCursor tools/call — returns CallToolResult with isError outputSchema in listing annotations field execution.taskSupport forbidden/optional/required - Synchronous & asynchronous handler interfaces - Name validation 1–128 chars notifications/tools/list changed on add/remove- Inline notifications + logging during tool call - Input schema validation resources/list — paginated resources/read — text & blob content resources/templates/list — URI templates resources/subscribe / unsubscribe notifications/resources/list changed notifications/resources/updated to subscribers- Dynamic content via ResourceHandler interface prompts/list — paginated with nextCursor prompts/get — invokes prompt resolver notifications/prompts/list changed tasks/list , tasks/get , tasks/cancel , tasks/result - State machine enforcement — SUBMITTED → WORKING → COMPLETED/FAILED/CANCELLED notifications/tasks/status broadcast on every transition- Task Janitor for stale tasks execution.taskSupport per tool forbidden/optional/required TasksExtension SEP-1686 https://modelcontextprotocol.io/seps/1686-tasks — negotiable extension exposing create task tool + task://{id} resource template- Extension-gated tool visibility hidden from un-negotiated clients logging/setLevel per session notifications/message emitted above threshold- Progress notifications sampling/createMessage — server → client request- Elicitation — ✅ form mode; ❌ url mode notifications/cancelled — bidirectional notifications/tasks/status from client - Netty 4.2 - io uring / epoll / kqueue / nio auto-detection - Platform-thread event loops + virtual-thread handlers - TCP NODELAY, SO KEEPALIVE - Channel writability backpressure setAutoRead - Configurable idle timeouts reader/writer Stateless mode — skip sessions for serverless- IN MEMORY session store ConcurrentHashMap - Session Janitor — 5s sweep, 30s TTL - SSE disconnect ≠ session removal supports reconnect - Event log replay on reconnection Requirements : JDK 21+