Documentation
¶
Overview ¶
Package mcpclient is spectackle's own MCP client: it lets the binary make a headless tool call against a spectackle server (spawned over stdio, or a resident server reached over Streamable HTTP) without an external wrapper script (CLI-002). It is a thin, single-purpose layer over the go-sdk mcp.Client — transport selection, one Call method, and dense-record passthrough. No hand-rolled JSON-RPC framing.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrToolRefused = errors.New("tool refused")
ErrToolRefused marks a tool result that carried IsError: the rendered text holds the refusal itself, and callers that already surfaced the text (the CLI prints it to stdout) need only the exit-code signal, not a second prose rendition of the failure.
Functions ¶
This section is empty.
Types ¶
type Call ¶
Call names a tool and its arguments, exactly as the MCP `tools/call` request takes them.
type Config ¶
type Config struct {
// Endpoint is the http(s) URL of a resident server (Streamable HTTP).
// Empty means: spawn a fresh server over stdio instead.
Endpoint string
// Command is the executable to spawn when Endpoint is empty. Empty
// means: re-exec the running binary (os.Executable()).
Command string
// Root is the workspace root passed to the spawned server (-root). Only
// used for the stdio transport.
Root string
}
Config selects the transport and, for a spawned server, its workspace.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session is a live connection to a spectackle MCP server, over whichever transport Dial picked.
func Dial ¶
Dial connects to a spectackle server: Streamable HTTP when cfg.Endpoint is set, otherwise a freshly spawned `<command> serve -root <cfg.Root>` over stdio. Connect performs the MCP `initialize` handshake and the `initialized` notification (go-sdk mcp.Client.Connect) — no hand-rolled JSON-RPC framing.
func (*Session) Call ¶
Call invokes a tool and renders its result the way every other spectackle surface does: the concatenation of the result's text content blocks, joined by newline, with no added framing, prefixes or JSON — the dense line-record grammar (docs/tools.md) passes through byte-identically. Non-text content blocks are skipped.
When the tool result carries IsError, Call returns the rendered text AND a non-nil error, so a caller can tell a refusal (`! GATE ...`, `! REJECTED ...`) from success without parsing prose.
func (*Session) Close ¶
Close is idempotent and releases the transport: for stdio, it closes the child's stdin and waits for it to exit (escalating to SIGTERM/SIGKILL if it doesn't); for http, it closes the client connection.
func (*Session) Instructions ¶
Instructions returns the server's instructions string, captured from the initialize handshake (mcp.InitializeResult.Instructions). This is the self-bootstrapping manifest that teaches a connecting agent the whole lifecycle loop and tool order; dropping it silently is what an earlier hand-rolled wrapper got wrong during this project's own development.
func (*Session) ShapeLine ¶ added in v0.2.0
ShapeLine renders one dense argument-shape line for a tool, from the live session's own tool list (cached after the first fetch): property names with required ones starred and enum-shaped descriptions inlined. Built for the CLI's schema-refusal path (B-01KYE69): the SDK validation message names only the REJECTED property, and a live judge burned fourteen refusals cycling invented decide arguments because nothing ever named the accepted vocabulary — `choose` cannot be guessed, it has to be said once.