mcp

package module
v0.9.6 Latest Latest
Warning

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

Go to latest
Published: Jan 23, 2026 License: MIT Imports: 19 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 discovery mode during initialization:

POST /mcp HTTP/1.1
Content-Type: application/json
X-MCP-Tool-Mode: discovery

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

Or via query parameter: /mcp?tool_mode=discovery

Normal Mode (default): All native tools visible in tools/list Discovery Mode: Only tool_search and execute_tool visible - all tools searchable

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 ToolModeDiscovery = "discovery"

ToolModeDiscovery is the value that enables discovery mode

View Source
const ToolModeHeader = "X-MCP-Tool-Mode"

ToolModeHeader is the HTTP header used to specify tool mode

View Source
const ToolModeQueryParam = "tool_mode"

ToolModeQueryParam is the query parameter used to specify tool mode (fallback)

Variables

View Source
var (
	ErrUnknownTool      = errors.New("unknown tool")
	ErrUnknownParameter = errors.New("parameter not found")
)
View Source
var DefaultNamespaceSeparator = "/"

DefaultNamespaceSeparator is the default separator used for namespacing tool names

Functions

func GenerateSigningKey added in v0.6.6

func GenerateSigningKey() ([]byte, error)

GenerateSigningKey creates a cryptographically secure random signing key

func HasOnDemandTools added in v0.9.2

func HasOnDemandTools(ctx context.Context) bool

HasOnDemandTools checks if any ondemand providers in the context actually have tools. This is more accurate than just checking if providers are registered, as providers may return empty tool lists depending on the context (e.g., no discoverable scripts configured).

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 WithForceOnDemandMode added in v0.9.0

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

WithForceOnDemandMode returns a context that forces all tools to ondemand mode. In this mode:

  • Only tool_search and execute_tool appear in tools/list
  • All native, provider, and remote tools are only available via search
  • This is useful for AI clients that work better with fewer initial tools

func WithOnDemandToolProviders added in v0.9.0

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

WithOnDemandToolProviders adds ondemand providers to the context. Tools from these providers are searchable via tool_search but do NOT appear in tools/list. This is useful for dynamic tools that should be discoverable but not clutter the tool list. Can be combined with WithToolProviders - native providers appear in list, ondemand are searchable only. When ondemand providers are added, tool_search and execute_tool are automatically available.

func WithToolModeFromRequest added in v0.9.1

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

WithToolModeFromRequest returns a context with the tool mode from the HTTP request. This is a convenience function that combines GetToolModeFromRequest and WithForceOnDemandMode. If the request specifies discovery mode, all tools will be hidden except tool_search and execute_tool.

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. In normal mode:

  • Native tools appear in tools/list
  • Provider tools appear in tools/list
  • OnDemand tools are hidden but searchable via tool_search

Types

type AuthProvider

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

AuthProvider interface for different authentication methods

type BearerTokenAuth

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

BearerTokenAuth implements simple bearer token authentication

func NewBearerTokenAuth

func NewBearerTokenAuth(token string) *BearerTokenAuth

NewBearerTokenAuth creates a new bearer token auth provider

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.

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) 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.

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, toolMode ToolListMode) (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) GetToolMode added in v0.9.1

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

GetToolMode extracts the tool mode 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
}

type OAuth2Auth

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

OAuth2Auth implements OAuth2 authentication with token refresh

func NewOAuth2Auth

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

NewOAuth2Auth creates a new OAuth2 auth provider

func (*OAuth2Auth) GetAuthHeader

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

func (*OAuth2Auth) Refresh

func (o *OAuth2Auth) Refresh() error

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 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 ondemand 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. In normal mode: returns native tools + provider tools (+ discovery tools if ondemand tools exist) In force ondemand mode: returns only tool_search and execute_tool 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) RegisterOnDemandTool added in v0.9.0

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

RegisterOnDemandTool registers a tool that is only available via tool_search and execute_tool. The tool does NOT appear in tools/list but can be discovered through keyword search. This causes tool_search and execute_tool to be dynamically included in tools/list. Use keywords to improve search relevance.

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 RegisterRemoteServerOnDemand for tools that should only be searchable.

func (*Server) RegisterRemoteServerOnDemand added in v0.9.0

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

RegisterRemoteServerOnDemand registers a remote MCP server with ondemand 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 native tool that appears in tools/list and is directly callable. This is the standard MCP behavior. Native tools are NOT searchable via tool_search in normal mode. Optional keywords are stored and used only in force ondemand mode, where native tools become searchable.

func (*Server) RegisterTools added in v0.8.0

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

RegisterTools registers multiple native 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. All tools are registered as native (visible in tools/list).

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

type SessionManager added in v0.6.6

type SessionManager interface {
	// CreateSession creates a new session and returns its ID
	// toolMode specifies whether this session uses discovery mode (ToolListModeForceOnDemand)
	CreateSession(ctx context.Context, protocolVersion string, toolMode ToolListMode) (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)

	// GetToolMode returns the tool mode for a session
	// Returns ToolListModeDefault if not set or session is invalid
	GetToolMode(ctx context.Context, sessionID string) (ToolListMode, 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) Name added in v0.6.0

func (t *ToolBuilder) Name() string

Name returns the tool's name

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 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 ToolListMode added in v0.9.0

type ToolListMode int

ToolListMode defines how tools are exposed in tools/list

const (
	// ToolListModeDefault - Standard behavior: shows native tools + provider tools
	ToolListModeDefault ToolListMode = iota

	// ToolListModeForceOnDemand - Force all tools to be ondemand for this request.
	// Only tool_search and execute_tool appear in tools/list.
	// All other tools (native, provider, remote) are only available via search.
	ToolListModeForceOnDemand
)

func GetToolListMode added in v0.9.0

func GetToolListMode(ctx context.Context) ToolListMode

GetToolListMode returns the tool list mode from the context

func GetToolModeFromRequest added in v0.9.1

func GetToolModeFromRequest(r *http.Request) ToolListMode

GetToolModeFromRequest extracts the tool mode from an HTTP request. It first checks the X-MCP-Tool-Mode header, then falls back to the tool_mode query parameter. Returns ToolListModeDefault if neither is set or the value is not "discovery".

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.
	// The Keywords field on MCPTool should be populated for discovery search functionality.
	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. This is the unified interface used for both native MCP endpoints and discovery search.

func GetOnDemandToolProviders added in v0.9.0

func GetOnDemandToolProviders(ctx context.Context) []ToolProvider

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

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

	// ToolVisibilityOnDemand 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
	ToolVisibilityOnDemand
)

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
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.
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