spring-ai-mcp-server-patterns

$npx mdskill add giuseppe-trisciuoglio/developer-kit/spring-ai-mcp-server-patterns

Build MCP servers with Spring AI for tool calling.

  • Creates MCP servers to extend AI with custom tool handlers and resources.
  • Depends on Spring Boot, Spring AI, and MCP transport libraries.
  • Uses @Tool, @PromptTemplate annotations to define AI-callable functions.
  • Delivers a configured MCP server with stdio, HTTP, or SSE transport.

SKILL.md

.github/skills/spring-ai-mcp-server-patternsView on GitHub ↗
---
name: spring-ai-mcp-server-patterns
description: Provides Spring Boot MCP server patterns that create Model Context Protocol servers with Spring AI by defining tool handlers, exposing resources, configuring prompt templates, and setting up transports for AI function calling and tool calling. Use when building MCP servers to extend AI capabilities with Spring's official AI framework, implementing AI tools, custom function calling, or MCP client integration.
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
---

# Spring AI MCP Server Implementation Patterns

Implements MCP servers with Spring AI for AI function calling, tool handlers, and MCP transport configuration.

## Overview

Production-ready MCP server patterns: `@Tool` functions, `@PromptTemplate` resources, and stdio/HTTP/SSE transports with Spring AI security.

## When to Use

MCP servers, Spring AI function calling, AI tools, tool calling, custom tool handlers, Spring Boot MCP, resource endpoints, or MCP transport configuration.

## Quick Reference

### Core Annotations

| Annotation | Target | Purpose |
|-----------|--------|---------|
| `@EnableMcpServer` | Class | Enable MCP server auto-configuration |
| `@Tool(description)` | Method | Declare AI-callable tool |
| `@ToolParam(value)` | Parameter | Document tool parameter for AI |
| `@PromptTemplate(name)` | Method | Declare reusable prompt template |
| `@PromptParam(value)` | Parameter | Document prompt parameter |

### Transport Types

| Transport | Use Case | Config |
|-----------|----------|--------|
| `stdio` | Local process / Claude Desktop | Default |
| `http` | Remote HTTP clients | `port`, `path` |
| `sse` | Real-time streaming clients | `port`, `path` |

### Key Dependencies

```xml
<!-- Maven -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mcp-server</artifactId>
    <version>1.0.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
    <version>1.0.0</version>
</dependency>
```

```gradle
// Gradle
implementation 'org.springframework.ai:spring-ai-mcp-server:1.0.0'
implementation 'org.springframework.ai:spring-ai-starter-model-openai:1.0.0'
```

## Instructions

### 1. Project Setup

Add Spring AI MCP dependencies (see Quick Reference above), configure the AI model in `application.properties`, and enable MCP with `@EnableMcpServer`:

```java
@SpringBootApplication
@EnableMcpServer
public class MyMcpApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyMcpApplication.class, args);
    }
}
```

```properties
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.mcp.enabled=true
spring.ai.mcp.transport.type=stdio
```

### 2. Define Tools

Annotate methods with `@Tool` inside `@Component` beans. Use `@ToolParam` to document parameters:

```java
@Component
public class WeatherTools {

    @Tool(description = "Get current weather for a city")
    public WeatherData getWeather(@ToolParam("City name") String city) {
        return weatherService.getCurrentWeather(city);
    }

    @Tool(description = "Get 5-day forecast for a city")
    public ForecastData getForecast(
            @ToolParam("City name") String city,
            @ToolParam(value = "Unit: celsius or fahrenheit", required = false) String unit) {
        return weatherService.getForecast(city, unit != null ? unit : "celsius");
    }
}
```

See [references/implementation-patterns.md](references/implementation-patterns.md) for database tools, API integration tools, and the `FunctionCallback` low-level pattern.

### 3. Create Prompt Templates

```java
@Component
public class CodeReviewPrompts {

    @PromptTemplate(
        name = "java-code-review",
        description = "Review Java code for best practices and issues"
    )
    public Prompt createCodeReviewPrompt(
            @PromptParam("code") String code,
            @PromptParam(value = "focusAreas", required = false) List<String> focusAreas) {

        String focus = focusAreas != null ? String.join(", ", focusAreas) : "general best practices";
        return Prompt.builder()
                .system("You are an expert Java code reviewer with 20 years of experience.")
                .user("Review the following Java code for " + focus + ":\n```java\n" + code + "\n```")
                .build();
    }
}
```

See [references/implementation-patterns.md](references/implementation-patterns.md) for additional prompt template patterns.

### 4. Configure Transport

```yaml
spring:
  ai:
    mcp:
      enabled: true
      transport:
        type: stdio       # stdio | http | sse
        http:
          port: 8080
          path: /mcp
      server:
        name: my-mcp-server
        version: 1.0.0
```

### 5. Add Security

```java
@Configuration
public class McpSecurityConfig {

    @Bean
    public ToolFilter toolFilter(SecurityService securityService) {
        return (tool, context) -> {
            User user = securityService.getCurrentUser();
            if (tool.name().startsWith("admin_")) {
                return user.hasRole("ADMIN");
            }
            return securityService.isToolAllowed(user, tool.name());
        };
    }
}
```

Use `@PreAuthorize("hasRole('ADMIN')")` on tool methods for method-level security. See [references/implementation-patterns.md](references/implementation-patterns.md) for full security patterns.

### 6. Testing

```java
@SpringBootTest
class WeatherToolsTest {

    @Autowired
    private WeatherTools weatherTools;

    @MockBean
    private WeatherService weatherService;

    @Test
    void testGetWeather_Success() {
        when(weatherService.getCurrentWeather("London"))
            .thenReturn(new WeatherData("London", "Cloudy", 15.0));

        WeatherData result = weatherTools.getWeather("London");

        assertThat(result.city()).isEqualTo("London");
        verify(weatherService).getCurrentWeather("London");
    }
}
```

See [references/testing-guide.md](references/testing-guide.md) for integration tests, Testcontainers, security tests, and slice tests.

## Best Practices

### Tool Design
- Keep tools focused — one operation per tool
- Use clear, action-oriented names (`getWeather`, `executeQuery`)
- Always annotate parameters with `@ToolParam` and descriptive text
- Return structured records/DTOs, not raw strings or maps
- Design tools to be idempotent when possible

### Security
- Validate and sanitize all inputs — AI-generated parameters are untrusted
- Use parameterized queries for SQL; validate and normalize paths for file tools
- Apply `@PreAuthorize` for role-based access on sensitive tools
- Audit log all data-modifying tool executions
- Never expose credentials or sensitive data in tool descriptions or error messages

### Performance
- Use `@Cacheable` for expensive operations with appropriate TTL
- Set timeouts for all external calls
- Use `@Async` for long-running operations
- Monitor with Micrometer metrics

### Error Handling
- Return structured error responses with user-friendly messages
- Log context (user, tool name, parameters) for debugging
- Implement retry logic for transient failures
- Implement `@ControllerAdvice` for consistent error responses

## Examples

### Example 1: Minimal Weather MCP Server

```java
@SpringBootApplication
@EnableMcpServer
public class WeatherMcpApplication {
    public static void main(String[] args) {
        SpringApplication.run(WeatherMcpApplication.class, args);
    }
}

@Component
public class WeatherTools {

    @Tool(description = "Get current weather for a city")
    public WeatherData getWeather(@ToolParam("City name") String city) {
        return new WeatherData(city, "Sunny", 22.5);
    }
}

record WeatherData(String city, String condition, double temperatureCelsius) {}
```

### Example 2: Secure Database Tool

```java
@Component
@PreAuthorize("hasRole('USER')")
public class DatabaseTools {

    private final JdbcTemplate jdbcTemplate;

    @Tool(description = "Execute a read-only SQL query and return results")
    public QueryResult executeQuery(
            @ToolParam("SQL SELECT query") String sql,
            @ToolParam(value = "Parameters as JSON map", required = false) String paramsJson) {

        if (!sql.trim().toUpperCase().startsWith("SELECT")) {
            throw new IllegalArgumentException("Only SELECT queries are allowed");
        }
        List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
        return new QueryResult(rows, rows.size());
    }
}
```

See [references/examples.md](references/examples.md) for complete examples including file system tools, REST API integration, and prompt template servers.

## Constraints and Warnings

### Security
- **Never expose** sensitive data in tool descriptions, parameters, or error messages
- **Input validation is mandatory** — always validate before executing
- **External content is untrusted** — tools fetching URLs may receive prompt injection payloads; validate all fetched content
- **SQL injection**: use parameterized queries exclusively
- **Path traversal**: normalize and validate all file paths against a base path

### Operational
- Responses should be concise — large responses can exceed AI context window limits
- All tools must implement timeouts; default should be configurable
- Rate limit expensive operations
- Tools may be called concurrently — ensure thread safety

### Spring AI Specific
- Spring AI is actively developed — pin specific versions in production
- Error messages thrown by tools are exposed to AI models; sanitize them
- Choose transport type carefully: `stdio` for local processes, `http`/`sse` for remote clients

## References

Consult these files for detailed patterns and examples:

- **[references/implementation-patterns.md](references/implementation-patterns.md)** - Tool creation, prompt templates, FunctionCallback, Spring Boot auto-configuration, application properties
- **[references/advanced-patterns.md](references/advanced-patterns.md)** - Dynamic tool registration, multi-model support, caching, error handling
- **[references/testing-guide.md](references/testing-guide.md)** - Unit tests, integration tests, Testcontainers, security tests, slice tests
- **[references/examples.md](references/examples.md)** - Complete server examples: weather, database, file system, REST API, prompt templates
- **[references/api-reference.md](references/api-reference.md)** - Full API: annotations, interfaces, configuration classes, transport implementations, event system
- **[references/migration-guide.md](references/migration-guide.md)** - Migrating from LangChain4j MCP to Spring AI MCP

More from giuseppe-trisciuoglio/developer-kit

SkillDescription
adr-draftingCreates new Architecture Decision Record (ADR) documents for significant architectural changes using a consistent template and repository-aware naming and storage guidance. Use when a user or agent decides on an architectural change, needs to document technical rationale, or wants to add a new ADR to the project history.
aws-cdkProvides AWS CDK TypeScript patterns for defining, validating, and deploying AWS infrastructure as code. Use when creating CDK apps, stacks, and reusable constructs, modeling serverless or VPC-based architectures, applying IAM and encryption defaults, or testing and reviewing `cdk synth`, `cdk diff`, and `cdk deploy` changes. Triggers include "aws cdk typescript", "create cdk app", "cdk stack", "cdk construct", "cdk deploy", and "cdk test".
aws-cli-beastProvides advanced AWS CLI patterns for managing EC2, Lambda, S3, DynamoDB, RDS, VPC, IAM, and CloudWatch. Generates bulk operation scripts, automates cross-service workflows, validates security configurations, and executes JMESPath queries for complex filtering. Triggers on "aws cli help", "aws command line", "aws scripting", "aws automation", "aws batch operations", "aws bulk operations", "aws cli pagination", "aws multi-region", "aws profiles", "aws cli troubleshooting".
aws-cloudformation-auto-scalingProvides AWS CloudFormation patterns for Auto Scaling including EC2, ECS, and Lambda. Use when creating Auto Scaling groups, launch configurations, launch templates, scaling policies, lifecycle hooks, and predictive scaling. Covers template structure with Parameters, Outputs, Mappings, Conditions, cross-stack references, and best practices for high availability and cost optimization.
aws-cloudformation-bedrockProvides AWS CloudFormation patterns for Amazon Bedrock resources including agents, knowledge bases, data sources, guardrails, prompts, flows, and inference profiles. Use when creating Bedrock agents with action groups, implementing RAG with knowledge bases, configuring vector stores, setting up content moderation guardrails, managing prompts, orchestrating workflows with flows, and configuring inference profiles for model optimization.
aws-cloudformation-cloudfrontProvides AWS CloudFormation patterns for CloudFront distributions, origins (ALB, S3, Lambda@Edge, VPC Origins), CacheBehaviors, Functions, SecurityHeaders, parameters, Outputs and cross-stack references. Use when creating CloudFront distributions with CloudFormation, configuring multiple origins, implementing caching strategies, managing custom domains with ACM, configuring WAF, and optimizing performance.
aws-cloudformation-cloudwatchProvides AWS CloudFormation patterns for CloudWatch monitoring, metrics, alarms, dashboards, logs, and observability. Use when creating CloudWatch metrics, alarms, dashboards, log groups, log subscriptions, anomaly detection, synthesized canaries, Application Signals, and implementing template structure with Parameters, Outputs, Mappings, Conditions, cross-stack references, and CloudWatch best practices for monitoring production infrastructure.
aws-cloudformation-dynamodbProvides AWS CloudFormation patterns for DynamoDB tables, GSIs, LSIs, auto-scaling, and streams. Use when creating DynamoDB tables with CloudFormation, configuring primary keys, local/global secondary indexes, capacity modes (on-demand/provisioned), point-in-time recovery, encryption, TTL, and implementing template structure with Parameters, Outputs, Mappings, Conditions, cross-stack references.
aws-cloudformation-ec2Provides AWS CloudFormation patterns for EC2 instances, Security Groups, IAM roles, and load balancers. Use when creating EC2 instances, SPOT instances, Security Groups, IAM roles for EC2, Application Load Balancers (ALB), Target Groups, and implementing template structure with Parameters, Outputs, Mappings, Conditions, and cross-stack references.
aws-cloudformation-ecsProvides AWS CloudFormation patterns for ECS clusters, task definitions, services, container definitions, auto scaling, blue/green deployments, CodeDeploy integration, ALB integration, service discovery, monitoring, logging, template structure, parameters, outputs, and cross-stack references. Use when creating ECS clusters with CloudFormation, configuring Fargate and EC2 launch types, implementing blue/green deployments, managing auto scaling, integrating with ALB and NLB, and implementing ECS best practices.