Source profileQuality 79/100

github/awesome-copilot/skills/java-mcp-server-generator/SKILL.md

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.

Source repository stars
37,126
Declared platforms
0
Static risk flags
1
Last source update
2026-07-28
Source checked
2026-07-28

Decision brief

What it does—and where it fits

Generate a complete, production-ready MCP server in Java using the official Java SDK with Maven or Gradle.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/github/awesome-copilot --skill "skills/java-mcp-server-generator"
    Safe inspection promptEditorial

    Inspect the Agent Skill "java-mcp-server-generator" from https://github.com/github/awesome-copilot/blob/9933dcad5be5caeb288cebcd370eeeb2fc2f1685/skills/java-mcp-server-generator/SKILL.md at commit 9933dcad5be5caeb288cebcd370eeeb2fc2f1685. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Generation 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 (camelCa…

      Ask for project name and packageChoose build tool (Maven or Gradle)Generate all files with proper package structure
    2. 02

      Project Generation

      When asked to create a Java MCP server, generate a complete project with this structure:

      When asked to create a Java MCP server, generate a complete project with this structure:
    3. 03

      Maven pom.xml Template

      Review the “Maven pom.xml Template” section in the pinned source before continuing.

      Review and apply the “Maven pom.xml Template” source section.
    4. 04

      Gradle build.gradle.kts Template

      Review the “Gradle build.gradle.kts Template” section in the pinned source before continuing.

      Review and apply the “Gradle build.gradle.kts Template” source section.
    5. 05

      McpServerApplication.java Template

      Review the “McpServerApplication.java Template” section in the pinned source before continuing.

      Review and apply the “McpServerApplication.java Template” source section.

    Permission review

    Static risk signals and limitations

    Network access

    medium · line 41

    The documentation includes network, browsing, or remote request actions.

    <project xmlns="http://maven.apache.org/POM/4.0.0"

    Network access

    medium · line 42

    The documentation includes network, browsing, or remote request actions.

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score79/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars37,126SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    github/awesome-copilot
    Skill path
    skills/java-mcp-server-generator/SKILL.md
    Commit
    9933dcad5be5caeb288cebcd370eeeb2fc2f1685
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md

    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 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
    
    ### Maven
    ```bash
    mvn clean package
    

    Gradle

    ./gradlew build
    

    Run

    Maven

    java -jar target/my-mcp-server-1.0.0.jar
    

    Gradle

    ./gradlew run
    

    Testing

    Maven

    mvn 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

    MIT

    
    ## Generation 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
    

    Alternatives

    Compare before choosing