mcp

package
v0.0.19 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 3, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package mcp implements a minimal Model Context Protocol client over the stdio transport. JSON-RPC 2.0 messages are exchanged as newline-delimited JSON on the server's stdin/stdout. We speak just enough of the protocol to discover and call tools (initialize, tools/list, tools/call); other MCP capabilities (resources, prompts, sampling, roots) are not used.

Index

Constants

View Source
const (
	// JSONRPCVersion is the JSON-RPC dialect we and the server agree on.
	JSONRPCVersion = "2.0"
	// ProtocolVersion is the MCP version we advertise during initialize.
	ProtocolVersion = "2024-11-05"
)
View Source
const NamespaceSeparator = "__"

NamespaceSeparator joins an MCP server's tool_prefix with the upstream tool name. Double-underscore is safe under Anthropic's and OpenAI's tool-name regex (`^[a-zA-Z0-9_-]{1,64}$`).

Variables

View Source
var ErrNoTransport = errors.New("mcp: no usable servers")

ErrNoTransport is returned when no spec is usable (every entry skipped).

Functions

func Resolve

func Resolve(docs []*config.Document, refs []string) (specs []*config.MCPServerSpec, missing []string)

Resolve picks out MCPServerSpec documents from a doc collection by name. Unknown refs are returned in missing.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a JSON-RPC peer talking to an MCP server over a pair of io streams. Stdio framing is one JSON object per line.

Construction: NewProcessClient (spawns a server) or NewPipeClient (tests / custom transports). Initialize must run before tools/list or tools/call.

func NewPipeClient

func NewPipeClient(in io.WriteCloser, out io.ReadCloser) *Client

NewPipeClient wires a Client to the given streams. Used by tests.

func NewProcessClient

func NewProcessClient(ctx context.Context, command []string, env map[string]string) (*Client, error)

NewProcessClient launches the given command with the supplied env and starts the read loop. Caller must call Close to terminate the subprocess.

env entries are appended to the parent environment so the child still sees PATH etc.; pass only the variables you want to add or override.

func (*Client) CallTool

func (c *Client) CallTool(ctx context.Context, name string, args json.RawMessage) (string, bool, error)

CallTool invokes name on the server with the given JSON-encoded args. Returns the concatenated text content, the isError flag from the server, and a transport-level error if any.

func (*Client) Close

func (c *Client) Close() error

Close closes the writer side, waits briefly for the subprocess (if any) to exit, and force-kills it on timeout.

func (*Client) Initialize

func (c *Client) Initialize(ctx context.Context, clientName, clientVersion string) error

Initialize performs the MCP handshake: sends initialize, then the notifications/initialized notification on success.

func (*Client) ListTools

func (c *Client) ListTools(ctx context.Context) ([]Tool, error)

ListTools returns the server's currently published tool listing.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager owns a set of running MCP clients and exposes their tools as adapters in a tools.Registry.

func Open

func Open(ctx context.Context, specs []*config.MCPServerSpec, agentName string, status io.Writer) (*Manager, error)

Open spawns the MCP servers in specs (filtered by allowed_agents if agentName is set), runs initialize + tools/list against each, and returns a Manager whose Registry() exposes namespaced tools. On any error the partially-opened clients are closed before returning.

Servers whose transport is not stdio are skipped with a warning on status; M5 supports stdio only.

func (*Manager) Close

func (m *Manager) Close() error

Close shuts down every client. The first error is returned; later errors are dropped so we always tear all servers down.

func (*Manager) Registry

func (m *Manager) Registry() *tools.Registry

Registry returns a fresh registry containing every tool exposed by every open client. Builtins are not included; callers compose them externally.

type RPCError

type RPCError struct {
	Code    int             `json:"code"`
	Message string          `json:"message"`
	Data    json.RawMessage `json:"data,omitempty"`
}

RPCError is a JSON-RPC error object surfaced to callers.

type Tool

type Tool struct {
	Name        string          `json:"name"`
	Description string          `json:"description,omitempty"`
	InputSchema json.RawMessage `json:"inputSchema"`
}

Tool is a single tool listing returned by tools/list.

type ToolAdapter

type ToolAdapter struct {
	// contains filtered or unexported fields
}

ToolAdapter wraps an MCP tool so it satisfies tools.Tool. The model sees a namespaced name (e.g. "github__create_issue"); the adapter strips the prefix when calling the upstream server.

func NewToolAdapter

func NewToolAdapter(client *Client, upstream Tool, prefix string) *ToolAdapter

NewToolAdapter binds upstream to client and constructs the namespaced name. If prefix is empty, the upstream name is used as-is.

func (*ToolAdapter) Description

func (a *ToolAdapter) Description() string

Description implements tools.Tool.

func (*ToolAdapter) InputSchema

func (a *ToolAdapter) InputSchema() json.RawMessage

InputSchema implements tools.Tool. Defaults to an empty object schema so providers don't reject the tool when an MCP server omits one.

func (*ToolAdapter) Name

func (a *ToolAdapter) Name() string

Name implements tools.Tool.

func (*ToolAdapter) Run

func (a *ToolAdapter) Run(ctx context.Context, input json.RawMessage) (string, error)

Run implements tools.Tool. Upstream errors (transport/protocol) become Go errors; an isError=true result is rendered as a non-nil error so the engine flags it accordingly to the model.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL