{{ message }}
feat(tunnel): connect on-prem MCP servers to a cloud agent#575
Merged
Conversation
Add veadk.tunnel: an outbound reverse tunnel so a cloud agent can use an enterprise's on-prem MCP servers without inbound ports. - Agent(enable_tunnel=True) injects a TunnelToolset; ADK resolves tools per turn, so registering/removing a server takes effect with no redeploy. - registry (per-agent buckets) + protocol/ factory (BaseProtocol -> McpProtocol) so the cloud detects the protocol type and mounts the right handler. - server.mount_tunnel(): /tunnel/connect WS (registration, token auth via header/querystring, target-agent validation) + streaming proxy + REST list. - connector (enterprise side): registers servers to a named agent and bridges calls, attaching per-server auth headers/query that stay on-prem. - examples/tunnel: enable_tunnel agent + app.py + connector.py + a demo MCP server + bilingual README. - remove the old toolkits/apps/reverse_mcp prototype. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- TunnelConnector gains extra_headers so an edge/API-gateway credential (Authorization) is sent on the WS handshake separately from the tunnel token (which goes via ?token=). Needed behind AgentKit key_auth. - examples/tunnel: GATEWAY_KEY wiring + agentkit deploy helpers (install_veadk.sh build script, requirements, .dockerignore, .gitignore). Verified on AgentKit: WebSocket passes the gateway, a connector registers an on-prem MCP server, and the deployed agent calls it through the tunnel (add_numbers -> 5). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
d5e6b5c to
7fdcb8b
Compare
Document veadk.tunnel as a top-level framework capability (Extend & UI), not buried under tools: how it works, enable_tunnel + mount_tunnel, the enterprise connector, two-layer auth, AgentKit deploy notes (gateway WS + extra_headers), and limitations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Number the example to match the other graded examples and name it after the MCP-tunnel scenario; update doc links. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…eral (MCP = first protocol) - examples/14_mcp-tunnel -> examples/12_mcp-tunnel - rewrite the Tunnel doc to present the tunnel as a generic on-prem resource bridge with a protocol layer (BaseProtocol + get_protocol factory); MCP is the first built-in protocol, extensible to others. Update example links. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
zakahan
approved these changes
Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What
Adds
veadk.tunnel: an outbound reverse tunnel so a cloud agent can use an enterprise's on-prem MCP servers without opening any inbound port. The connector dials out from the enterprise network and registers its MCP server(s) to a named cloud agent; the agent picks them up as tools dynamically.Design
Agent(enable_tunnel=True)injects a singleTunnelToolset. ADK resolves tools per turn (canonical_tools→get_tools), so registering/removing a server takes effect on the next turn — no redeploy.registry.py—TunnelRegistrykeyed by agent name (per-agent buckets), process-global singleton;ServerDescriptorcarries per-server auth (headers/query).protocol/—BaseProtocol+McpProtocol, with aget_protocol(type)factory so the cloud detects the protocol type and mounts the right handler (extensible to non-MCP later).server.py—mount_tunnel()/mount_tunnel_if_enabled():/tunnel/connectWS (registration + token auth via header/?token=+ target-agent validation) + streaming proxy +/tunnel/serversREST. Mounts only if some agent hasenable_tunnel.connector.py— enterprise side: registers servers to a named agent and bridges calls, attaching per-server auth that stays on-prem.extra_headerslets an edge/API-gateway credential ride the WS handshake separately from the tunnel token.Two-layer auth: tunnel token (connector→agent) + per-server headers/query (connector→your MCP server, secrets never leave the enterprise).
Removes
The old
veadk/toolkits/apps/reverse_mcp/prototype (no external importers).Example
examples/tunnel/: anenable_tunnelagent +app.py(ADK server + tunnel) +connector.py+ a demo MCP server + bilingual README + AgentKit deploy helpers.Verified on AgentKit
Deployed
examples/tunnelto Volcengine AgentKit (key_auth) and ran the full path:register_ack ok.invoke "计算 2 加 3"→ agent callsadd_numbersover gateway→WS→connector→local MCP → returns 5.Known limitations (documented)
🤖 Generated with Claude Code