Documentation
¶
Index ¶
- Constants
- Variables
- func CancelTask(c *Client, taskID string) error
- func CancelTaskV1(c *Client, taskID string) (*core.CancelTaskResultV1, error)
- func DoWithAuthRetry(ts core.TokenSource, buildReq func() (*http.Request, error), ...) (*http.Response, error)
- func ExtractMethodFromJSON(data []byte) string
- func FileInputsFromTool(tool core.ToolDef) map[string]core.FileInputDescriptor
- func GetTask(c *Client, taskID string) (*core.DetailedTask, error)
- func GetTaskPayloadV1(c *Client, taskID string) (*core.ToolResult, string, error)
- func GetTaskV1(c *Client, taskID string) (*core.GetTaskResultV1, error)
- func IsToolTaskV1(tool core.ToolDef) bool
- func IsTransientError(err error) bool
- func ListTasksV1(c *Client, cursor string) (*core.ListTasksResultV1, error)
- func PrepareFileArg(path string, desc *core.FileInputDescriptor) (string, error)
- func ResolveEndpointURL(baseSSEURL, endpointRef string) (string, error)
- func SetDefaultClientMode(m ClientMode)
- func ToolCallAsTaskV1(c *Client, name string, args any, opts ...*TaskCallOptionsV1) (*core.CreateTaskResultV1, error)
- func ToolCallTyped[T any](c *Client, name string, args any) (T, error)
- func UpdateTask(c *Client, req core.UpdateTaskRequest) error
- func WaitForTask(ctx context.Context, c *Client, taskID string, opts ...WaitOptions) (*core.DetailedTask, error)
- func WaitForTaskV1(ctx context.Context, c *Client, taskID string, pollInterval time.Duration) (*core.GetTaskResultV1, error)
- type CallContext
- type CallResult
- type Client
- func (c *Client) Call(method string, params any) (*CallResult, error)
- func (c *Client) CallContext(cc *CallContext, method string, params any) (*CallResult, error)
- func (c *Client) Close() error
- func (c *Client) Connect() error
- func (c *Client) Discover() (*DiscoverResult, error)
- func (c *Client) HandleServerRequest(req *core.Request) *core.Response
- func (c *Client) HandleServerRequestWithContext(ctx context.Context, req *core.Request) *core.Response
- func (c *Client) ListPrompts(ctx context.Context) ([]core.PromptDef, error)
- func (c *Client) ListPromptsPage(cursor string) (*core.PromptsListResult, error)
- func (c *Client) ListResourceTemplates(ctx context.Context) ([]core.ResourceTemplate, error)
- func (c *Client) ListResourceTemplatesPage(cursor string) (*core.ResourceTemplatesListResult, error)
- func (c *Client) ListResources(ctx context.Context) ([]core.ResourceDef, error)
- func (c *Client) ListResourcesPage(cursor string) (*core.ResourcesListResult, error)
- func (c *Client) ListTools(ctx context.Context) ([]core.ToolDef, error)
- func (c *Client) ListToolsForModel(ctx context.Context) ([]core.ToolDef, error)
- func (c *Client) ListToolsPage(cursor string) (*core.ToolsListResult, error)
- func (c *Client) NotifyRootsChanged() errordeprecated
- func (c *Client) Prompts(ctx context.Context) iter.Seq2[core.PromptDef, error]
- func (c *Client) ReadResource(uri string) (string, error)
- func (c *Client) ReadResourceFull(uri string) (*core.ResourceResult, error)
- func (c *Client) ResourceTemplates(ctx context.Context) iter.Seq2[core.ResourceTemplate, error]
- func (c *Client) Resources(ctx context.Context) iter.Seq2[core.ResourceDef, error]
- func (c *Client) ServerExtensionCapability(id string) (core.ExtensionCapability, bool)
- func (c *Client) ServerSupportsExtension(id string) bool
- func (c *Client) ServerSupportsUI() bool
- func (c *Client) SessionID() string
- func (c *Client) SetLogLevel(level string) error
- func (c *Client) SetTransport(t core.Transport)
- func (c *Client) SetURL(url string)
- func (c *Client) SubscribeResource(uri string) error
- func (c *Client) ToolCall(name string, args any) (string, error)
- func (c *Client) ToolCallFull(name string, args any) (*core.ToolResult, error)
- func (c *Client) Tools(ctx context.Context) iter.Seq2[core.ToolDef, error]
- func (c *Client) URL() string
- func (c *Client) UnsubscribeResource(uri string) error
- func (c *Client) UsingStatelessWire() bool
- type ClientAuthError
- type ClientCallFunc
- type ClientMiddleware
- type ClientMode
- type ClientOption
- func WithClientBearerToken(token string) ClientOption
- func WithClientKeepalive(interval time.Duration, maxFailures int) ClientOption
- func WithClientLogging(logger *log.Logger) ClientOption
- func WithClientMiddleware(mw ...ClientMiddleware) ClientOption
- func WithClientMode(m ClientMode) ClientOption
- func WithCommandTransport(name string, args []string, opts ...CommandOption) ClientOption
- func WithConnectTimeout(d time.Duration) ClientOption
- func WithContentChunkHandler(fn func(chunk core.ContentChunk)) ClientOption
- func WithElicitationCompleteHandler(h ElicitationCompleteHandler) ClientOption
- func WithElicitationHandler(h ElicitationHandler) ClientOption
- func WithElicitationURLSupport() ClientOption
- func WithExtension(id string, cap core.ClientExtensionCap) ClientOption
- func WithFileInputs() ClientOption
- func WithGetSSEStream() ClientOption
- func WithIOTransport(r io.Reader, w io.Writer) ClientOption
- func WithInspectResponse(fn func(*http.Response)) ClientOption
- func WithMaxListPages(n int) ClientOption
- func WithMaxRetries(n int) ClientOption
- func WithModifyRequest(fn func(*http.Request)) ClientOption
- func WithNotificationCallback(fn func(method string, params any)) ClientOption
- func WithReconnectBackoff(d time.Duration) ClientOption
- func WithRootsHandler(h RootsHandler) ClientOptiondeprecated
- func WithSSEClient() ClientOption
- func WithSamplingHandler(h SamplingHandler) ClientOptiondeprecated
- func WithStdioTransport(r io.Reader, w io.Writer) ClientOption
- func WithTasksExtension() ClientOption
- func WithTokenSource(ts core.TokenSource) ClientOption
- func WithTracerProvider(tp core.TracerProvider) ClientOption
- func WithTransport(t core.Transport) ClientOption
- func WithUIExtension() ClientOption
- type CommandOption
- type CommandTransport
- func (ct *CommandTransport) Call(ctx context.Context, req *core.Request) (*core.Response, error)
- func (ct *CommandTransport) Close() error
- func (ct *CommandTransport) Connect(ctx context.Context) error
- func (ct *CommandTransport) Notify(ctx context.Context, req *core.Request) error
- func (ct *CommandTransport) SessionID() string
- func (ct *CommandTransport) Stderr() string
- type DiscoverResult
- type ElicitationCompleteHandler
- type ElicitationHandler
- type HTTPStatusError
- type InputHandler
- type MRTROption
- type RPCError
- type RootsHandlerdeprecated
- type SamplingHandlerdeprecated
- type StdioTransport
- func (t *StdioTransport) Call(ctx context.Context, req *core.Request) (*core.Response, error)
- func (t *StdioTransport) Close() error
- func (t *StdioTransport) Connect(ctx context.Context) error
- func (t *StdioTransport) Notify(ctx context.Context, req *core.Request) error
- func (t *StdioTransport) SessionID() string
- type TaskCallOptionsV1
- type ToolCallResult
- type UnsupportedDiscoverError
- type WaitOptions
Constants ¶
const ClientModeEnvVar = "MCPKIT_CLIENT_MODE"
ClientModeEnvVar names the override-via-environment knob.
Variables ¶
var DefaultClientMode = ClientModeLegacyOnly
DefaultClientMode is the wire mode used when no WithClientMode option is passed and MCPKIT_CLIENT_MODE is unset.
Default: ClientModeLegacyOnly — preserves pre-SEP-2575 behavior so existing client code keeps working on upgrade. Opting into Adaptive (the recommended migration path) is one of:
client.NewClient(url, info, client.WithClientMode(client.ClientModeAdaptive))
export MCPKIT_CLIENT_MODE=adaptive
func init() { client.DefaultClientMode = client.ClientModeAdaptive }
The shipping default may flip to Adaptive in a future major release once the stateless wire is in widespread use. Until then, an extra server/discover probe on every Connect would be a silent latency regression for clients talking only to legacy servers.
Tests use SetDefaultClientMode to flip under write-lock for safe concurrent test execution.
var ErrListPaginationOverrun = errors.New("client: list pagination exceeded max pages")
ErrListPaginationOverrun is yielded by every paginated list iterator and returned by every zero-arg list helper (ListTools, ListResources, ListResourceTemplates, ListPrompts) when the per-client max page count is exceeded.
The default cap is 1000 pages; configure via WithMaxListPages. A cap of 0 disables the check (unbounded iteration — at your own risk).
This signals a likely-buggy server emitting an unbounded nextCursor, not a transient transport error. Callers should NOT retry blindly. The pages already yielded before the cap fired are safe to consume; what is uncertain is whether more pages legitimately existed beyond the cap or the server was wedged.
var ErrMRTRMaxRounds = errors.New("MRTR max rounds exceeded")
ErrMRTRMaxRounds is returned by CallToolWithInputs when the server keeps asking for more input past the configured round cap. Wrap-able via errors.Is.
Functions ¶
func CancelTask ¶ added in v0.2.41
CancelTask cancels a running task. Returns nil on success — the server response is an empty ack per SEP-2663 (no task state). Issue GetTask if you need to observe the resulting "cancelled" status.
func CancelTaskV1 ¶ added in v0.2.41
func CancelTaskV1(c *Client, taskID string) (*core.CancelTaskResultV1, error)
CancelTaskV1 cancels a running v1 task. Returns an error if the task is already in a terminal state. Per MCP spec 2025-11-25 §tasks/cancel: returns flat Result & Task. (V2 returns an empty ack; the v2 helper signature reflects that.)
func DoWithAuthRetry ¶
func DoWithAuthRetry( ts core.TokenSource, buildReq func() (*http.Request, error), do func(*http.Request) (*http.Response, error), ) (*http.Response, error)
DoWithAuthRetry executes an HTTP request with automatic retry on 401/403. Wraps core.TokenSource into servicekit's callback-based auth retry.
On 401: calls ts.Token() to refresh, retries once. On 403: parses WWW-Authenticate for required scopes, calls core.ScopeAwareTokenSource.TokenForScopes if available, retries once.
Lazy token sources (those returning core.ErrNoTokenYet from Token) are supported: the first request is sent WITHOUT an Authorization header so the server's 401 can select the scope, and the OnUnauthorized path below arms the source via TokenForScopes for the retry (RFC 6750 §3.1).
func ExtractMethodFromJSON ¶
extractMethodFromJSON extracts the "method" field from a JSON-RPC envelope without full deserialization. Returns "<unknown>" if extraction fails.
func FileInputsFromTool ¶ added in v0.2.44
func FileInputsFromTool(tool core.ToolDef) map[string]core.FileInputDescriptor
FileInputsFromTool returns a map of `propertyPath -> descriptor` for every file-input property in the tool's inputSchema. Handles both the single-file shape (`properties.<name>.x-mcp-file`) and the array shape (`properties.<name>.items.x-mcp-file`).
Property paths use bracket notation for arrays so callers can distinguish the two shapes:
upload_image → {"image": <desc>}
analyze_documents → {"documents[]": <desc>}
Returns an empty map if no file-input properties are declared (or the schema isn't a `map[string]any`-shaped object).
func GetTask ¶ added in v0.2.41
func GetTask(c *Client, taskID string) (*core.DetailedTask, error)
GetTask fetches the current state of a v2 task as a DetailedTask, with inlined result / error / inputRequests depending on status. Idempotent — safe to call as often as needed; servers gate this method on the io.modelcontextprotocol/tasks extension being negotiated.
func GetTaskPayloadV1 ¶ added in v0.2.41
GetTaskPayloadV1 fetches the result payload for a v1 task. Blocks until the task reaches a terminal state via the tasks/result long-poll. Per MCP spec 2025-11-25 §tasks/result: returns the original ToolResult with _meta["io.modelcontextprotocol/related-task"]. (V2 removed tasks/result — DetailedTask inlines the result instead.)
func GetTaskV1 ¶ added in v0.2.41
func GetTaskV1(c *Client, taskID string) (*core.GetTaskResultV1, error)
GetTaskV1 polls the status of a v1 task by ID. Non-blocking. Per MCP spec 2025-11-25 §tasks/get: returns flat Result & Task.
func IsToolTaskV1 ¶ added in v0.2.41
IsToolTaskV1 checks whether a tool supports task invocation based on its Execution.TaskSupport field. Returns true for "required" or "optional". Per MCP spec 2025-11-25: absent Execution = forbidden. (V2 servers decide task creation unilaterally — there is no equivalent client-side check.)
Use with ListTools to decide whether to call ToolCallAsTaskV1 or ToolCall:
tools, _ := c.ListTools()
for _, t := range tools {
if client.IsToolTaskV1(t) {
client.ToolCallAsTaskV1(c, t.Name, args)
} else {
c.ToolCall(t.Name, args)
}
}
func IsTransientError ¶
isTransientError returns true if the error indicates a recoverable transport failure that may succeed on reconnection. Network errors (EOF, connection reset, refused) are transient. Auth errors (401/403) and JSON-RPC errors are NOT transient — the server responded, just said no.
func ListTasksV1 ¶ added in v0.2.41
func ListTasksV1(c *Client, cursor string) (*core.ListTasksResultV1, error)
ListTasksV1 returns all v1 tasks with cursor-based pagination. Pass an empty cursor to start from the beginning. (Removed in v2 — tasks/list is no longer part of the protocol.)
func PrepareFileArg ¶ added in v0.2.44
func PrepareFileArg(path string, desc *core.FileInputDescriptor) (string, error)
PrepareFileArg reads a file from disk, validates it against the descriptor (size + MIME / extension), and returns an RFC 2397 base64 data URI suitable for use as a tool argument.
MIME detection follows two rules in order:
- mime.TypeByExtension on the filename — fast and deterministic.
- Fallback to http.DetectContentType on the first 512 bytes — used when the extension is unknown.
The detected media type is what the validator checks against `descriptor.Accept`; the SAME type is embedded in the resulting data URI so the server's decoder reads back what we sent.
A nil descriptor skips validation but still encodes — useful for the unconstrained `process_any_file`-style tool where any file is allowed.
Returns the validator's typed error (`*core.FileTooLargeError`, `*core.FileTypeNotAcceptedError`) on failure so callers can branch with `errors.As` and render rich error UX.
func ResolveEndpointURL ¶
ResolveEndpointURL resolves an SSE endpoint event URL against the base SSE connection URL per RFC 3986. Delegates to servicekit's ResolveURL.
func SetDefaultClientMode ¶ added in v0.2.47
func SetDefaultClientMode(m ClientMode)
SetDefaultClientMode mutates DefaultClientMode under write-lock. Prefer this over direct assignment in tests so ResolveClientMode's read-lock sees a consistent value.
func ToolCallAsTaskV1 ¶ added in v0.2.41
func ToolCallAsTaskV1(c *Client, name string, args any, opts ...*TaskCallOptionsV1) (*core.CreateTaskResultV1, error)
ToolCallAsTaskV1 invokes a v1 tool with a task hint, returning a CreateTaskResultV1 instead of the immediate tool result. The server creates a task and runs the tool asynchronously.
Pass nil for opts to use server defaults. Per MCP spec 2025-11-25: task hint at params.task, progressToken at params._meta.progressToken. (V2 removes the client task hint — the server decides unilaterally — so there is no V2 equivalent to this helper.)
func ToolCallTyped ¶ added in v0.1.13
ToolCallTyped invokes a tool and unmarshals the structured content into T. This is for tools that declare an OutputSchema and return StructuredContent. Returns an error if the tool has no structured content or if unmarshaling fails.
Example:
type SearchResult struct {
Results []string `json:"results"`
Total int `json:"total"`
}
result, err := client.ToolCallTyped[SearchResult](c, "search", map[string]any{"query": "test"})
func UpdateTask ¶ added in v0.2.41
func UpdateTask(c *Client, req core.UpdateTaskRequest) error
UpdateTask resumes a task parked in input_required by delivering the inputResponses the server's pending inputRequests are waiting on. The server matches keys, hands the payloads to the waiting goroutine, and the task transitions back to working (or directly to a terminal state if the tool finishes immediately after).
Returns nil on success — the server response is an empty ack per SEP-2663. Observe the resulting state via the next GetTask poll.
func WaitForTask ¶ added in v0.2.41
func WaitForTask(ctx context.Context, c *Client, taskID string, opts ...WaitOptions) (*core.DetailedTask, error)
WaitForTask polls tasks/get until the task reaches a terminal state or ctx fires. Each iteration honors:
- opts[0].PollInterval if non-zero (caller override),
- else the server's PollIntervalMs on the most recent response,
- else the 1-second default.
Returns the final DetailedTask snapshot (which inlines the result / error / inputRequests per SEP-2663). Note that input_required is NOT terminal — callers wanting to handle the MRTR resume should poll until terminal or use a tighter loop that checks for input_required and calls UpdateTask in between.
Cancel-poll abort (SEP-2663): a caller that issues tasks/cancel may stop polling immediately without waiting for the server to surface "cancelled" status. The recommended pattern is to derive a child context for the wait and cancel it after CancelTask returns:
pollCtx, stopPoll := context.WithCancel(ctx)
defer stopPoll()
go func() {
<-userCancelSignal
client.CancelTask(c, taskID)
stopPoll()
}()
dt, err := client.WaitForTask(pollCtx, taskID) // err == context.Canceled on abort
func WaitForTaskV1 ¶ added in v0.2.41
func WaitForTaskV1(ctx context.Context, c *Client, taskID string, pollInterval time.Duration) (*core.GetTaskResultV1, error)
WaitForTaskV1 polls tasks/get until the v1 task reaches a terminal state or the context is cancelled. Returns the final task info.
Use pollInterval of 0 for a 1-second default. The context controls the overall timeout — use context.WithTimeout for deadline-based waiting.
Types ¶
type CallContext ¶ added in v0.2.44
type CallContext struct {
context.Context
// Headers are additional HTTP headers to attach to the outbound request
// (Streamable HTTP transport only). Used by ToolCall to inject SEP-2243
// Mcp-Param-* headers derived from the tool's x-mcp-header inputSchema
// annotations; other transports ignore. Caller-supplied keys override the
// transport's defaults (Content-Type, Accept, Mcp-Session-Id) only if the
// caller deliberately sets them — which they shouldn't.
Headers map[string]string
// contains filtered or unexported fields
}
CallContext is a typed context for a single Client.CallContext invocation — the client-side analogue of the typed handler contexts in core/ (per constraint C1). Embeds context.Context for cancellation; carries a per-call notification hook for long-lived calls that need their own notification channel (events/stream and likely future tasks/progress streaming RPCs).
Construct via NewCallContext, configure via the chainable With* methods, then pass to Client.CallContext.
Goroutine model: the notify hook may be called concurrently with the session-global callback (set via WithNotificationCallback). Both fire on the same notification — the hook is additive, not a replacement.
func NewCallContext ¶ added in v0.2.44
func NewCallContext(ctx context.Context) *CallContext
NewCallContext wraps a context.Context as a CallContext for use with Client.CallContext. The wrapped context controls cancellation: on Streamable HTTP, the underlying http.Request is built with it so cancelling cancels the in-flight POST. Required for long-lived calls (events/stream) so Stop() actually closes the connection.
func (*CallContext) WithNotifyHook ¶ added in v0.2.44
func (cc *CallContext) WithNotifyHook(hook func(method string, params json.RawMessage)) *CallContext
WithNotifyHook installs a per-call notification hook. The hook fires for every notification arriving on this call's response stream — for Streamable HTTP, that's the POST SSE response stream the call holds open. ADDITIVE to WithNotificationCallback (both fire on the same notification).
Transport coverage: wired on the Streamable HTTP transport (the path used by events/stream). On stdio / SSE / in-memory transports the hook is a no-op for now — notifications still flow only via the global callback.
type CallResult ¶
type CallResult struct {
Raw json.RawMessage
}
CallResult holds the raw JSON result from a JSON-RPC call.
func (*CallResult) JSON ¶
func (r *CallResult) JSON() string
JSON returns the result as indented JSON.
func (*CallResult) Unmarshal ¶
func (r *CallResult) Unmarshal(v any) error
Unmarshal decodes the result into the given value.
type Client ¶
type Client struct {
// ServerInfo is populated after Connect.
ServerInfo core.ServerInfo
// contains filtered or unexported fields
}
Client is an MCP client that communicates over Streamable HTTP or SSE.
func NewClient ¶
func NewClient(url string, info core.ClientInfo, opts ...ClientOption) *Client
NewClient creates a new MCP client targeting the given server URL. By default uses Streamable HTTP. Use WithSSEClient() for SSE transport. Call Connect() to perform the protocol handshake.
func (*Client) Call ¶
func (c *Client) Call(method string, params any) (*CallResult, error)
Call makes a JSON-RPC call and returns the parsed response.
func (*Client) CallContext ¶ added in v0.2.44
func (c *Client) CallContext(cc *CallContext, method string, params any) (*CallResult, error)
CallContext issues a JSON-RPC call with per-call configuration carried on the typed CallContext. Identical to Call when cc has no hooks set beyond a plain context.
func (*Client) Connect ¶
Connect establishes the transport and performs the MCP initialize handshake.
For command and stdio transports, Connect is bounded by a default 30s timeout to prevent indefinite hangs when the subprocess doesn't speak the expected protocol. Override with WithConnectTimeout. HTTP transports are not bounded by this default (set WithConnectTimeout explicitly if needed).
func (*Client) Discover ¶ added in v0.2.47
func (c *Client) Discover() (*DiscoverResult, error)
Discover sends server/discover and returns the server's discovery response payload. Does not mutate the client's session state. On a server that does not implement server/discover (e.g., a legacy-only mcpkit server before SEP-2575 rolled out), Discover returns a typed *UnsupportedDiscoverError so callers can branch cleanly. Transport- level failures (network, TLS) propagate as-is.
Connect must be called before Discover so the underlying transport is initialized. Discover is the public entry point built on top of adaptiveProbe; Connect's ClientModeAdaptive path continues to call adaptiveProbe directly for the boolean fallback signal.
func (*Client) HandleServerRequest ¶
HandleServerRequest dispatches an incoming server-to-client JSON-RPC request to the appropriate registered handler (sampling, elicitation, or roots). Returns a JSON-RPC response to send back to the server.
Uses context.Background(); transports that wish to thread their own cancellation context (or callers needing to invoke the dispatch synthetically — e.g. SEP-2322 MRTR's CallToolWithInputs feeding inputRequests through the same routing logic) should call HandleServerRequestWithContext instead.
func (*Client) HandleServerRequestWithContext ¶ added in v0.2.41
func (c *Client) HandleServerRequestWithContext(ctx context.Context, req *core.Request) *core.Response
HandleServerRequestWithContext is the context-aware form of HandleServerRequest. Callers that have a real context (caller-driven cancellation, MRTR loops, future client middleware) thread it through here so handlers receive it instead of context.Background.
This is the single source of truth for "given an MCP method name and a registered handler, what's the response?" Both the transport's incoming-request path AND the SEP-2322 MRTR client-side input resolution route through this function.
func (*Client) ListPrompts ¶ added in v0.2.28
ListPrompts returns every registered prompt definition the server exposes. Same auto-iteration + cap contract as ListResources; see WithMaxListPages and ErrListPaginationOverrun.
func (*Client) ListPromptsPage ¶ added in v0.2.42
func (c *Client) ListPromptsPage(cursor string) (*core.PromptsListResult, error)
ListPromptsPage fetches one page of prompts/list and returns the typed result including the SEP-2549 ttlMs / cacheScope hints and pagination cursor.
func (*Client) ListResourceTemplates ¶
ListResourceTemplates returns every registered resource template the server exposes. Same auto-iteration + cap contract as ListResources; see WithMaxListPages and ErrListPaginationOverrun.
func (*Client) ListResourceTemplatesPage ¶ added in v0.2.42
func (c *Client) ListResourceTemplatesPage(cursor string) (*core.ResourceTemplatesListResult, error)
ListResourceTemplatesPage fetches one page of resources/templates/list and returns the typed result including the SEP-2549 ttlMs / cacheScope hints and pagination cursor.
func (*Client) ListResources ¶
ListResources returns every registered static resource the server exposes. Auto-iterates resources/list across every page the server advertises via nextCursor; capped at WithMaxListPages (default 1000) — a server emitting an unbounded cursor surfaces as ErrListPaginationOverrun rather than an infinite loop.
Discards the per-page envelope (TTLMs / CacheScope). Use ListResourcesPage(cursor) when you need the SEP-2549 cache hints.
func (*Client) ListResourcesPage ¶ added in v0.2.42
func (c *Client) ListResourcesPage(cursor string) (*core.ResourcesListResult, error)
ListResourcesPage fetches one page of resources/list and returns the typed result including the SEP-2549 ttlMs / cacheScope hints and pagination cursor.
func (*Client) ListTools ¶
ListTools returns every registered tool definition the server exposes. Auto-iterates tools/list across every page the server advertises via nextCursor; capped at WithMaxListPages (default 1000) — a server emitting an unbounded cursor surfaces as ErrListPaginationOverrun rather than an infinite loop.
As a side effect, caches each valid tool's full ToolDef (including inputSchema) keyed by name — ToolCall consults this cache to detect SEP-2243 x-mcp-header annotations without a second round-trip. The cache replace happens once, after every page has been drained, so concurrent lookupToolSchema readers never observe a partial cache.
Tools whose inputSchema fails SEP-2243 x-mcp-header validation (empty values, non-primitive types, name charset, case-insensitive duplicates) are silently filtered out. Spec: "Client MUST keep valid tools while excluding invalid ones." The cache and the returned slice are kept consistent — invalid tools never become callable through this client.
func (*Client) ListToolsForModel ¶
ListToolsForModel returns tools visible to the LLM, filtering out tools that are only visible to apps (visibility: ["app"]). Tools with no visibility set (nil/empty) are included — the default means visible to both model and app. This is a client-side convenience; the server always returns all tools.
func (*Client) ListToolsPage ¶ added in v0.2.42
func (c *Client) ListToolsPage(cursor string) (*core.ToolsListResult, error)
ListToolsPage fetches one page of tools/list and returns the typed result including the SEP-2549 ttlMs / cacheScope hints and pagination cursor. Use Tools(ctx) for the auto-paginating item iterator when you don't need the envelope metadata, or the zero-arg ListTools() if you only want the items from the first page.
func (*Client) NotifyRootsChanged
deprecated
added in
v0.1.24
NotifyRootsChanged sends a notifications/roots/list_changed notification to the server. Call this after the client's filesystem roots have changed so the server can re-fetch the current list via a roots/list request.
Deprecated: per SEP-2577, scheduled for removal in v0.4. See docs/SEP_2577_DEPRECATIONS.md.
func (*Client) Prompts ¶ added in v0.2.27
Prompts returns an iterator that yields all prompt definitions, automatically paginating through multiple pages.
func (*Client) ReadResource ¶
ReadResource reads a resource by URI and returns the first text content.
func (*Client) ReadResourceFull ¶ added in v0.2.47
func (c *Client) ReadResourceFull(uri string) (*core.ResourceResult, error)
ReadResourceFull reads a resource by URI and returns the full typed result — every content item plus the SEP-2549 ttlMs / cacheScope cache hints. The plain ReadResource helper drops that envelope and returns only the first text content; callers that want to cache a read response should use ReadResourceFull.
func (*Client) ResourceTemplates ¶ added in v0.2.27
ResourceTemplates returns an iterator that yields all resource template definitions, automatically paginating through multiple pages.
func (*Client) Resources ¶ added in v0.2.27
Resources returns an iterator that yields all resource definitions, automatically paginating through multiple pages.
func (*Client) ServerExtensionCapability ¶ added in v0.2.47
func (c *Client) ServerExtensionCapability(id string) (core.ExtensionCapability, bool)
ServerExtensionCapability returns the cached ExtensionCapability the server advertised for id during initialize, or false when the server did not declare the extension.
Use this to inspect extension-specific Config settings (e.g., the SEP-2640 directoryRead flag). The returned capability is decoded from the raw JSON captured at initialize time and reflects whatever the server emitted on the wire; callers should treat unknown Config keys permissively.
func (*Client) ServerSupportsExtension ¶
ServerSupportsExtension checks whether the server advertised support for the given extension ID in its initialize response. Call after Connect().
func (*Client) ServerSupportsUI ¶
ServerSupportsUI checks whether the server advertised MCP Apps (io.modelcontextprotocol/ui) support. Convenience wrapper around ServerSupportsExtension.
func (*Client) SetLogLevel ¶ added in v0.2.28
SetLogLevel sets the server's minimum log level for this session via logging/setLevel. The server will send notifications/message for log entries at or above this level. Use "debug" to see all logs.
func (*Client) SetTransport ¶
SetTransport sets the transport for the client. Use when the transport needs to reference the client (e.g., InProcessTransport with ServerRequestHandler that delegates to the client's sampling/elicitation handlers). Must be called before Connect().
func (*Client) SetURL ¶
SetURL updates the client's target URL. Used in reconnection tests to simulate DNS/load balancer changes.
func (*Client) SubscribeResource ¶
SubscribeResource subscribes to change notifications for a resource URI. The server will send notifications/resources/updated when the resource changes.
func (*Client) ToolCall ¶
ToolCall invokes a tool and returns the first text content.
If the tool's inputSchema (cached by a prior ListTools call) carries SEP-2243 x-mcp-header annotations on primitive-typed properties, the corresponding argument values are mirrored as Mcp-Param-{Name} HTTP headers on the outbound tools/call request (in addition to the JSON body). Header values are encoded plain-ASCII or =?base64?{...}?= per SEP-2243 §value-encoding. Tools without cached schemas or without x-mcp-header annotations send no extra headers (identical to pre- SEP-2243 behavior). Caller-side note: middleware registered via WithCallMiddleware does not run on the header-mirroring path.
func (*Client) ToolCallFull ¶ added in v0.2.6
ToolCallFull invokes a tool and returns the complete result including IsError, all content blocks, and the raw JSON. Unlike ToolCall, tool-level errors (isError: true) are returned in the result, not as Go errors. Only transport/protocol failures produce a Go error.
func (*Client) Tools ¶ added in v0.2.27
Tools returns an iterator that yields all tool definitions, automatically paginating through multiple pages if the server uses cursor-based pagination.
Example:
for tool, err := range c.Tools(ctx) {
if err != nil { log.Fatal(err) }
fmt.Println(tool.Name)
}
func (*Client) UnsubscribeResource ¶
UnsubscribeResource removes a subscription for a resource URI.
func (*Client) UsingStatelessWire ¶ added in v0.2.47
UsingStatelessWire reports whether Connect() landed on the SEP-2575 stateless wire (server/discover) rather than the legacy initialize handshake. Always false before Connect(). True when the client was constructed with WithClientMode(ClientModeStateless), or when ClientModeAdaptive's probe succeeded against a server that speaks server/discover.
Use to display which wire a session is on (walkthroughs, debug tools) or to gate behavior that only makes sense on one wire.
type ClientAuthError ¶
type ClientAuthError = ssehttp.AuthRetryError
ClientAuthError is returned by the client transport when the server rejects a request with 401 or 403 and the transport has exhausted its retry budget.
type ClientCallFunc ¶ added in v0.2.29
ClientCallFunc is the signature for the next handler in the client middleware chain.
type ClientMiddleware ¶ added in v0.2.29
type ClientMiddleware func(ctx context.Context, method string, params any, next ClientCallFunc) (*CallResult, error)
ClientMiddleware intercepts outgoing client calls before they reach the transport. Use for tracing, logging, metrics, or request transformation.
The middleware sees the method name (e.g., "tools/call", "tools/list", "logging/setLevel") and typed params. Call next to continue the chain, or return directly to short-circuit (e.g., cached responses, circuit breakers).
Example — tracing middleware:
client.WithClientMiddleware(func(ctx context.Context, method string, params any,
next client.ClientCallFunc) (*client.CallResult, error) {
start := time.Now()
result, err := next(ctx, method, params)
log.Printf("→ %s (%s)", method, time.Since(start))
return result, err
})
type ClientMode ¶ added in v0.2.47
type ClientMode int
ClientMode selects how the client negotiates the wire shape with the server during Connect.
const ( // ClientModeLegacyOnly performs the legacy initialize handshake at // Connect time. Never sends _meta envelopes or MCP-Protocol-Version // headers; pure pre-SEP-2575 behavior. Zero value (kept for the // strict-back-compat opt-out path). ClientModeLegacyOnly ClientMode = iota // ClientModeAdaptive probes server/discover first; on -32601 falls // back to the legacy initialize handshake. Once a server is // classified as stateless, subsequent calls carry the _meta envelope // and the MCP-Protocol-Version HTTP header. Default. ClientModeAdaptive // ClientModeStateless skips initialize entirely. Every call carries // the SEP-2575 _meta envelope and the MCP-Protocol-Version header. // server/discover may still be issued explicitly via DiscoverServer. ClientModeStateless )
func ParseClientMode ¶ added in v0.2.47
func ParseClientMode(s string) (ClientMode, bool)
ParseClientMode decodes a token (the inverse of String). Accepts "legacy", "adaptive", "stateless"; case-insensitive; empty maps to caller's fallback via ok=false.
func ResolveClientMode ¶ added in v0.2.47
func ResolveClientMode() ClientMode
ResolveClientMode seeds NewClient's mode from env var or DefaultClientMode. WithClientMode option clobbers when present (options run after seeding).
Precedence (high → low):
- client.WithClientMode(m)
- MCPKIT_CLIENT_MODE env var
- client.DefaultClientMode
func (ClientMode) String ¶ added in v0.2.47
func (m ClientMode) String() string
String returns the lowercase token used in env vars and structured logs.
type ClientOption ¶
type ClientOption func(*Client)
ClientOption configures a Client.
func WithClientBearerToken ¶
func WithClientBearerToken(token string) ClientOption
WithClientBearerToken sets a static bearer token for all client requests.
func WithClientKeepalive ¶ added in v0.1.11
func WithClientKeepalive(interval time.Duration, maxFailures int) ClientOption
WithClientKeepalive enables application-level keepalive pings. The client periodically sends JSON-RPC ping requests to the server. If maxFailures consecutive pings fail (timeout or error), the client triggers reconnection (if retries are configured) or closes.
func WithClientLogging ¶
func WithClientLogging(logger *log.Logger) ClientOption
WithClientLogging enables debug logging of all client transport operations. Every connect, call, notify, and close is logged with method name, latency, and error details. Pass nil to use the default logger.
Example:
client := mcpkit.NewClient(url, info,
mcpkit.WithClientLogging(log.Default()),
)
func WithClientMiddleware ¶ added in v0.2.29
func WithClientMiddleware(mw ...ClientMiddleware) ClientOption
WithClientMiddleware registers middleware that wraps all outgoing client calls (ToolCall, ListTools, ReadResource, etc.). Middleware executes in registration order: first registered = outermost (runs first on request, last on response).
func WithClientMode ¶ added in v0.2.47
func WithClientMode(m ClientMode) ClientOption
WithClientMode pins the wire mode for this Client. Highest-precedence override — beats MCPKIT_CLIENT_MODE env and DefaultClientMode.
func WithCommandTransport ¶ added in v0.1.14
func WithCommandTransport(name string, args []string, opts ...CommandOption) ClientOption
WithCommandTransport configures the client to spawn a subprocess MCP server and communicate over stdin/stdout. A fresh process is started on each Connect() (and on each reconnection if WithMaxRetries is set).
Example:
c := client.NewClient("", info,
client.WithCommandTransport("python", []string{"my_server.py"},
client.WithEnv("DEBUG=1"),
),
)
err := c.Connect()
func WithConnectTimeout ¶ added in v0.1.16
func WithConnectTimeout(d time.Duration) ClientOption
WithConnectTimeout sets a deadline for Connect() to complete. This covers both the transport connection (subprocess start, SSE stream open) and the MCP initialize handshake. If the timeout expires, Connect() returns an error immediately instead of blocking indefinitely.
This is especially important for CommandTransport: if the subprocess starts but doesn't speak Content-Length framed JSON-RPC (e.g., wrong mode, missing env vars), Connect() would block forever without a timeout.
Default is 0 (no timeout).
func WithContentChunkHandler ¶ added in v0.1.17
func WithContentChunkHandler(fn func(chunk core.ContentChunk)) ClientOption
WithContentChunkHandler sets a callback for streaming tool content chunks. The callback is invoked for each content chunk notification received during tool execution (method matching the server's configured content chunk method, default "notifications/tools/content_chunk").
If not set, content chunk notifications are silently ignored and the client relies on the final ToolResult for the complete response.
func WithElicitationCompleteHandler ¶ added in v0.2.41
func WithElicitationCompleteHandler(h ElicitationCompleteHandler) ClientOption
WithElicitationCompleteHandler registers a handler for notifications/elicitation/complete notifications (SEP-1036).
func WithElicitationHandler ¶
func WithElicitationHandler(h ElicitationHandler) ClientOption
WithElicitationHandler registers a handler for server-to-client elicitation requests. When set, the client advertises form-mode elicitation capability during initialization. To also support URL-mode elicitation, combine with WithElicitationURLSupport.
func WithElicitationURLSupport ¶ added in v0.2.41
func WithElicitationURLSupport() ClientOption
WithElicitationURLSupport enables URL-mode elicitation capability. The same ElicitationHandler receives both form and URL mode requests; it should branch on req.Mode. Must be combined with WithElicitationHandler.
func WithExtension ¶
func WithExtension(id string, cap core.ClientExtensionCap) ClientOption
WithExtension advertises support for an extension during the initialize handshake. The extension ID and capability are included in the client's capabilities.extensions map, allowing the server to detect client support via core.ClientSupportsExtension(ctx, id) in tool handlers.
func WithFileInputs ¶ added in v0.2.44
func WithFileInputs() ClientOption
WithFileInputs advertises SEP-2356 file-input support during the initialize handshake. Servers MUST NOT include `x-mcp-file` keywords in tool inputSchemas (or elicitation requestedSchemas) for clients that omit this capability — opt in here to receive the picker hints.
func WithGetSSEStream ¶
func WithGetSSEStream() ClientOption
WithGetSSEStream enables a background GET SSE stream on the Streamable HTTP endpoint after Connect(). The stream receives server-initiated notifications (list-changed, log messages, resource updates) that arrive outside POST request-response cycles. Only applies to Streamable HTTP transport; ignored for SSE and in-memory transports.
The notification callback (set via WithNotificationCallback) must be goroutine-safe when WithGetSSEStream is enabled, as notifications may arrive concurrently from both the GET SSE stream and POST SSE responses.
func WithIOTransport ¶ added in v0.2.27
func WithIOTransport(r io.Reader, w io.Writer) ClientOption
WithIOTransport configures a Client to use Content-Length framed JSON-RPC over arbitrary reader/writer streams. This is the generic IO transport — use it for Unix sockets, named pipes, SSH tunnels, test pipe pairs, or any other stream-based transport.
Example (pipe pair for testing):
sr, cw := io.Pipe()
cr, sw := io.Pipe()
go srv.RunIO(ctx, sr, sw)
c := client.NewClient("", info, client.WithIOTransport(cr, cw))
func WithInspectResponse ¶ added in v0.2.47
func WithInspectResponse(fn func(*http.Response)) ClientOption
WithInspectResponse sets a callback that is invoked with every HTTP response the transport receives. Mirror of WithModifyRequest for the inbound direction.
Use it to observe response headers and status — the callback must NOT read or close the response body, which the transport owns. Typical uses: surfacing custom deployment headers, capturing rate-limit hints, reading tracing IDs the server stamps on responses.
Fires on every HTTP response the transport's http.Client returns, including pre-retry 401/403 responses that DoWithAuthRetry will retry and any non-2xx final response. Only network-level errors (no response received) skip the callback.
Only applies to HTTP transports (Streamable HTTP, SSE); ignored for stdio and in-process transports.
Example (logging an arbitrary deployment header):
c := client.NewClient(url, info,
client.WithInspectResponse(func(resp *http.Response) {
if v := resp.Header.Get("X-Some-Deployment-Header"); v != "" {
log.Printf("response header: %s", v)
}
}),
)
func WithMaxListPages ¶ added in v0.2.47
func WithMaxListPages(n int) ClientOption
WithMaxListPages overrides the per-client cap on auto-iterating list helpers. The cap applies uniformly to the Tools / Resources / ResourceTemplates / Prompts iterators and to the zero-arg legacy helpers (ListTools etc.) which drain those iterators internally.
When the iterator would issue page N+1 and N >= cap, it yields ErrListPaginationOverrun and stops. The items already yielded are safe to consume; what is uncertain is whether more pages legitimately existed beyond the cap or the server was wedged.
Pass 0 to disable the check entirely (unbounded iteration). The default is 1000 pages, comfortably above any realistic MCP catalog at the standard 100-items-per-page rate.
func WithMaxRetries ¶
func WithMaxRetries(n int) ClientOption
WithMaxRetries sets the maximum number of reconnection attempts on transient transport failure. Default 0 (reconnection disabled). Each retry includes a full reconnect + initialize handshake.
Example:
client := mcpkit.NewClient(url, info,
mcpkit.WithMaxRetries(3),
mcpkit.WithReconnectBackoff(time.Second),
)
func WithModifyRequest ¶ added in v0.1.14
func WithModifyRequest(fn func(*http.Request)) ClientOption
WithModifyRequest sets a callback that is invoked on every outgoing HTTP request before authentication headers are applied. Use it to add custom headers (API keys, tracing IDs, tenant identifiers) without needing a custom http.RoundTripper.
The callback must not modify the request body or URL. Only applies to HTTP transports (Streamable HTTP, SSE); ignored for stdio and in-process transports.
Example:
c := client.NewClient(url, info,
client.WithModifyRequest(func(req *http.Request) {
req.Header.Set("X-Tenant-ID", "acme")
req.Header.Set("X-Request-ID", uuid.New().String())
}),
)
func WithNotificationCallback ¶
func WithNotificationCallback(fn func(method string, params any)) ClientOption
WithNotificationCallback sets a callback for server-to-client notifications (logging, progress, resource updates). Works across all transports.
func WithReconnectBackoff ¶
func WithReconnectBackoff(d time.Duration) ClientOption
WithReconnectBackoff sets the base delay for exponential backoff between reconnection attempts. Default 1s. Actual delay is base * 2^attempt + jitter.
func WithRootsHandler
deprecated
added in
v0.1.24
func WithRootsHandler(h RootsHandler) ClientOption
WithRootsHandler registers a handler for server-to-client roots/list requests. When set, the client advertises the "roots" capability (with listChanged: true) during initialization, enabling the server to fetch the client's filesystem roots after receiving a notifications/roots/list_changed notification.
Deprecated: per SEP-2577, scheduled for removal in v0.4. See docs/SEP_2577_DEPRECATIONS.md.
func WithSSEClient ¶
func WithSSEClient() ClientOption
WithSSEClient configures the client to use SSE transport instead of Streamable HTTP. The URL should point to the SSE endpoint (e.g., "http://localhost:8787/mcp/sse").
func WithSamplingHandler
deprecated
func WithSamplingHandler(h SamplingHandler) ClientOption
WithSamplingHandler registers a handler for server-to-client sampling requests. When set, the client advertises the "sampling" capability during initialization.
Deprecated: per SEP-2577, scheduled for removal in v0.4. See docs/SEP_2577_DEPRECATIONS.md.
func WithStdioTransport ¶
func WithStdioTransport(r io.Reader, w io.Writer) ClientOption
WithStdioTransport configures a Client to use stdio transport. This is equivalent to WithIOTransport with the given reader/writer pair — kept for backward compatibility and naming clarity when used with subprocess servers (where r is stdout and w is stdin of the child process).
func WithTasksExtension ¶ added in v0.2.41
func WithTasksExtension() ClientOption
WithTasksExtension advertises SEP-2663 Tasks support (io.modelcontextprotocol/tasks). v2 servers gate task creation and the tasks/* methods on this declaration — clients that omit it see synchronous tools/call responses and -32601 for tasks/get / tasks/cancel / tasks/update.
func WithTokenSource ¶
func WithTokenSource(ts core.TokenSource) ClientOption
WithTokenSource sets a dynamic token source for all client requests. Use this for OAuth flows where tokens are refreshed automatically.
func WithTracerProvider ¶ added in v0.2.47
func WithTracerProvider(tp core.TracerProvider) ClientOption
WithTracerProvider registers a core.TracerProvider that wraps every outbound Client.Call in a span and emits a wrap span around every inbound server-to-client request dispatch.
nil and core.NoopTracerProvider{} are treated identically: the trace middleware is not installed and no `_meta.traceparent` is stamped on outbound params. The default (no Option set) is the same "tracing disabled" behavior.
The trace middleware is positioned OUTERMOST in the user middleware chain, so user-registered ClientMiddleware (auth retry, header injection, custom logging) executes inside the span and contributes to the recorded latency. Symmetric with server.WithTracerProvider's outermost install.
Inbound (server-to-client) request resolution:
- `params._meta.traceparent` is extracted via core.ExtractTraceContextFromParams and attached to the handler's ctx via core.WithTraceContext. Handlers consume it through core.TraceContextFromContext(ctx) or pass ctx into a downstream OTel-instrumented call.
- A wrap span named after the request method (e.g. "sampling/createMessage") is emitted with the inbound trace context as parent. Handler-internal spans the user emits via their own tp are children of this wrap span.
Outbound (Client.Call): see traceMiddleware below for the full set of span attributes.
func WithTransport ¶
func WithTransport(t core.Transport) ClientOption
WithTransport sets a core.Transport for the client, bypassing the default HTTP transport creation. Use with server.NewInProcessTransport for testing or embedded scenarios.
Example:
transport := server.NewInProcessTransport(srv)
c := client.New("memory://", info, client.WithTransport(transport))
func WithUIExtension ¶
func WithUIExtension() ClientOption
WithUIExtension is a convenience wrapper that advertises MCP Apps (io.modelcontextprotocol/ui) support with the standard app MIME type.
type CommandOption ¶ added in v0.1.14
type CommandOption func(*commandOpts)
CommandOption configures a CommandTransport.
func WithDir ¶ added in v0.1.14
func WithDir(dir string) CommandOption
WithDir sets the working directory for the subprocess.
func WithEnv ¶ added in v0.1.14
func WithEnv(env ...string) CommandOption
WithEnv adds environment variables to the subprocess. Each value should be in KEY=VALUE format. These are appended to the current process environment.
func WithShutdownTimeout ¶ added in v0.1.14
func WithShutdownTimeout(d time.Duration) CommandOption
WithShutdownTimeout sets the duration to wait after sending SIGTERM before escalating to SIGKILL. Default is 5 seconds.
func WithStderr ¶ added in v0.1.14
func WithStderr(w io.Writer) CommandOption
WithStderr sets an additional writer for subprocess stderr output. Stderr is always captured in an internal buffer (for error messages on crash); this option tees it to an additional destination (e.g., os.Stderr, a logger).
type CommandTransport ¶ added in v0.1.14
type CommandTransport struct {
// contains filtered or unexported fields
}
CommandTransport implements core.Transport by spawning a subprocess and communicating via stdio. The subprocess is started on Connect() and gracefully shut down on Close().
func NewCommandTransport ¶ added in v0.1.14
func NewCommandTransport(name string, args []string, opts ...CommandOption) *CommandTransport
NewCommandTransport creates a CommandTransport that will spawn the given command with args when Connect() is called.
func (*CommandTransport) Close ¶ added in v0.1.14
func (ct *CommandTransport) Close() error
Close gracefully shuts down the subprocess. It first closes the stdin pipe (via StdioTransport) so well-behaved servers exit on EOF. If the process doesn't exit within a short grace period, it sends SIGTERM. If SIGTERM doesn't work within the shutdown timeout, it escalates to SIGKILL.
The grace period before SIGTERM handles servers that don't exit on stdin EOF (e.g., started in HTTP mode by mistake). Without this, StdioTransport.Close() would block forever waiting for readLoop to see EOF on a stdout pipe held open by a still-running process.
func (*CommandTransport) Connect ¶ added in v0.1.14
func (ct *CommandTransport) Connect(ctx context.Context) error
Connect starts the subprocess and establishes the stdio transport. The context is used only to bound the connect/handshake phase — the subprocess outlives it. If the context expires before the handshake completes, Connect returns an error and Close() should be called to clean up the process.
func (*CommandTransport) Notify ¶ added in v0.1.14
Notify delegates to the underlying StdioTransport.
func (*CommandTransport) SessionID ¶ added in v0.1.14
func (ct *CommandTransport) SessionID() string
SessionID returns "command" for the command transport.
func (*CommandTransport) Stderr ¶ added in v0.1.14
func (ct *CommandTransport) Stderr() string
Stderr returns the captured stderr output from the subprocess. Safe to call after Close(). Returns an empty string if no stderr was captured.
type DiscoverResult ¶ added in v0.2.47
type DiscoverResult struct {
SupportedVersions []string `json:"supportedVersions"`
Capabilities core.ServerCapabilities `json:"capabilities"`
ServerInfo core.ServerInfo `json:"serverInfo"`
}
DiscoverResult mirrors stateless.DiscoverResult shape. Defined locally so client/ does not import server/stateless/ (the package boundary runs the other direction; client only knows wire types in core/).
Surfaced through the public Client.Discover() helper for ad-hoc callers (CLI inspectors, conformance harnesses) that want to introspect a server's discovery payload without going through the Connect handshake.
type ElicitationCompleteHandler ¶ added in v0.2.41
type ElicitationCompleteHandler func(context.Context, core.ElicitationCompleteParams)
ElicitationCompleteHandler handles a notifications/elicitation/complete notification. Called when the server signals that an out-of-band URL-mode elicitation flow has been completed. The client can use this to retry the original request.
type ElicitationHandler ¶
type ElicitationHandler func(context.Context, core.ElicitationRequest) (core.ElicitationResult, error)
ElicitationHandler handles a server-to-client elicitation/create request. The client prompts the user for input and returns the result. For URL-mode requests (Mode == "url"), the handler should present the URL to the user and return once acknowledged. The actual completion is signaled separately via notifications/elicitation/complete.
type HTTPStatusError ¶
type HTTPStatusError = ssehttp.HTTPStatusError
HTTPStatusError is returned when the server responds with a non-2xx HTTP status code that is not 401/403 (those are handled by DoWithAuthRetry). This allows IsTransientError to classify 5xx responses as retriable.
type InputHandler ¶ added in v0.2.41
type InputHandler func(ctx context.Context, reqs core.InputRequests) (core.InputResponses, error)
InputHandler resolves an MRTR InputRequiredResult's inputRequests into the echoed inputResponses payload. Called once per retry round; returning an error aborts the loop.
The map shape mirrors the wire contract: keys are server-chosen identifiers that MUST round-trip verbatim; values are opaque JSON payloads matching the InputRequest.Method (ElicitResult, CreateMessageResult, ListRootsResult, etc.).
func DefaultInputHandler ¶ added in v0.2.41
func DefaultInputHandler(c *Client) InputHandler
DefaultInputHandler returns an InputHandler that resolves the standard MRTR inputRequest methods using the client's existing capability handlers:
- "elicitation/create" → samplingElicit via elicitationHandler
- "sampling/createMessage" → samplingHandler
- "roots/list" → rootsHandler
Unknown methods produce an error. Returns an error from the underlying handler too — CallToolWithInputs propagates it and aborts the loop.
This is a starting point. Wrap or replace it for custom inputRequest methods, alternative routing, or to inject non-default response payloads (e.g., declining elicitation requests, returning canned sampling output in tests).
type MRTROption ¶ added in v0.2.41
type MRTROption func(*mrtrConfig)
MRTROption tunes CallToolWithInputs behavior.
func WithMaxMRTRRounds ¶ added in v0.2.41
func WithMaxMRTRRounds(n int) MRTROption
WithMaxMRTRRounds caps how many times CallToolWithInputs will retry a tools/call when the server keeps returning InputRequiredResult. Default is 16 (enough for any sane workflow; high enough that hitting it suggests a bug). Zero or negative values fall back to the default.
type RPCError ¶ added in v0.2.41
type RPCError struct {
Code int `json:"code"`
Message string `json:"message"`
Data any `json:"data,omitempty"`
}
RPCError is a JSON-RPC error returned by the server. It preserves the error code, message, and optional data field for structured error handling.
Use errors.As to extract it from a Call/ToolCall error:
var rpcErr *client.RPCError
if errors.As(err, &rpcErr) {
fmt.Println(rpcErr.Code, rpcErr.Data)
}
type RootsHandler
deprecated
added in
v0.1.24
type SamplingHandler
deprecated
type SamplingHandler func(context.Context, core.CreateMessageRequest) (core.CreateMessageResult, error)
SamplingHandler handles a server-to-client sampling/createMessage request. The client performs LLM inference and returns the result.
Deprecated: per SEP-2577, scheduled for removal in v0.4. See docs/SEP_2577_DEPRECATIONS.md.
type StdioTransport ¶
type StdioTransport struct {
// contains filtered or unexported fields
}
StdioTransport implements core.Transport over Content-Length framed JSON-RPC. Messages are read from r and written to w using the same framing as the MCP stdio server transport (Content-Length: N\r\n\r\n<body>).
func NewStdioTransport ¶
func NewStdioTransport(r io.Reader, w io.Writer) *StdioTransport
NewStdioTransport creates a client transport that communicates via Content-Length framed JSON-RPC over the given reader/writer pair.
Typically the reader is connected to the server's stdout and the writer to the server's stdin (or pipe ends in tests).
Example:
cmd := exec.Command("my-mcp-server")
stdin, _ := cmd.StdinPipe()
stdout, _ := cmd.StdoutPipe()
cmd.Start()
transport := client.NewStdioTransport(stdout, stdin)
c := client.NewClient("stdio://", info, client.WithTransport(transport))
func (*StdioTransport) Close ¶
func (t *StdioTransport) Close() error
Close shuts down the transport and waits for the read loop to exit.
func (*StdioTransport) Connect ¶
func (t *StdioTransport) Connect(ctx context.Context) error
Connect starts the background read loop.
func (*StdioTransport) SessionID ¶
func (t *StdioTransport) SessionID() string
SessionID returns "stdio" for the stdio transport.
type TaskCallOptionsV1 ¶ added in v0.2.41
type TaskCallOptionsV1 struct {
// TTL in milliseconds. 0 = server default.
TTL int
// PollInterval in milliseconds. 0 = server default.
PollInterval int
// ProgressToken is passed as _meta.progressToken so the server
// echoes it in notifications/progress. Nil = no token.
ProgressToken any
}
TaskCallOptionsV1 configures a ToolCallAsTaskV1 invocation. Nil means use server defaults for everything.
type ToolCallResult ¶ added in v0.2.41
type ToolCallResult struct {
// Sync is populated when the server ran the tool to completion in the
// same request and returned a ToolResult directly (resultType:
// "complete" or absent).
Sync *core.ToolResult
// Task is populated when the server elected to create a task (the
// resultType: "task" discriminator was present on the response).
Task *core.CreateTaskResult
// InputRequired is populated when the server returned an SEP-2322
// InputRequiredResult — it needs more input before it can produce a
// final result. Callers using the bare ToolCall must handle this
// themselves (resolve inputRequests, retry tools/call with
// inputResponses + requestState); CallToolWithInputs handles the
// loop automatically. Renamed from Incomplete in lockstep with
// SEP-2322. The `requestState` echo on retry remains valid for the
// MRTR surface even though the tasks-v2 wire no longer carries it.
InputRequired *core.InputRequiredResult
}
ToolCallResult is the discriminated union returned by ToolCall. Exactly one of Sync, Task, or InputRequired is non-nil — branch on which is set (or use the IsTask / IsInputRequired helpers).
func CallToolWithInputs ¶ added in v0.2.41
func CallToolWithInputs(ctx context.Context, c *Client, name string, args any, handler InputHandler, opts ...MRTROption) (*ToolCallResult, error)
CallToolWithInputs invokes a tool with automatic SEP-2322 MRTR retry. On InputRequiredResult, the handler is called to resolve the inputRequests; the call is then retried with inputResponses + the echoed requestState. The loop terminates as soon as the server returns a complete ToolResult, a CreateTaskResult, or an error. Returns ErrMRTRMaxRounds if the round cap (default 16) is hit.
Pass DefaultInputHandler(c) to handle the standard inputRequest methods using the client's existing capability handlers.
func ToolCall ¶ added in v0.2.41
func ToolCall(c *Client, name string, args any) (*ToolCallResult, error)
ToolCall invokes a tool, transparently handling both the sync ToolResult and the SEP-2663 CreateTaskResult shapes. Branch on result.IsTask() (or the Sync / Task fields directly) to know which arrived.
Servers gate task creation on the io.modelcontextprotocol/tasks extension, so this only ever returns a Task result if the client declared the extension during initialize (or per-request via SEP-2575 _meta).
func (*ToolCallResult) IsInputRequired ¶ added in v0.2.46
func (r *ToolCallResult) IsInputRequired() bool
IsInputRequired reports whether the server returned an InputRequiredResult (SEP-2322 ephemeral MRTR). Callers needing the auto-retry loop should use CallToolWithInputs instead of inspecting this directly. Renamed from IsIncomplete to track the SEP-2322 wire-variant rename.
func (*ToolCallResult) IsTask ¶ added in v0.2.41
func (r *ToolCallResult) IsTask() bool
IsTask reports whether the result is the task-creation variant.
type UnsupportedDiscoverError ¶ added in v0.2.47
type UnsupportedDiscoverError struct {
// Source describes how the server signaled the gap, useful for
// diagnostics. Either "jsonrpc-32601" or "http-404".
Source string
}
UnsupportedDiscoverError is returned by Client.Discover() when the server reports it does not implement server/discover (either via JSON-RPC -32601 in a 200 body, which is what mcpkit's legacy dispatcher emits, or via HTTP 404 from a transport that does not route the method). Callers branch on this to fall back to the legacy initialize handshake when appropriate.
func (*UnsupportedDiscoverError) Error ¶ added in v0.2.47
func (e *UnsupportedDiscoverError) Error() string
type WaitOptions ¶ added in v0.2.41
type WaitOptions struct {
// PollInterval overrides the server's PollIntervalMs hint.
// 0 (the default) means: respect whatever the server returned, with a
// 1-second floor and a 30-second cap if the server didn't say.
PollInterval time.Duration
}
WaitOptions configures WaitForTask.