Solon v3.3.0

mcp - 鉴权设计参考

</> markdown

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

1、服务端的鉴权设计参考(sse 方式)

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

@Component
public class McpFilter implements Filter {
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        if (ctx.pathNew().startsWith("/mcp/")) {
            String authStr = ctx.header("Authorization");
            if (Utils.isEmpty(authStr)) {
                ctx.status(401);
                return;
            }

            //业务检测
        }

        chain.doFilter(ctx);
    }
}

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

@McpServerEndpoint(sseEndpoint = "/mcp/sse")
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(sseEndpoint = "/mcp/sse")
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 注解):

@McpServerEndpoint(sseEndpoint = "/mcp/sse")
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)
McpClientProvider toolProvider =  McpClientProvider.builder()
                .apiUrl("https://localhost:8080/mcp/sse")
                .apiKey("sk-xxxxx")
                .build();
  • 使用 queryString 参数(需要 3.2.1 之后支持)
McpClientProvider toolProvider =  McpClientProvider.builder()
                .apiUrl("https://localhost:8080/mcp/sse?token=xxxx")
                .build();
  • 使用其它 header
McpClientProvider toolProvider =  McpClientProvider.builder()
                .apiUrl("https://localhost:8080/mcp/sse")
                .headerSet("ak", "xxxx")
                .headerSet("sk", "yyy")
                .build();
                
McpClientProvider toolProvider =  McpClientProvider.builder()
                .apiUrl("https://localhost:8080/mcp/sse")
                .headerSet("token", "xxxx")
                .build();