Documentation
¶
Overview ¶
Package mcp implements a minimal Model Context Protocol (MCP) server over the stdio transport using JSON-RPC 2.0 (ADR-0028). It is deliberately stdlib-only (encoding/json + bufio framing) — CommitBrief carries no MCP SDK and the surface we expose (initialize, tools/list, tools/call) is small enough that a hand-rolled layer is cheaper than a heavy dependency.
The transport is line-delimited JSON: each JSON-RPC message is a single object written on its own line and flushed, matching the newline-delimited framing every MCP host that speaks stdio understands. We intentionally do NOT implement the optional Content-Length header framing — the line form is simpler, is what the reference hosts default to over stdio, and keeps the reader a plain bufio.Scanner.
Index ¶
Constants ¶
const ProtocolVersion = "2024-11-05"
ProtocolVersion is the MCP revision this server advertises in the initialize response. Kept as a constant so the handshake answer and any future negotiation logic share one source of truth.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is a minimal MCP server speaking JSON-RPC 2.0 over a line-delimited stdio transport (ADR-0028). Construct it with New, register tools with Register, then drive the read/dispatch/write loop with Serve. The server is single-connection and processes requests sequentially — there is exactly one host on the other end of stdio, and a review is a blocking operation, so concurrency would buy nothing and complicate the guard/preflight prompts.
func (*Server) Register ¶
func (s *Server) Register(def Tool, handler ToolHandler)
Register adds a tool. def.InputSchema must already be valid JSON Schema. Registering two tools with the same name panics — it is a programming error, caught at startup, never on the wire.
func (*Server) Serve ¶
Serve runs the read → dispatch → write loop until r reaches EOF (the host closed stdin) or a write to w fails. It returns nil on a clean EOF so a host disconnect is a normal shutdown, not an error. ctx is threaded into every tool handler so the host (or a signal) can cancel an in-flight review.
Framing: one JSON message per line. We use a bufio.Scanner with an enlarged buffer because a tools/call result can carry a sizeable findings document; the default 64KiB token cap would truncate large reviews.
type Tool ¶
type Tool struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema json.RawMessage `json:"inputSchema"`
}
Tool is one MCP tool advertised to the host. InputSchema is a JSON Schema object describing the tool's arguments; we marshal it from a Go map so the schema lives next to the handler (see tools.go).
type ToolHandler ¶
type ToolHandler func(ctx context.Context, arguments json.RawMessage) (summary string, structured string, err error)
ToolHandler runs one tool invocation. arguments is the raw JSON of the host-supplied "arguments" object (may be empty). The handler returns the text summary, the structured JSON payload, and an error.
A non-nil error is reported to the host as a tool-level failure (callToolResult.IsError = true) carrying err.Error() — NOT as a JSON-RPC protocol error, so a failed review (e.g. an aborted secret-scan guard) reaches the model as actionable content instead of tearing down the call.