Model Context Protocol (MCP) server implementation patterns with LangChain4j. Use when building MCP servers to extend AI capabilities with custom tools, resources, and prompt templates.
Install with Tessl CLI
npx tessl i github:giuseppe-trisciuoglio/developer-kit --skill langchain4j-mcp-server-patterns76
Does it follow best practices?
If you maintain this skill, you can automatically optimize it using the tessl CLI to improve its score:
npx tessl skill review --optimize ./path/to/skillValidation for skill structure
Implement Model Context Protocol (MCP) servers with LangChain4j to extend AI capabilities with standardized tools, resources, and prompt templates.
Use this skill when building:
Create a simple MCP server with one tool:
MCPServer server = MCPServer.builder()
.server(new StdioServer.Builder())
.addToolProvider(new SimpleWeatherToolProvider())
.build();
server.start();Configure MCP server in Spring Boot:
@Bean
public MCPSpringConfig mcpServer(List<ToolProvider> tools) {
return MCPSpringConfig.builder()
.tools(tools)
.server(new StdioServer.Builder())
.build();
}MCP standardizes AI application connections:
AI Application ←→ MCP Client ←→ Transport ←→ MCP Server ←→ External ServiceCreate tools with proper schema validation:
class WeatherToolProvider implements ToolProvider {
@Override
public List<ToolSpecification> listTools() {
return List.of(ToolSpecification.builder()
.name("get_weather")
.description("Get weather for a city")
.inputSchema(Map.of(
"type", "object",
"properties", Map.of(
"city", Map.of("type", "string", "description", "City name")
),
"required", List.of("city")
))
.build());
}
@Override
public String executeTool(String name, String arguments) {
// Parse arguments and execute tool logic
return "Weather data result";
}
}Provide static and dynamic resources:
class CompanyResourceProvider
implements ResourceListProvider, ResourceReadHandler {
@Override
public List<McpResource> listResources() {
return List.of(
McpResource.builder()
.uri("policies")
.name("Company Policies")
.mimeType("text/plain")
.build()
);
}
@Override
public String readResource(String uri) {
return loadResourceContent(uri);
}
}Create reusable prompt templates:
class PromptTemplateProvider
implements PromptListProvider, PromptGetHandler {
@Override
public List<Prompt> listPrompts() {
return List.of(
Prompt.builder()
.name("code-review")
.description("Review code for quality")
.build()
);
}
@Override
public String getPrompt(String name, Map<String, String> args) {
return applyTemplate(name, args);
}
}Local process communication:
McpTransport transport = new StdioMcpTransport.Builder()
.command(List.of("npm", "exec", "@modelcontextprotocol/server-everything"))
.logEvents(true)
.build();Remote server communication:
McpTransport transport = new HttpMcpTransport.Builder()
.sseUrl("http://localhost:3001/sse")
.logRequests(true)
.logResponses(true)
.build();Connect to MCP servers:
McpClient client = new DefaultMcpClient.Builder()
.key("my-client")
.transport(transport)
.cacheToolList(true)
.build();
// List available tools
List<ToolSpecification> tools = client.listTools();Bridge MCP servers to LangChain4j AI services:
McpToolProvider provider = McpToolProvider.builder()
.mcpClients(mcpClient)
.failIfOneServerFails(false)
.filter((client, tool) -> filterByPermissions(tool))
.build();
// Integrate with AI service
AIAssistant assistant = AiServices.builder(AIAssistant.class)
.chatModel(chatModel)
.toolProvider(provider)
.build();Implement secure tool filtering:
McpToolProvider secureProvider = McpToolProvider.builder()
.mcpClients(mcpClient)
.filter((client, tool) -> {
if (tool.name().startsWith("admin_") && !isAdmin()) {
return false;
}
return true;
})
.build();Apply access controls to resources:
public boolean canAccessResource(String uri, User user) {
return resourceService.hasAccess(uri, user);
}Implement robust error handling:
try {
String result = mcpClient.executeTool(request);
} catch (McpException e) {
log.error("MCP execution failed: {}", e.getMessage());
return fallbackResult();
}Configure multiple MCP servers:
@Bean
public List<McpClient> mcpClients(List<ServerConfig> configs) {
return configs.stream()
.map(this::createMcpClient)
.collect(Collectors.toList());
}
@Bean
public McpToolProvider multiServerProvider(List<McpClient> clients) {
return McpToolProvider.builder()
.mcpClients(clients)
.failIfOneServerFails(false)
.build();
}Runtime tool filtering based on context:
McpToolProvider contextualProvider = McpToolProvider.builder()
.mcpClients(clients)
.filter((client, tool) -> isToolAllowed(user, tool, context))
.build();Monitor MCP server health:
@Component
public class McpHealthChecker {
@Scheduled(fixedRate = 30000) // 30 seconds
public void checkServers() {
mcpClients.forEach(client -> {
try {
client.listTools();
markHealthy(client.key());
} catch (Exception e) {
markUnhealthy(client.key(), e.getMessage());
}
});
}
}Configure MCP servers in application.yml:
mcp:
servers:
github:
type: docker
command: ["/usr/local/bin/docker", "run", "-e", "GITHUB_TOKEN", "-i", "mcp/github"]
log-events: true
database:
type: stdio
command: ["/usr/bin/npm", "exec", "@modelcontextprotocol/server-sqlite"]
log-events: falseConfigure MCP with Spring Boot:
@Configuration
@EnableConfigurationProperties(McpProperties.class)
public class McpConfiguration {
@Bean
public MCPServer mcpServer(List<ToolProvider> providers) {
return MCPServer.builder()
.server(new StdioServer.Builder())
.addToolProvider(providers)
.enableLogging(true)
.build();
}
}Refer to examples.md for comprehensive implementation examples including:
Complete API documentation is available in api-reference.md covering:
6ecd0d8
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.