hexgate.mcp module wraps any MCP server as framework-native tool objects so they go through the same policy enforcement, audit, and approval flow as native tool functions. Zero glue code: connect the server, every tool it exposes auto-registers under a mcp-<server>-<tool> namespace. Wire the tools through whichever adapter your agent is built on (LangChain, OpenAI Agents, Pydantic AI, Google ADK).
Usage
Tool naming
Qualified name format:mcp-<server>-<tool>. Hyphens (not colons or
dots) so the name passes OpenAI Function Calling’s regex
^[a-zA-Z0-9_-]{1,64}$. The server name is caller-supplied and
validated against ^[a-z0-9-]{1,32}$ so qualified names stay under the
64-char OpenAI limit even for medium-long MCP tool names.
Reference MCP tools in policy.yaml by their qualified names:
Transports
Both transports are supported: stdio (command + args + env for
subprocess MCP servers) and streamable HTTP (url + headers for remote
endpoints). The toolset is an async context manager — opening connects + lists
every server’s catalog; closing tears down transports symmetrically (with
cleanup on partial-open failures).
Adapter coverage
MCPToolset produces framework-agnostic MCPToolProxy descriptors. Each adapter has a wrap_mcp_toolset that turns those into its own tool type. Same shape everywhere; pick the one that matches your agent.
{"ok": True | False, ...} envelope on invocation. The tools share the toolset’s connection lifecycle: once the async with MCPToolset(...) block exits, calls return a use_after_close envelope rather than crashing.
Try it
Two self-contained demos — both spawn a tiny FastMCP server, so there are no external services and no LLM key required. A quick one-shot run:examples/mcp_demo.py — attaches the server via MCPToolset and prints one call per policy outcome (allow / deny / approval-required).
An interactive notebook:
deploy/mcp_gate_demo.py — a marimo notebook that connects to the server, lists its tools under the mcp-<server>-<tool> namespace, and gates them with a default-deny policy plus per-argument constraints. Edit the tool and arguments and re-run to watch the gate decide live: allowed calls execute against the server, denied ones are stopped before it.
What hexgate does NOT do (yet)
- Catalog threat scanning — typosquatting and prompt-injection pattern detection on tool descriptions at registration time is not performed.
- Response-side gating — gating based on the return value of an MCP call. Today only the invocation is gated; returned content is passed through to the model.
- Reconnection — a dropped transport surfaces as a tool-call error; the toolset doesn’t auto-reconnect.
- Declarative
mcp_servers:block inagent.yaml— attach servers programmatically viaMCPToolset(...); there’s no YAML wiring yet.