DEV Community

Solon Framework
Solon Framework

Posted on

Building Your First MCP Server with Solon: A 5-Minute Hello World

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:

  1. Start on port 8080
  2. Expose a MCP endpoint at /mcp
  3. Use the STREAMABLE transport (the modern MCP protocol)
  4. Provide a hello tool 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>
Enter fullscreen mode Exit fullscreen mode

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 + "!";
    }
}
Enter fullscreen mode Exit fullscreen mode

That's the entire server. Let me break down what's happening:

  • @McpServerEndpoint — Tells Solon this class is an MCP server endpoint. The channel parameter specifies the transport protocol (STREAMABLE is the modern MCP 2025-03-26+ standard). The mcpEndpoint is the URL path.
  • @ToolMapping — Declares this method as an MCP tool. The description is 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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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!"
    }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 @ToolMapping methods
  • Return async results with CompletableFuture<String>
  • Use STREAMABLE_STATELESS for 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:

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)