
Java Mcp Server Generator
- 8.7k installs
- 37.1k repo stars
- Updated July 28, 2026
- github/awesome-copilot
java-mcp-server-generator is an agent skill that Generate a complete Model Context Protocol server project in Java using the official MCP Java SDK with reactive streams and optional Spring Boot integration.
About
Generate a complete Model Context Protocol server project in Java using the official MCP Java SDK with reactive streams and optional Spring Boot integration name java-mcp-server-generator description Generate a complete Model Context Protocol server project in Java using the official MCP Java SDK with reactive streams and optional Spring Boot integration Java MCP Server Generator Generate a complete production-ready MCP server in Java using the official Java SDK with Maven or Gradle Project Generation When asked to create a Java MCP server generate a complete project with this structure my-mcp-server pom xml or build gradle kts src main java com example mcp McpServerApplication java config ServerConfiguration java tools ToolDefinitions java ToolHandlers java resources ResourceDefinitions java ResourceHandlers java prompts PromptDefinitions java PromptHandlers java resources application properties if using Spring test java com example mcp McpServerTest java README md Maven pom xml Template xml xml version 1 0 encoding UTF-8 project xmlns http maven apache org POM 4 0 0 xmlns xsi http www w3 org 2001 XMLSchema-instance xsi schemaLocation http maven
- Java MCP Server Generator
- ✅ Tools: greet, calculate
- ✅ Resources: example data, configuration
- ✅ Prompts: code-review
- ✅ Reactive Streams with Project Reactor
Java Mcp Server Generator by the numbers
- 8,667 all-time installs (skills.sh)
- +23 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #157 of 2,184 Testing & QA skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
java-mcp-server-generator capabilities & compatibility
- Capabilities
- java mcp server generator · ✅ tools: greet, calculate · ✅ resources: example data, configuration · ✅ prompts: code review · ✅ reactive streams with project reactor
- Use cases
- documentation
What java-mcp-server-generator says it does
**Choose build tool** (Maven or Gradle) 3.
**Generate all files** with proper package structure 4.
**Use Reactive Streams** for async handlers 5.
**Include comprehensive logging** with SLF4J 6.
npx skills add https://github.com/github/awesome-copilot --skill java-mcp-server-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 8.7k |
|---|---|
| repo stars | ★ 37.1k |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 28, 2026 |
| Repository | github/awesome-copilot ↗ |
What problem does java-mcp-server-generator solve for developers using this skill?
Generate a complete Model Context Protocol server project in Java using the official MCP Java SDK with reactive streams and optional Spring Boot integration.
Who is it for?
Developers who need java-mcp-server-generator patterns described in the cached skill documentation.
Skip if: Skip when docs are empty or the task is outside the skill's documented scope.
When should I use this skill?
Generate a complete Model Context Protocol server project in Java using the official MCP Java SDK with reactive streams and optional Spring Boot integration.
What you get
Actionable workflows and conventions from SKILL.md for java-mcp-server-generator.
- Complete Java MCP server project
- pom.xml or build.gradle.kts
- SDK handler and config classes
Files
Java MCP Server Generator
Generate a complete, production-ready MCP server in Java using the official Java SDK with Maven or Gradle.
Project Generation
When asked to create a Java MCP server, generate a complete project with this structure:
my-mcp-server/
├── pom.xml (or build.gradle.kts)
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/mcp/
│ │ │ ├── McpServerApplication.java
│ │ │ ├── config/
│ │ │ │ └── ServerConfiguration.java
│ │ │ ├── tools/
│ │ │ │ ├── ToolDefinitions.java
│ │ │ │ └── ToolHandlers.java
│ │ │ ├── resources/
│ │ │ │ ├── ResourceDefinitions.java
│ │ │ │ └── ResourceHandlers.java
│ │ │ └── prompts/
│ │ │ ├── PromptDefinitions.java
│ │ │ └── PromptHandlers.java
│ │ └── resources/
│ │ └── application.properties (if using Spring)
│ └── test/
│ └── java/
│ └── com/example/mcp/
│ └── McpServerTest.java
└── README.mdMaven pom.xml Template
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-mcp-server</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>My MCP Server</name>
<description>Model Context Protocol server implementation</description>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mcp.version>0.14.1</mcp.version>
<slf4j.version>2.0.9</slf4j.version>
<logback.version>1.4.11</logback.version>
<junit.version>5.10.0</junit.version>
</properties>
<dependencies>
<!-- MCP Java SDK -->
<dependency>
<groupId>io.modelcontextprotocol.sdk</groupId>
<artifactId>mcp</artifactId>
<version>${mcp.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.mcp.McpServerApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>Gradle build.gradle.kts Template
plugins {
id("java")
id("application")
}
group = "com.example"
version = "1.0.0"
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
repositories {
mavenCentral()
}
dependencies {
// MCP Java SDK
implementation("io.modelcontextprotocol.sdk:mcp:0.14.1")
// Logging
implementation("org.slf4j:slf4j-api:2.0.9")
implementation("ch.qos.logback:logback-classic:1.4.11")
// Testing
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
testImplementation("io.projectreactor:reactor-test:3.5.0")
}
application {
mainClass.set("com.example.mcp.McpServerApplication")
}
tasks.test {
useJUnitPlatform()
}McpServerApplication.java Template
package com.example.mcp;
import com.example.mcp.tools.ToolHandlers;
import com.example.mcp.resources.ResourceHandlers;
import com.example.mcp.prompts.PromptHandlers;
import io.mcp.server.McpServer;
import io.mcp.server.McpServerBuilder;
import io.mcp.server.transport.StdioServerTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.Disposable;
public class McpServerApplication {
private static final Logger log = LoggerFactory.getLogger(McpServerApplication.class);
public static void main(String[] args) {
log.info("Starting MCP Server...");
try {
McpServer server = createServer();
StdioServerTransport transport = new StdioServerTransport();
// Start server
Disposable serverDisposable = server.start(transport).subscribe();
// Graceful shutdown
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
log.info("Shutting down MCP server");
serverDisposable.dispose();
server.stop().block();
}));
log.info("MCP Server started successfully");
// Keep running
Thread.currentThread().join();
} catch (Exception e) {
log.error("Failed to start MCP server", e);
System.exit(1);
}
}
private static McpServer createServer() {
McpServer server = McpServerBuilder.builder()
.serverInfo("my-mcp-server", "1.0.0")
.capabilities(capabilities -> capabilities
.tools(true)
.resources(true)
.prompts(true))
.build();
// Register handlers
ToolHandlers.register(server);
ResourceHandlers.register(server);
PromptHandlers.register(server);
return server;
}
}ToolDefinitions.java Template
package com.example.mcp.tools;
import io.mcp.json.JsonSchema;
import io.mcp.server.tool.Tool;
import java.util.List;
public class ToolDefinitions {
public static List<Tool> getTools() {
return List.of(
createGreetTool(),
createCalculateTool()
);
}
private static Tool createGreetTool() {
return Tool.builder()
.name("greet")
.description("Generate a greeting message")
.inputSchema(JsonSchema.object()
.property("name", JsonSchema.string()
.description("Name to greet")
.required(true)))
.build();
}
private static Tool createCalculateTool() {
return Tool.builder()
.name("calculate")
.description("Perform mathematical calculations")
.inputSchema(JsonSchema.object()
.property("operation", JsonSchema.string()
.description("Operation to perform")
.enumValues(List.of("add", "subtract", "multiply", "divide"))
.required(true))
.property("a", JsonSchema.number()
.description("First operand")
.required(true))
.property("b", JsonSchema.number()
.description("Second operand")
.required(true)))
.build();
}
}ToolHandlers.java Template
package com.example.mcp.tools;
import com.fasterxml.jackson.databind.JsonNode;
import io.mcp.server.McpServer;
import io.mcp.server.tool.ToolResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
public class ToolHandlers {
private static final Logger log = LoggerFactory.getLogger(ToolHandlers.class);
public static void register(McpServer server) {
// Register tool list handler
server.addToolListHandler(() -> {
log.debug("Listing available tools");
return Mono.just(ToolDefinitions.getTools());
});
// Register greet handler
server.addToolHandler("greet", ToolHandlers::handleGreet);
// Register calculate handler
server.addToolHandler("calculate", ToolHandlers::handleCalculate);
}
private static Mono<ToolResponse> handleGreet(JsonNode arguments) {
log.info("Greet tool called");
if (!arguments.has("name")) {
return Mono.just(ToolResponse.error()
.message("Missing 'name' parameter")
.build());
}
String name = arguments.get("name").asText();
String greeting = "Hello, " + name + "! Welcome to MCP.";
log.debug("Generated greeting for: {}", name);
return Mono.just(ToolResponse.success()
.addTextContent(greeting)
.build());
}
private static Mono<ToolResponse> handleCalculate(JsonNode arguments) {
log.info("Calculate tool called");
if (!arguments.has("operation") || !arguments.has("a") || !arguments.has("b")) {
return Mono.just(ToolResponse.error()
.message("Missing required parameters")
.build());
}
String operation = arguments.get("operation").asText();
double a = arguments.get("a").asDouble();
double b = arguments.get("b").asDouble();
double result;
switch (operation) {
case "add":
result = a + b;
break;
case "subtract":
result = a - b;
break;
case "multiply":
result = a * b;
break;
case "divide":
if (b == 0) {
return Mono.just(ToolResponse.error()
.message("Division by zero")
.build());
}
result = a / b;
break;
default:
return Mono.just(ToolResponse.error()
.message("Unknown operation: " + operation)
.build());
}
log.debug("Calculation: {} {} {} = {}", a, operation, b, result);
return Mono.just(ToolResponse.success()
.addTextContent("Result: " + result)
.build());
}
}ResourceDefinitions.java Template
package com.example.mcp.resources;
import io.mcp.server.resource.Resource;
import java.util.List;
public class ResourceDefinitions {
public static List<Resource> getResources() {
return List.of(
Resource.builder()
.name("Example Data")
.uri("resource://data/example")
.description("Example resource data")
.mimeType("application/json")
.build(),
Resource.builder()
.name("Configuration")
.uri("resource://config")
.description("Server configuration")
.mimeType("application/json")
.build()
);
}
}ResourceHandlers.java Template
package com.example.mcp.resources;
import io.mcp.server.McpServer;
import io.mcp.server.resource.ResourceContent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import java.time.Instant;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ResourceHandlers {
private static final Logger log = LoggerFactory.getLogger(ResourceHandlers.class);
private static final Map<String, Boolean> subscriptions = new ConcurrentHashMap<>();
public static void register(McpServer server) {
// Register resource list handler
server.addResourceListHandler(() -> {
log.debug("Listing available resources");
return Mono.just(ResourceDefinitions.getResources());
});
// Register resource read handler
server.addResourceReadHandler(ResourceHandlers::handleRead);
// Register resource subscribe handler
server.addResourceSubscribeHandler(ResourceHandlers::handleSubscribe);
// Register resource unsubscribe handler
server.addResourceUnsubscribeHandler(ResourceHandlers::handleUnsubscribe);
}
private static Mono<ResourceContent> handleRead(String uri) {
log.info("Reading resource: {}", uri);
switch (uri) {
case "resource://data/example":
String jsonData = String.format(
"{\"message\":\"Example resource data\",\"timestamp\":\"%s\"}",
Instant.now()
);
return Mono.just(ResourceContent.text(jsonData, uri, "application/json"));
case "resource://config":
String config = "{\"serverName\":\"my-mcp-server\",\"version\":\"1.0.0\"}";
return Mono.just(ResourceContent.text(config, uri, "application/json"));
default:
log.warn("Unknown resource requested: {}", uri);
return Mono.error(new IllegalArgumentException("Unknown resource URI: " + uri));
}
}
private static Mono<Void> handleSubscribe(String uri) {
log.info("Client subscribed to resource: {}", uri);
subscriptions.put(uri, true);
return Mono.empty();
}
private static Mono<Void> handleUnsubscribe(String uri) {
log.info("Client unsubscribed from resource: {}", uri);
subscriptions.remove(uri);
return Mono.empty();
}
}PromptDefinitions.java Template
package com.example.mcp.prompts;
import io.mcp.server.prompt.Prompt;
import io.mcp.server.prompt.PromptArgument;
import java.util.List;
public class PromptDefinitions {
public static List<Prompt> getPrompts() {
return List.of(
Prompt.builder()
.name("code-review")
.description("Generate a code review prompt")
.argument(PromptArgument.builder()
.name("language")
.description("Programming language")
.required(true)
.build())
.argument(PromptArgument.builder()
.name("focus")
.description("Review focus area")
.required(false)
.build())
.build()
);
}
}PromptHandlers.java Template
package com.example.mcp.prompts;
import io.mcp.server.McpServer;
import io.mcp.server.prompt.PromptMessage;
import io.mcp.server.prompt.PromptResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Map;
public class PromptHandlers {
private static final Logger log = LoggerFactory.getLogger(PromptHandlers.class);
public static void register(McpServer server) {
// Register prompt list handler
server.addPromptListHandler(() -> {
log.debug("Listing available prompts");
return Mono.just(PromptDefinitions.getPrompts());
});
// Register prompt get handler
server.addPromptGetHandler(PromptHandlers::handleCodeReview);
}
private static Mono<PromptResult> handleCodeReview(String name, Map<String, String> arguments) {
log.info("Getting prompt: {}", name);
if (!name.equals("code-review")) {
return Mono.error(new IllegalArgumentException("Unknown prompt: " + name));
}
String language = arguments.getOrDefault("language", "Java");
String focus = arguments.getOrDefault("focus", "general quality");
String description = "Code review for " + language + " with focus on " + focus;
List<PromptMessage> messages = List.of(
PromptMessage.user("Please review this " + language + " code with focus on " + focus + "."),
PromptMessage.assistant("I'll review the code focusing on " + focus + ". Please share the code."),
PromptMessage.user("Here's the code to review: [paste code here]")
);
log.debug("Generated code review prompt for {} ({})", language, focus);
return Mono.just(PromptResult.builder()
.description(description)
.messages(messages)
.build());
}
}McpServerTest.java Template
package com.example.mcp;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.mcp.server.McpServer;
import io.mcp.server.McpSyncServer;
import io.mcp.server.tool.ToolResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class McpServerTest {
private McpSyncServer syncServer;
private ObjectMapper objectMapper;
@BeforeEach
void setUp() {
McpServer server = createTestServer();
syncServer = server.toSyncServer();
objectMapper = new ObjectMapper();
}
private McpServer createTestServer() {
// Same setup as main application
McpServer server = McpServerBuilder.builder()
.serverInfo("test-server", "1.0.0")
.capabilities(cap -> cap.tools(true))
.build();
// Register handlers
ToolHandlers.register(server);
return server;
}
@Test
void testGreetTool() {
ObjectNode args = objectMapper.createObjectNode();
args.put("name", "Java");
ToolResponse response = syncServer.callTool("greet", args);
assertFalse(response.isError());
assertEquals(1, response.getContent().size());
assertTrue(response.getContent().get(0).getText().contains("Java"));
}
@Test
void testCalculateTool() {
ObjectNode args = objectMapper.createObjectNode();
args.put("operation", "add");
args.put("a", 5);
args.put("b", 3);
ToolResponse response = syncServer.callTool("calculate", args);
assertFalse(response.isError());
assertTrue(response.getContent().get(0).getText().contains("8"));
}
@Test
void testDivideByZero() {
ObjectNode args = objectMapper.createObjectNode();
args.put("operation", "divide");
args.put("a", 10);
args.put("b", 0);
ToolResponse response = syncServer.callTool("calculate", args);
assertTrue(response.isError());
}
}README.md Template
# My MCP Server
A Model Context Protocol server built with Java and the official MCP Java SDK.
## Features
- ✅ Tools: greet, calculate
- ✅ Resources: example data, configuration
- ✅ Prompts: code-review
- ✅ Reactive Streams with Project Reactor
- ✅ Structured logging with SLF4J
- ✅ Full test coverage
## Requirements
- Java 17 or later
- Maven 3.6+ or Gradle 7+
## Build
### Mavenmvn clean package
### Gradle./gradlew build
## Run
### Mavenjava -jar target/my-mcp-server-1.0.0.jar
### Gradle./gradlew run
## Testing
### Mavenmvn test
### Gradle./gradlew test
## Integration with Claude Desktop
Add to `claude_desktop_config.json`:
{ "mcpServers": { "my-mcp-server": { "command": "java", "args": ["-jar", "/path/to/my-mcp-server-1.0.0.jar"] } } }
## License
MITGeneration Instructions
1. Ask for project name and package 2. Choose build tool (Maven or Gradle) 3. Generate all files with proper package structure 4. Use Reactive Streams for async handlers 5. Include comprehensive logging with SLF4J 6. Add tests for all handlers 7. Follow Java conventions (camelCase, PascalCase) 8. Include error handling with proper responses 9. Document public APIs with Javadoc 10. Provide both sync and async examples
Related skills
How it compares
Pick java-mcp-server-generator for JVM-native MCP servers with Maven or Gradle; use TypeScript or Python MCP generators when the stack is not Java.
FAQ
What does java-mcp-server-generator do?
Generate a complete Model Context Protocol server project in Java using the official MCP Java SDK with reactive streams and optional Spring Boot integration.
When should I use java-mcp-server-generator?
Generate a complete Model Context Protocol server project in Java using the official MCP Java SDK with reactive streams and optional Spring Boot integration.
Is java-mcp-server-generator safe to install?
Review the Security Audits panel on this page before installing in production.