Documentation
¶
Overview ¶
Package mcp transcodes between the codefly toolbox v0 contract (Connect-RPC over gRPC) and the Model Context Protocol (JSON-RPC 2.0 over stdio). External AI clients that speak MCP — Claude Desktop, Cursor, etc. — connect to a transcoded toolbox the same way they connect to any other MCP server.
This is the Phase 2 transcoder: thin, stateless, no protocol translation logic beyond name/argument mapping. Every primitive in MCP has a 1:1 correspondent in the toolbox contract because we designed the contract that way:
MCP ↔ toolbox v0 ──────────────────────────────────────────────────────── tools/list ↔ ListTools tools/call ↔ CallTool resources/list ↔ ListResources resources/read ↔ ReadResource prompts/list ↔ ListPrompts prompts/get ↔ GetPrompt initialize → serverInfo ↔ Identity
Transport: JSON-RPC 2.0 over a single io.Reader / io.Writer pair, usually os.Stdin / os.Stdout. Each frame is a JSON object on its own line — same wire format used by the existing cli/pkg/mcp server, so an MCP client that talks to one talks to the other.
Why this lives in core/toolbox/mcp/ and not cli/pkg/mcp/: the transcoder takes a toolboxv0.ToolboxClient. That client may point at an in-process toolbox (for tests, for embedded use cases) or at a spawned plugin (host.Plugin.Client()). Keeping the transcoder in core means any binary — the codefly CLI, a future `codefly toolbox mcp <name>` subcommand, or a third-party host — can wrap a toolbox in MCP without depending on cli/.
Index ¶
Constants ¶
const JSONRPCVersion = "2.0"
JSONRPCVersion is pinned in every reply. Per JSON-RPC 2.0 spec the field must be exactly the string "2.0".
const MCPProtocolVersion = "2024-11-05"
MCPProtocolVersion advertises which MCP revision the transcoder targets. Bumping this is a coordinated change with downstream clients; currently aligned with the cli/pkg/mcp server.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Transcoder ¶
type Transcoder struct {
// contains filtered or unexported fields
}
Transcoder wraps a toolboxv0.ToolboxClient and serves the MCP JSON-RPC protocol against it. One Transcoder owns one client; concurrent Serve calls against the same Transcoder are NOT safe (writes would interleave on the shared Writer).
func New ¶
func New(client toolboxv0.ToolboxClient) *Transcoder
New returns a Transcoder bound to the given toolbox client. The client must already be connected (e.g. host.Plugin.Client()). Closing the underlying connection is the caller's responsibility; Transcoder doesn't own the lifecycle.
func (*Transcoder) Serve ¶
Serve reads JSON-RPC frames from r, dispatches each to the toolbox over gRPC, and writes the result back to w. Returns when r yields io.EOF or ctx is cancelled. A malformed request is replied with a ParseError but does NOT terminate the loop — MCP clients recover from individual bad frames.
Stdio transport: pass os.Stdin and os.Stdout. JSON-RPC framing is "one JSON object per line"; bufio.Scanner with the default split fits.