mcp

package module
v0.4.5 Latest Latest
Warning

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

Go to latest
Published: May 28, 2025 License: MIT Imports: 7 Imported by: 0

README

MCP Go SDK

Build Go Report Card GoDoc

A Go implementation of the Model Context Protocol (MCP), providing both client and server capabilities for integrating with LLM surfaces.

Overview

The Model Context Protocol allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction. This Go SDK implements the full MCP specification, making it easy to:

  • Build MCP clients that can connect to any MCP server
  • Create MCP servers that expose resources, prompts and tools
  • Use standard transports like stdio and SSE (coming soon)
  • Handle all MCP protocol messages and lifecycle events

A small example

Curious what all this looks like in practice? Here's an example server that exposes the contents of an io.FS as resources.

package main

import (
	"context"
	"flag"
	"io/fs"
	"log"
	"mime"
	"os"
	"path/filepath"
	"strings"

	"github.com/riza-io/mcp-go"
)

type FSServer struct {
	fs fs.FS

	mcp.UnimplementedServer
}

func (s *FSServer) Initialize(ctx context.Context, req *mcp.Request[mcp.InitializeRequest]) (*mcp.Response[mcp.InitializeResponse], error) {
	return mcp.NewResponse(&mcp.InitializeResponse{
		ProtocolVersion: req.Params.ProtocolVersion,
		Capabilities: mcp.ServerCapabilities{
			Resources: &mcp.Resources{},
		},
	}), nil
}

func (s *FSServer) ListResources(ctx context.Context, req *mcp.Request[mcp.ListResourcesRequest]) (*mcp.Response[mcp.ListResourcesResponse], error) {
	var resources []mcp.Resource
	fs.WalkDir(s.fs, ".", func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if d.IsDir() {
			return nil
		}
		resources = append(resources, mcp.Resource{
			URI:      "file://" + path,
			Name:     path,
			MimeType: mime.TypeByExtension(filepath.Ext(path)),
		})
		return nil
	})
	return mcp.NewResponse(&mcp.ListResourcesResponse{
		Resources: resources,
	}), nil
}

func (s *FSServer) ReadResource(ctx context.Context, req *mcp.Request[mcp.ReadResourceRequest]) (*mcp.Response[mcp.ReadResourceResponse], error) {
	contents, err := fs.ReadFile(s.fs, strings.TrimPrefix(req.Params.URI, "file://"))
	if err != nil {
		return nil, err
	}
	return mcp.NewResponse(&mcp.ReadResourceResponse{
		Contents: []mcp.ResourceContent{
			{
				URI:      req.Params.URI,
				MimeType: mime.TypeByExtension(filepath.Ext(req.Params.URI)),
				Text:     string(contents), // TODO: base64 encode
			},
		},
	}), nil
}

func main() {
	flag.Parse()

	root := flag.Arg(0)
	if root == "" {
		root = "/"
	}

	server := mcp.NewStdioServer(&FSServer{
		fs: os.DirFS(root),
	})

	if err := server.Listen(context.Background(), os.Stdin, os.Stdout); err != nil {
		log.Fatal(err)
	}
}

You can compile this example and wire it up to Claude Desktop (or any other MCP client).

{
	"mcpServers": {
		"fs": {
			"command": "/path/to/mcp-go-fs",
			"args": [
				"/path/to/root/directory"
			]
		}
	}
}

Documentation

Roadmap

The majority of the base protocol is implemented. The following features are on our roadmap:

  • Notifications
  • Sampling
  • Roots

Offered under the MIT license.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AnyRequest

type AnyRequest interface {
	Any() any
	ID() string
	Method() string
	Metadata() map[string]string
	// contains filtered or unexported methods
}

AnyRequest is the common method set of every Request, regardless of type parameter. It's used in unary interceptors.

To preserve our ability to add methods to this interface without breaking backward compatibility, only types defined in this package can implement AnyRequest.

type AnyResponse

type AnyResponse interface {
	Any() any
	ID() string
	// contains filtered or unexported methods
}

AnyResponse is the common method set of every Response, regardless of type parameter. It's used in unary interceptors.

Headers and trailers beginning with "Connect-" and "Grpc-" are reserved for use by the gRPC and Connect protocols: applications may read them but shouldn't write them.

To preserve our ability to add methods to this interface without breaking backward compatibility, only types defined in this package can implement AnyResponse.

type Argument

type Argument struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Required    bool   `json:"required"`
}

type CallToolRequest

type CallToolRequest struct {
	Name      string          `json:"name"`
	Arguments json.RawMessage `json:"arguments"`
}

type CallToolResponse

type CallToolResponse struct {
	IsError bool      `json:"isError"`
	Content []Content `json:"content"`
}

type Client

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

func NewClient added in v0.2.0

func NewClient(stream Stream, handler ClientHandler, opts ...Option) *Client

func (*Client) CallTool

func (c *Client) CallTool(ctx context.Context, request *Request[CallToolRequest]) (*Response[CallToolResponse], error)

func (*Client) Completion

func (c *Client) Completion(ctx context.Context, request *Request[CompletionRequest]) (*Response[CompletionResponse], error)

func (*Client) GetPrompt

func (c *Client) GetPrompt(ctx context.Context, request *Request[GetPromptRequest]) (*Response[GetPromptResponse], error)

func (*Client) Initialize

func (c *Client) Initialize(ctx context.Context, request *Request[InitializeRequest]) (*Response[InitializeResponse], error)

func (*Client) ListPrompts

func (c *Client) ListPrompts(ctx context.Context, request *Request[ListPromptsRequest]) (*Response[ListPromptsResponse], error)

func (*Client) ListResources

func (c *Client) ListResources(ctx context.Context, request *Request[ListResourcesRequest]) (*Response[ListResourcesResponse], error)

func (*Client) ListTools

func (c *Client) ListTools(ctx context.Context, request *Request[ListToolsRequest]) (*Response[ListToolsResponse], error)

func (*Client) Listen added in v0.2.0

func (c *Client) Listen(ctx context.Context) error

sync.Once?

func (*Client) Ping added in v0.2.0

func (c *Client) Ping(ctx context.Context, request *Request[PingRequest]) (*Response[PingResponse], error)

func (*Client) ReadResource

func (c *Client) ReadResource(ctx context.Context, request *Request[ReadResourceRequest]) (*Response[ReadResourceResponse], error)

func (*Client) ServeMCP added in v0.4.3

func (c *Client) ServeMCP(ctx context.Context, msg *Message) (*Message, error)

func (*Client) SetLogLevel added in v0.2.0

func (c *Client) SetLogLevel(ctx context.Context, request *Request[SetLogLevelRequest]) (*Response[SetLogLevelResponse], error)

type ClientCapabilities

type ClientCapabilities struct {
	Roots    Roots    `json:"roots"`
	Sampling Sampling `json:"sampling"`
}

Capabilities represents the available feature capabilities

type ClientHandler added in v0.2.0

type ClientHandler interface {
	Sampling(ctx context.Context, request *Request[SamplingRequest]) (*Response[SamplingResponse], error)
	Ping(ctx context.Context, request *Request[PingRequest]) (*Response[PingResponse], error)
	LogMessage(ctx context.Context, request *Request[LogMessageRequest])
}

type ClientInfo

type ClientInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

ClientInfo contains information about the connected client

type ClientOption

type ClientOption interface {
	// contains filtered or unexported methods
}

type CompletionArgument

type CompletionArgument struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

type CompletionRef

type CompletionRef struct {
	Type string `json:"type"`
	Name string `json:"name"`
}

type CompletionRequest

type CompletionRequest struct {
	Ref      CompletionRef      `json:"ref"`
	Argument CompletionArgument `json:"argument"`
}

type CompletionResponse

type CompletionResponse struct {
	Completion CompletionResult `json:"completion"`
}

type CompletionResult

type CompletionResult struct {
	Values  []string `json:"values"`
	HasMore bool     `json:"hasMore"`
	Total   int      `json:"total"`
}

type Content

type Content struct {
	Type     string `json:"type"`
	Text     string `json:"text,omitempty"`
	Data     string `json:"data,omitempty"`
	MimeType string `json:"mimeType,omitempty"`
}

type Error

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

func NewError

func NewError(code int, underlying error) *Error

func (*Error) Error

func (e *Error) Error() string

type ErrorDetail added in v0.2.0

type ErrorDetail struct {
	Code    int             `json:"code"`
	Message string          `json:"message"`
	Data    json.RawMessage `json:"data"`
}

type GetPromptRequest

type GetPromptRequest struct {
	Name      string            `json:"name"`
	Arguments map[string]string `json:"arguments"`
}

type GetPromptResponse

type GetPromptResponse struct {
	Description string          `json:"description"`
	Messages    []PromptMessage `json:"messages"`
}

type InitializeRequest

type InitializeRequest struct {
	ProtocolVersion string             `json:"protocolVersion"`
	Capabilities    ClientCapabilities `json:"capabilities"`
	ClientInfo      ClientInfo         `json:"clientInfo"`
}

type InitializeResponse

type InitializeResponse struct {
	ProtocolVersion string             `json:"protocolVersion"`
	Capabilities    ServerCapabilities `json:"capabilities"`
	ServerInfo      ServerInfo         `json:"serverInfo"`
}

type Interceptor

type Interceptor interface {
	WrapUnary(UnaryFunc) UnaryFunc
}

type Level added in v0.2.0

type Level string
const (
	LevelDebug     Level = "debug"
	LevelAlert     Level = "alert"
	LevelCritical  Level = "critical"
	LevelEmergency Level = "emergency"
	LevelError     Level = "error"
	LevelInfo      Level = "info"
	LevelNotice    Level = "notice"
	LevelWarning   Level = "warning"
)

type ListPromptsRequest

type ListPromptsRequest struct {
	Cursor string `json:"cursor,omitempty"`
}

type ListPromptsResponse

type ListPromptsResponse struct {
	Prompts    []Prompt `json:"prompts"`
	NextCursor string   `json:"nextCursor,omitempty"`
}

type ListResourceTemplatesRequest

type ListResourceTemplatesRequest struct {
	Cursor string `json:"cursor,omitempty"`
}

type ListResourceTemplatesResponse

type ListResourceTemplatesResponse struct {
	Templates  []ResourceTemplate `json:"resourceTemplates"`
	NextCursor string             `json:"nextCursor,omitempty"`
}

type ListResourcesRequest

type ListResourcesRequest struct {
	Cursor string `json:"cursor,omitempty"`
}

type ListResourcesResponse

type ListResourcesResponse struct {
	Resources  []Resource `json:"resources"`
	NextCursor string     `json:"nextCursor,omitempty"`
}

type ListToolsRequest

type ListToolsRequest struct {
	Cursor string `json:"cursor,omitempty"`
}

type ListToolsResponse

type ListToolsResponse struct {
	Tools      []Tool `json:"tools"`
	NextCursor string `json:"nextCursor,omitempty"`
}

type LogMessageRequest added in v0.2.0

type LogMessageRequest struct {
	Level  Level           `json:"level"`
	Logger string          `json:"logger"`
	Data   json.RawMessage `json:"data"`
}

type Logging

type Logging struct{}

type Message

type Message struct {
	ID      *json.Number     `json:"id,omitempty"`
	JsonRPC *string          `json:"jsonrpc"`
	Method  *string          `json:"method,omitempty"`
	Params  *json.RawMessage `json:"params,omitempty"`
	Result  *json.RawMessage `json:"result,omitempty"`
	Error   *ErrorDetail     `json:"error,omitempty"`

	// Metadata is used to store additional information about the message for
	// processing by the client or server. It is never sent across the wire.
	Metadata map[string]string `json:"-"`
}

type Method added in v0.4.3

type Method string
const (
	MethodInitialize            Method = "initialize"
	MethodCompletion            Method = "completion/complete"
	MethodListTools             Method = "tools/list"
	MethodCallTool              Method = "tools/call"
	MethodListPrompts           Method = "prompts/list"
	MethodGetPrompt             Method = "prompts/get"
	MethodListResources         Method = "resources/list"
	MethodReadResource          Method = "resources/read"
	MethodListResourceTemplates Method = "resources/templates/list"
	MethodPing                  Method = "ping"
	MethodSetLogLevel           Method = "logging/setLevel"
	MethodNotificationsMessage  Method = "notifications/message"
)

type Option

type Option interface {
	ClientOption
	ServerOption
}

func WithInterceptors

func WithInterceptors(interceptors ...Interceptor) Option

type PingRequest added in v0.2.0

type PingRequest struct {
}

type PingResponse added in v0.2.0

type PingResponse struct {
}

type Prompt

type Prompt struct {
	Name        string     `json:"name"`
	Description string     `json:"description"`
	Arguments   []Argument `json:"arguments"`
}

type PromptMessage added in v0.2.0

type PromptMessage struct {
	Role    string  `json:"role"`
	Content Content `json:"content"`
}

type Prompts

type Prompts struct {
	ListChanged bool `json:"listChanged,omitempty"`
}

type ReadResourceRequest

type ReadResourceRequest struct {
	URI string `json:"uri"`
}

type ReadResourceResponse

type ReadResourceResponse struct {
	Contents []ResourceContent `json:"contents"`
}

type Request

type Request[T any] struct {
	Params *T
	// contains filtered or unexported fields
}

func NewRequest

func NewRequest[T any](params *T) *Request[T]

func (*Request[_]) Any

func (r *Request[_]) Any() any

Any returns the concrete request params as an empty interface, so that *Request implements the AnyRequest interface.

func (*Request[T]) ID

func (r *Request[T]) ID() string

func (*Request[T]) Metadata added in v0.4.1

func (r *Request[T]) Metadata() map[string]string

func (*Request[_]) Method

func (r *Request[_]) Method() string

type Resource

type Resource struct {
	URI         string `json:"uri"`
	Name        string `json:"name"`
	Description string `json:"description"`
	MimeType    string `json:"mimeType"`
}

type ResourceContent

type ResourceContent struct {
	URI      string `json:"uri"`
	MimeType string `json:"mimeType"`
	Text     string `json:"text,omitempty"`
	Blob     string `json:"blob,omitempty"`
}

type ResourceTemplate

type ResourceTemplate struct {
	URITemplate string `json:"uriTemplate"`
	Name        string `json:"name"`
	Description string `json:"description"`
	MimeType    string `json:"mimeType"`
}

type Resources

type Resources struct {
	ListChanged bool `json:"listChanged,omitempty"`
}

type Response

type Response[T any] struct {
	Result *T
	// contains filtered or unexported fields
}

func NewResponse

func NewResponse[T any](result *T) *Response[T]

func (*Response[_]) Any

func (r *Response[_]) Any() any

Any returns the concrete result as an empty interface, so that *Response implements the AnyResponse interface.

func (*Response[_]) ID

func (r *Response[_]) ID() string

type Roots

type Roots struct {
	ListChanged bool `json:"listChanged"`
}

Roots contains root-level capabilities

type Sampling

type Sampling struct{}

Sampling represents sampling-related capabilities Currently empty but structured for future expansion

type SamplingRequest added in v0.2.0

type SamplingRequest struct {
	MaxTokens int `json:"maxTokens"`
}

type SamplingResponse added in v0.2.0

type SamplingResponse struct {
	Role string `json:"role"`
}

type Server

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

func NewServer added in v0.2.0

func NewServer(stream Stream, handler ServerHandler, opts ...Option) *Server

func (*Server) Listen added in v0.2.0

func (s *Server) Listen(ctx context.Context) error

func (*Server) LogMessage added in v0.2.0

func (s *Server) LogMessage(ctx context.Context, request *Request[LogMessageRequest]) error

func (*Server) Ping added in v0.2.0

func (s *Server) Ping(ctx context.Context, request *Request[PingRequest]) (*Response[PingResponse], error)

func (*Server) PromptsListChanged added in v0.3.0

func (s *Server) PromptsListChanged(ctx context.Context) error

func (*Server) ResourcesListChanged added in v0.3.0

func (s *Server) ResourcesListChanged(ctx context.Context) error

func (*Server) ServeMCP added in v0.4.3

func (s *Server) ServeMCP(ctx context.Context, msg *Message) (*Message, error)

func (*Server) ToolsListChanged added in v0.3.0

func (s *Server) ToolsListChanged(ctx context.Context) error

type ServerCapabilities

type ServerCapabilities struct {
	Logging   *Logging   `json:"logging,omitempty"`
	Tools     *Tools     `json:"tools,omitempty"`
	Resources *Resources `json:"resources,omitempty"`
	Prompts   *Prompts   `json:"prompts,omitempty"`
}

Capabilities represents the available feature capabilities

type ServerInfo

type ServerInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

ClientInfo contains information about the connected client

type ServerOption

type ServerOption interface {
	// contains filtered or unexported methods
}

type SetLogLevelRequest added in v0.2.0

type SetLogLevelRequest struct {
	Level Level `json:"level"`
}

type SetLogLevelResponse added in v0.2.0

type SetLogLevelResponse struct {
}

type Stream added in v0.2.0

type Stream interface {
	Recv() (*Message, error)
	Send(msg *Message) error
}

type Tool

type Tool struct {
	Name        string          `json:"name"`
	Description string          `json:"description"`
	InputSchema json.RawMessage `json:"inputSchema"`
}

type Tools

type Tools struct {
	ListChanged bool `json:"listChanged,omitempty"`
}

type UnaryFunc

type UnaryFunc func(context.Context, AnyRequest) (AnyResponse, error)

type UnaryInterceptorFunc

type UnaryInterceptorFunc func(UnaryFunc) UnaryFunc

func (UnaryInterceptorFunc) WrapUnary

func (f UnaryInterceptorFunc) WrapUnary(next UnaryFunc) UnaryFunc

type UnimplementedClient added in v0.2.0

type UnimplementedClient struct{}

func (*UnimplementedClient) LogMessage added in v0.2.0

func (u *UnimplementedClient) LogMessage(ctx context.Context, request *Request[LogMessageRequest])

func (*UnimplementedClient) Ping added in v0.2.0

func (*UnimplementedClient) Sampling added in v0.2.0

type UnimplementedServer

type UnimplementedServer struct{}

func (*UnimplementedServer) CallTool

func (*UnimplementedServer) Completion

func (*UnimplementedServer) GetPrompt

func (*UnimplementedServer) Initialize

func (*UnimplementedServer) ListPrompts

func (*UnimplementedServer) ListResources

func (*UnimplementedServer) ListTools

func (*UnimplementedServer) Ping added in v0.2.0

func (*UnimplementedServer) ReadResource

func (*UnimplementedServer) SetLogLevel added in v0.2.0

Directories

Path Synopsis
examples
fs command
weather command
internal

Jump to

Keyboard shortcuts

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