feat(tunnel): connect on-prem MCP servers to a cloud agent by yaozheng-fang · Pull Request #575 · volcengine/veadk-python · GitHub
Skip to content

feat(tunnel): connect on-prem MCP servers to a cloud agent#575

Merged
zakahan merged 6 commits into
mainfrom
feat/tunnel
Jun 2, 2026
Merged

feat(tunnel): connect on-prem MCP servers to a cloud agent#575
zakahan merged 6 commits into
mainfrom
feat/tunnel

Conversation

@yaozheng-fang

Copy link
Copy Markdown
Collaborator

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 single TunnelToolset. ADK resolves tools per turn (canonical_toolsget_tools), so registering/removing a server takes effect on the next turn — no redeploy.
  • registry.pyTunnelRegistry keyed by agent name (per-agent buckets), process-global singleton; ServerDescriptor carries per-server auth (headers/query).
  • protocol/BaseProtocol + McpProtocol, with a get_protocol(type) factory so the cloud detects the protocol type and mounts the right handler (extensible to non-MCP later).
  • server.pymount_tunnel() / mount_tunnel_if_enabled(): /tunnel/connect WS (registration + token auth via header/?token= + target-agent validation) + streaming proxy + /tunnel/servers REST. Mounts only if some agent has enable_tunnel.
  • connector.py — enterprise side: registers servers to a named agent and bridges calls, attaching per-server auth that stays on-prem. extra_headers lets 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/: an enable_tunnel agent + app.py (ADK server + tunnel) + connector.py + a demo MCP server + bilingual README + AgentKit deploy helpers.

Verified on AgentKit

Deployed examples/tunnel to Volcengine AgentKit (key_auth) and ran the full path:

  • ✅ WebSocket passes the gateway (the main risk) — register_ack ok.
  • ✅ Connector (local) registers an on-prem MCP server through the gateway.
  • ✅ Deployed agent calls the tunneled tool end-to-end: invoke "计算 2 加 3" → agent calls add_numbers over gateway→WS→connector→local MCP → returns 5.

Known limitations (documented)

  • Registry is in-process: the connector WS and the agent run must hit the same process → single replica / sticky routing until a shared registry/bus is added.
  • Cancellation of a cloud-side request doesn't yet stop the connector's long-lived stream.
  • No web config page yet (registration is via the connector + token).

🤖 Generated with Claude Code

yaozheng-fang and others added 2 commits June 2, 2026 13:44
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>
yaozheng-fang and others added 4 commits June 2, 2026 13:49
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 zakahan merged commit 4bfdcf5 into main Jun 2, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants