sse 方式，可以使用 web 的变量做鉴权；studio 方式，则需要使用环境变量。


### 1、服务端的鉴权设计参考（http 传输方式）

（1）可以使用过滤器或者路由拦截器（全局连接控制），检查请求信息并校验。比如：Basic Authentication

```java
import org.noear.solon.Utils;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;

@Component(index = -1) //按需设定顺序位
public class McpFilter implements Filter {
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        //如何鉴权“按需”设定
        if (ctx.pathNew().startsWith("/mcp/") && ctx.pathNew().endsWith("/message") == false) { //message 端点不需要签权
            String authStr = ctx.header("Authorization");
            if (Utils.isEmpty(authStr)) {
                ctx.status(401);
                return;
            }

            //业务检测
        }

        chain.doFilter(ctx);
    }
}
```

（2）也可以在每个接口层面使用上下文做鉴权（要用异常触发）：

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

@McpServerEndpoint(channel = McpChannel.STREAMABLE_STATELESS, mcpEndpoint = "/mcp")
public class McpServerTool {
    @ToolMapping(description = "你好世界")
    public String hello(@Param(name="name", description = "名字") String name, Context ctx) {
        if(ctx.header("token") == null) {
            throw new IllegalArgumentException("你没有权限!");
        }

        return "你好，" + name;
    }
}

//支持 @Header 和 @Cookie 注解
@McpServerEndpoint(channel = McpChannel.STREAMABLE_STATELESS, mcpEndpoint = "/mcp")
public class McpServerTool {
    @ToolMapping(description = "你好世界")
    public String hello(@Param(name="name", description = "名字") String name, @Header("token") token) {
        if(token == null) {
             throw new IllegalArgumentException("你没有权限!");
        }
        
        return "你好，" + name;
    }
}
```


（3）还可以在接口层面使用 AOP 鉴权注解（参考 solon auth 的资料，或其它 AOP 注解）：

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

@McpServerEndpoint(channel = McpChannel.STREAMABLE_STATELESS, mcpEndpoint = "/mcp")
public class McpServerTool {
    @AuthPermissions("msg:hello")
    @ToolMapping(description = "你好世界")
    public String hello(@Param(name="name", description = "名字") String name) {
        return "你好，" + name;
    }
}
```

### 2、客户的鉴权设计参考

McpClientProvider 为服务端的鉴权需求，提供了丰富的支持：

* 使用 Basic Authentication（by header）

```java
McpClientProvider toolProvider =  McpClientProvider.builder()
                .channel(McpChannel.STREAMABLE)
                .url("https://localhost:8080/mcp")
                .apiKey("sk-xxxxx")
                .build();
```


* 使用 queryString 参数（需要 3.2.1 之后支持）

```java
McpClientProvider toolProvider =  McpClientProvider.builder()
                .channel(McpChannel.STREAMABLE)
                .url("https://localhost:8080/mcp?token=xxxx")
                .build();
```

* 使用其它 header

```java
McpClientProvider toolProvider =  McpClientProvider.builder()
                .channel(McpChannel.STREAMABLE)
                .url("https://localhost:8080/mcp")
                .headerSet("ak", "xxxx")
                .headerSet("sk", "yyy")
                .build();
                
McpClientProvider toolProvider =  McpClientProvider.builder()
                .channel(McpChannel.STREAMABLE)
                .apiUrl("https://localhost:8080/mcp")
                .headerSet("token", "xxxx")
                .build();
```


### 3、用户身份与数据隔离（参考）

可以采用 header 信息传递用户身份，进而实现用户数据隔离

* 客户端添加 header ，传递用户身份（示例参考）

```java       
McpClientProvider toolProvider =  McpClientProvider.builder()
                .channel(McpChannel.STREAMABLE)
                .apiUrl("https://localhost:8080/mcp")
                .headerSet("user", "1")
                .build();
```


* 服务端使用 header 注解

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

@McpServerEndpoint(channel = McpChannel.STREAMABLE_STATELESS, mcpEndpoint = "/mcp")
public class McpServerTool {
    @ToolMapping(description = "获取订单数据")
    public Order getOrder(@Param long orderId, @Header("user") String user) {
        return new Order();
    }
}
```



