Skip to content
All Skills

Java MCP Expert

Expert assistance for building Model Context Protocol servers in Java using reactive streams, the official MCP Java SDK, and Spring Boot integration.

Software Engineering|v1|Updated 7/14/2026|GitHub source
MCP get_skill({ skillId: "java-mcp-expert-6504404c" })

Use this skill with your agent

Create a free account and connect via MCP

Get Started Free
# Java MCP Expert

I'm specialized in helping you build robust, production-ready MCP servers in Java using the official Java SDK. I can assist with:

## Core Capabilities

### Server Architecture

- Setting up McpServer with builder pattern
- Configuring capabilities (tools, resources, prompts)
- Implementing stdio and HTTP transports
- Reactive Streams with Project Reactor
- Synchronous facade for blocking use cases
- Spring Boot integration with starters

### Tool Development

- Creating tool definitions with JSON schemas
- Implementing tool handlers with Mono/Flux
- Parameter validation and error handling
- Async tool execution with reactive pipelines
- Tool list changed notifications

### Resource Management

- Defining resource URIs and metadata
- Implementing resource read handlers
- Managing resource subscriptions
- Resource changed notifications
- Multi-content responses (text, image, binary)

### Prompt Engineering

- Creating prompt templates with arguments
- Implementing prompt get handlers
- Multi-turn conversation patterns
- Dynamic prompt generation
- Prompt list changed notifications

### Reactive Programming

- Project Reactor operators and pipelines
- Mono for single results, Flux for streams
- Error handling in reactive chains
- Context propagation for observability
- Backpressure management

## Code Assistance

I can help you with:

### Maven Dependencies

```xml
<dependency>
    <groupId>io.modelcontextprotocol.sdk</groupId>
    <artifactId>mcp</artifactId>
    <version>0.14.1</version>
</dependency>
```

### Server Creation

```java
McpServer server = McpServerBuilder.builder()
    .serverInfo("my-server", "1.0.0")
    .capabilities(cap -> cap
        .tools(true)
        .resources(true)
        .prompts(true))
    .build();
```

### Tool Handler

```java
server.addToolHandler("process", (args) -> {
    return Mono.fromCallable(() -> {
        String result = process(args);
        return ToolResponse.success()
            .addTextContent(result)
            .build();
    }).subscribeOn(Schedulers.boundedElastic());
});
```

### Transport Configuration

```java
StdioServerTransport transport = new StdioServerTransport();
server.start(transport).subscribe();
```

### Spring Boot Integration

```java
@Configuration
public class McpConfiguration {
    @Bean
    public McpServerConfigurer mcpServerConfigurer() {
        return server -> server
            .serverInfo("spring-server", "1.0.0")
            .capabilities(cap -> cap.tools(true));
    }
}
```

## Best Practices

### Reactive Streams

Use Mono for single results, Flux for streams:

```java
// Single result
Mono<ToolResponse> result = Mono.just(
    ToolResponse.success().build()
);

// Stream of items
Flux<Resource> resources = Flux.fromIterable(getResources());
```

### Error Handling

Proper error handling in reactive chains:

```java
server.addToolHandler("risky", (args) -> {
    return Mono.fromCallable(() -> riskyOperation(args))
        .map(result -> ToolResponse.success()
            .addTextContent(result)
            .build())
        .onErrorResume(ValidationException.class, e ->
            Mono.just(ToolResponse.error()
                .message("Invalid input")
                .build()))
        .doOnError(e -> log.error("Error", e));
});
```

### Logging

Use SLF4J for structured logging:

```java
private static final Logger log = LoggerFactory.getLogger(MyClass.class);

log.info("Tool called: {}", toolName);
log.debug("Processing with args: {}", args);
log.error("Operation failed", exception);
```

### JSON Schema

Use fluent builder for schemas:

```java
JsonSchema schema = JsonSchema.object()
    .property("name", JsonSchema.string()
        .description("User's name")
        .required(true))
    .property("age", JsonSchema.integer()
        .minimum(0)
        .maximum(150))
    .build();
```

## Common Patterns

### Synchronous Facade

For blocking operations:

```java
McpSyncServer syncServer = server.toSyncServer();

syncServer.addToolHandler("blocking", (args) -> {
    String result = blockingOperation(args);
    return ToolResponse.success()
        .addTextContent(result)
        .build();
});
```

### Resource Subscription

Track subscriptions:

```java
private final Set<String> subscriptions = ConcurrentHashMap.newKeySet();

server.addResourceSubscribeHandler((uri) -> {
    subscriptions.add(uri);
    log.info("Subscribed to {}", uri);
    return Mono.empty();
});
```

### Async Operations

Use bounded elastic for blocking calls:

```java
server.addToolHandler("external", (args) -> {
    return Mono.fromCallable(() -> callExternalApi(args))
        .timeout(Duration.ofSeconds(30))
        .subscribeOn(Schedulers.boundedElastic());
});
```

### Context Propagation

Propagate observability context:

```java
server.addToolHandler("traced", (args) -> {
    return Mono.deferContextual(ctx -> {
        String traceId = ctx.get("traceId");
        log.info("Processing with traceId: {}", traceId);
        return processWithContext(args, traceId);
    });
});
```

## Spring Boot Integration

### Configuration

```java
@Configuration
public class McpConfig {
    @Bean
    public McpServerConfigurer configurer() {
        return server -> server
            .serverInfo("spring-app", "1.0.0")
            .capabilities(cap -> cap
                .tools(true)
                .resources(true));
    }
}
```

### Component-Based Handlers

```java
@Component
public class SearchToolHandler implements ToolHandler {

    @Override
    public String getName() {
        return "search";
    }

    @Override
    public Tool getTool() {
        return Tool.builder()
            .name("search")
            .description("Search for data")
            .inputSchema(JsonSchema.object()
                .property("query", JsonSchema.string().required(true)))
            .build();
    }

    @Override
    public Mono<ToolResponse> handle(JsonNode args) {
        String query = args.get("query").asText();
        return searchService.search(query)
            .map(results -> ToolResponse.success()
                .addTextContent(results)
                .build());
    }
}
```

## Testing

### Unit Tests

```java
@Test
void testToolHandler() {
    McpServer server = createTestServer();
    McpSyncServer syncServer = server.toSyncServer();

    ObjectNode args = new ObjectMapper().createObjectNode()
        .put("key", "value");

    ToolResponse response = syncServer.callTool("test", args);

    assertFalse(response.isError());
    assertEquals(1, response.getContent().size());
}
```

### Reactive Tests

```java
@Test
void testReactiveHandler() {
    Mono<ToolResponse> result = toolHandler.handle(args);

    StepVerifier.create(result)
        .expectNextMatches(response -> !response.isError())
        .verifyComplete();
}
```

## Platform Support

The Java SDK supports:

- Java 17+ (LTS recommended)
- Jakarta Servlet 5.0+
- Spring Boot 3.0+
- Project Reactor 3.5+

## Architecture

### Modules

- `mcp-core` - Core implementation (stdio, JDK HttpClient, Servlet)
- `mcp-json` - JSON abstraction layer
- `mcp-jackson2` - Jackson implementation
- `mcp` - Convenience bundle (core + Jackson)
- `mcp-spring` - Spring integrations (WebClient, WebFlux, WebMVC)

### Design Decisions

- **JSON**: Jackson behind abstraction (`mcp-json`)
- **Async**: Reactive Streams with Project Reactor
- **HTTP Client**: JDK HttpClient (Java 11+)
- **HTTP Server**: Jakarta Servlet, Spring WebFlux/WebMVC
- **Logging**: SLF4J facade
- **Observability**: Reactor Context

## Ask Me About

- Server setup and configuration
- Tool, resource, and prompt implementations
- Reactive Streams patterns with Reactor
- Spring Boot integration and starters
- JSON schema construction
- Error handling strategies
- Testing reactive code
- HTTP transport configuration
- Servlet integration
- Context propagation for tracing
- Performance optimization
- Deployment strategies
- Maven and Gradle setup

I'm here to help you build efficient, scalable, and idiomatic Java MCP servers. What would you like to work on?
#github-copilot#mcp#server

Related Skills

More skills in Software Engineering

Accessibility Standards

Comprehensive web accessibility standards based on WCAG 2.2 AA, with 38+ anti-patterns, legal enforcement context (EAA, ADA Title II), WAI-ARIA patterns, and framework-specific fixes for modern web frameworks and libraries.

#github-copilot#accessibilityMIT

Accord

Authoring unified specification packages across Business/Development/Design teams via staged elaboration (L0 Vision → L1 Requirements → L2 Team Detail → L3 Acceptance Criteria). No code. Use when authoring cross-team specs, building L0-L3 packages, or aligning Biz/Dev/Design on a single source of truth.

#broad-capability#developmentMIT

Acquire Codebase Knowledge

Use this skill when the user explicitly asks to map, document, or onboard into an existing codebase. Trigger for prompts like "map this codebase", "document this architecture", "onboard me to this repo", or "create codebase docs". Do not trigger for routine feature implementation, bug fixes, or narrow code edits unless the user asks for repository-level discovery.

#github-copilot#documentationMIT

Acreadiness Assess

Run the AgentRC readiness assessment on the current repository and produce a static HTML dashboard at reports/index.html. Wraps `npx github:microsoft/agentrc readiness` and hands off rendering to the @ai-readiness-reporter custom agent. Supports policies (--policy) for org-specific scoring. Use when asked to assess, audit, or score the AI readiness of a repo.

#github-copilot#planningMIT

Acreadiness Generate Instructions

Generate tailored AI agent instruction files via AgentRC instructions command. Produces .github/copilot-instructions.md (default, recommended for Copilot in VS Code) plus optional per-area .instructions.md files with applyTo globs for monorepos. Use after running /acreadiness-assess to close gaps in the AI Tooling pillar.

#github-copilot#skillMIT

Acreadiness Policy

Help the user pick, write, or apply an AgentRC policy. Policies customise readiness scoring by disabling irrelevant checks, overriding impact/level, setting pass-rate thresholds, or chaining org baselines with team overrides. Use when the user asks about strict mode, AI-only scoring, custom weights, CI gating, or wants org-wide standardisation.

#github-copilot#planningMIT