Help us shape the future of Go! Take the 2026 Go Developer Survey

mcp

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 34 Imported by: 0

Documentation

Overview

Package mcp connects burrow agents to Model Context Protocol servers, as pi's MCP extension does. The protocol and transports come from github.com/modelcontextprotocol/go-sdk; this package keeps one ServerConnection per server (connected on first use, reconnected when a call finds it gone), registers the servers' tools on an agent session through an Extension, and keeps OAuth credentials in a baseAgent.AuthStore.

Wiring an agent session to remote servers for one user:

handler, err := mcp.NewOAuthHandler(&mcp.OAuthOptions{
	Store: store, OwnerID: userID, Server: "docs", ServerURL: serverURL,
	HTTPClient: guarded, RedirectURL: "https://app.example/mcp/callback",
})
ext, err := mcp.NewExtension(mcp.ExtensionOptions{
	Servers: []mcp.ServerConnectionOptions{{
		Name: "docs", OAuth: handler,
		CreateTransport: mcp.HTTPTransport(serverURL, &mcp.HTTPTransportOptions{HTTPClient: guarded}),
	}},
	Tools: session, // a *baseAgent.AgentSession
})
ext.Start()
defer ext.Close(ctx)
// Before each prompt:
ext.WaitForStartup(ctx)
ext.ReconnectSignedIn(ctx)

Local servers use StdioTransport, whose errors end with what the server last wrote to stderr.

A server whose user must sign in shows StateNeedsAuth in its status, and its tools return an error result whose ToolDetails has SignInRequired set. A local app such as a TUI signs in with Extension.SignIn, which uses a loopback callback and a pasted redirect URL as fallback. A web app sends the user to OAuthHandler.StartSignIn's URL; its callback finds the sign-in with FindPendingSignIn, for the owner of the app's own session, and passes the query to OAuthHandler.CompleteSignIn. ReconnectSignedIn then picks up the new tokens. Apps that host Client ID Metadata Documents set OAuthOptions.ClientMetadataDocument, for example with HostedClientMetadataDocument, instead of registering clients.

Close waits for a token refresh in progress, so rotated tokens are saved before the process exits.

Index

Constants

View Source
const (
	ListResourcesTool         = "list_mcp_resources"
	ListResourceTemplatesTool = "list_mcp_resource_templates"
	ReadResourceTool          = "read_mcp_resource"
)

Names of the resource tools. Codex and opencode use the same tools, so models trained on them use these unchanged.

View Source
const DefaultStartupWait = 10 * time.Second

DefaultStartupWait is how long WaitForStartup waits for servers still connecting when ExtensionOptions.StartupWait is zero.

View Source
const DefaultTimeout = 60 * time.Second

DefaultTimeout bounds connecting and each request when ServerConnectionOptions.Timeout is zero.

View Source
const OAuthNamespace = "mcp"

OAuthNamespace is the AuthStore namespace of MCP OAuth state.

View Source
const OutputMaxBytes = 20 * 1024

OutputMaxBytes is the size of model-facing text beyond which a result is cut in the middle.

Variables

View Source
var ErrNoPendingSignIn = errors.New("mcp: no sign-in is waiting for this response; sign in again")

ErrNoPendingSignIn is returned when no started sign-in matches an authorization response's state.

View Source
var ErrSignInCancelled = errors.New("sign-in cancelled")

ErrSignInCancelled is returned by SignInMcpServer when the user or ctx cancels the sign-in.

View Source
var ErrSignInRequired = errors.New("sign-in required")

ErrSignInRequired is returned, wrapped, when only a new sign-in gives access to a server: nothing is stored, the refresh token is gone or was rejected, or the server asks for more scope. Connect and CallTool errors wrap it, so check them with errors.Is and offer StartSignIn.

Functions

func CallbackID

func CallbackID(serverURL string) (string, error)

CallbackID is 12 characters identifying an MCP server URL in callback paths, computed like Codex does: the first 9 bytes of the SHA-256 of the URL without its fragment, in unpadded base64url.

func ConvertResult

func ConvertResult(server, tool string, result *sdk.CallToolResult, opts *ConvertResultOptions) agent.AgentToolResult[any]

ConvertResult converts a tool result to model-facing content, within OutputMaxBytes. A result without content blocks becomes its structured content as JSON. An error result keeps its content and is marked IsError, getting a generic message when it has no text. opts may be nil.

func CreateResourceToolDefinitions

func CreateResourceToolDefinitions(servers func() []ResourceServer) []agent.AgentTool[any, any]

CreateResourceToolDefinitions returns list_mcp_resources, list_mcp_resource_templates and read_mcp_resource. They take a server argument; servers returns the servers they reach, at call time. Listings are JSON, as in Codex. MCP App resources (ui:// URIs and profile=mcp-app HTML) are left out, since they are user interfaces for hosts that render them.

func CreateToolDefinition

func CreateToolDefinition(opts ToolDefinitionOptions) agent.AgentTool[any, any]

CreateToolDefinition adapts one MCP tool to an agent tool. Progress notifications become tool updates. A call that fails because the user must sign in returns an error result with ToolDetails.SignInRequired set.

func CreateToolName

func CreateToolName(server, tool string, isTaken func(name string) bool) string

CreateToolName is mcp__<server>__<tool>, sanitized and shortened with a hash suffix when too long. Like Codex, everything but [A-Za-z0-9_] becomes _. isTaken reports names used by a different MCP tool: sanitizing can map two tools to one name (a-b and a_b), which then get the hash suffix. isTaken may be nil.

func SignInMcpServer

func SignInMcpServer(ctx context.Context, handler *OAuthHandler, opts SignInOptions) error

SignInMcpServer signs the user in to handler's server from a local app, such as a TUI: it uses the stored refresh token when possible, and otherwise runs the browser authorization code flow against a loopback callback. The tokens are stored like CompleteSignIn stores them. Cancelling ctx stops the sign-in with ErrSignInCancelled; requests to the authorization server are also time-limited.

Types

type ClientMetadataDocument

type ClientMetadataDocument struct {
	URL         string
	RedirectURL string
}

ClientMetadataDocument is a Client ID Metadata Document: an https URL the client uses as its client_id, and a redirect URI the document lists.

type ClientMetadataDocumentFunc

type ClientMetadataDocumentFunc func(serverURL, redirectURL string, metadata *oauthex.AuthServerMeta) (*ClientMetadataDocument, error)

ClientMetadataDocumentFunc chooses the Client ID Metadata Document to sign in to serverURL with, given the redirect URI of the sign-in and the authorization server's metadata. It is called at every sign-in, and the result is stored with the tokens.

func HostedClientMetadataDocument

func HostedClientMetadataDocument(baseURL string) ClientMetadataDocumentFunc

HostedClientMetadataDocument chooses documents served under baseURL, as pi chooses its own and Codex its. When the authorization server sends the iss parameter in authorization responses (RFC 9207), the document is baseURL/client.json and the redirect URI the one given. Otherwise the document and redirect URI are specific to the MCP server, so a response cannot be mixed up with one from another authorization server (RFC 9700 section 4.4.2.2): baseURL/<id>/client.json with the redirect path followed by /<id>, where id is CallbackID of the server URL. The app serves those documents and receives the authorization response on those paths too.

type ConvertResultOptions

type ConvertResultOptions struct {
	// ReadableResources reports that read_mcp_resource can read the server's
	// resources, which resource links then name.
	ReadableResources bool
}

ConvertResultOptions configures ConvertResult.

type Extension

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

Extension connects an agent session to MCP servers, as pi's MCP extension does. Each server's tools are registered when it connects and again when they change. Names stay stable for the session, since its history calls tools by name. Tools a server no longer offers are deactivated, and activated again if it offers them again. The resource tools are registered once a server offers resources.

Wire it into a session:

ext, err := mcp.NewExtension(mcp.ExtensionOptions{Servers: servers, Tools: session})
ext.Start()
defer ext.Close(ctx)
// Before each prompt:
ext.WaitForStartup(ctx)
ext.ReconnectSignedIn(ctx)
session.Prompt(ctx, text, nil)

func NewExtension

func NewExtension(opts ExtensionOptions) (*Extension, error)

NewExtension creates the servers' connections. Call Start to connect them.

func (*Extension) Close

func (e *Extension) Close(ctx context.Context) error

Close closes every connection. See ServerConnection.Close.

func (*Extension) Connection

func (e *Extension) Connection(name string) *ServerConnection

Connection is the connection of the server named name, or nil.

func (*Extension) Connections

func (e *Extension) Connections() []*ServerConnection

Connections are the servers' connections, in the order configured.

func (*Extension) Logout

func (e *Extension) Logout(ctx context.Context, name string) error

Logout deletes the stored credentials of the server named name and disconnects it.

func (*Extension) Reconnect

func (e *Extension) Reconnect(ctx context.Context, name string) error

Reconnect reconnects the server named name.

func (*Extension) ReconnectSignedIn

func (e *Extension) ReconnectSignedIn(ctx context.Context) error

ReconnectSignedIn reconnects the servers that need a sign-in when their credentials were stored since, for example by CompleteSignIn in another request or process. Call it before each prompt or turn.

func (*Extension) SignIn

func (e *Extension) SignIn(ctx context.Context, name string, opts SignInOptions) error

SignIn signs the user in to the server named name with SignInMcpServer, then reconnects. Closing the extension cancels it.

func (*Extension) Start

func (e *Extension) Start()

Start connects every server in the background. Failures show in each connection's Status. Calling it again does nothing.

func (*Extension) WaitForStartup

func (e *Extension) WaitForStartup(ctx context.Context) bool

WaitForStartup lets the first prompt wait for the servers Start is still connecting, so their tools are declared in its first request, but not indefinitely: a slow or hanging server must not hold up the prompt. Its tools become available once it connects. Later calls return at once. It reports whether every server finished connecting.

type ExtensionOptions

type ExtensionOptions struct {
	// Servers are the servers to connect, with distinct names. The
	// extension sets their OnTools; their OnChange is called after the
	// extension's.
	Servers []ServerConnectionOptions
	// Tools receives the servers' tools and the resource tools. Required.
	Tools ToolRegistry
	// StartupWait is how long WaitForStartup waits for servers still
	// connecting. Zero means DefaultStartupWait.
	StartupWait time.Duration
}

ExtensionOptions configures an Extension.

type HTTPTransportOptions

type HTTPTransportOptions struct {
	// HTTPClient sends the requests. Nil means a default client. Apps that
	// let users add servers should pass a client that refuses private
	// addresses.
	HTTPClient *http.Client
	// Headers are sent with each request to the endpoint's origin, for
	// example an API key for a server without OAuth. Headers the transport
	// sets itself take precedence, among them the OAuth access token once the
	// user has signed in, as in pi.
	Headers map[string]string
}

HTTPTransportOptions configures HTTPTransport.

type OAuthCallback

type OAuthCallback struct {
	Code  string
	State string
	Iss   string
}

OAuthCallback is an authorization response.

type OAuthCallbackPage

type OAuthCallbackPage struct {
	OK      bool
	Message string
	Details string
}

OAuthCallbackPage is the outcome shown on the browser page after the redirect.

type OAuthCallbackServer

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

OAuthCallbackServer receives authorization responses on a loopback address, for apps such as a TUI where the browser runs on the user's machine.

func ListenOAuthCallback

func ListenOAuthCallback(opts OAuthCallbackServerOptions) (*OAuthCallbackServer, error)

ListenOAuthCallback starts a callback server. Close it when done.

func (*OAuthCallbackServer) Close

func (s *OAuthCallbackServer) Close() error

Close fails the waits in progress and stops the server.

func (*OAuthCallbackServer) RedirectURL

func (s *OAuthCallbackServer) RedirectURL() string

RedirectURL is the URL of Path on the port the server listens on.

func (*OAuthCallbackServer) WaitForCallback

func (s *OAuthCallbackServer) WaitForCallback(state, path string) (func(ctx context.Context) (*OAuthCallback, error), error)

WaitForCallback expects the authorization response with state, and returns a function that waits for it. Call it before sending the user to the authorization URL, since a response nobody expects is refused. With a path, the server receives responses on it too, and a response on another path fails, so a server-specific redirect URI can tell authorization servers apart (RFC 9700 section 4.4.2.2).

type OAuthCallbackServerOptions

type OAuthCallbackServerOptions struct {
	// Host is the address to listen on. Empty means 127.0.0.1.
	Host string
	// RedirectHost is the host name in the redirect URL, for example
	// localhost for a client registered with it while listening on
	// 127.0.0.1. Empty means Host.
	RedirectHost string
	// Port is the port to listen on. Zero means a free port.
	Port int
	// Path receives the callback. Empty means /callback.
	Path string
	// ExtraPaths receive the callback too, for example the server-specific
	// path of a redirect URI.
	ExtraPaths []string
	// Timeout bounds each wait. Zero means 5 minutes.
	Timeout time.Duration
	// RenderPage renders the browser page as HTML. Nil means a plain-text
	// message.
	RenderPage func(OAuthCallbackPage) string
}

OAuthCallbackServerOptions configures ListenOAuthCallback.

type OAuthError

type OAuthError struct {
	Code        string
	Description string
	StatusCode  int
}

OAuthError is an error response of an authorization server's token endpoint (RFC 6749 section 5.2).

func (*OAuthError) Error

func (e *OAuthError) Error() string

type OAuthHandler

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

OAuthHandler authorizes requests to one MCP server for one owner. Set it as the OAuthHandler of an sdk.StreamableClientTransport, with OAuthHandler.HTTPClient as its HTTPClient, as HTTPTransport does.

Connections never start a browser flow on their own. They send the stored access token, refresh it when it is about to expire or after a 401, and otherwise fail with ErrSignInRequired. The app then signs the user in with StartSignIn and CompleteSignIn, which may run in different processes.

Many servers rotate refresh tokens, so two refreshes with the same refresh token lose the grant. Refreshes hold the store's lock from reading the tokens to saving new ones, in every process, and tokens that changed meanwhile are used without refreshing.

func NewOAuthHandler

func NewOAuthHandler(opts *OAuthOptions) (*OAuthHandler, error)

NewOAuthHandler returns a handler for opts.Server and opts.OwnerID.

func (*OAuthHandler) Authorize

func (h *OAuthHandler) Authorize(ctx context.Context, req *http.Request, resp *http.Response) error

Authorize handles a 401 or 403 from the server. It refreshes the rejected token, or returns ErrSignInRequired when only a new sign-in helps. It implements auth.OAuthHandler.

func (*OAuthHandler) CompleteSignIn

func (h *OAuthHandler) CompleteSignIn(ctx context.Context, query url.Values) error

CompleteSignIn finishes the sign-in StartSignIn began, given the query of the authorization server's redirect to RedirectURL. It checks the state and issuer, exchanges the code for tokens, and stores them.

func (*OAuthHandler) HTTPClient

func (h *OAuthHandler) HTTPClient(base *http.Client) *http.Client

HTTPClient returns base, nil meaning a default client, with a transport that reports ErrSignInRequired when the server rejects the tokens Authorize just refreshed. Use it as the HTTPClient of the sdk.StreamableClientTransport the handler authorizes; HTTPTransport does. The SDK retries a request once after Authorize and reports a second 401 as a plain error that breaks the connection, so without it a server that rejects every token makes each connect refresh again and fail instead of asking the user to sign in.

func (*OAuthHandler) SignOut

func (h *OAuthHandler) SignOut(ctx context.Context) error

SignOut deletes everything stored for the server, including the client registration.

func (*OAuthHandler) SignedIn

func (h *OAuthHandler) SignedIn(ctx context.Context) (bool, error)

SignedIn reports whether tokens are stored for the server. They may still be rejected.

func (*OAuthHandler) StartSignIn

func (h *OAuthHandler) StartSignIn(ctx context.Context) (string, error)

StartSignIn begins signing in. It discovers the authorization server, registers a client if needed, stores the pending request, and returns the URL to send the user to. The authorization server redirects the user to RedirectURL; pass that request's query to CompleteSignIn, in any process. Starting again replaces the pending request.

func (*OAuthHandler) TokenSource

func (h *OAuthHandler) TokenSource(ctx context.Context) (oauth2.TokenSource, error)

TokenSource returns the stored access token, refreshed first when it is about to expire, or nil when there is none. It implements auth.OAuthHandler.

func (*OAuthHandler) Wait

func (h *OAuthHandler) Wait(ctx context.Context) error

Wait returns once no store update of this handler is running, or with ctx's error when ctx is done first. Call it before the process exits: a refresh or code exchange the server already answered may have rotated the refresh token, and exiting before the new tokens are saved loses the grant. Updates keep running when the request that started them is cancelled, so they can still be in progress after every request returned.

type OAuthOptions

type OAuthOptions struct {
	// Store keeps the state of each owner's sign-in: client registration,
	// tokens and the pending authorization request. Required.
	Store baseAgent.AuthStore
	// OwnerID is the user or tenant the credentials belong to.
	OwnerID string
	// Server names the server. With ServerURL it keys the stored state, so
	// servers sharing a URL keep separate accounts. Required.
	Server string
	// ServerURL is the MCP endpoint. Required.
	ServerURL string
	// HTTPClient sends discovery, registration and token requests. Apps that
	// let users add servers should pass a client that refuses private
	// addresses, and use it for the transport too. Nil means a default client.
	HTTPClient *http.Client
	// RequestTimeout bounds each request to the authorization server. Zero
	// means 15 seconds.
	RequestTimeout time.Duration

	// RedirectURL receives the authorization response; pass its query to
	// CompleteSignIn. It may be specific to the server, so the callback
	// knows which handler to complete. Required to sign in.
	RedirectURL string
	// ClientID and ClientSecret identify a client registered with the
	// authorization server beforehand. Without ClientID, sign-in registers
	// one dynamically (RFC 7591) and stores it.
	ClientID     string
	ClientSecret string
	// ClientName is the client_name of dynamic registration. Empty means
	// "burrow".
	ClientName string
	// ClientMetadataDocument, when set and ClientID is empty, identifies the
	// client with a Client ID Metadata Document instead of registering it
	// dynamically. See [HostedClientMetadataDocument].
	ClientMetadataDocument ClientMetadataDocumentFunc
	// Scope lists scopes, separated by spaces, to request in addition to the
	// ones the server asks for.
	Scope string
	// AuthServerMetadataURL is an authorization server metadata document
	// (RFC 8414 or OpenID Connect discovery) to use instead of discovery
	// through the server, for servers that advertise a wrong authorization
	// server or none. The document is trusted as configured, so its issuer is
	// not checked. It must use HTTPS, except on loopback hosts.
	AuthServerMetadataURL string

	// Now returns the current time. Nil means time.Now.
	Now func() time.Time
}

OAuthOptions configures an OAuthHandler.

type PendingSignIn

type PendingSignIn struct {
	Server    string
	ServerURL string
}

PendingSignIn identifies the server of a started sign-in.

func FindPendingSignIn

func FindPendingSignIn(ctx context.Context, store baseAgent.AuthStore, ownerID, state string) (*PendingSignIn, error)

FindPendingSignIn finds ownerID's started sign-in that the authorization response with state belongs to, for apps with one redirect URL for every server. Construct the result's OAuthHandler and pass the response to its CompleteSignIn. It returns ErrNoPendingSignIn when none matches.

ownerID must come from the app's own authenticated session, never from the response. A lookup across owners would let an attacker send a victim the authorization URL of the attacker's sign-in: the victim's grant would then complete it, storing the victim's tokens under the attacker's account (login CSRF, RFC 9700 section 4.7).

type RequestOptions

type RequestOptions struct {
	// Timeout bounds the request, restarting at each progress notification
	// when OnProgress is set. Zero leaves it bounded only by its context.
	Timeout time.Duration
	// OnProgress receives the server's progress notifications for the
	// request. Nil means the request does not ask for progress.
	OnProgress func(*sdk.ProgressNotificationParams)
}

RequestOptions are the options of one request to a server.

type ResourceServer

type ResourceServer interface {
	Name() string
	Timeout() time.Duration
	ResourcesPage(ctx context.Context, cursor string, opts *RequestOptions) (*sdk.ListResourcesResult, error)
	ResourceTemplatesPage(ctx context.Context, cursor string, opts *RequestOptions) (*sdk.ListResourceTemplatesResult, error)
	AllResources(ctx context.Context, opts *RequestOptions) ([]*sdk.Resource, error)
	AllResourceTemplates(ctx context.Context, opts *RequestOptions) ([]*sdk.ResourceTemplate, error)
	ReadResource(ctx context.Context, uri string, opts *RequestOptions) (*sdk.ReadResourceResult, error)
}

ResourceServer is a connected server that offers resources. ServerConnection implements it.

type ServerConnection

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

ServerConnection is one configured server. It connects on first use and reconnects lazily when a call finds the connection gone. Callbacks run without its lock held, so they may call its methods.

func NewServerConnection

func NewServerConnection(opts ServerConnectionOptions) (*ServerConnection, error)

NewServerConnection returns a connection that has not connected yet. Call GetClient to connect.

func (*ServerConnection) AllResourceTemplates

func (c *ServerConnection) AllResourceTemplates(ctx context.Context, opts *RequestOptions) ([]*sdk.ResourceTemplate, error)

AllResourceTemplates lists every page of resource templates.

func (*ServerConnection) AllResources

func (c *ServerConnection) AllResources(ctx context.Context, opts *RequestOptions) ([]*sdk.Resource, error)

AllResources lists every page of resources.

func (*ServerConnection) CallTool

func (c *ServerConnection) CallTool(ctx context.Context, name string, args map[string]any, opts *RequestOptions) (*sdk.CallToolResult, error)

CallTool calls the server's tool name. It is not retried after a transient error, since the tool may have run.

func (*ServerConnection) Close

func (c *ServerConnection) Close(ctx context.Context) error

Close closes the connection and returns once no transport of this server is open, including one that was still connecting, and no refresh of its tokens is saving. A refresh the server already answered may have rotated the refresh token; exiting before the new tokens are saved would lose the grant. It returns early with ctx's error.

func (*ServerConnection) GetClient

func (c *ServerConnection) GetClient(ctx context.Context) (*sdk.ClientSession, error)

GetClient returns the connected session, connecting first if needed. Concurrent callers share one connect. Cancelling ctx stops waiting, not the connect.

func (*ServerConnection) HasResources

func (c *ServerConnection) HasResources() bool

HasResources reports whether the server offers resources, which the resource tools list and read on demand. They are not listed at connect: listing every resource can take long (a large drive, say).

func (*ServerConnection) Instructions

func (c *ServerConnection) Instructions() string

Instructions are the server's instructions from initialize, describing its tools as a group.

func (*ServerConnection) Name

func (c *ServerConnection) Name() string

Name is the server's name.

func (*ServerConnection) OAuth

func (c *ServerConnection) OAuth() *OAuthHandler

OAuth is the handler that authorizes requests, or nil.

func (*ServerConnection) ReadResource

func (c *ServerConnection) ReadResource(ctx context.Context, uri string, opts *RequestOptions) (*sdk.ReadResourceResult, error)

ReadResource reads the resource at uri.

func (*ServerConnection) Reconnect

func (c *ServerConnection) Reconnect(ctx context.Context) error

Reconnect connects again with fresh credentials, for example after signing in.

func (*ServerConnection) ResourceTemplatesPage

func (c *ServerConnection) ResourceTemplatesPage(ctx context.Context, cursor string, opts *RequestOptions) (*sdk.ListResourceTemplatesResult, error)

ResourceTemplatesPage lists one page of resource templates, starting at cursor. Servers that do not implement resources/templates/list have none.

func (*ServerConnection) ResourcesPage

func (c *ServerConnection) ResourcesPage(ctx context.Context, cursor string, opts *RequestOptions) (*sdk.ListResourcesResult, error)

ResourcesPage lists one page of resources, starting at cursor.

func (*ServerConnection) SignOut

func (c *ServerConnection) SignOut(ctx context.Context) error

SignOut disconnects after the stored credentials were removed.

func (*ServerConnection) Status

func (c *ServerConnection) Status() ServerStatus

Status is the connection's state and why it is in it.

func (*ServerConnection) Timeout

func (c *ServerConnection) Timeout() time.Duration

Timeout bounds connecting and each request.

func (*ServerConnection) Tools

func (c *ServerConnection) Tools() []*sdk.Tool

Tools are the tools the server offered when last listed.

type ServerConnectionOptions

type ServerConnectionOptions struct {
	// Name names the server in tool names, labels and messages. Required.
	Name string
	// CreateTransport returns the transport of each connection attempt.
	// Required.
	CreateTransport TransportFactory
	// OAuth authorizes requests to a server that signs users in with OAuth.
	// It is passed to CreateTransport.
	OAuth *OAuthHandler
	// Timeout bounds connecting and each request; for tool calls, the time
	// between progress notifications. Zero means DefaultTimeout.
	Timeout time.Duration
	// Client identifies the client to the server. Nil means burrow.
	Client *sdk.Implementation
	// OnTools is called when the server's tools were listed: after each
	// connect and when the server reports that they changed.
	OnTools func(*ServerConnection)
	// OnChange is called when the status or the tools change.
	OnChange func(*ServerConnection)
}

ServerConnectionOptions configures a ServerConnection.

type ServerState

type ServerState string

ServerState is the state of a ServerConnection.

const (
	StateConnecting ServerState = "connecting"
	StateConnected  ServerState = "connected"
	// StateDisconnected means the connection dropped, for example because
	// the stdio server exited. The next call reconnects.
	StateDisconnected ServerState = "disconnected"
	// StateNeedsAuth means the user must sign in; see [ErrSignInRequired].
	StateNeedsAuth ServerState = "needs-auth"
	StateFailed    ServerState = "failed"
	StateClosed    ServerState = "closed"
)

type ServerStatus

type ServerStatus struct {
	State ServerState
	// Error says why the server failed or disconnected, or that refreshing
	// its tools failed.
	Error string
}

ServerStatus is the state of a ServerConnection and why it is in it.

type SignInOptions

type SignInOptions struct {
	// Prompt shows the authorization URL and asks for the redirect URL.
	// Required.
	Prompt SignInPrompt
	// CallbackURL is the loopback redirect URI. Empty means
	// http://127.0.0.1/callback. One with a port is sent exactly as
	// written, since servers compare it as a string; localhost is served on
	// 127.0.0.1.
	CallbackURL string
	// CallbackPort is the port of a CallbackURL without one. Zero means the
	// port of the stored client's redirect URI, so it stays valid, else a
	// free port.
	CallbackPort int
	// RenderPage renders the browser page after the redirect as HTML. Nil
	// means a plain-text message.
	RenderPage func(OAuthCallbackPage) string
}

SignInOptions configures SignInMcpServer.

type SignInPrompt

type SignInPrompt interface {
	// ShowAuthorizationURL shows the authorization URL to the user and opens
	// it in a browser.
	ShowAuthorizationURL(url string)
	// PromptForRedirectURL asks for the redirect URL from the browser
	// address bar, for when the browser cannot reach the loopback callback
	// (for example over SSH). ctx is cancelled once the callback arrives or
	// the sign-in is cancelled. An empty answer cancels the sign-in. A
	// prompt that cannot ask waits for ctx and returns its error.
	PromptForRedirectURL(ctx context.Context) (string, error)
}

SignInPrompt asks the user to authorize in a browser.

type ToolCaller

type ToolCaller interface {
	CallTool(ctx context.Context, name string, args map[string]any, opts *RequestOptions) (*sdk.CallToolResult, error)
}

ToolCaller calls tools of one server. ServerConnection implements it.

type ToolDefinitionOptions

type ToolDefinitionOptions struct {
	// Server names the server in labels and messages.
	Server string
	Tool   *sdk.Tool
	// Name is the agent tool name, from [CreateToolName].
	Name string
	// Timeout bounds each call, restarting at each progress notification.
	// Zero leaves calls bounded only by their context.
	Timeout time.Duration
	// GetClient returns the caller at execution time, so a tool outlives the
	// connection it was listed on.
	GetClient func(ctx context.Context) (ToolCaller, error)
	// ReadableResources reports whether read_mcp_resource can read the
	// server's resources, which resource links then name. Nil means it
	// cannot.
	ReadableResources func() bool
}

ToolDefinitionOptions configures CreateToolDefinition.

type ToolDetails

type ToolDetails struct {
	Server string `json:"server"`
	Tool   string `json:"tool"`
	// StructuredContent is the result's structured content, if any. It is
	// never truncated.
	StructuredContent any `json:"structuredContent,omitempty"`
	// SignInRequired reports that the call failed because the user must sign
	// in to Server (see [ErrSignInRequired]); the result is an error result
	// saying so. Apps check it in tool events to offer sign-in. Details
	// restored from a session store are decoded JSON, not ToolDetails.
	SignInRequired bool `json:"signInRequired,omitempty"`
}

ToolDetails are the details of every MCP tool result and update.

type ToolRegistry

type ToolRegistry interface {
	// RegisterTool adds a tool, active, or replaces the tool of that name,
	// keeping whether it is active.
	RegisterTool(tool agent.AgentTool[any, any]) error
	GetActiveToolNames() ([]string, error)
	// SetActiveToolsByName activates the named tools and deactivates the
	// rest, ignoring unknown names.
	SetActiveToolsByName(names []string) error
}

ToolRegistry is where an Extension registers tools. baseAgent.AgentSession implements it: a tool registered during a prompt is declared from the prompt's next turn.

type TransportFactory

type TransportFactory func(oauth *OAuthHandler) (sdk.Transport, error)

TransportFactory returns a new transport for each connection attempt. When oauth is not nil, the transport must authorize its requests with it, and send them with its HTTPClient.

func HTTPTransport

func HTTPTransport(endpoint string, opts *HTTPTransportOptions) TransportFactory

HTTPTransport connects to a streamable HTTP endpoint. Nil opts means the default client and no headers.

func StdioTransport

func StdioTransport(command func() *exec.Cmd) TransportFactory

StdioTransport runs a stdio server. command returns the process to start for each connection attempt; set its Dir and Env there. The end of what the server writes to stderr is added to the error when it fails to connect or exits. A Stderr the command sets still receives all of it.

Jump to

Keyboard shortcuts

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