or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

auth.mdindex.mdjsonrpc.mdmcp-capabilities.mdmcp-client.mdmcp-content.mdmcp-protocol.mdmcp-server.mdmcp-transports.mdoauthex.md
tile.json

mcp-client.mddocs/

MCP Client

The client API enables connecting to MCP servers and invoking their capabilities including tools, prompts, resources, and sampling.

Client Creation

func NewClient(impl *Implementation, opts *ClientOptions) *Client

Creates a new MCP client instance.

Client Type

type Client struct {
	// Has unexported fields
}

Client Options

type ClientOptions struct {
	CreateMessageHandler        func(context.Context, *CreateMessageRequest) (*CreateMessageResult, error)
	ElicitationHandler          func(context.Context, *ElicitRequest) (*ElicitResult, error)
	ToolListChangedHandler      func(context.Context, *ToolListChangedRequest)
	PromptListChangedHandler    func(context.Context, *PromptListChangedRequest)
	ResourceListChangedHandler  func(context.Context, *ResourceListChangedRequest)
	ResourceUpdatedHandler      func(context.Context, *ResourceUpdatedNotificationRequest)
	LoggingMessageHandler       func(context.Context, *LoggingMessageRequest)
	ProgressNotificationHandler func(context.Context, *ProgressNotificationClientRequest)
	KeepAlive                   time.Duration
}

Fields:

  • CreateMessageHandler: Handler for server sampling requests (LLM generation)
  • ElicitationHandler: Handler for server elicitation requests (user input)
  • ToolListChangedHandler: Notified when server's tool list changes
  • PromptListChangedHandler: Notified when server's prompt list changes
  • ResourceListChangedHandler: Notified when server's resource list changes
  • ResourceUpdatedHandler: Notified when a specific resource is updated
  • LoggingMessageHandler: Handler for server log messages
  • ProgressNotificationHandler: Handler for server progress notifications
  • KeepAlive: Duration for connection keep-alive (0 to disable)

Client Methods

Connecting to Servers

func (c *Client) Connect(ctx context.Context, t Transport, _ *ClientSessionOptions) (*ClientSession, error)

Connects to a server over the given transport and performs initialization handshake.

Root Management

func (c *Client) AddRoots(roots ...*Root)

Adds roots to the client and notifies all connected servers.

func (c *Client) RemoveRoots(uris ...string)

Removes roots by URI and notifies all connected servers.

Middleware

func (c *Client) AddReceivingMiddleware(middleware ...Middleware)

Adds middleware for processing incoming requests from servers.

func (c *Client) AddSendingMiddleware(middleware ...Middleware)

Adds middleware for processing outgoing requests to servers.

Client Session

type ClientSession struct {
	// Has unexported fields
}

A logical connection with an MCP server.

Client Session Options

type ClientSessionOptions struct{}

Reserved for future use.

Client Session Methods

Session Information

func (s *ClientSession) ID() string

Returns the unique session identifier.

func (s *ClientSession) InitializeResult() *InitializeResult

Returns the initialization result from the server containing capabilities and server info.

Connection Management

func (s *ClientSession) Close() error

Gracefully closes the connection to the server.

func (s *ClientSession) Wait() error

Waits for the server to close the connection.

func (s *ClientSession) Ping(ctx context.Context, params *PingParams) error

Pings the server to check connectivity.

Tool Operations

func (s *ClientSession) ListTools(ctx context.Context, params *ListToolsParams) (*ListToolsResult, error)

Lists available tools from the server.

func (s *ClientSession) Tools(ctx context.Context, params *ListToolsParams) iter.Seq2[*Tool, error]

Returns an iterator over all tools, automatically handling pagination.

func (s *ClientSession) CallTool(ctx context.Context, params *CallToolParams) (*CallToolResult, error)

Calls a tool on the server.

Prompt Operations

func (s *ClientSession) ListPrompts(ctx context.Context, params *ListPromptsParams) (*ListPromptsResult, error)

Lists available prompts from the server.

func (s *ClientSession) Prompts(ctx context.Context, params *ListPromptsParams) iter.Seq2[*Prompt, error]

Returns an iterator over all prompts, automatically handling pagination.

func (s *ClientSession) GetPrompt(ctx context.Context, params *GetPromptParams) (*GetPromptResult, error)

Gets a specific prompt with arguments.

Resource Operations

func (s *ClientSession) ListResources(ctx context.Context, params *ListResourcesParams) (*ListResourcesResult, error)

Lists available resources from the server.

func (s *ClientSession) Resources(ctx context.Context, params *ListResourcesParams) iter.Seq2[*Resource, error]

Returns an iterator over all resources, automatically handling pagination.

func (s *ClientSession) ListResourceTemplates(ctx context.Context, params *ListResourceTemplatesParams) (*ListResourceTemplatesResult, error)

Lists available resource templates from the server.

func (s *ClientSession) ResourceTemplates(ctx context.Context, params *ListResourceTemplatesParams) iter.Seq2[*ResourceTemplate, error]

Returns an iterator over all resource templates, automatically handling pagination.

func (s *ClientSession) ReadResource(ctx context.Context, params *ReadResourceParams) (*ReadResourceResult, error)

Reads a resource from the server.

func (s *ClientSession) Subscribe(ctx context.Context, params *SubscribeParams) error

Subscribes to updates for a resource.

func (s *ClientSession) Unsubscribe(ctx context.Context, params *UnsubscribeParams) error

Unsubscribes from updates for a resource.

Completion Operations

func (s *ClientSession) Complete(ctx context.Context, params *CompleteParams) (*CompleteResult, error)

Requests argument completion suggestions from the server.

Logging Operations

func (s *ClientSession) SetLoggingLevel(ctx context.Context, params *SetLoggingLevelParams) error

Sets the logging level for the server.

Progress Notifications

func (s *ClientSession) NotifyProgress(ctx context.Context, params *ProgressNotificationParams) error

Sends a progress notification to the server.

Client Request Types

These types represent requests received by the client from servers.

type ClientRequest[P Params] struct {
	Session *ClientSession
	Params  P
}

Generic client request with session and parameters.

Methods:

func (r *ClientRequest[P]) GetExtra() *RequestExtra
func (r *ClientRequest[P]) GetParams() Params
func (r *ClientRequest[P]) GetSession() Session

Specific Client Request Types

type InitializeRequest = ClientRequest[*InitializeParams]
type CreateMessageRequest = ClientRequest[*CreateMessageParams]
type ElicitRequest = ClientRequest[*ElicitParams]
type ListRootsRequest = ClientRequest[*ListRootsParams]
type ToolListChangedRequest = ClientRequest[*ToolListChangedParams]
type PromptListChangedRequest = ClientRequest[*PromptListChangedParams]
type ResourceListChangedRequest = ClientRequest[*ResourceListChangedParams]
type ResourceUpdatedNotificationRequest = ClientRequest[*ResourceUpdatedNotificationParams]
type LoggingMessageRequest = ClientRequest[*LoggingMessageParams]
type ProgressNotificationClientRequest = ClientRequest[*ProgressNotificationParams]

Root Types

type Root struct {
	Meta `json:"_meta,omitempty"`
	Name string `json:"name,omitempty"`
	URI  string `json:"uri"`
}

Represents a root directory or file that the server can operate on.

Fields:

  • Meta: Additional metadata
  • Name: Human-readable name
  • URI: Root URI (typically a file:// URL)

Example: Complete Client

package main

import (
	"context"
	"fmt"
	"log"
	"os/exec"
	"github.com/modelcontextprotocol/go-sdk/mcp"
)

func main() {
	ctx := context.Background()

	// Create client with handlers
	client := mcp.NewClient(
		&mcp.Implementation{Name: "example-client", Version: "1.0.0"},
		&mcp.ClientOptions{
			// Handle server sampling requests
			CreateMessageHandler: func(ctx context.Context, req *mcp.CreateMessageRequest) (*mcp.CreateMessageResult, error) {
				return &mcp.CreateMessageResult{
					Role:  "assistant",
					Model: "gpt-4",
					Content: &mcp.TextContent{
						Text: "This is a generated response",
					},
				}, nil
			},
			// Handle server log messages
			LoggingMessageHandler: func(ctx context.Context, req *mcp.LoggingMessageRequest) {
				log.Printf("[%s] %v", req.Params.Level, req.Params.Data)
			},
			// Handle resource list changes
			ResourceListChangedHandler: func(ctx context.Context, req *mcp.ResourceListChangedRequest) {
				log.Println("Server's resource list changed")
			},
		},
	)

	// Add roots
	client.AddRoots(&mcp.Root{
		URI:  "file:///home/user/projects",
		Name: "Projects Directory",
	})

	// Connect to server
	transport := &mcp.CommandTransport{
		Command: exec.Command("my-mcp-server"),
	}
	session, err := client.Connect(ctx, transport, nil)
	if err != nil {
		log.Fatal(err)
	}
	defer session.Close()

	// Check server capabilities
	initResult := session.InitializeResult()
	fmt.Printf("Connected to: %s v%s\n",
		initResult.ServerInfo.Name,
		initResult.ServerInfo.Version)

	// List and call tools
	toolsResult, err := session.ListTools(ctx, &mcp.ListToolsParams{})
	if err != nil {
		log.Fatal(err)
	}

	for _, tool := range toolsResult.Tools {
		fmt.Printf("Tool: %s - %s\n", tool.Name, tool.Description)
	}

	if len(toolsResult.Tools) > 0 {
		result, err := session.CallTool(ctx, &mcp.CallToolParams{
			Name:      toolsResult.Tools[0].Name,
			Arguments: map[string]any{"input": "test"},
		})
		if err != nil {
			log.Fatal(err)
		}
		if result.IsError {
			log.Println("Tool call failed")
		} else {
			for _, content := range result.Content {
				if text, ok := content.(*mcp.TextContent); ok {
					fmt.Println(text.Text)
				}
			}
		}
	}

	// Use iterator for all resources
	for resource, err := range session.Resources(ctx, &mcp.ListResourcesParams{}) {
		if err != nil {
			log.Printf("Error iterating resources: %v", err)
			break
		}
		fmt.Printf("Resource: %s (%s)\n", resource.Name, resource.URI)

		// Read the resource
		readResult, err := session.ReadResource(ctx, &mcp.ReadResourceParams{
			URI: resource.URI,
		})
		if err != nil {
			log.Printf("Error reading resource: %v", err)
			continue
		}
		for _, content := range readResult.Contents {
			if content.Text != "" {
				fmt.Printf("  Content: %s\n", content.Text[:min(50, len(content.Text))])
			}
		}
	}

	// Get a prompt
	promptResult, err := session.GetPrompt(ctx, &mcp.GetPromptParams{
		Name:      "greeting",
		Arguments: map[string]string{"name": "Alice"},
	})
	if err == nil {
		for _, msg := range promptResult.Messages {
			if text, ok := msg.Content.(*mcp.TextContent); ok {
				fmt.Printf("Prompt: %s\n", text.Text)
			}
		}
	}

	// Wait for server to disconnect
	if err := session.Wait(); err != nil {
		log.Printf("Session ended: %v", err)
	}
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

Example: Using Iterators for Pagination

// Iterate over all tools automatically handling pagination
for tool, err := range session.Tools(ctx, &mcp.ListToolsParams{}) {
	if err != nil {
		log.Printf("Error: %v", err)
		break
	}
	fmt.Printf("Tool: %s\n", tool.Name)
}

// Iterate over all prompts
for prompt, err := range session.Prompts(ctx, &mcp.ListPromptsParams{}) {
	if err != nil {
		log.Printf("Error: %v", err)
		break
	}
	fmt.Printf("Prompt: %s\n", prompt.Name)
}

// Iterate over all resources
for resource, err := range session.Resources(ctx, &mcp.ListResourcesParams{}) {
	if err != nil {
		log.Printf("Error: %v", err)
		break
	}
	fmt.Printf("Resource: %s\n", resource.URI)
}

// Iterate over all resource templates
for template, err := range session.ResourceTemplates(ctx, &mcp.ListResourceTemplatesParams{}) {
	if err != nil {
		log.Printf("Error: %v", err)
		break
	}
	fmt.Printf("Template: %s\n", template.URITemplate)
}

Example: Handling Server Notifications

client := mcp.NewClient(
	&mcp.Implementation{Name: "reactive-client", Version: "1.0.0"},
	&mcp.ClientOptions{
		// Automatically refetch when lists change
		ToolListChangedHandler: func(ctx context.Context, req *mcp.ToolListChangedRequest) {
			tools, err := req.Session.ListTools(ctx, &mcp.ListToolsParams{})
			if err != nil {
				log.Printf("Error refreshing tools: %v", err)
				return
			}
			log.Printf("Tools updated: %d available", len(tools.Tools))
		},

		// Subscribe to resource updates
		ResourceUpdatedHandler: func(ctx context.Context, req *mcp.ResourceUpdatedNotificationRequest) {
			log.Printf("Resource updated: %s", req.Params.URI)
			// Re-read the resource
			content, err := req.Session.ReadResource(ctx, &mcp.ReadResourceParams{
				URI: req.Params.URI,
			})
			if err != nil {
				log.Printf("Error reading updated resource: %v", err)
				return
			}
			log.Printf("New content received: %d items", len(content.Contents))
		},

		// Handle progress from long-running operations
		ProgressNotificationHandler: func(ctx context.Context, req *mcp.ProgressNotificationClientRequest) {
			progress := (req.Params.Progress / req.Params.Total) * 100
			log.Printf("Progress: %.1f%% - %s", progress, req.Params.Message)
		},
	},
)