[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ADR98NWYD2S44DH0HG6WKX":3,"skill-same:01M6ADR98NWYD2S44DH0HG6WKX":100},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":54,"linkOnly":55,"markdownContent":56,"markdownBody":57,"frontMatter":58,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":65,"ownerHtmlUrl":66,"ownerBlogUrl":67,"ownerDescription":68,"updatedAt":69,"install":70,"resources":83},"01M6ADR98NWYD2S44DH0HG6WKX","java-mcp-server-generator",null,"Use this skill when the user wants to create a Model Context Protocol (MCP) server in Java or in a Spring Boot app. Also use it when the user wants AI agents, such as GitHub Copilot or Claude, to use Java code, an API, or a database. Use it even if the user does not say \"MCP\". The skill makes a Maven or Gradle project with the MCP Java SDK 2.x, tools, JUnit tests, and client configuration. Do not use it for Quarkus\u002FQuarkiverse MCP servers (use the `quarkus-mcp-server-sse` instruction), for an MCP client or for a server in another language.","github\u002Fawesome-copilot","github","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F9919?v=4","01M6AC83DS133TPXFSP1DHNCC6","GitHub","01M6AD3PBDYPK7NVFJNJ66Y8RS",41162,"MIT","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fjava-mcp-server-generator\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,9],"generator","mcp server","java mcp server generator","server","MCP","java","database","when","app","gradle","project","model","access","api","network","spring boot","mcp servers","mcp client","protocol","code","create","boot","copilot","github copilot","model context protocol","sdk","ai agents","2026-11-10 10:12:30",false,"---\nname: java-mcp-server-generator\ndescription: 'Use this skill when the user wants to create a Model Context Protocol (MCP) server in Java or in a Spring Boot app. Also use it when the user wants AI agents, such as GitHub Copilot or Claude, to use Java code, an API, or a database. Use it even if the user does not say \"MCP\". The skill makes a Maven or Gradle project with the MCP Java SDK 2.x, tools, JUnit tests, and client configuration. Do not use it for Quarkus\u002FQuarkiverse MCP servers (use the `quarkus-mcp-server-sse` instruction), for an MCP client or for a server in another language.'\ncompatibility: 'JDK 17 or later, Maven 3.9 or later or Gradle 9 or later, and network access to download dependencies. The MCP Inspector also uses Node.js.'\n---\n\n# Java MCP Server Generator\n\nCreate a Model Context Protocol (MCP) server in Java with the official [MCP Java SDK](https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fjava-sdk) 2.x. SDK 2.0.x supports the MCP specification revision [2025-11-25](https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2025-11-25) and the earlier revisions. SDK 3.x will add the revision [2026-07-28](https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2026-07-28).\n\n## Workflow\n\nCopy this checklist and track your progress:\n\n- [ ] Step 1: Create the project.\n- [ ] Step 2: Write the server.\n- [ ] Step 3: Write the tests.\n- [ ] Step 4: Build until the tests pass.\n- [ ] Step 5: Configure the client.\n\n### Step 1: Create the project\n\nUse Maven by default. If the project uses Gradle or the user asks for Gradle, read [references\u002Fgradle.md](references\u002Fgradle.md). Use it for Step 1, Step 4, and Step 5.\n\nMake this layout:\n\n```text\nproject-name\u002F\n├── pom.xml\n└── src\u002F\n    ├── main\u002Fjava\u002Fcom\u002Fexample\u002FMcpServerApp.java\n    └── test\u002Fjava\u002Fcom\u002Fexample\u002FMcpServerAppTest.java\n```\n\nWrite `pom.xml`:\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003Cproject xmlns=\"http:\u002F\u002Fmaven.apache.org\u002FPOM\u002F4.0.0\"\n         xmlns:xsi=\"http:\u002F\u002Fwww.w3.org\u002F2001\u002FXMLSchema-instance\"\n         xsi:schemaLocation=\"http:\u002F\u002Fmaven.apache.org\u002FPOM\u002F4.0.0 https:\u002F\u002Fmaven.apache.org\u002Fxsd\u002Fmaven-4.0.0.xsd\">\n  \u003CmodelVersion>4.0.0\u003C\u002FmodelVersion>\n\n  \u003CgroupId>com.example\u003C\u002FgroupId>\n  \u003CartifactId>mcp-server-demo\u003C\u002FartifactId>\n  \u003Cversion>0.1.0\u003C\u002Fversion>\n\n  \u003Cproperties>\n    \u003Cmaven.compiler.release>17\u003C\u002Fmaven.compiler.release>\n    \u003Cproject.build.sourceEncoding>UTF-8\u003C\u002Fproject.build.sourceEncoding>\n  \u003C\u002Fproperties>\n\n  \u003CdependencyManagement>\n    \u003Cdependencies>\n      \u003Cdependency>\n        \u003CgroupId>io.modelcontextprotocol.sdk\u003C\u002FgroupId>\n        \u003CartifactId>mcp-bom\u003C\u002FartifactId>\n        \u003Cversion>2.0.1\u003C\u002Fversion>\n        \u003Ctype>pom\u003C\u002Ftype>\n        \u003Cscope>import\u003C\u002Fscope>\n      \u003C\u002Fdependency>\n      \u003Cdependency>\n        \u003CgroupId>org.junit\u003C\u002FgroupId>\n        \u003CartifactId>junit-bom\u003C\u002FartifactId>\n        \u003Cversion>6.1.3\u003C\u002Fversion>\n        \u003Ctype>pom\u003C\u002Ftype>\n        \u003Cscope>import\u003C\u002Fscope>\n      \u003C\u002Fdependency>\n    \u003C\u002Fdependencies>\n  \u003C\u002FdependencyManagement>\n\n  \u003Cdependencies>\n    \u003Cdependency>\n      \u003CgroupId>io.modelcontextprotocol.sdk\u003C\u002FgroupId>\n      \u003CartifactId>mcp\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n      \u003CgroupId>org.slf4j\u003C\u002FgroupId>\n      \u003CartifactId>slf4j-simple\u003C\u002FartifactId>\n      \u003Cversion>2.0.17\u003C\u002Fversion>\n      \u003Cscope>runtime\u003C\u002Fscope>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n      \u003CgroupId>org.junit.jupiter\u003C\u002FgroupId>\n      \u003CartifactId>junit-jupiter\u003C\u002FartifactId>\n      \u003Cscope>test\u003C\u002Fscope>\n    \u003C\u002Fdependency>\n  \u003C\u002Fdependencies>\n\n  \u003Cbuild>\n    \u003Cplugins>\n      \u003Cplugin>\n        \u003CgroupId>org.apache.maven.plugins\u003C\u002FgroupId>\n        \u003CartifactId>maven-shade-plugin\u003C\u002FartifactId>\n        \u003Cversion>3.6.2\u003C\u002Fversion>\n        \u003Cexecutions>\n          \u003Cexecution>\n            \u003Cphase>package\u003C\u002Fphase>\n            \u003Cgoals>\n              \u003Cgoal>shade\u003C\u002Fgoal>\n            \u003C\u002Fgoals>\n            \u003Cconfiguration>\n              \u003CcreateDependencyReducedPom>false\u003C\u002FcreateDependencyReducedPom>\n              \u003Ctransformers>\n                \u003Ctransformer implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\">\n                  \u003CmainClass>com.example.McpServerApp\u003C\u002FmainClass>\n                \u003C\u002Ftransformer>\n              \u003C\u002Ftransformers>\n            \u003C\u002Fconfiguration>\n          \u003C\u002Fexecution>\n        \u003C\u002Fexecutions>\n      \u003C\u002Fplugin>\n    \u003C\u002Fplugins>\n  \u003C\u002Fbuild>\n\u003C\u002Fproject>\n```\n\n- The `mcp` artifact contains `mcp-core` and the Jackson 3 JSON mapper `mcp-json-jackson3`.\n- `slf4j-simple` writes the SDK logs to stderr.\n- The shade plugin makes one executable JAR with all dependencies.\n\n### Step 2: Write the server\n\nStart from this template:\n\n```java\npackage com.example;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport io.modelcontextprotocol.json.McpJsonDefaults;\nimport io.modelcontextprotocol.server.McpServer;\nimport io.modelcontextprotocol.server.McpServerFeatures.SyncToolSpecification;\nimport io.modelcontextprotocol.server.transport.StdioServerTransportProvider;\nimport io.modelcontextprotocol.spec.McpSchema.CallToolResult;\nimport io.modelcontextprotocol.spec.McpSchema.ServerCapabilities;\nimport io.modelcontextprotocol.spec.McpSchema.Tool;\n\npublic final class McpServerApp {\n\n    static SyncToolSpecification divideTool() {\n        Tool tool = Tool.builder(\"divide\", Map.of(\n                        \"type\", \"object\",\n                        \"properties\", Map.of(\n                                \"a\", Map.of(\"type\", \"number\", \"description\", \"Dividend\"),\n                                \"b\", Map.of(\"type\", \"number\", \"description\", \"Divisor\")),\n                        \"required\", List.of(\"a\", \"b\")))\n                .description(\"Divide a by b.\")\n                .build();\n\n        return SyncToolSpecification.builder()\n                .tool(tool)\n                .callHandler((exchange, request) -> {\n                    double a = ((Number) request.arguments().get(\"a\")).doubleValue();\n                    double b = ((Number) request.arguments().get(\"b\")).doubleValue();\n                    if (b == 0) {\n                        return CallToolResult.builder().addTextContent(\"b must not be zero.\").isError(true).build();\n                    }\n                    return CallToolResult.builder().addTextContent(String.valueOf(a \u002F b)).build();\n                })\n                .build();\n    }\n\n    public static void main(String[] args) {\n        McpServer.sync(new StdioServerTransportProvider(McpJsonDefaults.getMapper()))\n                .serverInfo(\"demo\", \"0.1.0\")\n                .capabilities(ServerCapabilities.builder().tools(false).build())\n                .tools(divideTool())\n                .build();\n    }\n}\n```\n\nThen change the template to match the request of the user:\n\n1. Replace `divideTool()` with the tools that the user asks for. Make one method for each tool.\n2. Give each tool a JSON Schema `inputSchema` and a `description`. The description tells the model when to use the tool.\n3. When the client must get machine-readable data, add `.outputSchema(Map)` to the tool. Return the data with `CallToolResult.builder().structuredContent(map)`. Also add the same data as text content for older clients.\n4. Mark a read-only tool with `.annotations(ToolAnnotations.builder().readOnlyHint(true).build())`. Use `destructiveHint(true)` for a destructive tool.\n5. Add resources, resource templates, and prompts only when the user asks for them. Also enable them in `ServerCapabilities`.\n\nUse stdio by default. Read [references\u002Fstreamable-http.md](references\u002Fstreamable-http.md) only when the user asks for a remote server, an HTTP server, or Spring Boot.\n\n### Step 3: Write the tests\n\nThe test starts the server as a subprocess and connects to it with the SDK client. Write a test for each tool and for each error result:\n\n```java\npackage com.example;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\nimport java.nio.file.Path;\nimport java.util.Map;\n\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\n\nimport io.modelcontextprotocol.client.McpClient;\nimport io.modelcontextprotocol.client.McpSyncClient;\nimport io.modelcontextprotocol.client.transport.ServerParameters;\nimport io.modelcontextprotocol.client.transport.StdioClientTransport;\nimport io.modelcontextprotocol.json.McpJsonDefaults;\nimport io.modelcontextprotocol.spec.McpSchema.CallToolRequest;\nimport io.modelcontextprotocol.spec.McpSchema.CallToolResult;\nimport io.modelcontextprotocol.spec.McpSchema.TextContent;\n\nclass McpServerAppTest {\n\n    private static McpSyncClient client;\n\n    @BeforeAll\n    static void startServer() {\n        String java = Path.of(System.getProperty(\"java.home\"), \"bin\", \"java\").toString();\n        ServerParameters server = ServerParameters.builder(java)\n                .args(\"-cp\", System.getProperty(\"java.class.path\"), McpServerApp.class.getName())\n                .build();\n        client = McpClient.sync(new StdioClientTransport(server, McpJsonDefaults.getMapper())).build();\n        client.initialize();\n    }\n\n    @AfterAll\n    static void stopServer() {\n        client.close();\n    }\n\n    @Test\n    void divide() {\n        CallToolResult result = client.callTool(\n                CallToolRequest.builder(\"divide\").arguments(Map.of(\"a\", 6, \"b\", 3)).build());\n        assertEquals(\"2.0\", ((TextContent) result.content().get(0)).text());\n    }\n\n    @Test\n    void divideByZero() {\n        CallToolResult result = client.callTool(\n                CallToolRequest.builder(\"divide\").arguments(Map.of(\"a\", 1, \"b\", 0)).build());\n        assertTrue(result.isError());\n        assertTrue(((TextContent) result.content().get(0)).text().contains(\"must not be zero\"));\n    }\n}\n```\n\n- The test uses the `java` command of the JDK that runs Maven. Do not use the `java` command from `PATH`.\n- The test uses the real stdio transport and the real JSON-RPC messages.\n\n### Step 4: Build until the tests pass\n\n1. Run `mvn verify`. This command compiles the code, runs the tests, and makes `target\u002Fmcp-server-demo-0.1.0.jar`.\n2. If a test fails, read the error. Fix the server or the test.\n3. Run `mvn verify` again.\n4. Continue only when the build is successful.\n\n### Step 5: Configure the client\n\nFor VS Code, write `.vscode\u002Fmcp.json`:\n\n```json\n{\n  \"servers\": {\n    \"demo\": {\n      \"type\": \"stdio\",\n      \"command\": \"java\",\n      \"args\": [\"-jar\", \"\u002Fabsolute\u002Fpath\u002Fto\u002Fproject\u002Ftarget\u002Fmcp-server-demo-0.1.0.jar\"]\n    }\n  }\n}\n```\n\nFor Claude Desktop, put the same `command` and `args` in `claude_desktop_config.json`, below the `mcpServers` key.\n\nFor an HTTP server, use the client configuration in [references\u002Fstreamable-http.md](references\u002Fstreamable-http.md).\n\nTell the user these facts:\n\n- `java -jar target\u002Fmcp-server-demo-0.1.0.jar` starts the stdio server. The server waits for a host on stdin. The SDK logs go to stderr.\n- To test the server manually, start the MCP Inspector with the same command. The Inspector uses Node.js.\n\n## Gotchas\n\nSDK 2.x changed many patterns of SDK 0.x and 1.x. Do not copy examples from earlier versions. Read the [migration guide](https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fjava-sdk\u002Fblob\u002Fmain\u002FMIGRATION-2.0.md) for the full list.\n\n- Use the builders that take the required fields first: `Tool.builder(name, inputSchema)`, `Resource.builder(uri, name)`, `Prompt.builder(name)`, `TextContent.builder(text)`, and `ReadResourceResult.builder(contents)`. The builders without arguments are deprecated.\n- A required field must not be `null`. A `null` value causes an `IllegalArgumentException`.\n- Tool names must have 1 to 128 characters: letters, digits, `_`, `-`, and `.`. The server builder rejects an incorrect name with an `IllegalArgumentException`. `addTool()` at runtime does not check the name.\n- `inputSchema` and `outputSchema` are `Map\u003CString, Object>` values. The `JsonSchema` record is deprecated.\n- The server checks each schema against JSON Schema 2020-12 when you call `build()` or `addTool()`. An incorrect schema causes an `IllegalArgumentException`.\n- The SDK validates the tool arguments against `inputSchema`. It also validates `structuredContent` against `outputSchema`. If the validation fails, the client gets a tool result with `isError` set to `true`. Thus, the handler gets only valid arguments.\n- If a tool has an `outputSchema`, return `structuredContent` in each successful result. Without it, the SDK returns a tool result with `isError` set to `true`.\n- Return `CallToolResult` with `isError(true)` for an error that the model must read.\n- Do not throw an exception or an `McpError` for a tool failure. The client gets a JSON-RPC error, not a tool result. Many hosts do not show this error to the model.\n- In a stdio server, stdout is the protocol channel. Do not call `System.out.println()`.\n- Log with SLF4J to stderr. The default console appender of Logback writes to stdout. If you use Logback, set its target to `System.err`.\n- The Spring transports moved to [Spring AI](https:\u002F\u002Fdocs.spring.io\u002Fspring-ai\u002Freference\u002Fapi\u002Fmcp\u002Fmcp-overview.html) 2.0 and later (group `org.springframework.ai`). Do not use the `io.modelcontextprotocol.sdk:mcp-spring-*` artifacts.\n- Do not use the deprecated SSE transports. Use Streamable HTTP for a remote server.\n- The revision 2026-07-28 deprecates these features ([SEP-2577](https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fmodelcontextprotocol\u002Fpull\u002F2577)). Do not add them to a new server:\n  - **Sampling** (`exchange.createMessage()`): Call the LLM provider API directly.\n  - **Protocol logging** (`exchange.loggingNotification()`): Use SLF4J.\n  - **Roots** (`exchange.listRoots()`): Get paths from tool arguments, resource URIs, or the server configuration.\n","# Java MCP Server Generator\n\nCreate a Model Context Protocol (MCP) server in Java with the official [MCP Java SDK](https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fjava-sdk) 2.x. SDK 2.0.x supports the MCP specification revision [2025-11-25](https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2025-11-25) and the earlier revisions. SDK 3.x will add the revision [2026-07-28](https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2026-07-28).\n\n## Workflow\n\nCopy this checklist and track your progress:\n\n- [ ] Step 1: Create the project.\n- [ ] Step 2: Write the server.\n- [ ] Step 3: Write the tests.\n- [ ] Step 4: Build until the tests pass.\n- [ ] Step 5: Configure the client.\n\n### Step 1: Create the project\n\nUse Maven by default. If the project uses Gradle or the user asks for Gradle, read [references\u002Fgradle.md](references\u002Fgradle.md). Use it for Step 1, Step 4, and Step 5.\n\nMake this layout:\n\n```text\nproject-name\u002F\n├── pom.xml\n└── src\u002F\n    ├── main\u002Fjava\u002Fcom\u002Fexample\u002FMcpServerApp.java\n    └── test\u002Fjava\u002Fcom\u002Fexample\u002FMcpServerAppTest.java\n```\n\nWrite `pom.xml`:\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003Cproject xmlns=\"http:\u002F\u002Fmaven.apache.org\u002FPOM\u002F4.0.0\"\n         xmlns:xsi=\"http:\u002F\u002Fwww.w3.org\u002F2001\u002FXMLSchema-instance\"\n         xsi:schemaLocation=\"http:\u002F\u002Fmaven.apache.org\u002FPOM\u002F4.0.0 https:\u002F\u002Fmaven.apache.org\u002Fxsd\u002Fmaven-4.0.0.xsd\">\n  \u003CmodelVersion>4.0.0\u003C\u002FmodelVersion>\n\n  \u003CgroupId>com.example\u003C\u002FgroupId>\n  \u003CartifactId>mcp-server-demo\u003C\u002FartifactId>\n  \u003Cversion>0.1.0\u003C\u002Fversion>\n\n  \u003Cproperties>\n    \u003Cmaven.compiler.release>17\u003C\u002Fmaven.compiler.release>\n    \u003Cproject.build.sourceEncoding>UTF-8\u003C\u002Fproject.build.sourceEncoding>\n  \u003C\u002Fproperties>\n\n  \u003CdependencyManagement>\n    \u003Cdependencies>\n      \u003Cdependency>\n        \u003CgroupId>io.modelcontextprotocol.sdk\u003C\u002FgroupId>\n        \u003CartifactId>mcp-bom\u003C\u002FartifactId>\n        \u003Cversion>2.0.1\u003C\u002Fversion>\n        \u003Ctype>pom\u003C\u002Ftype>\n        \u003Cscope>import\u003C\u002Fscope>\n      \u003C\u002Fdependency>\n      \u003Cdependency>\n        \u003CgroupId>org.junit\u003C\u002FgroupId>\n        \u003CartifactId>junit-bom\u003C\u002FartifactId>\n        \u003Cversion>6.1.3\u003C\u002Fversion>\n        \u003Ctype>pom\u003C\u002Ftype>\n        \u003Cscope>import\u003C\u002Fscope>\n      \u003C\u002Fdependency>\n    \u003C\u002Fdependencies>\n  \u003C\u002FdependencyManagement>\n\n  \u003Cdependencies>\n    \u003Cdependency>\n      \u003CgroupId>io.modelcontextprotocol.sdk\u003C\u002FgroupId>\n      \u003CartifactId>mcp\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n      \u003CgroupId>org.slf4j\u003C\u002FgroupId>\n      \u003CartifactId>slf4j-simple\u003C\u002FartifactId>\n      \u003Cversion>2.0.17\u003C\u002Fversion>\n      \u003Cscope>runtime\u003C\u002Fscope>\n    \u003C\u002Fdependency>\n    \u003Cdependency>\n      \u003CgroupId>org.junit.jupiter\u003C\u002FgroupId>\n      \u003CartifactId>junit-jupiter\u003C\u002FartifactId>\n      \u003Cscope>test\u003C\u002Fscope>\n    \u003C\u002Fdependency>\n  \u003C\u002Fdependencies>\n\n  \u003Cbuild>\n    \u003Cplugins>\n      \u003Cplugin>\n        \u003CgroupId>org.apache.maven.plugins\u003C\u002FgroupId>\n        \u003CartifactId>maven-shade-plugin\u003C\u002FartifactId>\n        \u003Cversion>3.6.2\u003C\u002Fversion>\n        \u003Cexecutions>\n          \u003Cexecution>\n            \u003Cphase>package\u003C\u002Fphase>\n            \u003Cgoals>\n              \u003Cgoal>shade\u003C\u002Fgoal>\n            \u003C\u002Fgoals>\n            \u003Cconfiguration>\n              \u003CcreateDependencyReducedPom>false\u003C\u002FcreateDependencyReducedPom>\n              \u003Ctransformers>\n                \u003Ctransformer implementation=\"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer\">\n                  \u003CmainClass>com.example.McpServerApp\u003C\u002FmainClass>\n                \u003C\u002Ftransformer>\n              \u003C\u002Ftransformers>\n            \u003C\u002Fconfiguration>\n          \u003C\u002Fexecution>\n        \u003C\u002Fexecutions>\n      \u003C\u002Fplugin>\n    \u003C\u002Fplugins>\n  \u003C\u002Fbuild>\n\u003C\u002Fproject>\n```\n\n- The `mcp` artifact contains `mcp-core` and the Jackson 3 JSON mapper `mcp-json-jackson3`.\n- `slf4j-simple` writes the SDK logs to stderr.\n- The shade plugin makes one executable JAR with all dependencies.\n\n### Step 2: Write the server\n\nStart from this template:\n\n```java\npackage com.example;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport io.modelcontextprotocol.json.McpJsonDefaults;\nimport io.modelcontextprotocol.server.McpServer;\nimport io.modelcontextprotocol.server.McpServerFeatures.SyncToolSpecification;\nimport io.modelcontextprotocol.server.transport.StdioServerTransportProvider;\nimport io.modelcontextprotocol.spec.McpSchema.CallToolResult;\nimport io.modelcontextprotocol.spec.McpSchema.ServerCapabilities;\nimport io.modelcontextprotocol.spec.McpSchema.Tool;\n\npublic final class McpServerApp {\n\n    static SyncToolSpecification divideTool() {\n        Tool tool = Tool.builder(\"divide\", Map.of(\n                        \"type\", \"object\",\n                        \"properties\", Map.of(\n                                \"a\", Map.of(\"type\", \"number\", \"description\", \"Dividend\"),\n                                \"b\", Map.of(\"type\", \"number\", \"description\", \"Divisor\")),\n                        \"required\", List.of(\"a\", \"b\")))\n                .description(\"Divide a by b.\")\n                .build();\n\n        return SyncToolSpecification.builder()\n                .tool(tool)\n                .callHandler((exchange, request) -> {\n                    double a = ((Number) request.arguments().get(\"a\")).doubleValue();\n                    double b = ((Number) request.arguments().get(\"b\")).doubleValue();\n                    if (b == 0) {\n                        return CallToolResult.builder().addTextContent(\"b must not be zero.\").isError(true).build();\n                    }\n                    return CallToolResult.builder().addTextContent(String.valueOf(a \u002F b)).build();\n                })\n                .build();\n    }\n\n    public static void main(String[] args) {\n        McpServer.sync(new StdioServerTransportProvider(McpJsonDefaults.getMapper()))\n                .serverInfo(\"demo\", \"0.1.0\")\n                .capabilities(ServerCapabilities.builder().tools(false).build())\n                .tools(divideTool())\n                .build();\n    }\n}\n```\n\nThen change the template to match the request of the user:\n\n1. Replace `divideTool()` with the tools that the user asks for. Make one method for each tool.\n2. Give each tool a JSON Schema `inputSchema` and a `description`. The description tells the model when to use the tool.\n3. When the client must get machine-readable data, add `.outputSchema(Map)` to the tool. Return the data with `CallToolResult.builder().structuredContent(map)`. Also add the same data as text content for older clients.\n4. Mark a read-only tool with `.annotations(ToolAnnotations.builder().readOnlyHint(true).build())`. Use `destructiveHint(true)` for a destructive tool.\n5. Add resources, resource templates, and prompts only when the user asks for them. Also enable them in `ServerCapabilities`.\n\nUse stdio by default. Read [references\u002Fstreamable-http.md](references\u002Fstreamable-http.md) only when the user asks for a remote server, an HTTP server, or Spring Boot.\n\n### Step 3: Write the tests\n\nThe test starts the server as a subprocess and connects to it with the SDK client. Write a test for each tool and for each error result:\n\n```java\npackage com.example;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\nimport static org.junit.jupiter.api.Assertions.assertTrue;\n\nimport java.nio.file.Path;\nimport java.util.Map;\n\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\n\nimport io.modelcontextprotocol.client.McpClient;\nimport io.modelcontextprotocol.client.McpSyncClient;\nimport io.modelcontextprotocol.client.transport.ServerParameters;\nimport io.modelcontextprotocol.client.transport.StdioClientTransport;\nimport io.modelcontextprotocol.json.McpJsonDefaults;\nimport io.modelcontextprotocol.spec.McpSchema.CallToolRequest;\nimport io.modelcontextprotocol.spec.McpSchema.CallToolResult;\nimport io.modelcontextprotocol.spec.McpSchema.TextContent;\n\nclass McpServerAppTest {\n\n    private static McpSyncClient client;\n\n    @BeforeAll\n    static void startServer() {\n        String java = Path.of(System.getProperty(\"java.home\"), \"bin\", \"java\").toString();\n        ServerParameters server = ServerParameters.builder(java)\n                .args(\"-cp\", System.getProperty(\"java.class.path\"), McpServerApp.class.getName())\n                .build();\n        client = McpClient.sync(new StdioClientTransport(server, McpJsonDefaults.getMapper())).build();\n        client.initialize();\n    }\n\n    @AfterAll\n    static void stopServer() {\n        client.close();\n    }\n\n    @Test\n    void divide() {\n        CallToolResult result = client.callTool(\n                CallToolRequest.builder(\"divide\").arguments(Map.of(\"a\", 6, \"b\", 3)).build());\n        assertEquals(\"2.0\", ((TextContent) result.content().get(0)).text());\n    }\n\n    @Test\n    void divideByZero() {\n        CallToolResult result = client.callTool(\n                CallToolRequest.builder(\"divide\").arguments(Map.of(\"a\", 1, \"b\", 0)).build());\n        assertTrue(result.isError());\n        assertTrue(((TextContent) result.content().get(0)).text().contains(\"must not be zero\"));\n    }\n}\n```\n\n- The test uses the `java` command of the JDK that runs Maven. Do not use the `java` command from `PATH`.\n- The test uses the real stdio transport and the real JSON-RPC messages.\n\n### Step 4: Build until the tests pass\n\n1. Run `mvn verify`. This command compiles the code, runs the tests, and makes `target\u002Fmcp-server-demo-0.1.0.jar`.\n2. If a test fails, read the error. Fix the server or the test.\n3. Run `mvn verify` again.\n4. Continue only when the build is successful.\n\n### Step 5: Configure the client\n\nFor VS Code, write `.vscode\u002Fmcp.json`:\n\n```json\n{\n  \"servers\": {\n    \"demo\": {\n      \"type\": \"stdio\",\n      \"command\": \"java\",\n      \"args\": [\"-jar\", \"\u002Fabsolute\u002Fpath\u002Fto\u002Fproject\u002Ftarget\u002Fmcp-server-demo-0.1.0.jar\"]\n    }\n  }\n}\n```\n\nFor Claude Desktop, put the same `command` and `args` in `claude_desktop_config.json`, below the `mcpServers` key.\n\nFor an HTTP server, use the client configuration in [references\u002Fstreamable-http.md](references\u002Fstreamable-http.md).\n\nTell the user these facts:\n\n- `java -jar target\u002Fmcp-server-demo-0.1.0.jar` starts the stdio server. The server waits for a host on stdin. The SDK logs go to stderr.\n- To test the server manually, start the MCP Inspector with the same command. The Inspector uses Node.js.\n\n## Gotchas\n\nSDK 2.x changed many patterns of SDK 0.x and 1.x. Do not copy examples from earlier versions. Read the [migration guide](https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fjava-sdk\u002Fblob\u002Fmain\u002FMIGRATION-2.0.md) for the full list.\n\n- Use the builders that take the required fields first: `Tool.builder(name, inputSchema)`, `Resource.builder(uri, name)`, `Prompt.builder(name)`, `TextContent.builder(text)`, and `ReadResourceResult.builder(contents)`. The builders without arguments are deprecated.\n- A required field must not be `null`. A `null` value causes an `IllegalArgumentException`.\n- Tool names must have 1 to 128 characters: letters, digits, `_`, `-`, and `.`. The server builder rejects an incorrect name with an `IllegalArgumentException`. `addTool()` at runtime does not check the name.\n- `inputSchema` and `outputSchema` are `Map\u003CString, Object>` values. The `JsonSchema` record is deprecated.\n- The server checks each schema against JSON Schema 2020-12 when you call `build()` or `addTool()`. An incorrect schema causes an `IllegalArgumentException`.\n- The SDK validates the tool arguments against `inputSchema`. It also validates `structuredContent` against `outputSchema`. If the validation fails, the client gets a tool result with `isError` set to `true`. Thus, the handler gets only valid arguments.\n- If a tool has an `outputSchema`, return `structuredContent` in each successful result. Without it, the SDK returns a tool result with `isError` set to `true`.\n- Return `CallToolResult` with `isError(true)` for an error that the model must read.\n- Do not throw an exception or an `McpError` for a tool failure. The client gets a JSON-RPC error, not a tool result. Many hosts do not show this error to the model.\n- In a stdio server, stdout is the protocol channel. Do not call `System.out.println()`.\n- Log with SLF4J to stderr. The default console appender of Logback writes to stdout. If you use Logback, set its target to `System.err`.\n- The Spring transports moved to [Spring AI](https:\u002F\u002Fdocs.spring.io\u002Fspring-ai\u002Freference\u002Fapi\u002Fmcp\u002Fmcp-overview.html) 2.0 and later (group `org.springframework.ai`). Do not use the `io.modelcontextprotocol.sdk:mcp-spring-*` artifacts.\n- Do not use the deprecated SSE transports. Use Streamable HTTP for a remote server.\n- The revision 2026-07-28 deprecates these features ([SEP-2577](https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fmodelcontextprotocol\u002Fpull\u002F2577)). Do not add them to a new server:\n  - **Sampling** (`exchange.createMessage()`): Call the LLM provider API directly.\n  - **Protocol logging** (`exchange.loggingNotification()`): Use SLF4J.\n  - **Roots** (`exchange.listRoots()`): Get paths from tool arguments, resource URIs, or the server configuration.\n",{"name":5,"description":7,"compatibility":59},"JDK 17 or later, Maven 3.9 or later or Gradle 9 or later, and network access to download dependencies. The MCP Inspector also uses Node.js.","main","5269f7ea2d6c3a9bfda5ed878b6726cf509121fd","skills\u002Fjava-mcp-server-generator",5360,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot","https:\u002F\u002Fawesome-copilot.github.com\u002F","https:\u002F\u002Fgithub.com\u002Fgithub","https:\u002F\u002Fgithub.com\u002Fabout","How people build software.","2026-11-15 04:42:30",{"source":8,"skillName":5,"commands":71,"prompt":81,"zipAvailable":82},[72,75,78],{"tool":73,"command":74},"npx","npx skills add github\u002Fawesome-copilot --skill java-mcp-server-generator",{"tool":76,"command":77},"bunx","bunx skills add github\u002Fawesome-copilot --skill java-mcp-server-generator",{"tool":79,"command":80},"pnpm","pnpm dlx skills add github\u002Fawesome-copilot --skill java-mcp-server-generator","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fjava-mcp-server-generator\u002FSKILL.md",true,[84,90,94],{"path":85,"resourceType":86,"resourceTypeDesc":87,"sizeBytes":88,"sourceHtmlUrl":89},"references\u002Fgradle.md","REFERENCE","参考文档",2333,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fjava-mcp-server-generator\u002Freferences\u002Fgradle.md",{"path":91,"resourceType":86,"resourceTypeDesc":87,"sizeBytes":92,"sourceHtmlUrl":93},"references\u002Fstreamable-http.md",5205,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fjava-mcp-server-generator\u002Freferences\u002Fstreamable-http.md",{"path":95,"resourceType":96,"resourceTypeDesc":97,"sizeBytes":98,"sourceHtmlUrl":99},"SKILL.md.tmpl","OTHER","其他",48624,"https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fgstack\u002Fland-and-deploy\u002FSKILL.md.tmpl",[101,130,158,187,217,234],{"skillNo":102,"name":103,"nameZh":6,"description":104,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":105,"categories":106,"keywords":111,"publishedAt":54},"01M70KXZNX9ES38N2A8M58ZZMZ","supabase-rls-policies","Write, review, and test Supabase Row Level Security (RLS) policies so that one user cannot read or change another user's rows. Use when creating or changing tables, policies, views, or security definer functions in a Supabase project, when reviewing a migration that touches RLS, or when asked to prove user isolation with pgTAP tests that sign in as two users.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fsupabase-rls-policies\u002FSKILL.md",[107,110],{"categoryNo":108,"categoryName":109,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[112,113,114,115,37,34,116,117,118,119,120,121,122,123,124,125,126,127,128,129],"supabase","rls","supabase rls","supabase rls policies","review","change","read","write","security","isolation","tables","as","tests","prove","use","users","functions","with",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":137,"publishedAt":54},"01M70KWA5YWXDV6V8DZ19E3T2Y","skill-distribution-audit","Audit a skill collection before release or investigate installer omissions, archived\u002Ftemplate leakage, duplicate identities, and manifest drift. Reconcile the intended public source set, distribution manifest, and actual discovery output for a specified consumer version. Includes a deterministic set-comparison helper.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fskill-distribution-audit\u002FSKILL.md",[136],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157],"distribution","skill distribution audit","audit","SET","deterministic","installer","for","discovery","comparison","helper","manifest","version","collection","drift","output","investigate","duplicate","template","release","reconcile",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":162,"sourceHtmlUrl":163,"categories":164,"keywords":170,"publishedAt":54},"01M70KCJPFVW7PPQ49CC5R8JGK","logicapps-custom-code-net10-migration","Migrate Azure Logic Apps Standard local-function custom-code projects from .NET 8 to .NET 10. Use for legacy Logic Apps custom-code workspace upgrades, project\u002Fpackage configuration, custom-worker settings, publication, and integrated VS Code debugging. Not for ordinary .NET applications, standalone Azure Functions, Consumption workflows, or cloud deployment.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Flogicapps-custom-code-net10-migration\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Flogicapps-custom-code-net10-migration\u002FSKILL.md",[165],{"categoryNo":166,"categoryName":167,"taxonomyType":168,"taxonomyTypeDesc":169},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[171,46,172,173,174,175,144,37,176,177,178,179,180,181,182,126,183,184,185,186],"custom","logicapps custom code net10 migration","migration","projects","standalone","deployment","applications","local","azure","worker","upgrades","package","apps","Legacy","debugging","workflows",{"skillNo":188,"name":189,"nameZh":6,"description":190,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":191,"sourceHtmlUrl":192,"categories":193,"keywords":196,"publishedAt":54},"01M6AEBN37RQMXJ3298PEY7PG1","winmd-api-search","Find and explore Windows desktop APIs. Use when building features that need platform capabilities — camera, file access, notifications, UI controls, AI\u002FML, sensors, networking, etc. Discovers the right API for a task and retrieves full type details (methods, properties, events, enumeration values).","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fwinmd-api-search\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fwinmd-api-search\u002FSKILL.md",[194,195],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":166,"categoryName":167,"taxonomyType":168,"taxonomyTypeDesc":169},[197,198,40,199,200,201,202,203,204,205,206,207,208,209,39,34,210,211,212,213,214,144,215,216],"winmd api search","search","windows","desktop","file access","enumeration","ui","ml","file","networking","capabilities","notifications","explore","features","full","camera","events","platform","methods","controls",{"skillNo":218,"name":219,"nameZh":6,"description":220,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":221,"licenseFileUrl":222,"sourceHtmlUrl":223,"categories":224,"keywords":230,"publishedAt":54},"01M6AE571R3SC1ZGE202B3NB5S","resemble-detect","Deepfake detection and media safety — detect AI-generated audio, images, video, and text, trace synthesis sources, apply watermarks, verify speaker identity, and analyze media intelligence using Resemble AI","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fresemble-detect\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fresemble-detect\u002FSKILL.md",[225,226,229],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":227,"categoryName":228,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[231,141,205,232,233],"resemble detect","https","identity",{"skillNo":235,"name":236,"nameZh":6,"description":237,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":221,"licenseFileUrl":238,"sourceHtmlUrl":239,"categories":240,"keywords":245,"publishedAt":54},"01M6AE30BSK2HCY4TQQ22Z8JRD","quality-playbook","Run a complete quality engineering audit on any codebase. Derives behavioral requirements from the code, generates spec-traced functional tests, runs a three-pass code review with regression tests, executes a multi-model spec audit (Council of Three), and produces a consolidated bug report with TDD-verified patches. Finds the 35% of real defects that structural code review alone cannot catch. Works with any language. Trigger on 'quality playbook', 'spec audit', 'Council of Three', 'fitness-to-purpose', or 'coverage theater'.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fquality-playbook\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fquality-playbook\u002FSKILL.md",[241,244],{"categoryNo":242,"categoryName":243,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[246,247,248,249,46,116,9,140,250,251,232,252,253,254,255,256,257,258,259,260,261,262,124,263,38,264,265],"playbook","quality playbook","quality","code review","tdd","run","report","spec","bug report","council","engineering","functional","spec audit","bug","verified","multi-model","three","coverage","regression","structural"]