最近在折腾MCP服务,想把它部署在自己的Linux服务器上,然后让本地的Cursor和VS Code Agent通过MCP协议调用里面的工具。但搞了两天,一直卡在认证和权限这块。我是直接用HTTP暴露的,但这样肯定不安全,而且Agent每次连接都要手动配置token,感觉很麻烦。有没有大佬分享下比较成熟的方案?比如用SSH隧道或者反向代理加HTTPS?另外MCP的transport层支持WebSocket吗?我看官方文档说支持stdio和HTTP,但没提WebSocket,不知道是不是我理解错了。希望有实际部署经验的朋友指点一下,谢谢!
MCP部署在自建服务器上,怎么跟本地IDE的Agent安全通信?
全部回复
共 156 条之前折腾过类似场景,我是用tailscale把服务器和本地组了个内网,然后MCP直接走内网IP+自定义header里的静态token,比暴露公网省心多了,agent那边配一次就不用管了。WebSocket确实官方没提,但实测用ws作为底层传输也能跑,就是得自己包一层认证逻辑,不如直接HTTP+SSH隧道稳。另外你可以看看mcp的streamable-http,新版文档里其实已经暗戳戳支持了,用起来比裸HTTP舒服。
说实话我之前也被这个问题折磨过,后来直接放弃了HTTP暴露,改用Tailscale把服务器和本地电脑组进同一个虚拟局域网,然后MCP服务只监听内网IP,认证这块就用简单的API Key配合IP白名单,虽然不算多高级但胜在省心。关于WebSocket,官方文档确实只提了stdio和HTTP,但HTTP transport其实可以跑在WebSocket上层,不过没必要自己折腾,直接用官方SDK里的Streamable HTTP就行,Cursor和VS Code都兼容。如果你坚持要用SSH隧道,我建议用autossh保持长连接,然后在本地把远程端口映射到127.0.0.1,这样MCP配置里直接写localhost就行,token可以藏在环境变量里,每次启动Agent前source一下脚本,比手动输入强多了。还有一个坑是如果MCP服务里要调用本地文件系统或者执行Shell命令,权限模型一定要设计好,不然Agent拿到token后能做的事可能超出你预期,最好在服务端做细粒度的工具级鉴权。我现在是反向代理加mTLS,证书用mkcert自己签,虽然配置麻烦点但一劳永逸,Agent那边只需要信任你的CA就行,token都不用了。
用tailscale组虚拟内网最简单,本地IDE直连内网IP就行,token用短期密钥自动刷新。
之前折腾过类似场景,最省心的方案其实是tailscale或者zerotier组内网,然后MCP直接走HTTP绑内网IP,配合API key做简单鉴权,比暴露公网省事多了。SSH隧道也行但每次重连要维护连接,反向代理加HTTPS还得处理证书轮换,有点重。关于WebSocket,官方transport确实只写了stdio和HTTP,但HTTP那层其实可以接在websocket后面,只是客户端要自己适配,我试过sse方式也凑合能用。另外token自动刷新这块,可以在IDE侧写个脚本定期换,或者直接用OAuth2的device flow,虽然麻烦点但能省心不少。
直接用 cloudflared tunnel 套一层,比 SSH 省心,token 用环境变量注入,别写死在配置里。
我最近也踩过这个坑,试下来最省心的方案是cloudflared tunnel,直接给本地服务套个公网HTTPS入口,比手动配反向代理简单太多。MCP的transport确实没原生支持WebSocket,不过你可以自己包一层,或者用SSE做替代。认证这块建议直接用OAuth2的device flow,Cursor那边能弹浏览器授权,不用每次手撸token,体验会顺很多。
顺便说下,如果Agent只在你自己的设备上用,其实SSH隧道就够了,反向转发端口后本地IDE配置localhost地址就行,根本不用暴露到公网。但你要是想远程访问,那就老老实实上带mTLS的网关,别为省事牺牲安全性。
MCP官方确实只定了stdio和HTTP,WebSocket得靠HTTP那层自己升级,不过实际用起来没必要纠结这个,反代加个HTTPS就够了。我自己的做法是拿Caddy反代MCP服务,自动签证书,然后配个简单的API key头,Agent那边用环境变量引用,不用每次输。SSH隧道也行,但只适合单机临时调试,长期用还是反代省心。另外token管理可以试试让Agent端读本地配置文件,别硬编码在代码里。
我用的cloudflared隧道加Access策略,比纯SSH省心,token用短期凭证自动刷新就行。
我最近也在搞这个,直接HTTP裸奔肯定不行,我最后是用Caddy反代加了mTLS,证书一配好,本地Agent那边用自定义CA签发的客户端证书就不用每次输token了,自动认证很省心。SSH隧道我试过,但Cursor重启后隧道容易断,不太适合长期用。另外MCP的HTTP transport层其实是支持WebSocket的,就是那个/ws端点,官方文档写得不明显,你抓包看握手就能发现,不过得用带token的Header,跟纯HTTP还是有点区别。
说实话我最近也在搞类似的,试下来最省心的是用tailscale或者wireguard组个虚拟内网,MCP服务只监听内网IP,然后本地IDE直接走内网地址访问,完全不用折腾HTTPS和token。至于WebSocket,官方确实没提,但MCP的HTTP transport走的是streamable HTTP,本质上是长连接,你如果用nginx反代的话记得开proxy_http_version 1.1和read timeout,不然容易断。另外你要是嫌每次手动配token烦,可以在Cursor那边写个启动脚本自动去服务器拉临时的key,不过得注意别把key打到git里。我觉得你方向没问题,就是别直接暴露HTTP,哪怕套个cloudflare tunnel也行。
说实话我也踩过这个坑,后来直接用tailscale组内网,MCP服务只监听在虚拟网卡上,本地IDE连那个私有IP,认证这块用静态token先顶着,反正流量不经过公网,安全性够用。WebSocket官方确实没提,但MCP的HTTP其实可以走WS升级,我折腾过能通,不过文档不写就别指望社区有现成方案,自己封装层挺麻烦的。
反向代理加HTTPS我也试过,主要是证书轮换和客户端校验配置太啰嗦,不如SSH隧道来得干净,一条命令搞定,就是每次重连要写脚本。你要是懒,也可以看看cloudflared的tunnel,免费版够个人用,但延迟比直连高点。token每次手动配的话,可以在IDE的agent配置里写个环境变量读取,别硬编码在MCP配置里,至少换起来方便点。
SSH隧道最省事,token都不用配。MCP目前确实只支持stdio和HTTP,WebSocket还没见影子。
我之前也是HTTP裸奔,后来换成Caddy反代加HTTPS,再配合Cloudflare Access做前置认证,本地Agent就省了手动配token的麻烦。SSH隧道偶尔用,适合临时调试,长期跑还是反代稳一点。MCP现在transport确实只有stdio和HTTP(含SSE),WebSocket还没进标准,我试过自己套一层ws转http,能用但有点折腾。你可以看看有没有人用mcp-proxy这类工具,能省不少事。
我目前是SSH隧道加本地端口转发,MCP服务只监听127.0.0.1,这样HTTP流量走加密通道,token也能写在本地配置里不用每次手填。WebSocket这块你没理解错,官方transport确实只提了stdio和HTTP,不过社区有人用HTTP upgrade硬上,稳定性一般,不建议生产用。如果想省事,可以看看mcp-proxy这类工具,帮你把远程stdio包装成HTTP,再配合反向代理加个短时token,体验会好很多。
我之前也是直接HTTP暴露的,后来改成SSH隧道加本地端口转发,token只存本地环境变量,Agent那边就不用反复填了,体验好很多。反向代理加HTTPS也靠谱,但证书和鉴权得自己维护,稍微麻烦点。WebSocket这块你没理解错,MCP transport目前主要就是stdio和HTTP,SSE算HTTP的一种,WebSocket确实没在官方支持列表里,别在这上面绕太久。
我也在折腾类似的东西,之前直接把MCP用HTTP裸奔在内网,后来发现Cursor那边每次都要手动填token确实烦,而且万一服务器有点公网暴露风险就很大。我现在用的是SSH隧道方案,本地开一个端口转发到服务器的MCP端口,然后IDE里配localhost就行,token那套直接用SSH密钥认证顶掉,省事很多。反向代理加HTTPS也可以,但证书和认证那一套配下来比较重,除非你有多人共用或者要对外提供服务。WebSocket的事我没记错的话,MCP官方transport确实主要就是stdio和HTTP SSE这两种,WebSocket不是标准支持,有些社区实现自己包了一层,但兼容性得自己扛。另外提醒一下,就算走隧道,MCP工具的权限scope最好还是在服务端做一层校验,别全信Agent传过来的参数,不然本地一旦被恶意prompt注入就麻烦了。