mcp

package
v0.9.1 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MethodInitialize    = "initialize"
	MethodInitialized   = "notifications/initialized"
	MethodToolsList     = "tools/list"
	MethodToolsCall     = "tools/call"
	MethodResourcesList = "resources/list"
	MethodResourcesRead = "resources/read"
	MethodPromptsList   = "prompts/list"
	MethodPromptsGet    = "prompts/get"
	MethodPing          = "ping"
	MethodShutdown      = "shutdown"
)
View Source
const (
	ErrCodeParseError     = -32700
	ErrCodeInvalidRequest = -32600
	ErrCodeMethodNotFound = -32601
	ErrCodeInvalidParams  = -32602
	ErrCodeInternalError  = -32603
	ErrCodeServerError    = -32000
)
View Source
const JSONRPCVersion = "2.0"

Variables

View Source
var ErrorHintRegistry = map[string][]ErrorHint{
	"repository": {
		{
			Original:   "Could not resolve to a Repository",
			Suggestion: "Check the owner/repo spelling. Ensure the repository exists and you have access. Tip: Use the exact format 'owner/repo' (e.g., 'mmornati/leanproxy-mcp').",
			Action:     "check_repo",
			Reference:  "https://docs.github.com/en/github/finding-open-source-projects-on-github",
		},
	},
	"not running": {
		{
			Original:   "is not running",
			Suggestion: "The MCP server is not running. Run 'leanproxy server start <server_name>' or check server status with 'leanproxy status'.",
			Action:     "restart_server",
		},
	},
	"not healthy": {
		{
			Original:   "not healthy",
			Suggestion: "The server is in an error state. Check 'leanproxy-mcp status --running' for details. The server will automatically restart on the next request.",
			Action:     "restart_server",
		},
	},
	"server not available": {
		{
			Original:   "server not available",
			Suggestion: "The server crashed or failed to start. Check the logs at /tmp/leanproxy.log for error details. The server will attempt to restart automatically.",
			Action:     "check_logs",
		},
	},
	"signal: killed": {
		{
			Original:   "signal: killed",
			Suggestion: "The server process was killed (likely by the system or OOM). Check /tmp/leanproxy.log for more details. Auto-restart will attempt recovery.",
			Action:     "check_logs",
		},
	},
	"command not found": {
		{
			Original:   "command not found",
			Suggestion: "The server command (e.g., npx, uv) is not installed or not in PATH. Check your configuration and install the required dependencies.",
			Action:     "check_dependencies",
		},
	},
	"failed": {
		{
			Original:   "server error",
			Suggestion: "The remote server encountered an error. Try again in a few moments, or check the server logs for more details.",
			Action:     "retry",
		},
	},
	"not authenticated": {
		{
			Original:   "not authenticated",
			Suggestion: "Authentication required. Check your credentials configuration for this server.",
			Action:     "check_auth",
		},
		{
			Original:   "401",
			Suggestion: "Authentication failed. Verify your API token or credentials are correct.",
			Action:     "check_auth",
		},
	},
	"forbidden": {
		{
			Original:   "403",
			Suggestion: "Access denied. You may not have permission for this operation. Check your API token scopes.",
			Action:     "check_permissions",
		},
		{
			Original:   "permission denied",
			Suggestion: "Insufficient permissions. Verify your account has the required access rights.",
			Action:     "check_permissions",
		},
	},
	"not found": {
		{
			Original:   "404",
			Suggestion: "The requested resource was not found. Check if the resource exists and the URL is correct.",
			Action:     "verify_resource",
		},
	},
	"rate limited": {
		{
			Original:   "429",
			Suggestion: "Rate limit exceeded. Wait a moment before retrying, or check if you need to configure rate limiting.",
			Action:     "wait_retry",
		},
		{
			Original:   "rate limit",
			Suggestion: "Too many requests. Consider adding a delay between requests or reducing request frequency.",
			Action:     "wait_retry",
		},
	},
	"timeout": {
		{
			Original:   "timeout",
			Suggestion: "The request timed out. The server may be slow or unavailable. Try again or increase timeout settings.",
			Action:     "retry",
		},
		{
			Original:   "context deadline exceeded",
			Suggestion: "The request took too long. Try again or check if the server is experiencing issues.",
			Action:     "retry",
		},
	},
	"invalid params": {
		{
			Original:   "invalid params",
			Suggestion: "Check the parameter names and types. Use list_servers to get servers, then list_tools to see available parameters.",
			Action:     "check_params",
		},
		{
			Original:   "missing",
			Suggestion: "A required parameter is missing. Use list_servers to get servers, then list_tools to see required parameters.",
			Action:     "check_params",
		},
	},
	"connection refused": {
		{
			Original:   "connection refused",
			Suggestion: "Cannot connect to the server. Verify the server is running and the connection settings are correct.",
			Action:     "check_server",
		},
	},
	"tool not found": {
		{
			Original:   "tool not found",
			Suggestion: "The tool doesn't exist on this server. Use list_servers to get servers, then list_tools to discover available tools.",
			Action:     "list_tools",
		},
	},
}
View Source
var InvokeToolParamDefaults = map[string]interface{}{}
View Source
var InvokeToolParamMeta = map[string]ParameterMeta{
	"server": {
		Required:    true,
		Description: "Server name from list_servers (e.g., 'github', 'garmin', 'filesystem'). Must be a configured and running MCP server.",
	},
	"tool": {
		Required:    true,
		Description: "Tool name from list_tools (e.g., 'list_issues', 'get_activities'). Do NOT prefix with server name.",
	},
	"arguments": {
		Required:    false,
		Description: "Tool arguments as key-value pairs. Refer to list_tools output for available parameters. Pass empty object {} if no arguments needed.",
	},
}
View Source
var LeanproxyTools = []ToolDefinition{
	{
		Name:        "list_tools",
		Description: "List all tools available on a specific MCP server. **IMPORTANT:** Always call list_servers first to get available server names, then use this tool to see tools on a specific server.",
		Categories:  []string{"discovery", "meta"},
		Examples: []ToolExample{
			{
				Input: map[string]interface{}{
					"server_name": "github",
				},
				Description: "List all tools available on the github server",
			},
			{
				Input: map[string]interface{}{
					"server_name": "garmin",
				},
				Description: "List all tools available on the garmin server",
			},
			{
				Input: map[string]interface{}{
					"server_name":           "github",
					"max_description_chars": 150,
				},
				Description: "List github tools with shorter descriptions",
			},
		},
		Returns: ReturnSchema{
			Type:        "object",
			Description: "Returns a content block with formatted tool list for the specified server",
			Fields: []FieldDescription{
				{Name: "content", Type: "array", Desc: "Array of text content blocks"},
			},
		},
		InputSchema: json.RawMessage(`{
			"type": "object",
			"properties": {
				"server_name": {
					"type": "string",
					"description": "MCP server name (from list_servers). Required - identifies which server's tools to list."
				},
				"max_description_chars": {
					"type": "number",
					"description": "Maximum characters for tool descriptions (default: 200, min: 50, max: 500)",
					"default": 200
				}
			},
			"required": ["server_name"]
		}`),
	},
	{
		Name:        "invoke_tool",
		Description: "Invoke a tool on a configured MCP server. **Required:** First use list_servers to get server names, then use list_tools to discover available tools on that server.",
		Categories:  []string{"execution", "meta"},
		Examples: []ToolExample{
			{
				Input: map[string]interface{}{
					"server": "github",
					"tool":   "list_issues",
					"arguments": map[string]interface{}{
						"owner":   "mmornati",
						"repo":    "leanproxy-mcp",
						"state":   "open",
						"perPage": 10,
					},
				},
				Description: "List open issues on leanproxy-mcp repository",
			},
			{
				Input: map[string]interface{}{
					"server": "github",
					"tool":   "search_issues",
					"arguments": map[string]interface{}{
						"query":   "is:issue is:open label:bug",
						"owner":   "mmornati",
						"repo":    "leanproxy-mcp",
						"perPage": 5,
					},
				},
				Description: "Search for open bug issues",
			},
		},
		Returns: ReturnSchema{
			Type:        "object",
			Description: "Returns the result from the remote MCP tool invocation",
			Fields: []FieldDescription{
				{Name: "content", Type: "array", Desc: "Array of content blocks from tool"},
			},
		},
		InputSchema: json.RawMessage(`{
			"type": "object",
			"properties": {
				"server": {
					"type": "string",
					"description": "Server name from list_servers (e.g., 'github', 'garmin', 'filesystem'). Must be a configured MCP server."
				},
				"tool": {
					"type": "string",
					"description": "Tool name from list_tools (e.g., 'list_issues', 'get_activities'). Do NOT prefix with server name."
				},
				"arguments": {
					"type": "object",
					"description": "Tool arguments as key-value pairs. Refer to list_tools output for available parameters."
				}
			},
			"required": ["server", "tool"],
			"additionalProperties": false
		}`),
	},
}
View Source
var ListToolsParamDefaults = map[string]interface{}{
	"max_description_chars": 200,
}
View Source
var ListToolsParamMeta = map[string]ParameterMeta{
	"server_name": {
		Required:        true,
		Default:         nil,
		Description:     "MCP server name (from list_servers). Required - identifies which server's tools to list.",
		SuggestedValues: []string{"github", "garmin", "filesystem", "intervals"},
	},
	"max_description_chars": {
		Required:    false,
		Default:     200,
		Min:         50,
		Max:         500,
		Description: "Maximum characters for tool descriptions. Default: 200. Range: 50-500.",
	},
}

Functions

func AddErrorContext added in v0.5.2

func AddErrorContext(originalMessage, serverName, toolName string) string

func ApplyDefaults added in v0.5.2

func ApplyDefaults(toolName string, args map[string]interface{}) map[string]interface{}

func EnrichError added in v0.5.2

func EnrichError(originalMessage string) string

func FormatErrorWithHint added in v0.5.2

func FormatErrorWithHint(originalMessage, serverName, toolName string) string

func GetAllParamDefaults added in v0.5.2

func GetAllParamDefaults(toolName string) map[string]interface{}

func GetParamDefault added in v0.5.2

func GetParamDefault(toolName, paramName string) interface{}

func ValidateParam added in v0.5.2

func ValidateParam(toolName, paramName string, value interface{}) (bool, string)

Types

type AggregatedManifest

type AggregatedManifest struct {
	Tools     []Tool
	Resources []Resource
	Prompts   []Prompt
}

type ClientCapabilities

type ClientCapabilities struct {
	Roots    *RootsCapability          `json:"roots,omitempty"`
	Sampling *ClientSamplingCapability `json:"sampling,omitempty"`
}

type ClientInfo

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

type ClientSamplingCapability

type ClientSamplingCapability struct{}

type ContentBlock

type ContentBlock struct {
	Type string `json:"type"`
	Text string `json:"text,omitempty"`
}

type Error

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

func NewError

func NewError(code int, message string) *Error

func (*Error) Error

func (e *Error) Error() string

type ErrorHint added in v0.5.2

type ErrorHint struct {
	Original   string
	Suggestion string
	Action     string
	Reference  string
}

func GetAllHintsForError added in v0.5.2

func GetAllHintsForError(originalMessage string) []ErrorHint

func GetErrorHint added in v0.5.2

func GetErrorHint(originalMessage string) *ErrorHint

type FieldDescription added in v0.5.2

type FieldDescription struct {
	Name string `json:"name"`
	Type string `json:"type"`
	Req  bool   `json:"required,omitempty"`
	Desc string `json:"description"`
}

type Handler

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

func NewHandler

func NewHandler(p pool.ServerSource, logger *slog.Logger) *Handler

func NewHandlerWithToolStore

func NewHandlerWithToolStore(p pool.ServerSource, logger *slog.Logger, store toolstore.Cache) *Handler

func (*Handler) EnableLazyLoading added in v0.7.0

func (h *Handler) EnableLazyLoading(ttl time.Duration)

func (*Handler) HandleRequest

func (h *Handler) HandleRequest(ctx context.Context, req *Request) (*Response, error)

func (*Handler) PopulateToolCache added in v0.5.0

func (h *Handler) PopulateToolCache(ctx context.Context)

func (*Handler) ResetManifest

func (h *Handler) ResetManifest()

func (*Handler) SetDefaultTimeout added in v0.9.1

func (h *Handler) SetDefaultTimeout(timeout time.Duration)

SetDefaultTimeout overrides the fallback timeout used when a server has no explicit per-server entry. A zero or negative value is ignored (the 30s default remains in effect).

func (*Handler) SetTimeout added in v0.9.1

func (h *Handler) SetTimeout(serverName string, timeout time.Duration)

SetTimeout registers a per-server request timeout. The handler falls back to its default timeout (30s unless changed via SetDefaultTimeout) for any server that has no explicit entry. A zero duration clears the entry.

type HealthcheckCapability

type HealthcheckCapability struct{}

type InitializeParams

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

type InitializeResult

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

type MCPServerInstance

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

func NewMCPServerInstance

func NewMCPServerInstance(logger *slog.Logger) *MCPServerInstance

func (*MCPServerInstance) GetServer

func (m *MCPServerInstance) GetServer() *server.MCPServer

func (*MCPServerInstance) ServeSSE

func (m *MCPServerInstance) ServeSSE(addr string) error

func (*MCPServerInstance) ServeStdio

func (m *MCPServerInstance) ServeStdio() error

func (*MCPServerInstance) ServeStreamableHTTP

func (m *MCPServerInstance) ServeStreamableHTTP(addr string) error

func (*MCPServerInstance) SetStdioPool

func (m *MCPServerInstance) SetStdioPool(p *pool.StdioPool)

func (*MCPServerInstance) SetupGatewayTools

func (m *MCPServerInstance) SetupGatewayTools()

type ParamInfo

type ParamInfo struct {
	Name        string
	Type        string
	IsRequired  bool
	Description string
}

type ParameterMeta added in v0.5.2

type ParameterMeta struct {
	Required        bool
	Default         interface{}
	Min             interface{}
	Max             interface{}
	Description     string
	SuggestedValues []string
}

func GetParamMeta added in v0.5.2

func GetParamMeta(toolName, paramName string) *ParameterMeta

type Prompt

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

type PromptArgument

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

type PromptsCapability

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

type PromptsListParams

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

type PromptsListResult

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

type Request

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

func (*Request) IsNotification

func (r *Request) IsNotification() bool

type Resource

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

type ResourcesCapability

type ResourcesCapability struct {
	Subscribe   bool `json:"subscribe,omitempty"`
	ListChanged bool `json:"listChanged,omitempty"`
}

type ResourcesListParams

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

type ResourcesListResult

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

type Response

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

type ReturnSchema added in v0.5.2

type ReturnSchema struct {
	Type        string             `json:"type"`
	Description string             `json:"description"`
	Fields      []FieldDescription `json:"fields,omitempty"`
}

type RootsCapability

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

type ServerCapabilities

type ServerCapabilities struct {
	Tools     *ToolsCapability          `json:"tools,omitempty"`
	Resources *ResourcesCapability      `json:"resources,omitempty"`
	Prompts   *PromptsCapability        `json:"prompts,omitempty"`
	Sampling  *ServerSamplingCapability `json:"sampling,omitempty"`
	Health    *HealthcheckCapability    `json:"healthcheck,omitempty"`
}

type ServerInfo

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

type ServerSamplingCapability

type ServerSamplingCapability struct{}

type Tool

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

type ToolCache

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

type ToolDefinition added in v0.5.2

type ToolDefinition struct {
	Name        string          `json:"name"`
	Description string          `json:"description"`
	Examples    []ToolExample   `json:"examples,omitempty"`
	Returns     ReturnSchema    `json:"returns,omitempty"`
	Categories  []string        `json:"categories,omitempty"`
	InputSchema json.RawMessage `json:"inputSchema"`
}

func GetAllToolDefinitions added in v0.5.2

func GetAllToolDefinitions() []ToolDefinition

func GetToolDefinition added in v0.5.2

func GetToolDefinition(name string) *ToolDefinition

type ToolExample added in v0.5.2

type ToolExample struct {
	Input       map[string]interface{} `json:"input"`
	Description string                 `json:"description"`
}

type ToolsCallParams

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

type ToolsCallResult

type ToolsCallResult struct {
	Content []ContentBlock `json:"content"`
	IsError bool           `json:"isError,omitempty"`
}

type ToolsCapability

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

type ToolsListParams

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

type ToolsListResult

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

Jump to

Keyboard shortcuts

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