mcp

package module
v0.0.0-...-6dc8f68 Latest Latest
Warning

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

Go to latest
Published: Nov 26, 2024 License: ISC Imports: 9 Imported by: 0

Documentation

Overview

Package mcp implements the Model Context Protocol (MCP).

Notifications

The MCP protocol supports various types of notifications that can be sent between client and server. Notifications are capability-based, meaning both sides must agree to support specific notification types during initialization.

Server Capabilities:

  • Tool list changes (tools.listChanged)
  • Resource list changes (resources.listChanged)
  • Progress updates
  • Logging messages

Client Capabilities:

  • Root list changes (roots.listChanged)

Example server with notifications:

svc := mcp.NewService("example", "1.0.0")

// Handle logging notifications
svc.Handle(mcp.MethodLogging, func(method string, params json.RawMessage) error {
    var msg struct {
        Level  mcp.LoggingLevel `json:"level"`
        Logger string           `json:"logger"`
        Data   interface{}      `json:"data"`
    }
    if err := json.Unmarshal(params, &msg); err != nil {
        return err
    }
    log.Printf("[%s] %s: %v\n", msg.Level, msg.Logger, msg.Data)
    return nil
})

Example client with notifications:

client := mcp.NewClient(conn)

// Handle tool list changes
client.Handle(mcp.MethodToolListChanged, func(method string, params json.RawMessage) error {
    log.Println("Tool list changed")
    return nil
})

// Initialize with capabilities
reply, err := client.Initialize(context.Background(), mcp.Implementation{
    Name:    "example-client",
    Version: "1.0.0",
}, mcp.ClientCapabilities{
    Sampling: &struct{}{},
})

For more examples, see the examples directory.

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net"

	"github.com/tmc/mcp"
)

func main() {
	// Create a server
	svc := mcp.NewService("example", "1.0.0")

	// Register a tool
	err := svc.RegisterTool(mcp.Tool{
		Name:        "echo",
		Description: "Echo the input",
		InputSchema: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"message": map[string]any{"type": "string"},
			},
		},
		Handler: func(ctx context.Context, args json.RawMessage) (*mcp.ToolResult, error) {
			var params struct {
				Message string `json:"message"`
			}
			if err := json.Unmarshal(args, &params); err != nil {
				return nil, err
			}
			return &mcp.ToolResult{
				Content: []mcp.Content{{
					Type: "text",
					Text: params.Message,
				}},
			}, nil
		},
	})
	if err != nil {
		log.Fatal(err)
	}

	// Create server
	server := mcp.NewServer(svc)

	// Set up connection (example uses pipe)
	clientConn, serverConn := net.Pipe()

	// Serve in background
	go server.ServeConn(serverConn)

	// Create client
	c := mcp.NewClient(clientConn)
	defer c.Close()

	// Initialize
	reply, err := c.Initialize(context.Background(), mcp.Implementation{
		Name:    "example-client",
		Version: "1.0.0",
	})
	fmt.Println(reply.Instructions)
	if err != nil {
		log.Fatal(err)
	}

	// Call tool
	result, err := c.CallTool(context.Background(), "echo", map[string]string{
		"message": "Hello, World!",
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result.Content[0].Text)
}
Output:

Hello, World!

Index

Examples

Constants

View Source
const (
	ProtocolVersion = "2024-11-05"
	JSONRPCVersion  = "2.0"
)

Protocol version constants

View Source
const (
	MethodRootsListChanged    = "notifications/roots/list_changed"
	MethodResourceListChanged = "notifications/resources/list_changed"
	MethodPromptListChanged   = "notifications/prompts/list_changed"
	MethodToolListChanged     = "notifications/tools/list_changed"
)

List change notification methods

View Source
const (
	MethodProgress = "notifications/progress"
	MethodLogging  = "notifications/message"
)

Progress and logging notification methods

View Source
const (
	MethodCancelled   = "notifications/cancelled"
	MethodInitialized = "notifications/initialized"
)

Other notification methods

Variables

This section is empty.

Functions

This section is empty.

Types

type CallToolArgs

type CallToolArgs struct {
	Name      string          `json:"name"`
	Arguments json.RawMessage `json:"arguments,omitempty"`
}

Protocol types

type CallToolReply

type CallToolReply ToolResult

Protocol types

type Capabilities

type Capabilities struct {
	Experimental map[string]any `json:"experimental,omitempty"`
	Tools        *struct {
		ListChanged bool `json:"listChanged,omitempty"`
	} `json:"tools,omitempty"`
}

Protocol types

type Client

type Client struct {
	*rpc.Client
}

Client represents an MCP client.

func NewClient

func NewClient(conn io.ReadWriteCloser) *Client

NewClient creates a new MCP client.

func (*Client) CallTool

func (c *Client) CallTool(ctx context.Context, name string, args interface{}) (*ToolResult, error)

CallTool executes a tool.

func (*Client) Initialize

func (c *Client) Initialize(ctx context.Context, clientInfo Implementation) (*InitializeReply, error)

Initialize sends the initialize request.

func (*Client) ListTools

func (c *Client) ListTools(ctx context.Context) ([]Tool, error)

ListTools requests available tools.

func (*Client) SendNotification

func (c *Client) SendNotification(ctx context.Context, method string, params interface{}) error

SendNotification sends a notification without expecting a response

type ClientCapabilities

type ClientCapabilities struct {
	Experimental map[string]any `json:"experimental,omitempty"`
	Sampling     *struct{}      `json:"sampling,omitempty"`
}

Protocol types

type Content

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

Protocol types

type Dispatcher

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

Dispatcher manages MCP notification routing

func NewDispatcher

func NewDispatcher() *Dispatcher

NewDispatcher creates a new notification dispatcher

func (*Dispatcher) Dispatch

func (d *Dispatcher) Dispatch(method string, params json.RawMessage) error

Dispatch sends a notification to all registered handlers

func (*Dispatcher) Handle

func (d *Dispatcher) Handle(method string, h Handler)

Handle registers a handler for a notification method

func (*Dispatcher) NotifyListChanged

func (d *Dispatcher) NotifyListChanged(method string) error

List change notifications

func (*Dispatcher) NotifyLoggingMessage

func (d *Dispatcher) NotifyLoggingMessage(level LoggingLevel, logger string, data interface{}) error

Logging notifications

func (*Dispatcher) NotifyProgress

func (d *Dispatcher) NotifyProgress(token interface{}, progress float64, total *float64) error

Progress notifications

type Handler

type Handler func(method string, params json.RawMessage) error

Handler handles an MCP notification

type Implementation

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

Protocol types

type InitializeArgs

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

Protocol types

type InitializeReply

type InitializeReply struct {
	ProtocolVersion string         `json:"protocolVersion"`
	Capabilities    Capabilities   `json:"capabilities"`
	ServerInfo      Implementation `json:"serverInfo"`
	Instructions    string         `json:"instructions,omitempty"`
}

Protocol types

type ListToolsArgs

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

Protocol types

type ListToolsReply

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

Protocol types

type LoggingLevel

type LoggingLevel string

LoggingLevel represents the severity of a log message (RFC-5424)

const (
	LogDebug     LoggingLevel = "debug"
	LogInfo      LoggingLevel = "info"
	LogNotice    LoggingLevel = "notice"
	LogWarning   LoggingLevel = "warning"
	LogError     LoggingLevel = "error"
	LogCritical  LoggingLevel = "critical"
	LogAlert     LoggingLevel = "alert"
	LogEmergency LoggingLevel = "emergency"
)

type Option

type Option func(*Service)

Option configures a Service

func WithCapabilities

func WithCapabilities(caps Capabilities) Option

WithCapabilities configures initial service capabilities

func WithDispatcher

func WithDispatcher(d *Dispatcher) Option

WithDispatcher configures a custom notification dispatcher

func WithRateLimiting

func WithRateLimiting(cfg RateLimitConfig) Option

WithRateLimiting configures custom rate limiting for the service

type RateLimitConfig

type RateLimitConfig struct {
	// Global requests per second
	GlobalRPS float64
	// Burst size for global limit
	GlobalBurst int
	// Per-method RPS limits
	MethodRPS map[string]float64
	// Per-method burst limits
	MethodBurst map[string]int
	// Per-tool RPS limits
	ToolRPS map[string]float64
	// Per-tool burst limits
	ToolBurst map[string]int
}

RateLimitConfig defines rate limiting settings

func DefaultRateLimitConfig

func DefaultRateLimitConfig() RateLimitConfig

DefaultRateLimitConfig provides sensible defaults

type RateLimiter

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

RateLimiter provides rate limiting functionality for MCP services

func NewRateLimiter

func NewRateLimiter(cfg RateLimitConfig) *RateLimiter

NewRateLimiter creates a new rate limiter with the given config

func (*RateLimiter) Allow

func (rl *RateLimiter) Allow(ctx context.Context, method string) error

Allow checks if a request should be allowed

func (*RateLimiter) AllowTool

func (rl *RateLimiter) AllowTool(ctx context.Context, toolName string) error

AllowTool checks if a tool invocation should be allowed

func (*RateLimiter) UpdateMethodLimit

func (rl *RateLimiter) UpdateMethodLimit(method string, rps float64, burst int)

UpdateMethodLimit updates the rate limit for a specific method

func (*RateLimiter) UpdateToolLimit

func (rl *RateLimiter) UpdateToolLimit(tool string, rps float64, burst int)

UpdateToolLimit updates the rate limit for a specific tool

type Role

type Role string

Role represents a participant in the protocol.

const (
	RoleUser      Role = "user"
	RoleAssistant Role = "assistant"
)

type Server

type Server struct {
	*rpc.Server
}

Server wraps an MCP service for network serving.

func NewServer

func NewServer(service *Service) *Server

NewServer creates a new MCP server.

func (*Server) ServeConn

func (s *Server) ServeConn(conn io.ReadWriteCloser)

ServeConn serves a single connection.

type Service

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

Service implements the MCP RPC service.

func NewService

func NewService(name, version string, opts ...Option) *Service

NewService creates a new MCP service with default configuration

func (*Service) CallTool

func (s *Service) CallTool(args *CallToolArgs, reply *CallToolReply) error

CallTool executes a tool.

func (*Service) Handle

func (s *Service) Handle(method string, h Handler)

Add notification methods

func (*Service) Initialize

func (s *Service) Initialize(args *InitializeArgs, reply *InitializeReply) error

Initialize handles client initialization.

func (*Service) ListTools

func (s *Service) ListTools(args *ListToolsArgs, reply *ListToolsReply) error

ListTools returns available tools.

func (*Service) NotifyListChanged

func (s *Service) NotifyListChanged(method string) error

func (*Service) RegisterTool

func (s *Service) RegisterTool(t Tool) error

RegisterTool adds a tool to the service.

type StdioTransport

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

StdioTransport implements Transport over stdin/stdout

func NewStdioTransport

func NewStdioTransport(ctx context.Context) *StdioTransport

NewStdioTransport creates a new stdio transport

func (*StdioTransport) Close

func (t *StdioTransport) Close() error

func (*StdioTransport) Context

func (t *StdioTransport) Context() context.Context

func (*StdioTransport) Read

func (t *StdioTransport) Read(p []byte) (n int, err error)

func (*StdioTransport) Write

func (t *StdioTransport) Write(p []byte) (n int, err error)

type Tool

type Tool struct {
	Name        string                                                      `json:"name"`
	Description string                                                      `json:"description,omitempty"`
	InputSchema map[string]any                                              `json:"inputSchema"`
	Handler     func(context.Context, json.RawMessage) (*ToolResult, error) `json:"-"`
}

Protocol types

type ToolResult

type ToolResult struct {
	Content []Content `json:"content"`
	IsError bool      `json:"isError,omitempty"`
	Meta    any       `json:"_meta,omitempty"`
}

Protocol types

type Transport

type Transport interface {
	io.ReadWriteCloser
	// Context returns the context for this transport
	Context() context.Context
}

Transport handles communication between client and server

Directories

Path Synopsis
examples
internal

Jump to

Keyboard shortcuts

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