mcp局部隧道
暴露本地 MCP服务器 远程客户端——无需打开端口。
你跑了一个 继电器 在具有公共URL的服务器上,以及 代理 在您的本地机器上。代理通过WebSocket向外连接到中继——不需要入站端口。继电器暴露了一个标准 可流式传输HTTP MCP端点 OAuth 2.1 auth,因此任何MCP客户端都可以连接到它。
MCP client (Claude.ai, Cursor, etc.)
|
v
relay (tunnel.example.com) you host this
^
| outbound WebSocket
|
agent (npx mcp-local-tunnel) your laptop
|
v
local MCP servers stdio or HTTP中继和代理都是一样的 mcp-local-tunnel 包裹——你刚刚设置好 "mode": "relay" 或 "mode": "agent" 在配置中。它也作为上游 mcp聚合器 --聚合器只看到另一个带有工具的MCP服务器。
用法
中继
集 MCP_LOCAL_TUNNEL_CONFIG 转到JSON配置对象并运行:
MCP_LOCAL_TUNNEL_CONFIG='{
"mode": "relay",
"auth": {"issuer": "https://auth.example.com"}
}' npx -y mcp-local-tunnel这将在localhost:3000上启动HTTP MCP服务器。MCP客户端连接到 /mcp 使用OAuth。代理连接到 /ws 带有不记名代币。
Other configuration methods
env-var也可以指向文件路径:
MCP_LOCAL_TUNNEL_CONFIG=/path/to/config.json npx -y mcp-local-tunnel或创建 mcp-local-tunnel.config.json 在工作目录中,它会被自动拾取:
npx -y mcp-local-tunnelRunning with Docker
docker run -e 'MCP_LOCAL_TUNNEL_CONFIG={"mode":"relay","auth":{"issuer":"..."}}' -p 3000:3000 ghcr.io/domdomegg/mcp-local-tunnel代理
MCP_LOCAL_TUNNEL_CONFIG='{
"mode": "agent",
"relay": "tunnel.example.com",
"servers": {
"shell": {"command": ["npx", "-y", "shell-exec-mcp"]},
"computer": {"command": ["npx", "-y", "computer-use-mcp"]},
"filesystem": {"command": ["npx", "-y", "filesystem-mcp"]}
}
}' npx -y mcp-local-tunnel在第一次运行时,代理打开您的浏览器进行登录(与中继相同的身份提供程序)。身份验证后,令牌将缓存在 ~/.config/mcp-local-tunnel/ 因此后续运行会立即连接。
代理生成已配置的本地MCP服务器,连接到中继,并注册其所有工具。远程客户端可以看到以下工具 shell__execute 和 computer__computer --按服务器名称分隔的名称。
当在Claude Code或opencode等工具中用作MCP服务器时,代理作为后台守护进程运行。多个会话共享一个中继连接——只要至少有一个会话存在,守护进程就会保持活动状态,并在最后一个会话结束后自动关闭。守护进程日志被写入 ~/.config/mcp-local-tunnel/logs/.
如果代理断开连接(笔记本电脑休眠、网络中断),它会自动以指数回退方式重新连接。
配置
两种模式都使用相同的配置加载: MCP_LOCAL_TUNNEL_CONFIG env-var(JSON字符串或文件路径),或 mcp-local-tunnel.config.json 在工作目录中。
共享
| 字段 | 必填 | 描述 |
|---|---|---|
mode | 是的 | "relay" 或 "agent". |
中继模式
仅 mode 和 auth.issuer 是必需的。其他一切都有合理的违约。
| 字段 | 必填 | 描述 |
|---|---|---|
auth.issuer | 是 | 您的登录提供商的URL。必须支持 OpenID连接发现. |
auth.clientId | 没有 | 在您的登录提供商处注册的客户端ID。默认为 "mcp-local-tunnel". |
auth.clientSecret | 否 | 客户端机密。为公众客户省略。 |
auth.scopes | 无 | 登录时请求的范围。默认为 ["openid"]. |
auth.userClaim | 否 | 登录令牌中的哪个字段标识用户。默认为 "sub". |
port | 无 | 要监听的端口。默认为 3000. |
host | 无 | 要绑定的主机。默认为 "0.0.0.0". |
issuerUrl | 否 | 此服务器的公共URL。在反向代理后面时需要。 |
secret | 没有 | 令牌的签名密钥。如果未设置,则为随机。设置一个固定值以在重新启动后继续运行。 |
一个完整的中继示例:
{
"mode": "relay",
"auth": {
"issuer": "https://keycloak.example.com/realms/myrealm",
"clientId": "mcp-local-tunnel",
"clientSecret": "optional-secret"
},
"port": 3000,
"host": "0.0.0.0",
"issuerUrl": "https://tunnel.example.com",
"secret": "some-persistent-secret"
}代理模式
仅 mode, relay,以及 servers 是必需的。
| 字段 | 必填 | 描述 |
|---|---|---|
relay | 是 | 中继服务器的域(例如。 tunnel.example.com).代理连接到 wss:///ws. |
name | 否 | 此设备的名称。默认为计算机主机名。用于区分每个用户的多个设备。 |
servers | 是 | 要公开的本地MCP服务器的映射。键成为工具名称前缀。 |
servers..command | -- | 生成stdio MCP服务器的命令数组(例如。 ["npx", "-y", "shell-exec-mcp"]). |
servers..url | -- | 已运行的HTTP MCP服务器的URL。提供其中之一 command 或 url不是两者都有。 |
servers..env | 无 | 生成命令时要设置的额外环境变量。 |
一个完整的代理示例:
{
"mode": "agent",
"relay": "tunnel.example.com",
"name": "my-laptop",
"servers": {
"shell": {
"command": ["npx", "-y", "shell-exec-mcp"]
},
"computer": {
"command": ["npx", "-y", "computer-use-mcp"]
},
"filesystem": {
"command": ["npx", "-y", "filesystem-mcp"]
}
}
}登录提供者示例
Google Workspace
{
"mode": "relay",
"auth": {
"issuer": "https://accounts.google.com",
"clientId": "...",
"clientSecret": "..."
}
}在中创建OAuth 2.0凭据 谷歌云控制台。选择“Web应用程序”,添加 https:///callback 作为授权的重定向URI。要限制对组织的访问,请将OAuth同意屏幕配置为“内部”。
Microsoft Entra ID
{
"mode": "relay",
"auth": {
"issuer": "https://login.microsoftonline.com//v2.0",
"clientId": "...",
"clientSecret": "..."
}
}在 Azure门户.添加 https:///callback 作为“Web”下的重定向URI。在“证书和机密”下创建客户端机密。替换 `` 使用您的目录(租户)ID。
Okta
{
"mode": "relay",
"auth": {
"issuer": "https://your-org.okta.com",
"clientId": "...",
"clientSecret": "..."
}
}在Okta中创建Web应用程序。将登录重定向URI设置为 https:///callback。发行人URL是您的Okta组织URL(或自定义授权服务器URL,如果您使用的话)。
Keycloak
{
"mode": "relay",
"auth": {
"issuer": "https://keycloak.example.com/realms/myrealm",
"clientSecret": "..."
}
}使用客户端ID在Keycloak领域中创建OpenID Connect客户端 mcp-local-tunnel (或设置 auth.clientId 匹配)。将重定向URI设置为 https:///callback。用户由以下人员标识 sub 默认情况下为(Keycloak用户ID)。集 auth.userClaim 到 preferred_username 改为按用户名匹配。
Auth0
{
"mode": "relay",
"auth": {
"issuer": "https://your-tenant.auth0.com",
"clientId": "...",
"clientSecret": "..."
}
}在Auth0中创建常规Web应用程序。添加 https:///callback 作为允许的回调URL。设置 auth.clientId 到Auth0应用程序的客户端ID sub Auth0中的声明通常以连接类型作为前缀(例如。 auth0|abc123).
Authentik
{
"mode": "relay",
"auth": {
"issuer": "https://authentik.example.com/application/o/myapp/",
"clientSecret": "...",
"userClaim": "preferred_username"
}
}使用客户端ID在Authentik中创建OAuth2/OpenID提供程序 mcp-local-tunnel (或设置 auth.clientId 匹配)。将重定向URI设置为 https:///callback.
Home Assistant (via hass-oidc-provider)
Home Assistant本身不支持OpenID Connect。使用 hass oidc提供商 为了弥合差距,它与Home Assistant一起运行,并添加了缺失的部分。
{
"mode": "relay",
"auth": {
"issuer": "https://hass-oidc-provider.example.com"
}
}点 auth.issuer 在您的hass-oidc提供商实例上(而不是直接在Home Assistant上)。这 sub claims是家庭助理用户ID。否 clientId 或 clientSecret 需要。
元工具
继电器暴露了两个内置工具:
status--显示代理是否已连接、其设备名称、正常运行时间和可用工具。restart-告诉连接的代理重新启动其本地MCP服务器进程。如果服务器卡住或其配置已更改,则很有用。
即使没有连接代理,这些也始终可用。
多个设备
如果你在多台机器上运行代理 name 场区分他们。当连接多个设备时,工具前缀为设备名称:
laptop__shell__execute
desktop__shell__execute当只有一个设备连接时,设备前缀将被省略。
贡献
GitHub上欢迎拉取请求!开始:
- 安装Git和Node.js
- 克隆存储库
- 安装依赖项
npm install - 跑
npm run test运行测试 - 构建于
npm run build
发布
版本遵循 语义版本规范.
要发布:
- 使用
npm version升级版本 - 跑
git push --follow-tags使用标签推送 - 等待GitHub Actions发布到NPM注册表和GHCR(Docker)。
