三种传输方式（sse、streamable 和 stdio ），streamable 还有无状态的 streamable_stateless。可归为两大类：

* http（sse、streamable、streamable_stateless和），远程通讯
* stdio，进程通讯


具体对比说明（区别）：


| 服务端                       | 客户端            |   会话<br/>状态  | 链接     | 集群路由     | 端点    | 通讯方式         |
| ------------------ | ---------- | ------------- | ----- | --------- | ----- | -------- |
| stdio                           | stdio             |  有                    | /         |  /              |  /       | 进程通讯     |
| sse（已标为弃用）        | sse               |   有                   | 长链接  |  ip_hash     |  2个    | http 通讯     |
| streamable                  | streamable     |   有                   | 长链接  |  ip_hash     |  1个    | http 通讯      |
| streamable_stateless    | streamable     |   有                  | 短链接  | 随意           |  1个    | http 通讯     |


有会话状态？

* 可以支持反向通讯（server -> client：发通知、采样）

sse 和 streamable 有什么不同？

* 都用到了 http sse。
* sse 需要两个端点（uri path）。一般配置一个，另一个自动生成。
* streamable 协议内部采用了流式传输，用于替代 sse。（这个流式传输与应用接口开发无关）
* streamable 在 server 侧，支持 stateless 模式（无会话状态，无长链接，集群友好）。


solon mcp 开发时的体验都是一致的，主要是 channel （通讯方式）配置不同。


### 1、构建 stdio 服务端点参考

一个进程内只能有一个 stdio 服务端点，且 server 侧不能启用控制台日志（否则会协议串流）。


```java
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.STDIO) //表示使用 stdio
public class McpServerTool {
    @ToolMapping(description = "查询天气预报")
    public String get_weather(@Param(description = "城市位置") String location) {
        return "晴，14度";
    }
}
```




### 2、构建 http 服务端点参考（sse、streamable、streamable_stateless）

sse、streamable、streamable_stateless 者是构建在 http 协议的基础上。开发体验类似 web mvc，配置服务端点的 mcpEndpoint 属性即可。


```java
import org.noear.solon.ai.annotation.ToolMapping;
import org.noear.solon.ai.mcp.server.annotation.McpServerEndpoint;
import org.noear.solon.annotation.Param;

@McpServerEndpoint(channel = McpChannel.STREAMABLE, mcpEndpoint = "/mcp/case1") 
public class McpServerTool1 {
    @ToolMapping(description = "查询天气预报")
    public String getWeather(@Param(description = "城市位置") String location) {
        return "晴，14度";
    }
}

@McpServerEndpoint(channel = McpChannel.STREAMABLE_STATELESS, mcpEndpoint = "/mcp/case2") 
public class McpServerTool2 {
    @ToolMapping(description = "查询天气预报")
    public String getWeather(@Param(description = "城市位置") String location) {
        return "晴，14度";
    }
}

@McpServerEndpoint(channel = McpChannel.SSE, mcpEndpoint = "/mcp/case3") 
public class McpServerTool3 {
    @ToolMapping(description = "查询天气预报")
    public String getWeather(@Param(description = "城市位置") String location) {
        return "晴，14度";
    }
}
```

