mcp

package module
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2026 License: MIT Imports: 21 Imported by: 7

README

MCP Server Library for Go

A Go library for building Model Context Protocol (MCP) servers with a clean, fluent API.

Features

  • Simple API: Fluent interface for defining tools and parameters
  • Type Safety: Strongly typed parameter access with automatic conversion
  • Rich Responses: Support for text, image, audio, resource, and structured content
  • TOON Support: Compact, human-readable JSON encoding for LLM prompts
  • Thread Safe: Concurrent request handling with mutex protection
  • Remote Servers: Connect to and proxy remote MCP servers with authentication
  • Searchable Tools: Reduce context window usage with on-demand tool discovery
  • Dynamic Tool Providers: Load tools from external sources (databases, scripts, APIs)
  • MCP Compliant: Full support for protocol versions 2024-11-05 through 2025-11-25

Installation

go get github.com/paularlott/mcp

Quick Start

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"

    "github.com/paularlott/mcp"
)

func main() {
    // Create server
    server := mcp.NewServer("my-server", "1.0.0")

    // Register a tool
    server.RegisterTool(
        mcp.NewTool("greet", "Greet someone",
            mcp.String("name", "Name to greet", mcp.Required()),
            mcp.String("greeting", "Custom greeting"),
        ),
        func(ctx context.Context, req *mcp.ToolRequest) (*mcp.ToolResponse, error) {
            name, _ := req.String("name")
            greeting := req.StringOr("greeting", "Hello")
            return mcp.NewToolResponseText(fmt.Sprintf("%s, %s!", greeting, name)), nil
        },
    )

    // Start server
    http.HandleFunc("/mcp", server.HandleRequest)
    log.Fatal(http.ListenAndServe(":8000", nil))
}

Documentation

For comprehensive guides, patterns, and API documentation, see the docs/ directory:

Get Started
How-To Guides
Quick References

Tool Discovery Mode

The server supports two modes for tool visibility, selectable via HTTP header:

Header-Based Mode Selection

Clients can request show-all mode (useful for MCP server chaining):

POST /mcp HTTP/1.1
Content-Type: application/json
X-MCP-Show-All: true

{"jsonrpc":"2.0","id":1,"method":"initialize",...}

Or via query parameter: /mcp?show_all=true

Normal Mode (default): Native tools visible in tools/list. If discoverable tools exist, tool_search and execute_tool are also available.

Show-All Mode: ALL tools visible in tools/list including discoverable ones. This is useful when chaining MCP servers together.

Discoverable Tools

Tools can be marked as discoverable, meaning they won't appear in the normal tools/list but can be found via tool_search:

// Discoverable tool using the fluent builder
server.RegisterTool(
    mcp.NewTool("specialized_tool", "A specialized tool").Discoverable("keyword1", "keyword2"),
    handler,
)

With session management enabled, the mode is stored in the session token. See Tool Discovery Guide for details.

Examples

See the examples/ directory for complete, runnable examples:

Testing

Run tests to ensure everything works:

go test ./...

View specific test categories:

# Provider tests
go test -run TestAddRemoveProviders -v

# Dynamic tool state transitions
go test -run TestDynamicToolState -v

# Full test suite
go test -v

Documentation

Index

Constants

View Source
const (
	MCPProtocolVersionLatest = "2025-11-25"
	MCPProtocolVersionMin    = "2024-11-05"

	// DefaultSessionTTL is the default session lifetime for JWT session management
	DefaultSessionTTL = 30 * time.Minute

	// DefaultOAuthRefreshTimeout is the default timeout for OAuth token refresh operations
	DefaultOAuthRefreshTimeout = 30 * time.Second
)
View Source
const (
	// ErrorCodeParseError indicates invalid JSON was received by the server.
	// Use when the request body cannot be parsed as JSON.
	ErrorCodeParseError = -32700

	// ErrorCodeInvalidRequest indicates the JSON sent is not a valid Request object.
	// Use when required fields are missing or have wrong types.
	ErrorCodeInvalidRequest = -32600

	// ErrorCodeMethodNotFound indicates the method does not exist or is not available.
	// Used internally when an unknown MCP method is called.
	ErrorCodeMethodNotFound = -32601

	// ErrorCodeInvalidParams indicates invalid method parameters.
	// Use this in tool handlers when required parameters are missing or invalid.
	// Prefer using NewToolErrorInvalidParams() helper.
	ErrorCodeInvalidParams = -32602

	// ErrorCodeInternalError indicates an internal JSON-RPC error.
	// Use this in tool handlers for unexpected server-side errors.
	// Prefer using NewToolErrorInternal() helper.
	ErrorCodeInternalError = -32603

	// ErrorCodeImplementationErrorStart is the start of the implementation-defined
	// server error range (-32000 to -32099). Use codes in this range for
	// application-specific errors. Create with NewToolError().
	ErrorCodeImplementationErrorStart = -32000

	// ErrorCodeImplementationErrorEnd is the end of the implementation-defined
	// server error range.
	ErrorCodeImplementationErrorEnd = -32099
)

MCP JSON-RPC Error Codes These are standard JSON-RPC 2.0 error codes used by the MCP protocol. See: https://www.jsonrpc.org/specification#error_object

View Source
const (
	ToolSearchName  = "tool_search"
	ExecuteToolName = "execute_tool"
)

Discovery tool names

View Source
const ShowAllHeader = "X-MCP-Show-All"

ShowAllHeader is the HTTP header used to show all tools regardless of visibility

View Source
const ShowAllQueryParam = "show_all"

ShowAllQueryParam is the query parameter used to show all tools (fallback)

Variables

View Source
var (
	ErrUnknownTool      = errors.New("unknown tool")
	ErrUnknownParameter = errors.New("parameter not found")
	ErrToolFiltered     = errors.New("tool is filtered out")
)
View Source
var DefaultNamespaceSeparator = "."

DefaultNamespaceSeparator is the default separator used for namespacing tool names. Uses "." by default for compatibility with OpenAI function naming constraints (which require: a-z, A-Z, 0-9, underscores, dashes, and non-consecutive dots).

Functions

func GenerateSigningKey added in v0.6.6

func GenerateSigningKey() ([]byte, error)

GenerateSigningKey creates a cryptographically secure random signing key

func GetShowAllFromRequest added in v0.10.0

func GetShowAllFromRequest(r *http.Request) bool

GetShowAllFromRequest extracts the show-all flag from an HTTP request. It first checks the X-MCP-Show-All header, then falls back to the show_all query parameter. Returns true if either is set to "true" (case-insensitive).

func GetShowAllTools added in v0.10.0

func GetShowAllTools(ctx context.Context) bool

GetShowAllTools returns true if show-all mode is enabled in the context.

func NewToolError

func NewToolError(code int, message string, data interface{}) error

NewToolError creates a custom MCP error with a specific code. Use codes in the range -32000 to -32099 for application-specific errors. The data parameter can include additional error details and will be serialized to JSON.

Example:

return nil, mcp.NewToolError(-32001, "Rate limit exceeded", map[string]interface{}{
    "retry_after": 60,
    "limit": 100,
})

func NewToolErrorInternal

func NewToolErrorInternal(message string) error

NewToolErrorInternal creates an error for internal server errors. Use this for unexpected failures like database errors, network issues, etc. This returns ErrorCodeInternalError (-32603).

func NewToolErrorInvalidParams

func NewToolErrorInvalidParams(message string) error

NewToolErrorInvalidParams creates an error for invalid or missing parameters. Use this when a required parameter is missing, has the wrong type, or fails validation. This returns ErrorCodeInvalidParams (-32602).

func RegisterOAuthClient added in v0.13.0

func RegisterOAuthClient(ctx context.Context, registrationEndpoint, clientName, redirectURI string) (string, error)

RegisterOAuthClient performs RFC 7591 dynamic client registration. Returns the issued client_id.

func WithShowAllFromRequest added in v0.10.0

func WithShowAllFromRequest(ctx context.Context, r *http.Request, providers ...ToolProvider) context.Context

WithShowAllFromRequest returns a context with show-all mode set based on the HTTP request. This is a convenience function that combines GetShowAllFromRequest and WithShowAllTools. Also attaches any provided tool providers.

func WithShowAllTools added in v0.10.0

func WithShowAllTools(ctx context.Context) context.Context

WithShowAllTools returns a context that shows all tools in tools/list, regardless of their Visibility setting. This is useful for MCP server chaining where the consuming server needs to see all available tools. Can be enabled via X-MCP-Show-All header or ?show_all=true query param.

func WithToolProviders added in v0.9.0

func WithToolProviders(ctx context.Context, providers ...ToolProvider) context.Context

WithToolProviders returns a context with the given tool providers attached. Multiple providers can be attached and all will be queried for tools. Tools from providers are filtered by their Visibility field:

  • ToolVisibilityNative: appears in tools/list
  • ToolVisibilityDiscoverable: only searchable via tool_search

Use WithShowAllTools to make all tools appear in tools/list regardless of visibility.

Types

type AuthProvider

type AuthProvider interface {
	GetAuthHeader() (string, error)
	Refresh() error
}

AuthProvider is the interface for MCP client authentication.

type BearerTokenAuth

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

BearerTokenAuth implements simple static bearer token authentication.

func NewBearerTokenAuth

func NewBearerTokenAuth(token string) *BearerTokenAuth

func (*BearerTokenAuth) GetAuthHeader

func (b *BearerTokenAuth) GetAuthHeader() (string, error)

func (*BearerTokenAuth) Refresh

func (b *BearerTokenAuth) Refresh() error

type Client

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

Client represents an MCP client for connecting to remote servers

func NewClient

func NewClient(baseURL string, auth AuthProvider, namespace string) *Client

NewClient creates a new MCP client using the shared HTTP pool. The namespace will be added to all tool names (e.g., namespace "scriptling" makes tool "search" available as "scriptling.search"). Use an empty namespace for no namespacing.

The namespace should be a simple identifier (letters, numbers, hyphens, underscores). Whitespace is trimmed automatically.

func NewClientWithPool added in v0.9.5

func NewClientWithPool(baseURL string, auth AuthProvider, namespace string, httpPool pool.HTTPPool) *Client

NewClientWithPool creates a new MCP client with a custom HTTP pool. If httpPool is nil, the default secure pool is used. This is useful when you need to use a pool with custom settings (e.g., InsecureSkipVerify for internal services).

Example:

// Create an insecure pool for internal services with self-signed certs
insecurePool := pool.NewPool(&pool.PoolConfig{InsecureSkipVerify: true})
client := mcp.NewClientWithPool("https://internal.service", auth, "ns", insecurePool)

func (*Client) CallTool

func (c *Client) CallTool(ctx context.Context, name string, args map[string]interface{}) (*ToolResponse, error)

CallTool executes a tool on the remote server. If the client has a namespace, the tool name should include it (e.g., "scriptling.search"). The namespace will be stripped before calling the underlying tool. If a tool filter is set and the tool is filtered out, returns ErrToolFiltered.

func (*Client) ExecuteDiscoveredTool added in v0.8.0

func (c *Client) ExecuteDiscoveredTool(ctx context.Context, name string, arguments map[string]interface{}) (*ToolResponse, error)

ExecuteDiscoveredTool executes a tool by name using the execute_tool MCP tool. This is the only way to call tools that were discovered via ToolSearch. Discovered tools cannot be called directly via CallTool.

func (*Client) GetToolFilter added in v0.9.9

func (c *Client) GetToolFilter() ToolFilterFunc

GetToolFilter returns the current tool filter, or nil if none is set.

func (*Client) Initialize

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

Initialize performs the MCP handshake with the remote server

func (*Client) ListTools

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

ListTools retrieves tools from the remote server

func (*Client) Namespace added in v0.8.0

func (c *Client) Namespace() string

Namespace returns the namespace for this client's tools.

func (*Client) RefreshToolCache

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

RefreshToolCache explicitly refreshes the tool cache

func (*Client) ToolSearch added in v0.8.0

func (c *Client) ToolSearch(ctx context.Context, query string, maxResults int) ([]map[string]interface{}, error)

ToolSearch performs a tool search using the tool_search MCP tool. This is useful when the server has many tools registered via a discovery registry. The query searches tool names, descriptions, and keywords.

func (*Client) WithToolFilter added in v0.9.9

func (c *Client) WithToolFilter(filter ToolFilterFunc) *Client

WithToolFilter sets a filter function for this client. The filter receives the original tool name (without namespace prefix). When set, ListTools will only return tools where filter returns true, and CallTool will reject calls to filtered-out tools. Pass nil to clear the filter. Returns the client for chaining. Note: Setting a filter clears the tool cache to ensure consistency.

type JWTSessionManager added in v0.6.6

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

JWTSessionManager provides stateless session management using JWT tokens This is the RECOMMENDED approach for production clusters as it: - Requires no external storage (Redis, Database) - Scales horizontally without coordination - Works across all server instances - Has zero infrastructure dependencies

Trade-off: Sessions cannot be revoked before expiry (acceptable for most use cases)

func NewJWTSessionManager added in v0.6.6

func NewJWTSessionManager(signingKey []byte, ttl time.Duration) *JWTSessionManager

NewJWTSessionManager creates a new JWT-based session manager signingKey should be a cryptographically secure random key (at least 32 bytes recommended) ttl is the session lifetime (e.g., 30 * time.Minute)

func NewJWTSessionManagerWithAutoKey added in v0.9.1

func NewJWTSessionManagerWithAutoKey(ttl time.Duration) (*JWTSessionManager, error)

NewJWTSessionManagerWithAutoKey creates a JWT session manager with an auto-generated signing key. This is convenient for development or single-instance deployments.

For production clusters with multiple instances, use NewJWTSessionManager with a persisted key to ensure all instances can validate each other's sessions.

func (*JWTSessionManager) CleanupExpiredSessions added in v0.6.6

func (m *JWTSessionManager) CleanupExpiredSessions(ctx context.Context, maxIdleTime time.Duration) error

CleanupExpiredSessions is a no-op for JWT sessions (tokens expire automatically)

func (*JWTSessionManager) CreateSession added in v0.6.6

func (m *JWTSessionManager) CreateSession(ctx context.Context, protocolVersion string, showAll bool) (string, error)

CreateSession generates a new JWT session token

func (*JWTSessionManager) DeleteSession added in v0.6.6

func (m *JWTSessionManager) DeleteSession(ctx context.Context, sessionID string) error

DeleteSession is a no-op for JWT sessions (cannot revoke before expiry)

func (*JWTSessionManager) GetProtocolVersion added in v0.6.6

func (m *JWTSessionManager) GetProtocolVersion(ctx context.Context, sessionID string) (string, error)

GetProtocolVersion extracts the protocol version from a JWT session token

func (*JWTSessionManager) GetShowAll added in v0.10.0

func (m *JWTSessionManager) GetShowAll(ctx context.Context, sessionID string) (bool, error)

GetShowAll extracts the show-all flag from a JWT session token

func (*JWTSessionManager) ValidateSession added in v0.6.6

func (m *JWTSessionManager) ValidateSession(ctx context.Context, sessionID string) (bool, error)

ValidateSession validates a JWT session token

type MCPError

type MCPError struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data,omitempty"`
}

type MCPRequest

type MCPRequest struct {
	JSONRPC string      `json:"jsonrpc"`
	ID      interface{} `json:"id"`
	Method  string      `json:"method"`
	Params  interface{} `json:"params,omitempty"`
}

MCP Protocol types

type MCPResponse

type MCPResponse struct {
	JSONRPC string      `json:"jsonrpc"`
	ID      interface{} `json:"id,omitempty"`
	Result  interface{} `json:"result,omitempty"`
	Error   *MCPError   `json:"error,omitempty"`
}

type MCPTool

type MCPTool struct {
	Name         string         `json:"name"`
	Description  string         `json:"description"`
	InputSchema  interface{}    `json:"inputSchema"`
	OutputSchema interface{}    `json:"outputSchema,omitempty"`
	Keywords     []string       `json:"-"` // For discovery search, not serialized to clients
	Visibility   ToolVisibility `json:"-"` // Native or Discoverable
}

type OAuth2Auth

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

OAuth2Auth implements OAuth2 authentication backed by an oauth2.TokenSource. Supports both client credentials (machine-to-machine) and refresh token (user-delegated, e.g. PKCE) flows.

func NewOAuth2Auth

func NewOAuth2Auth(clientID, clientSecret, tokenURL string, scopes []string) *OAuth2Auth

NewOAuth2Auth creates an OAuth2 provider using the client credentials flow.

func NewOAuth2RefreshTokenAuth added in v0.13.0

func NewOAuth2RefreshTokenAuth(tokenURL, clientID, accessToken, refreshToken string) *OAuth2Auth

NewOAuth2RefreshTokenAuth creates an OAuth2 provider from an existing access + refresh token pair (e.g. obtained via browser-based PKCE flow). clientID is the dynamically registered client ID. accessToken may be empty.

func (*OAuth2Auth) GetAuthHeader

func (o *OAuth2Auth) GetAuthHeader() (string, error)

func (*OAuth2Auth) Refresh

func (o *OAuth2Auth) Refresh() error

type OAuthMeta added in v0.13.0

type OAuthMeta struct {
	AuthorizationEndpoint string `json:"authorization_endpoint"`
	TokenEndpoint         string `json:"token_endpoint"`
	RegistrationEndpoint  string `json:"registration_endpoint"`
}

OAuthMeta holds the OAuth2 server metadata discovered via RFC 8414.

func DiscoverOAuthMeta added in v0.13.0

func DiscoverOAuthMeta(ctx context.Context, serverURL string) (*OAuthMeta, error)

DiscoverOAuthMeta fetches OAuth2 server metadata from the MCP server URL by probing RFC 8414 and OIDC well-known endpoints.

type Option

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

Option interface for parameter options

func Required

func Required() Option

type Parameter

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

Parameter interface for all parameter types

func Boolean

func Boolean(name, description string, options ...Option) Parameter

Boolean creates a boolean parameter

func BooleanArray added in v0.9.0

func BooleanArray(name, description string, options ...Option) Parameter

BooleanArray creates a boolean array parameter

func Number

func Number(name, description string, options ...Option) Parameter

Number creates a number parameter

func NumberArray

func NumberArray(name, description string, options ...Option) Parameter

NumberArray creates a number array parameter

func Object

func Object(name, description string, propertiesAndOptions ...interface{}) Parameter

Object creates an object parameter with properties

func ObjectArray

func ObjectArray(name, description string, propertiesAndOptions ...interface{}) Parameter

ObjectArray creates an array of objects parameter

func Output

func Output(parameters ...Parameter) Parameter

func String

func String(name, description string, options ...Option) Parameter

String creates a string parameter

func StringArray

func StringArray(name, description string, options ...Option) Parameter

StringArray creates a string array parameter

type RemoteServerEntry added in v0.12.11

type RemoteServerEntry struct {
	Client     *Client
	Visibility ToolVisibility
}

RemoteServerEntry pairs a client with the visibility to use when registering.

type ResourceContent

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

type ResourceResponse

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

func NewResourceResponseBlob

func NewResourceResponseBlob(uri string, data []byte, mimeType string) *ResourceResponse

func NewResourceResponseText

func NewResourceResponseText(uri, text, mimeType string) *ResourceResponse

type SearchResult added in v0.9.0

type SearchResult struct {
	Name        string      `json:"name"`
	Description string      `json:"description"`
	Score       float64     `json:"score"`
	InputSchema interface{} `json:"input_schema,omitempty"`
}

SearchResult represents a tool found via search

type Server

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

Server represents an MCP server instance.

Design Philosophy

The Server struct is the central hub for MCP protocol handling. It intentionally combines several related concerns to provide a cohesive API:

  • Core Identity: name, version, and instructions for protocol negotiation
  • Tool Management: local tools with thread-safe registration and caching
  • Federation: remote MCP server integration with namespacing
  • Sessions: pluggable session management for stateful deployments
  • Discovery: optional tool registry for large tool sets

This design prioritizes ease of use over strict separation of concerns. A typical server setup requires only a few lines:

server := mcp.NewServer("myapp", "1.0.0")
server.RegisterTool(myTool, myHandler)
http.HandleFunc("/mcp", server.HandleRequest)

For advanced use cases, the server delegates to specialized components:

  • SessionManager interface for custom session storage
  • Client for remote server federation

Thread Safety: All methods are safe for concurrent use. The server uses RWMutex for read-heavy operations (ListTools, CallTool) with minimal lock contention.

func NewServer

func NewServer(name, version string) *Server

NewServer creates a new MCP server instance

func (*Server) CallTool

func (s *Server) CallTool(ctx context.Context, name string, args map[string]interface{}) (*ToolResponse, error)

CallTool executes a tool directly with namespace support (direct API) It checks discovery tools first, then local tools, then remote tools, then providers from context.

func (*Server) CleanupExpiredSessions added in v0.6.6

func (s *Server) CleanupExpiredSessions(maxIdleTime time.Duration) error

CleanupExpiredSessions removes sessions that haven't been used in the specified duration Only works if a session manager is configured

func (*Server) HandleRequest

func (s *Server) HandleRequest(w http.ResponseWriter, r *http.Request)

HandleRequest handles MCP protocol requests

func (*Server) ListTools

func (s *Server) ListTools() []MCPTool

ListTools returns all native tools including remote ones (direct API). If discoverable tools are registered, discovery tools (tool_search, execute_tool) are also included. The returned slice is a copy, safe for concurrent use and modification.

Performance Note: This method allocates and copies the tool cache on every call. For high-frequency polling scenarios, consider caching the result on the caller side. The tool list only changes when RegisterTool, RegisterRemoteServer, or RefreshTools is called.

func (*Server) ListToolsWithContext added in v0.9.0

func (s *Server) ListToolsWithContext(ctx context.Context) []MCPTool

ListToolsWithContext returns tools based on the context mode. Normal mode: returns native tools + native provider tools (+ discovery tools if any discoverable tools exist) Show-all mode: returns ALL tools regardless of visibility The context is used to retrieve request-scoped tool providers.

func (*Server) RefreshTools

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

RefreshTools manually refreshes the tool cache and lookup from all remote servers. This method is safe for concurrent use - it releases the lock during network calls to avoid blocking other operations, then atomically swaps in the new data. The context can be used to cancel the operation if needed.

func (*Server) RegisterRemoteServer

func (s *Server) RegisterRemoteServer(client *Client) error

RegisterRemoteServer registers a remote MCP server with native visibility. Remote server tools appear in tools/list and are directly callable. Use RegisterRemoteServerDiscoverable for tools that should only be searchable.

func (*Server) RegisterRemoteServerDiscoverable added in v0.10.0

func (s *Server) RegisterRemoteServerDiscoverable(client *Client) error

RegisterRemoteServerDiscoverable registers a remote MCP server with discoverable visibility. Remote server tools do NOT appear in tools/list but are searchable via tool_search. This automatically registers tool_search and execute_tool if not already registered.

func (*Server) RegisterTool

func (s *Server) RegisterTool(tool *ToolBuilder, handler ToolHandler, keywords ...string)

RegisterTool registers a tool with the server. The tool's visibility is determined by whether Discoverable() was called on the ToolBuilder:

  • Native tools (default): appear in tools/list and are directly callable
  • Discoverable tools (via .Discoverable(keywords...)): only available via tool_search and execute_tool

Optional keywords parameter is merged with keywords set via Discoverable() for search relevance. Keywords are used in show-all mode and for discoverable tool search.

func (*Server) RegisterTools added in v0.8.0

func (s *Server) RegisterTools(tools ...*ToolRegistration)

RegisterTools registers multiple tools with the server in a single batch. This is more efficient than calling RegisterTool multiple times as it only sorts the cache once at the end. Each tool's visibility is determined by whether Discoverable() was called on its ToolBuilder.

func (*Server) ReplaceRemoteServers added in v0.12.11

func (s *Server) ReplaceRemoteServers(servers []RemoteServerEntry) error

ReplaceRemoteServers atomically replaces all registered remote servers with the provided list. Each entry is a (*Client, ToolVisibility) pair. Use ToolVisibilityNative for tools that should appear in tools/list, or ToolVisibilityDiscoverable for tools only findable via tool_search. All previously registered remote servers and their cached tools are removed first.

func (*Server) SetInstructions

func (s *Server) SetInstructions(instructions string)

SetInstructions sets the server instructions that are returned during protocol initialization. Instructions provide guidance to the LLM about how to use the server's capabilities.

func (*Server) SetSessionManager added in v0.6.6

func (s *Server) SetSessionManager(manager SessionManager)

SetSessionManager sets a custom session manager for the server. For JWT-based sessions, use NewJWTSessionManager or NewJWTSessionManagerWithAutoKey.

Example:

sm, _ := mcp.NewJWTSessionManagerWithAutoKey(30 * time.Minute)
server.SetSessionManager(sm)

Use a custom SessionManager when you need:

  • Session revocation (logout functionality, security incidents)
  • Session listing (admin dashboards, audit trails)
  • Custom session metadata

func (*Server) UnregisterRemoteServer added in v0.12.11

func (s *Server) UnregisterRemoteServer(client *Client)

UnregisterRemoteServer removes a previously registered remote server and all its cached tools.

type SessionManager added in v0.6.6

type SessionManager interface {
	// CreateSession creates a new session and returns its ID
	// showAll specifies whether this session shows all tools regardless of visibility
	CreateSession(ctx context.Context, protocolVersion string, showAll bool) (sessionID string, err error)

	// ValidateSession checks if a session exists and is valid
	// Returns true if valid, updates lastUsed timestamp if applicable
	ValidateSession(ctx context.Context, sessionID string) (valid bool, err error)

	// GetProtocolVersion returns the negotiated protocol version for a session
	GetProtocolVersion(ctx context.Context, sessionID string) (version string, err error)

	// GetShowAll returns whether show-all mode is enabled for a session
	// Returns false if not set or session is invalid
	GetShowAll(ctx context.Context, sessionID string) (bool, error)

	// DeleteSession removes a session
	DeleteSession(ctx context.Context, sessionID string) error

	// CleanupExpiredSessions removes sessions older than maxIdleTime
	CleanupExpiredSessions(ctx context.Context, maxIdleTime time.Duration) error
}

SessionManager defines the interface for session storage and validation Implement this interface to create custom session stores (Redis, Database, etc.)

type ToolBuilder

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

ToolBuilder provides fluent API for building tools

func NewTool

func NewTool(name, description string, parameters ...Parameter) *ToolBuilder

NewTool creates a new tool with the declarative API

func (*ToolBuilder) BuildOutputSchema

func (t *ToolBuilder) BuildOutputSchema() map[string]interface{}

BuildOutputSchema returns the JSON Schema for the tool's structured output. Returns nil if no output schema was defined with Output(). This is used internally and for tools that return structured content.

func (*ToolBuilder) BuildSchema

func (t *ToolBuilder) BuildSchema() map[string]interface{}

BuildSchema returns the JSON Schema for the tool's input parameters. This is used internally for tool registration and search functionality, but can also be used for documentation or schema validation purposes.

func (*ToolBuilder) Description added in v0.6.0

func (t *ToolBuilder) Description() string

Description returns the tool's description with newlines normalized to spaces and multiple whitespace collapsed to single spaces

func (*ToolBuilder) Discoverable added in v0.10.0

func (t *ToolBuilder) Discoverable(keywords ...string) *ToolBuilder

Discoverable marks the tool as discoverable via tool_search. Discoverable tools do NOT appear in tools/list but can be found through search. Keywords improve search relevance - include terms users might search for. When any discoverable tools exist, tool_search and execute_tool are automatically added to tools/list.

func (*ToolBuilder) IsDiscoverable added in v0.10.0

func (t *ToolBuilder) IsDiscoverable() bool

IsDiscoverable returns true if the tool is marked as discoverable.

func (*ToolBuilder) Keywords added in v0.10.0

func (t *ToolBuilder) Keywords() []string

Keywords returns the keywords set for this tool.

func (*ToolBuilder) Name added in v0.6.0

func (t *ToolBuilder) Name() string

Name returns the tool's name

func (*ToolBuilder) ToMCPTool added in v0.9.8

func (t *ToolBuilder) ToMCPTool() MCPTool

ToMCPTool converts the ToolBuilder to an MCPTool struct. This is useful for tool providers that use the fluent API to build tools but need to return MCPTool structs from their GetTools method. Use .Discoverable(keywords...) before calling this to set keywords and mark as discoverable.

type ToolCallParams

type ToolCallParams struct {
	Name      string                 `json:"name"`
	Arguments map[string]interface{} `json:"arguments,omitempty"`
}

type ToolContent

type ToolContent struct {
	Type     string           `json:"type"`
	Text     string           `json:"text,omitempty"`
	Data     string           `json:"data,omitempty"`
	MimeType string           `json:"mimeType,omitempty"`
	Resource *ResourceContent `json:"resource,omitempty"`
}

type ToolError

type ToolError struct {
	Code    int
	Message string
	Data    interface{}
}

ToolError represents an MCP protocol error that can be returned from tool handlers. When returned from a ToolHandler, the error code and message are sent to the client in the JSON-RPC error response.

Example usage in a tool handler:

func myHandler(ctx context.Context, req *mcp.ToolRequest) (*mcp.ToolResponse, error) {
    name, err := req.String("name")
    if err != nil {
        return nil, mcp.NewToolErrorInvalidParams("name parameter is required")
    }
    // ... process request
}

func (*ToolError) Error

func (e *ToolError) Error() string

type ToolFilterFunc added in v0.9.9

type ToolFilterFunc func(toolName string) bool

ToolFilterFunc is a function that determines if a tool should be included. It receives the original tool name (without namespace prefix). Return true to include the tool, false to exclude it.

type ToolHandler

type ToolHandler func(ctx context.Context, req *ToolRequest) (*ToolResponse, error)

ToolHandler represents a function that handles tool calls. It receives the request context and a ToolRequest with typed argument accessors.

type ToolProvider added in v0.9.0

type ToolProvider interface {
	// GetTools returns all tools available from this provider.
	// The context contains tenant/user information for filtering.
	// Each tool's Visibility field determines whether it appears in tools/list
	// or only via tool_search. Keywords should be populated for discoverable tools.
	GetTools(ctx context.Context) ([]MCPTool, error)

	// ExecuteTool executes a tool by name and returns the result.
	// Returns nil, ErrUnknownTool if the tool is not handled by this provider.
	ExecuteTool(ctx context.Context, name string, params map[string]interface{}) (interface{}, error)
}

ToolProvider is the interface that providers implement to expose tools. Tools returned by providers should set their Visibility field:

  • ToolVisibilityNative: Tool appears in tools/list
  • ToolVisibilityDiscoverable: Tool only available via tool_search

func GetToolProviders added in v0.9.0

func GetToolProviders(ctx context.Context) []ToolProvider

GetToolProviders returns the tool providers from the context. Returns nil if no providers are attached.

type ToolRegistration added in v0.8.0

type ToolRegistration struct {
	Tool    *ToolBuilder
	Handler ToolHandler
}

ToolRegistration pairs a tool builder with its handler for batch registration.

func NewToolRegistration added in v0.8.0

func NewToolRegistration(tool *ToolBuilder, handler ToolHandler) *ToolRegistration

NewToolRegistration creates a tool registration for use with RegisterTools.

type ToolRequest

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

ToolRequest provides typed access to tool arguments. Use the accessor methods (String, Int, Bool, etc.) to retrieve parameters with automatic type conversion and validation.

func NewToolRequest added in v0.6.0

func NewToolRequest(args map[string]interface{}) *ToolRequest

NewToolRequest creates a new ToolRequest with the given arguments. This is typically called by the server when dispatching tool calls.

func (*ToolRequest) Args added in v0.6.3

func (r *ToolRequest) Args() map[string]interface{}

Args returns all arguments as a map

func (*ToolRequest) Bool

func (r *ToolRequest) Bool(name string) (bool, error)

Bool returns a boolean parameter by name. Returns ErrUnknownParameter if the parameter doesn't exist.

func (*ToolRequest) BoolOr

func (r *ToolRequest) BoolOr(name string, defaultValue bool) bool

BoolOr returns a boolean parameter or defaultValue if not present or invalid.

func (*ToolRequest) BoolSlice added in v0.9.0

func (r *ToolRequest) BoolSlice(name string) ([]bool, error)

BoolSlice returns a boolean array parameter by name. Returns ErrUnknownParameter if the parameter doesn't exist.

func (*ToolRequest) BoolSliceOr added in v0.9.0

func (r *ToolRequest) BoolSliceOr(name string, defaultValue []bool) []bool

BoolSliceOr returns a boolean array parameter or defaultValue if not present or invalid.

func (*ToolRequest) Float

func (r *ToolRequest) Float(name string) (float64, error)

Float returns a float64 parameter by name. Returns ErrUnknownParameter if the parameter doesn't exist.

func (*ToolRequest) FloatOr

func (r *ToolRequest) FloatOr(name string, defaultValue float64) float64

FloatOr returns a float64 parameter or defaultValue if not present or invalid.

func (*ToolRequest) FloatSlice

func (r *ToolRequest) FloatSlice(name string) ([]float64, error)

FloatSlice returns a float64 array parameter by name. Returns ErrUnknownParameter if the parameter doesn't exist.

func (*ToolRequest) FloatSliceOr

func (r *ToolRequest) FloatSliceOr(name string, defaultValue []float64) []float64

FloatSliceOr returns a float64 array parameter or defaultValue if not present or invalid.

func (*ToolRequest) GetObjectBoolProperty

func (r *ToolRequest) GetObjectBoolProperty(objectName, propertyName string) (bool, error)

GetObjectBoolProperty extracts a bool property from an object parameter

func (*ToolRequest) GetObjectIntProperty

func (r *ToolRequest) GetObjectIntProperty(objectName, propertyName string) (int, error)

GetObjectIntProperty extracts an int property from an object parameter

func (*ToolRequest) GetObjectProperty

func (r *ToolRequest) GetObjectProperty(objectName, propertyName string) (interface{}, error)

GetObjectProperty extracts a property from an object parameter

func (*ToolRequest) GetObjectStringProperty

func (r *ToolRequest) GetObjectStringProperty(objectName, propertyName string) (string, error)

GetObjectStringProperty extracts a string property from an object parameter

func (*ToolRequest) Int

func (r *ToolRequest) Int(name string) (int, error)

Int returns an integer parameter by name. Handles both int and float64 types (JSON numbers are parsed as float64). Returns ErrUnknownParameter if the parameter doesn't exist.

func (*ToolRequest) IntOr

func (r *ToolRequest) IntOr(name string, defaultValue int) int

IntOr returns an integer parameter or defaultValue if not present or invalid.

func (*ToolRequest) IntSlice

func (r *ToolRequest) IntSlice(name string) ([]int, error)

IntSlice returns an integer array parameter by name. Handles both int and float64 array elements (JSON numbers are parsed as float64). Returns ErrUnknownParameter if the parameter doesn't exist.

func (*ToolRequest) IntSliceOr

func (r *ToolRequest) IntSliceOr(name string, defaultValue []int) []int

IntSliceOr returns an integer array parameter or defaultValue if not present or invalid.

func (*ToolRequest) Object

func (r *ToolRequest) Object(name string) (map[string]interface{}, error)

Object returns a parameter as a map[string]interface{} (generic object). Returns ErrUnknownParameter if the parameter doesn't exist.

func (*ToolRequest) ObjectOr

func (r *ToolRequest) ObjectOr(name string, defaultValue map[string]interface{}) map[string]interface{}

ObjectOr returns a parameter as an object or the default value

func (*ToolRequest) ObjectSlice

func (r *ToolRequest) ObjectSlice(name string) ([]map[string]interface{}, error)

ObjectSlice returns a parameter as a slice of objects

func (*ToolRequest) ObjectSliceOr

func (r *ToolRequest) ObjectSliceOr(name string, defaultValue []map[string]interface{}) []map[string]interface{}

ObjectSliceOr returns a parameter as a slice of objects or the default value

func (*ToolRequest) String

func (r *ToolRequest) String(name string) (string, error)

String returns a string parameter by name. Returns ErrUnknownParameter if the parameter doesn't exist.

func (*ToolRequest) StringOr

func (r *ToolRequest) StringOr(name, defaultValue string) string

StringOr returns a string parameter or defaultValue if not present or invalid.

func (*ToolRequest) StringSlice

func (r *ToolRequest) StringSlice(name string) ([]string, error)

StringSlice returns a string array parameter by name. Returns ErrUnknownParameter if the parameter doesn't exist.

func (*ToolRequest) StringSliceOr

func (r *ToolRequest) StringSliceOr(name string, defaultValue []string) []string

StringSliceOr returns a string array parameter or defaultValue if not present or invalid.

type ToolResponse

type ToolResponse struct {
	Content           []ToolContent `json:"content"`
	StructuredContent interface{}   `json:"structuredContent,omitempty"`
}

ToolResponse represents the response from a tool

func NewToolResponseAudio

func NewToolResponseAudio(data []byte, mimeType string) *ToolResponse

func NewToolResponseImage

func NewToolResponseImage(data []byte, mimeType string) *ToolResponse

func NewToolResponseJSON

func NewToolResponseJSON(data interface{}) *ToolResponse

func NewToolResponseMulti

func NewToolResponseMulti(responses ...*ToolResponse) *ToolResponse

func NewToolResponseResource

func NewToolResponseResource(uri, text, mimeType string) *ToolResponse
func NewToolResponseResourceLink(uri, text string) *ToolResponse

func NewToolResponseStructured

func NewToolResponseStructured(data interface{}) *ToolResponse

func NewToolResponseTOON added in v0.7.0

func NewToolResponseTOON(data interface{}) *ToolResponse

func NewToolResponseText

func NewToolResponseText(text string) *ToolResponse

type ToolResult

type ToolResult struct {
	Content           []ToolContent `json:"content,omitempty"`
	StructuredContent interface{}   `json:"structuredContent,omitempty"`
	IsError           bool          `json:"isError,omitempty"`
}

type ToolVisibility added in v0.6.12

type ToolVisibility int

ToolVisibility defines how a tool is exposed to clients. This controls whether tools appear in tools/list or only via tool_search.

const (
	// ToolVisibilityNative means the tool appears in tools/list and is directly callable.
	// This is the standard MCP behavior - tools are visible and can be called by name.
	ToolVisibilityNative ToolVisibility = iota

	// ToolVisibilityDiscoverable means the tool is only available via tool_search and execute_tool.
	// The tool does NOT appear in tools/list but can be discovered and executed through
	// the tool_search and execute_tool meta-tools. This is useful for:
	// - Large tool sets where listing all tools would overwhelm the LLM
	// - Dynamic tools that should be discovered by keyword search
	// - Tools that should only be used when specifically relevant
	ToolVisibilityDiscoverable
)

func (ToolVisibility) String added in v0.9.0

func (v ToolVisibility) String() string

String returns a human-readable name for the visibility level.

Directories

Path Synopsis
ai
examples
client command
object-example command
openai command
per-user-tools command
Package main demonstrates per-user tool access using ToolProvider.
Package main demonstrates per-user tool access using ToolProvider.
remote-server command
server command
session-server command
tool-discovery command
unified-server command
Package toon implements the TOON (Token-Oriented Object Notation) format.
Package toon implements the TOON (Token-Oriented Object Notation) format.

Jump to

Keyboard shortcuts

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