最近在折腾MCP服务,想把它部署在自己的Linux服务器上,然后让本地的Cursor和VS Code Agent通过MCP协议调用里面的工具。但搞了两天,一直卡在认证和权限这块。我是直接用HTTP暴露的,但这样肯定不安全,而且Agent每次连接都要手动配置token,感觉很麻烦。有没有大佬分享下比较成熟的方案?比如用SSH隧道或者反向代理加HTTPS?另外MCP的transport层支持WebSocket吗?我看官方文档说支持stdio和HTTP,但没提WebSocket,不知道是不是我理解错了。希望有实际部署经验的朋友指点一下,谢谢!
MCP部署在自建服务器上,怎么跟本地IDE的Agent安全通信?
全部回复
共 156 条WebSocket确实不在官方transport列表里,我只试过反向代理套HTTPS加token,还行,但每次换IP就想骂人。
说实话我之前也被这个坑过,后来直接上了Caddy反代加mTLS,客户端那边用自签证书配好就一劳永逸了,比每次手动塞token省心太多。WebSocket官方确实没提,但你看下MCP的规范,其实HTTP transport本身就支持升级到WS,只是文档没明说,自己封装一层也不算麻烦。另外如果只是本地开发用,SSH隧道其实最稳,不用暴露任何端口,就是每次重连得重新建隧道,有点烦。
搞过类似的,别直接暴露HTTP,用Caddy或者Nginx反代加个mTLS或者Cloudflare Access,比token省心多了,而且IDE侧不用每次手动配。SSH隧道也行,但维护起来麻烦,尤其是多设备。MCP的transport确实没原生WebSocket,不过你可以用websocat之类的工具包一层,把HTTP升级成WS,实测能用,但别指望官方支持。
我们团队现在就是反代+短时token,配合Agent的自动刷新机制,基本无感。你卡在认证这块,可以试试搞个本地代理服务,专门处理跟服务器的认证,IDE只连localhost,这样token轮换和权限控制都集中在一个地方,省得每个客户端都配一遍。
直接上Caddy反代套个Cloudflare Tunnel,token走环境变量注入,体验会顺滑很多。
试过用tailscale组虚拟局域网,配合Caddy反代加mTLS,比token省心多了,WebSocket官方不支持但可以用SSE凑合。
WebSocket确实支持,但官方文档没细写,用subpath挂载到nginx后面配wss就行。认证这块别折腾token了,直接用Caddy自动HTTPS加forward_auth,配合Tailscale SSH做内网穿透,比手动管token省心得多。我目前是MCP server只监听本地回环,然后让VS Code的Remote-SSH连服务器,Agent走本地stdio转发,既安全又不用处理网络协议。
我之前也踩过这个坑,最后是直接用tailscale组了内网,然后MCP只绑内网IP,配合API key做简单鉴权,比暴露公网省心太多。WebSocket官方确实没直接写,但MCP的HTTP transport其实可以走WebSocket升级,不过得自己封装一层,挺折腾的。你如果非要公网访问,caddy反代加个basic auth或者mTLS也算成熟方案,就是每次换token确实烦,可以考虑用短期token加自动刷新,或者干脆用系统级密钥环存一下。
我上周刚踩完这坑,分享下我的方案:用Caddy反代你的MCP服务,自动配HTTPS和Basic Auth,然后本地IDE用Bearer token,这样比裸HTTP安全得多。SSH隧道也行,但每次重连要维护连接,麻烦。另外MCP官方确实只定义了stdio和HTTP,但HTTP transport是可以支持WebSocket的,你可以在HTTP Upgrade头里做协议升级,或者直接用SSE替代长连接。还有个小技巧,把token写进IDE的env文件里,配合Cursor的变量替换,能省掉手动输token的麻烦。
说下我的实践,SSH隧道是最省事的,本地起个ssh -L把远程端口映射到localhost,IDE里直接连127.0.0.1,完全不用暴露公网,token都省了。不过你要是多台机器或者跨网段,反向代理加HTTPS更靠谱,但caddy或者nginx里配mTLS会好很多,光靠bearer token还是不够。MCP的transport确实官方只写了stdio和HTTP,但HTTP那层理论上可以升级成WebSocket,社区有人用websocket跑通了,不过非标准实现,坑比较多,不建议折腾。你如果只是自己用,我建议直接用SSH隧道加stdio模式,让Agent通过ssh执行远程的mcp-server,Cursor和VS Code都支持command配置,这样连token都不用配,权限直接走系统用户,最干净。还有个思路是用Cloudflare Tunnel,免费且自带认证,但延迟稍高,适合偶尔用。最后提醒下,别在HTTP上裸跑,哪怕加了token,MCP工具里如果有读文件或者执行命令的,风险太大了。
SSH隧道最省心,配个密钥自动登录就完事了,token那套反而容易把自己锁外面。
反向代理加mTLS也行,但折腾完发现还是tailscale最香,组网直接走内网IP,IDE里填localhost就行。
WebSocket确实支持,官方文档没细说但社区早就有人在用了,配合wss反向代理比裸HTTP省心太多。
我也踩过这个坑,直接裸HTTP确实不行,后来用Caddy反代加了个Basic Auth和mTLS,至少比裸奔强。MCP官方确实只写了stdio和HTTP,但HTTP transport其实可以跑在WebSocket上,只是没明说,你可以试试用nginx把WebSocket Upgrade转发给MCP服务端。
token管理这事,我建议你写个脚本用系统keyring存着,别放配置文件里,Cursor那边配个环境变量引用就行,省得每次手输。另外如果你用的是VS Code的Agent,可以试试用Remote SSH直接连服务器跑MCP,这样本地IDE和远程服务走的是SSH加密通道,认证直接走SSH密钥,省掉一层HTTPS配置。最后提醒下,MCP服务端最好加个白名单,只允许你本地IP段访问,不然暴露公网风险太大。
说实话我之前也踩过这个坑,后来直接用tailscale组了虚拟内网,本地IDE走100网段连MCP服务,配合一个简单的API key放在环境变量里,折腾一次后面就不用管了。关于WebSocket,官方确实没把它列为正式transport,但社区有实现能兼容,不过稳定性一般,不如直接走HTTP加TLS。如果你不想维护token,可以试试用cloudflared隧道,自签证书加Access策略,比反代配置省心不少。
这问题我上个月刚趟完坑,跟你分享下实际折腾下来的结论。MCP的transport层确实官方只写了stdio和HTTP,但HTTP那套其实支持Streamable HTTP,底层就是类WebSocket的长连接,所以你要是想用WS得自己包一层协议转换,我试过用gin做代理,可行但有点费劲。至于安全,我强烈建议别裸奔HTTP,最简单的是用cloudflared隧道,免费且自动带TLS,然后通过Cloudflare Access做OAuth认证,这样Agent连接时只用处理一次token刷新,配合环境变量存密钥能省不少事。我现在的方案是服务器上跑个Caddy反向代理,自动签发HTTPS证书,然后在Caddyfile里用forward_auth接一个轻量的OAuth2中间件(比如oauth2-proxy),本地IDE那边配个curl的wrapper脚本,启动前自动去拿短期token,这样每次连接都换新token,权限也能按工具粒度控制。另外你提到的SSH隧道,如果只有你一个人用其实最稳,直接本地起个ssh -L把远程端口映射到localhost,然后MCP服务只监听127.0.0.1,这样连认证都省了,但多人协作就麻烦点。还有一个坑是Cursor的MCP客户端对HTTP响应格式要求挺严格,如果中间加了代理层,记得要把Content-Type和MCP的JSON-RPC版本头都透传对,不然会一直报handshake失败。
我用的tailscale+反向代理,内网穿透比SSH省心,token用环境变量注入就行。
WebSocket transport官方确实没支持,不过HTTP+SSE够用了,别折腾WS。
我用的nginx反代加mTLS,token用短期JWT自动刷新,体验还行,就是配置有点繁琐。
WebSocket官方确实没提,但实测HTTP升级协议能走通,就是文档不太完善。
直接上cloudflared隧道或者frp内网穿透,比裸HTTP省心多了,token用短期JWT自动刷新就行。
MCP官方确实还没正式支持WebSocket,但社区有PR在推,现阶段用SSH隧道最稳。
用cloudflared隧道最省事,免费版就够,还能顺带把HTTPS和域名都解决了。
WebSocket在MCP里其实走的是HTTP升级,你直接用反向代理把/ws路径转过去就行。
直接上tailscale组虚拟局域网,mcp走内网HTTP就行,token用短期密钥自动签发,省事又安全。
WebSocket官方没提但可以用nginx反代升级协议,我试过能跑,不过得自己处理下重连逻辑。
直接上Caddy反代加Cloudflare Tunnel吧,免费且自动续证书,token用Header里塞一次性密钥就行。