mcpclient

package
v0.37.0 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package mcpclient implements the MCP client (consumer side) the harness uses to talk to external MCP servers.

v0.1: stdio transport only (the only one needed for the gofastr-introspection and kiln MCP servers shipped with the v0.1 profile presets). HTTP+SSE / streamable HTTP land in v0.2.

Wire format: JSON-RPC 2.0 (newline-delimited).

Package mcpclient is part of the GoFastr harness.

See docs/harness-architecture.md for the architecture this package implements.

Index

Constants

This section is empty.

Variables

View Source
var ErrClosed = errors.New("mcpclient: closed")

ErrClosed is returned when methods are called after Close.

Functions

This section is empty.

Types

type Client

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

Client speaks the MCP wire protocol over stdio against a child process. Concurrency-safe.

func Spawn

func Spawn(ctx context.Context, cmd string, args []string, expectedSHA256 string) (*Client, error)

Spawn launches the MCP server subprocess and performs the `initialize` handshake. If `expectedSHA256` is non-empty, the binary is checked against the hash and refused on mismatch.

The child receives ONLY a minimal allowlisted environment (PATH, HOME, TMPDIR, plus the platform basics needed to exec) — NOT the host's full os.Environ(). This prevents host secrets (JWT_SECRET, DB DSN, OAuth keys, …) from leaking into every spawned MCP server. Callers that need more must use SpawnWithConfig.

func SpawnWithConfig added in v0.31.0

func SpawnWithConfig(ctx context.Context, cmd string, args []string, expectedSHA256 string, cfg SpawnConfig) (*Client, error)

SpawnWithConfig is Spawn with an explicit SpawnConfig for callers that need env vars beyond the scrubbed default allowlist. See SpawnConfig for the fields and Spawn for the rest of the behaviour.

func (*Client) Call

func (c *Client) Call(ctx context.Context, method string, params any) (json.RawMessage, error)

Call issues a JSON-RPC request and waits for the response.

func (*Client) CallTool

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

CallTool invokes a tool. Returns the structured result.

func (*Client) Close

func (c *Client) Close() error

Close terminates the child process.

func (*Client) ListTools

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

ListTools requests the server's tools/list. With schemas=false (lazy discovery), inputSchema fields are dropped client-side to save the per-startup tier-2 cost.

func (*Client) Notify

func (c *Client) Notify(_ context.Context, method string, params any) error

Notify sends a notification (no response expected).

type SHA256MismatchError

type SHA256MismatchError struct {
	Path     string
	Expected string
	Actual   string
}

SHA256MismatchError is returned when the configured binary hash doesn't match the on-disk hash. Maps to the ReasonMCPServerSHA256Mismatch wire error code.

func (*SHA256MismatchError) Error

func (e *SHA256MismatchError) Error() string

type Source

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

Source adapts an MCP Client into a tool.ToolSource. Tools the remote server exposes are surfaced under namespace prefixes like "mcp:kiln.create_entity" so they don't collide with built-ins.

func NewSource

func NewSource(name, discovery string, c *Client) *Source

NewSource constructs a Source.

discovery selects between:

  • "eager": tools/list + schemas fetched at startup. Use for low-tool-count servers (<=20 tools).
  • "lazy": tools/list only at startup; tool_schema fetched on first invocation. Default for high-tool-count servers.

Per the spec, /list already returns names + descriptions + inputSchema. The "lazy" mode in v0.1 just defers tool registration to later if no schema has been seen — but most servers return schemas in /list anyway, so the actual savings come from server implementations that elide schemas in /list.

func (*Source) Name

func (s *Source) Name() string

Name implements tool.ToolSource.

func (*Source) Tools

func (s *Source) Tools(ctx context.Context) ([]tool.Tool, error)

Tools implements tool.ToolSource by calling the MCP server's tools/list.

type SpawnConfig added in v0.31.0

type SpawnConfig struct {
	Env        []string // extra "KEY=VALUE" entries; override allowlist on collision
	InheritEnv []string // host env var names to copy through beyond the allowlist
}

SpawnConfig controls the extras a Spawn caller may pass beyond the default scrubbed allowlist. Both fields are additive on top of the allowlist; neither ever causes the host's full os.Environ() to be inherited.

  • Env: explicit "KEY=VALUE" entries. These win over the allowlist when a name collides, so a caller can pin a tool's config without touching the host. Use this for values the caller knows.
  • InheritEnv: names of host env vars to copy through verbatim (value taken from os.Getenv at spawn time). Use this when a tool needs a host var by name (e.g. an API key the operator intentionally exposes to that one child). Every name is a deliberate allow decision — do not list secrets here unless the child is meant to see them.

type ToolDescriptor

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

ToolDescriptor is the tier-1 metadata for one tool.

Jump to

Keyboard shortcuts

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