-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
🎯 The Goal / Use Case
MCP (Model Context Protocol) has become a common standard for exposing tools to LLMs, but it carries significant architectural constraints: it is tightly coupled to a request/response JSON-RPC pattern, struggles to scale across large tool registries, and offers no native way for an LLM to compose multi-step tool workflows without generating verbose, brittle JSON plans.
This proposal introduces two complementary capabilities:
- UTCP (Universal Tool Calling Protocol) as a first-class transport layer alongside or in place of MCP.
- CodeMode as a plugin that lets LLMs express tool workflows as lightweight Go-like code snippets instead of flat JSON tool calls.
Together these address the core limitations of MCP for production, multi-tool, agentic workloads.
💡 Proposed Solution
Part 1 — UTCP Integration
Integrate go-utcp (github.com/universal-tool-calling-protocol/go-utcp) as a supported tool provider transport. UTCP is a modern, transport-agnostic protocol that natively supports HTTP, WebSockets, gRPC, Server-Sent Events, GraphQL, CLI, UDP, WebRTC, and MCP providers under a single unified client interface.
Key capabilities gained:
- Multi-transport discovery — a single
UTCPClientdiscovers and calls tools over any supported transport without bespoke adapter code per protocol. - OpenAPI compatibility — the built-in
OpenApiConvertermaps existing REST APIs into UTCP tool definitions automatically, reducing onboarding friction. - Scalable tool registry — UTCP's in-memory repository handles large tool sets without performance degradation, unlike MCP's flat tool list model.
- MCP backward compatibility — UTCP ships an MCP provider adapter, meaning existing MCP servers continue to work without modification.
Part 2 — CodeMode Plugin
Register the CodeMode plugin (codemode.NewCodeModeUTCP(client, llmodel)) to unlock a fundamentally different interaction model. Instead of asking the LLM to emit a JSON object per tool call, CodeMode lets the LLM write a small Go-like snippet that is executed inside a Yaegi sandbox.
Inside a CodeMode snippet, the LLM has access to three native helpers:
CallTool(name string, args map[string]any) (any, error)
CallToolStream(name string, args map[string]any) (*StreamResult, error)
SearchTools(query string, limit int) ([]tools.Tool, error)This means the LLM can loop, branch, compose tool results, and handle errors — all within a single "tool call" turn — rather than requiring the orchestrator to manage multi-turn JSON planning.
Example CodeMode snippet an LLM might emit:
sum, err := CallTool("math.add", map[string]any{"a": 12, "b": 30})
if err != nil { return err }
result, err := CallTool("string.format", map[string]any{"template": "Total: {n}", "n": sum})
return result🛠 Potential Implementation
Phase 1 — UTCP Client Adapter
- Add
go-utcpas a dependency (go get github.com/universal-tool-calling-protocol/go-utcp@latest). - Implement a
UTCPToolProvideradapter that satisfies the existing internalToolProviderinterface. - Load provider definitions from a
providers.jsonconfig file (consistent with UTCP conventions). - Expose a
SearchTools(query, limit)surface for dynamic tool discovery.
Phase 2 — CodeMode Registration
- Instantiate
codemode.NewCodeModeUTCP(client, llmodel)after the UTCP client is initialized. - Register
codemode.run_codeas a native tool in the tool registry so the LLM can invoke it like any other tool. - Define a sandboxing policy (timeouts, memory limits, allowed imports) for the Yaegi execution environment.
Configuration Example
// providers.json
[
{
"name": "math-service",
"type": "http",
"url": "https://api.example.com/utcp"
},
{
"name": "legacy-mcp-server",
"type": "mcp",
"command": ["npx", "-y", "@example/mcp-server"]
}
]🚦 Impact & Roadmap Alignment
- Core Feature — multi-transport tool calling is foundational to agentic capability.
- Nice-to-Have / Enhancement — CodeMode is an opt-in plugin.
Expected Impact
| Area | Before | After |
|---|---|---|
| Supported transports | MCP / HTTP | HTTP, WS, gRPC, SSE, GraphQL, CLI, UDP, WebRTC, MCP |
| Multi-step tool composition | Multi-turn JSON planning | Single-turn code snippet (CodeMode) |
| OpenAPI tool onboarding | Manual adapter per endpoint | Automatic via OpenApiConverter |
| MCP compatibility | Full | Full (via UTCP MCP provider adapter) |
💬 Additional Context
- Repository: github.com/universal-tool-calling-protocol/go-utcp
- Spec site: utcp.io
- License: MPL-2.0
- Language: Go (98.8%), with Python examples
CodeMode's Yaegi-based sandbox means untrusted LLM-generated code never runs on the host OS directly — a meaningful security property for production deployments. Sandboxing limits (timeout, import allowlist) should be defined as part of the Phase 2 implementation spec.