# mcp-sdk-plain Companion code for *Write an MCP Server with the Plain MCP Java SDK (No Spring): stdio and Streamable HTTP* on [ankurm.com](https://ankurm.com). One tool/resource set, two transports, one fat jar. No Spring in the server. ```bash mvn -pl mcp-sdk-plain package # runs the tests (rewrites output/01-04) and builds target/mcp-sdk-plain.jar java -jar mcp-sdk-plain/target/mcp-sdk-plain.jar stdio # for Claude Desktop java -jar mcp-sdk-plain/target/mcp-sdk-plain.jar http 8080 # Streamable HTTP on http://127.0.0.1:8080/mcp bash mcp-sdk-plain/scripts/run-all.sh # regenerates output/01-06 bash mcp-sdk-plain/examples/spring-ai-client/run.sh # output/07, after package ``` | File | Role | |---|---| | `NoteTools` | Three tools: a happy path, a domain error returned as `isError`, and a handler that throws | | `NoteResources` | A fixed resource (`notes://readme`) and a resource template (`notes://{name}`) | | `PlainMcpServer` | Server name, capabilities, tools and resources, shared by both transports | | `Main` | `stdio` or `http [port]`; stdout is left to the protocol, logs go to stderr | | `HttpMain` | The SDK's Streamable HTTP servlet inside an embedded Jetty 12.1 (ee11) | | `StdioTest`, `HttpTest`, `NoisyStdoutTest` | Each writes an `output/NN-*.txt` transcript and asserts the same facts | | `scripts/raw-stdio.sh`, `scripts/curl-http.sh` | Drive the packaged jar with raw JSON-RPC and with curl (`output/05`, `06`) | | `examples/spring-ai-client` | A standalone Spring Boot 4.1.2 + Spring AI 2.0.2 client that connects to the HTTP server (`output/07`) | Verified against `io.modelcontextprotocol.sdk:mcp` **2.1.0**, Jetty **12.1.14**, JDK 25, JUnit 6.1.3.