Documentation
¶
Index ¶
- func DoWithAuthRetry(ts core.TokenSource, buildReq func() (*http.Request, error), ...) (*http.Response, error)
- func ExtractMethodFromJSON(data []byte) string
- func IsTransientError(err error) bool
- func ResolveEndpointURL(baseSSEURL, endpointRef string) (string, error)
- func ToolCallTyped[T any](c *Client, name string, args any) (T, error)
- type CallResult
- type Client
- func (c *Client) Call(method string, params any) (*CallResult, error)
- func (c *Client) Close() error
- func (c *Client) Connect() error
- func (c *Client) HandleServerRequest(req *core.Request) *core.Response
- func (c *Client) ListPrompts() ([]core.PromptDef, error)
- func (c *Client) ListResourceTemplates() ([]core.ResourceTemplate, error)
- func (c *Client) ListResources() ([]core.ResourceDef, error)
- func (c *Client) ListTools() ([]core.ToolDef, error)
- func (c *Client) ListToolsForModel() ([]core.ToolDef, error)
- func (c *Client) NotifyRootsChanged() error
- func (c *Client) Prompts(ctx context.Context) iter.Seq2[core.PromptDef, error]
- func (c *Client) ReadResource(uri string) (string, 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) 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
- type ClientAuthError
- type ClientOption
- func WithClientBearerToken(token string) ClientOption
- func WithClientKeepalive(interval time.Duration, maxFailures int) ClientOption
- func WithClientLogging(logger *log.Logger) 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 WithElicitationHandler(h ElicitationHandler) ClientOption
- func WithExtension(id string, cap core.ClientExtensionCap) ClientOption
- func WithGetSSEStream() ClientOption
- func WithIOTransport(r io.Reader, w io.Writer) 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) ClientOption
- func WithSSEClient() ClientOption
- func WithSamplingHandler(h SamplingHandler) ClientOption
- func WithStdioTransport(r io.Reader, w io.Writer) ClientOption
- func WithTokenSource(ts core.TokenSource) 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 ElicitationHandler
- type HTTPStatusError
- type RootsHandler
- type SamplingHandler
- 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
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
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.
func ExtractMethodFromJSON ¶
extractMethodFromJSON extracts the "method" field from a JSON-RPC envelope without full deserialization. Returns "<unknown>" if extraction fails.
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 ResolveEndpointURL ¶
ResolveEndpointURL resolves an SSE endpoint event URL against the base SSE connection URL per RFC 3986. Delegates to servicekit's ResolveURL.
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"})
Types ¶
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) 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) HandleServerRequest ¶
handleServerRequest dispatches an incoming server-to-client JSON-RPC request to the appropriate registered handler (sampling or elicitation). Returns a JSON-RPC response to send back to the server.
func (*Client) ListPrompts ¶ added in v0.2.28
ListPrompts returns all registered prompt definitions.
func (*Client) ListResourceTemplates ¶
func (c *Client) ListResourceTemplates() ([]core.ResourceTemplate, error)
ListResourceTemplates returns all registered resource templates.
func (*Client) ListResources ¶
func (c *Client) ListResources() ([]core.ResourceDef, error)
ListResources returns all registered static resources.
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) NotifyRootsChanged ¶ 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.
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) 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) 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) 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.
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 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 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 WithElicitationHandler ¶
func WithElicitationHandler(h ElicitationHandler) ClientOption
WithElicitationHandler registers a handler for server-to-client elicitation requests. When set, the client advertises the "elicitation" capability during initialization.
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 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 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 ¶ 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.
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 ¶
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.
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 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 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 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.
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 RootsHandler ¶ added in v0.1.24
RootsHandler handles a server-to-client roots/list request. The client returns its current filesystem roots.
type SamplingHandler ¶
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.
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.