Building Your First MCP Server with Solon: A 5-Minute Hello World
If you've been following the AI tooling space, you've probably heard about MCP (Model Context Protocol) — the open standard that lets AI models interact with external tools and data sources. It's been called "the USB-C for AI" and for good reason.
But here's the thing: setting up an MCP server from scratch can be surprisingly verbose. The official SDK requires you to wire up transports, capability negotiation, and tool specifications by hand.
Solon's approach is different. With @McpServerEndpoint, the whole thing collapses into a single annotated class. Let me show you.
What We're Building
A simple MCP server that exposes a hello tool. The server will:
- Start on port 8080
- Expose a MCP endpoint at
/mcp - Use the
STREAMABLEtransport (the modern MCP protocol) - Provide a
hellotool that takes a name and returns a greeting
Step 1: Add the Dependency
Add the MCP module to your pom.xml:
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-ai-mcp</artifactId>
</dependency>
That's it. One dependency gives you server, client, and all transport types. No extra SDKs to wire up.
Step 2: Create the Server
Create a class and annotate it with @McpServerEndpoint:
import org.noear.solon.ai.annotation.ToolMapping;
import org.noear.solon.ai.mcp.McpChannel;
import org.noear.solon.ai.mcp.server.annotation.McpServerEndpoint;
import org.noear.solon.annotation.Param;
@McpServerEndpoint(channel = McpChannel.STREAMABLE, mcpEndpoint = "/mcp")
public class McpServerTool {
@ToolMapping(description = "Say hello to someone")
public String hello(@Param(name = "name", description = "The person's name") String name) {
return "Hello, " + name + "!";
}
}
That's the entire server. Let me break down what's happening:
-
@McpServerEndpoint— Tells Solon this class is an MCP server endpoint. Thechannelparameter specifies the transport protocol (STREAMABLEis the modern MCP 2025-03-26+ standard). ThemcpEndpointis the URL path. -
@ToolMapping— Declares this method as an MCP tool. Thedescriptionis passed to the AI model so it knows when to use this tool. -
@Param— Describes each parameter. The model uses this to generate the correct arguments. -
McpChannel.STREAMABLE— The current MCP standard transport. It supports streaming responses and is the recommended channel for new projects.
Step 3: Start the Application
import org.noear.solon.Solon;
public class McpServerApp {
public static void main(String[] args) {
Solon.start(McpServerApp.class, args);
}
}
Solon's component scanner will automatically discover the @McpServerEndpoint class and register it as a real MCP service. No XML, no config classes, no @Bean declarations.
Step 4: Connect with a Client
Once the server is running on port 8080, you can connect with the MCP client:
import org.noear.solon.ai.mcp.client.McpClientProvider;
import java.util.Map;
public class McpClientDemo {
public static void main(String[] args) {
McpClientProvider client = McpClientProvider.builder()
.channel(McpChannel.STREAMABLE)
.url("http://localhost:8080/mcp")
.build();
String result = client.callTool("hello", Map.of("name", "Solon"))
.getContent();
System.out.println(result); // Output: "Hello, Solon!"
}
}
Connecting to an AI Model
The real power of MCP is connecting your tools to an LLM. Here's how:
ChatModel chatModel = ChatModel.of(apiUrl)
.provider("openai")
.model("gpt-4")
.defaultToolsAdd(mcpClient) // Bind MCP tools to the model
.build();
ChatResponse resp = chatModel
.prompt("Say hello to Alice")
.call();
System.out.println(resp.getMessage());
// The model will call the MCP tool automatically
Transport Options
Solon MCP supports four transport types:
| Transport | When to Use |
|---|---|
STREAMABLE |
Default for new projects. Modern MCP protocol with streaming support. |
STREAMABLE_STATELESS |
For clustered deployments. No sticky sessions needed. |
SSE |
Legacy MCP protocol. Server-Sent Events based. |
STDIO |
For local subprocess communication (e.g., CLI tools). |
Important: Server and client must use matching transport types. STREAMABLE and SSE are not interchangeable.
What's Next
This is the simplest possible MCP server. From here you can:
- Add more tools with
@ToolMappingmethods - Return async results with
CompletableFuture<String> - Use
STREAMABLE_STATELESSfor cluster-friendly deployments - Add authentication with
ServerTransportSecurityValidator - Build a full RAG pipeline with MCP resources
The full Solon MCP documentation covers all of these. I found these particularly helpful:
- MCP Hello World — The starting point
- MCP Tool Services — Publishing and consuming tools
- MCP Transport Types — Deep dive on transport options
- MCP Async Support — For non-blocking server operations
- MCP McpTalent — Combining MCP with Solon's Talent system
If you've been avoiding MCP because the setup looked complex, give Solon's approach a try. One annotation, one dependency, and you're in business.
Top comments (0)