Documentation
¶
Overview ¶
Package finemcp is a production-ready Go framework for building Model Context Protocol (MCP) servers.
FineMCP implements the full MCP specification (2025-11-25) over JSON-RPC 2.0, with backward compatibility for 2025-06-18, 2025-03-26, and 2024-11-05. It provides typed tool handlers with automatic JSON Schema generation, streaming tool responses, a composable middleware architecture, and a zero-network test harness.
Quick start ¶
s := finemcp.NewServer("my-server", "1.0.0")
tool, _ := finemcp.NewTool("greet", func(ctx context.Context, input json.RawMessage) (*finemcp.CallToolResult, error) {
return finemcp.NewTextResult("Hello!"), nil
}, finemcp.WithDescription("Say hello"))
s.AddTool(tool)
finemcp.ServeStdio(s)
Transports ¶
Four built-in transports are available in the github.com/finemcp/finemcp/transport package:
- stdio — newline-delimited JSON over stdin/stdout
- SSE — HTTP Server-Sent Events
- Streamable HTTP — MCP Streamable HTTP with session management
- WebSocket — full-duplex WebSocket
Middleware ¶
The github.com/finemcp/finemcp/middleware package provides 16 composable middleware components including authentication, RBAC, rate limiting, circuit breaking, OpenTelemetry tracing, audit logging, cost tracking, and more.
Streaming ¶
Long-running tools can stream incremental results via ToolStream:
stream := finemcp.StreamFromCtx(ctx)
if stream != nil {
stream.SendText("progress update…")
}
Streaming works over SSE and Streamable HTTP transports.
Testing ¶
The github.com/finemcp/finemcp/mcptest package provides an in-memory test server that requires no network and works with the race detector.
Content types ¶
Tool results use the sealed Content interface, implemented by TextContent, ImageContent, AudioContent, and EmbeddedResource.
For the complete documentation, see https://finemcp.dev/docs
Index ¶
- Constants
- Variables
- func BoolPtr(v bool) *bool
- func DefaultSupportedVersions() []string
- func GenerateSchema(t reflect.Type) map[string]any
- func IsResponse(data []byte) bool
- func IsSimulatedFromCtx(ctx context.Context) bool
- func MetaFromCtx(ctx context.Context) map[string]any
- func ReportProgress(ctx context.Context, progress, total float64)
- func RequestID(ctx context.Context) any
- func RolesFromCtx(ctx context.Context) []string
- func SetResponseMeta(ctx context.Context, key string, value any)
- func SimDepthFromCtx(ctx context.Context) int
- func SkipValidationFromCtx(ctx context.Context) bool
- func SubscriberIDFromCtx(ctx context.Context) string
- func TenantIDFromCtx(ctx context.Context) string
- func ToolName(ctx context.Context) string
- func ToolRolesFromCtx(ctx context.Context) []string
- func ToolSchemaFromCtx(ctx context.Context) any
- func WithAuthInfo(ctx context.Context, info AuthInfo) context.Context
- func WithMeta(ctx context.Context, meta map[string]any) context.Context
- func WithNotificationSender(ctx context.Context, fn NotificationSender) context.Context
- func WithRequestID(ctx context.Context, id any) context.Context
- func WithRequestSender(ctx context.Context, fn RequestSender) context.Context
- func WithRolesCtx(ctx context.Context, roles []string) context.Context
- func WithSimDepth(ctx context.Context, depth int) context.Context
- func WithSimulated(ctx context.Context) context.Context
- func WithSubscriberID(ctx context.Context, id string) context.Context
- func WithTenantID(ctx context.Context, id string) context.Context
- func WithToolName(ctx context.Context, name string) context.Context
- type AudioContent
- type AuthChecker
- type AuthInfo
- type CallToolParams
- type CallToolResult
- type CancelledParams
- type ClientCaps
- type CompleteHandler
- type CompleteParams
- type CompleteRequest
- type CompleteResult
- type CompletionArgument
- type CompletionCapability
- type CompletionRef
- type CompletionResult
- type Content
- type CreateMessageParams
- type CreateMessageResult
- type CreateTaskResult
- type ElicitationCapability
- type ElicitationParams
- type ElicitationResult
- type EmbeddedResource
- type GetPromptParams
- type GetPromptResult
- type Icon
- type ImageContent
- type InitializeParams
- type InitializeResult
- type ItemFilter
- type JSONRPCError
- type JSONRPCNotification
- type JSONRPCRequest
- type JSONRPCResponse
- type Job
- type JobStatus
- type JobStore
- func (js *JobStore) Cancel(id string) error
- func (js *JobStore) Complete(id string, result *CallToolResult) error
- func (js *JobStore) Delete(id string) error
- func (js *JobStore) Fail(id string, errMsg string) error
- func (js *JobStore) Get(id string) (*Job, error)
- func (js *JobStore) List() []*Job
- func (js *JobStore) MarkRunning(id string) error
- func (js *JobStore) Submit(id, toolName string) (*Job, error)
- type JobStoreOption
- type LifespanFunc
- type ListParams
- type ListPromptsResult
- type ListResourceTemplatesResult
- type ListResourcesResult
- type ListRootsResult
- type ListTasksResult
- type ListToolsResult
- type LogHandler
- type LogLevel
- type LogMessageParams
- type LoggingCapability
- type MergeFunc
- type Middleware
- type ModelHint
- type ModelPreferences
- type NamedHandler
- type NotificationHandlerFunc
- type NotificationPanicHandler
- type NotificationSender
- type ParallelResult
- type PendingRequests
- type ProcessInfo
- type ProgressParams
- type ProgressReporter
- type Prompt
- type PromptArgument
- type PromptCapability
- type PromptHandler
- type PromptInfo
- type PromptMessage
- type PromptOption
- type ReadResourceParams
- type ReadResourceResult
- type RequestSender
- type Resource
- type ResourceCapability
- type ResourceContent
- type ResourceHandler
- type ResourceInfo
- type ResourceOption
- type ResourceTemplate
- type ResourceTemplateInfo
- type ResourceTemplateOption
- type ResourceUpdatedParams
- type Root
- type RootInfo
- type RootOption
- type SamplingCapability
- type SamplingMessage
- type Server
- func (s *Server) AddSender(id string, sender NotificationSender) error
- func (s *Server) AddSessionTool(ctx context.Context, sessionID string, tool *Tool) error
- func (s *Server) CallTool(ctx context.Context, name string, input []byte) (*CallToolResult, error)
- func (s *Server) CreateMessage(ctx context.Context, params CreateMessageParams) (*CreateMessageResult, error)
- func (s *Server) ElicitUser(ctx context.Context, params ElicitationParams) (*ElicitationResult, error)
- func (s *Server) GetPrompt(ctx context.Context, name string, args map[string]string) (*GetPromptResult, error)
- func (s *Server) HandleMessage(ctx context.Context, data []byte) (*JSONRPCResponse, error)
- func (s *Server) ListPrompts() []*Prompt
- func (s *Server) ListResourceTemplates() []*ResourceTemplate
- func (s *Server) ListResources() []*Resource
- func (s *Server) ListRoots() []*Root
- func (s *Server) ListTools() []*Tool
- func (s *Server) Name() string
- func (s *Server) NegotiatedVersion() string
- func (s *Server) NotificationStats() map[string]int
- func (s *Server) NotifyPromptsListChanged()
- func (s *Server) NotifyResourceUpdated(uri string)
- func (s *Server) NotifyResourcesListChanged()
- func (s *Server) NotifyRootsListChanged()
- func (s *Server) NotifyToolsListChanged()
- func (s *Server) OnNotification(method string, handler NotificationHandlerFunc)
- func (s *Server) OnSessionToolShadow(cb SessionToolShadowCallback)
- func (s *Server) ReadResource(ctx context.Context, uri string) (*ReadResourceResult, error)
- func (s *Server) RegisterPrompt(p *Prompt) error
- func (s *Server) RegisterResource(r *Resource) error
- func (s *Server) RegisterResourceTemplate(t *ResourceTemplate) error
- func (s *Server) RegisterRoot(r *Root) error
- func (s *Server) RegisterTool(tool *Tool) error
- func (s *Server) RegisterTools(tools ...*Tool) error
- func (s *Server) RemoveNotificationHandlers(method string) int
- func (s *Server) RemoveSender(id string)
- func (s *Server) RemoveSessionTool(sessionID, name string) error
- func (s *Server) RemoveSessionTools(sessionID string)
- func (s *Server) RemoveTool(name string) error
- func (s *Server) SendLogMessage(ctx context.Context, level LogLevel, logger string, data any) error
- func (s *Server) SessionTools(sessionID string) []*Tool
- func (s *Server) SetAuthChecker(checker AuthChecker)
- func (s *Server) SetLogHandler(handler LogHandler)
- func (s *Server) SetTenantResolver(resolver TenantResolver)
- func (s *Server) Shutdown(ctx context.Context) error
- func (s *Server) Start(ctx context.Context, runFn func(ctx context.Context) error) error
- func (s *Server) Subscribe(subscriberID, uri string, sender NotificationSender) error
- func (s *Server) Unsubscribe(subscriberID, uri string)
- func (s *Server) UnsubscribeAll(subscriberID string)
- func (s *Server) Use(mw ...Middleware)
- func (s *Server) Version() string
- type ServerCapabilities
- type ServerOption
- func WithIcons(icons ...Icon) ServerOption
- func WithInstructions(instructions string) ServerOption
- func WithLifespan(fn LifespanFunc) ServerOption
- func WithMaxHandlersPerNotification(n int) ServerOption
- func WithMaxNotificationMethods(n int) ServerOption
- func WithMaxSessionTools(n int) ServerOption
- func WithMaxSessions(n int) ServerOption
- func WithNotificationPanicHandler(h NotificationPanicHandler) ServerOption
- func WithResourceSubscriptions() ServerOption
- func WithServerDescription(desc string) ServerOption
- func WithServerTitle(title string) ServerOption
- func WithStreamBufferSize(n int) ServerOption
- func WithSupportedVersions(versions ...string) ServerOption
- func WithTaskStore(ts *TaskStore) ServerOption
- func WithWebsiteURL(url string) ServerOption
- type SessionToolShadowCallback
- type SetLevelParams
- type SetLevelResult
- type SimulatorFunc
- type StreamChunkData
- type SubscribeParams
- type Task
- type TaskCapability
- type TaskIdParams
- type TaskMetadata
- type TaskOptions
- type TaskRequestsCapability
- type TaskStatus
- type TaskStore
- func (ts *TaskStore) Cancel(id string) (*Task, error)
- func (ts *TaskStore) Complete(id string, result *CallToolResult) error
- func (ts *TaskStore) Delete(id string) error
- func (ts *TaskStore) Fail(id string, errMsg string) error
- func (ts *TaskStore) GenerateID() string
- func (ts *TaskStore) Get(id string) (*Task, error)
- func (ts *TaskStore) GetResult(id string) (*CallToolResult, error)
- func (ts *TaskStore) List() []Task
- func (ts *TaskStore) ListByOwner(ownerID string) []Task
- func (ts *TaskStore) Submit(id string) (*Task, error)
- func (ts *TaskStore) SubmitWithOptions(id string, opts TaskOptions) (*Task, error)
- type TaskStoreOption
- type TaskToolsCapability
- type TenantResolver
- type TextContent
- type Tool
- type ToolAnnotations
- type ToolCapability
- type ToolHandler
- type ToolInfo
- type ToolOption
- func WithAnnotations(a ToolAnnotations) ToolOption
- func WithDescription(desc string) ToolOption
- func WithDestructive() ToolOption
- func WithIdempotent() ToolOption
- func WithInputSchema(schema any) ToolOption
- func WithOpenWorld() ToolOption
- func WithReadOnly() ToolOption
- func WithRoles(roles ...string) ToolOption
- func WithSimulator(fn SimulatorFunc) ToolOption
- func WithTitle(title string) ToolOption
- func WithValidation(enabled bool) ToolOption
- type ToolStream
- type TypedHandler
Examples ¶
Constants ¶
const ( RefTypePrompt = "ref/prompt" RefTypeResource = "ref/resource" )
Ref type constants.
const ( ErrCodeParseError = -32700 ErrCodeInvalidRequest = -32600 ErrCodeMethodNotFound = -32601 ErrCodeInvalidParams = -32602 ErrCodeInternalError = -32603 )
Standard JSON-RPC 2.0 error codes.
const ( // credentials. Returned when an AuthChecker is configured and the request // context does not contain a verified identity. ErrCodeUnauthorized = -32001 // ErrCodeTenantRequired indicates that tenant identification could not be // resolved for the request. Returned when a TenantResolver is configured // and the tenant ID is missing, invalid, or not found in the store. // The error message is intentionally generic ("tenant identification required") // to prevent enumeration of valid tenant IDs. ErrCodeTenantRequired = -32002 )
Application-level JSON-RPC error codes (reserved range: -32000 to -32099).
const ( // DefaultMaxNotificationMethods is the default maximum number of distinct // notification methods that can have handlers registered. Override via // [WithMaxNotificationMethods] if you expect more than 1000 custom methods. DefaultMaxNotificationMethods = 1000 // DefaultMaxHandlersPerMethod is the default maximum number of handlers // that can be registered for a single notification method. Override via // [WithMaxHandlersPerNotification] if you need more than 100 handlers per // method (uncommon: most applications use 1-5 handlers per notification; // event-bus or plugin-system patterns may need more). DefaultMaxHandlersPerMethod = 100 )
Defaults for notification handler limits.
const ( MethodInitialize = methodInitialize MethodInitialized = methodInitialized MethodToolsList = methodToolsList MethodToolsCall = methodToolsCall MethodResourcesList = methodResourcesList MethodResourcesRead = methodResourcesRead MethodResourcesTemplatesList = methodResourcesTemplatesList MethodRootsList = methodRootsList MethodPromptsList = methodPromptsList MethodPromptsGet = methodPromptsGet MethodPing = methodPing MethodProgress = methodProgress MethodCancelled = methodCancelled MethodResourcesSubscribe = methodResourcesSubscribe MethodResourcesUnsubscribe = methodResourcesUnsubscribe MethodCompletionComplete = methodCompletionComplete MethodTasksGet = methodTasksGet MethodTasksResult = methodTasksResult MethodTasksCancel = methodTasksCancel MethodTasksList = methodTasksList MethodResourcesUpdated = methodResourcesUpdated MethodToolsListChanged = methodToolsListChanged MethodResourcesListChanged = methodResourcesListChanged MethodPromptsListChanged = methodPromptsListChanged MethodRootsListChanged = methodRootsListChanged MethodSamplingCreateMessage = methodSamplingCreateMessage MethodElicitationCreate = methodElicitationCreate MethodLoggingSetLevel = methodLoggingSetLevel MethodLoggingMessage = methodLoggingMessage )
Exported MCP method constants for use by the client package and external consumers.
const ( // DefaultMaxSessionTools is the default maximum number of tools per session. DefaultMaxSessionTools = 100 // DefaultMaxSessions is the default maximum number of concurrent sessions // that can have session tools. Prevents unbounded memory growth from // rogue transport connections. DefaultMaxSessions = 10000 )
const DefaultStreamBufferSize = 16
DefaultStreamBufferSize is the default number of content chunks buffered before Send blocks, providing backpressure to the tool handler.
const ProtocolVersion = "2025-11-25"
ProtocolVersion is the latest MCP protocol version this server supports. Format is YYYY-MM-DD (e.g., "2025-11-25"). This is the preferred version used in negotiation when the client's requested version is not in the server's supported set. Must always equal defaultSupportedVersions[0]; the init() guard below panics at program start if they drift.
Variables ¶
var ErrStreamClosed = errors.New("stream closed")
ErrStreamClosed is returned by ToolStream.Send and ToolStream.SendText when the stream has already been closed by the framework. Tool handlers can use errors.Is(err, finemcp.ErrStreamClosed) to distinguish this from context cancellation or marshaling errors.
Functions ¶
func BoolPtr ¶
BoolPtr returns a pointer to the given bool value. Exported so callers can build ToolAnnotations literals without a local helper.
func DefaultSupportedVersions ¶
func DefaultSupportedVersions() []string
DefaultSupportedVersions returns all MCP protocol versions the server supports by default, ordered from latest to oldest. The first entry is the preferred version. A fresh copy is returned each time.
func GenerateSchema ¶
GenerateSchema produces a JSON Schema (as map[string]any) from a Go reflect.Type.
For struct types it generates an "object" schema with properties derived from exported fields. Struct tags control the output:
- json:"name" → property name
- json:",omitempty" → field is optional (not in "required")
- json:"-" → field is skipped
- description:"..." → sets the property's "description"
Pointer fields are treated as optional. Nested structs, slices, and maps are recursively expanded.
For non-struct types (e.g. string, int) it returns the corresponding primitive JSON Schema.
func IsResponse ¶
IsResponse checks whether a raw JSON message is a JSON-RPC response (has "id" and either "result" or "error", but no "method"). This is used by transports to distinguish client responses from client requests.
func IsSimulatedFromCtx ¶
IsSimulatedFromCtx reports whether the current call is a simulation. This is only true inside the simulator and any code it calls; outer middleware should use MetaFromCtx to check for dry-run mode.
func MetaFromCtx ¶
MetaFromCtx extracts the request _meta from the context. Returns nil if the client did not send _meta.
func ReportProgress ¶
ReportProgress emits a notifications/progress event for the current tool call. progress is the current value (e.g. bytes processed, items completed). total is the expected final value; pass 0 for indeterminate progress.
If the transport does not support server-to-client notifications (e.g. plain HTTP), or if no reporter was injected into ctx, this call is a no-op.
On the SSE transport, progress notifications are delivered on a best-effort basis: if the session's event buffer is full the notification is silently dropped. Tool authors should not rely on every notification being delivered.
Example:
tool, _ := finemcp.NewTypedTool("process", func(ctx context.Context, in Input) (string, error) {
for i, item := range in.Items {
finemcp.ReportProgress(ctx, float64(i+1), float64(len(in.Items)))
// ... process item ...
}
return "done", nil
})
func RequestID ¶
RequestID extracts the JSON-RPC request ID from the context. Returns nil if not set.
func RolesFromCtx ¶
RolesFromCtx extracts the caller's roles from the context. Returns nil if not set.
func SetResponseMeta ¶
SetResponseMeta attaches a key-value pair to the response _meta. Tool, resource, and prompt handlers can call this to include custom metadata in the response without modifying the result struct directly.
This is only effective for tools/call, resources/read, and prompts/get handlers — the dispatch layer wires up the response meta holder for those methods. Calls from other contexts are a safe no-op.
Example:
func myHandler(ctx context.Context, input []byte) ([]byte, error) {
finemcp.SetResponseMeta(ctx, "processingTimeMs", 42)
return []byte("done"), nil
}
func SimDepthFromCtx ¶
SimDepthFromCtx returns the current simulation nesting depth. Returns 0 if not inside a simulation.
func SkipValidationFromCtx ¶
SkipValidationFromCtx reports whether input validation should be skipped. Returns false if not set.
func SubscriberIDFromCtx ¶
SubscriberIDFromCtx extracts the subscriber/connection ID from the context. Returns "" if not set.
func TenantIDFromCtx ¶
TenantIDFromCtx extracts the resolved tenant ID from the context. Returns "" if no tenant ID is set (single-tenant mode or before resolution).
func ToolRolesFromCtx ¶
ToolRolesFromCtx extracts the tool's required roles from the context. Returns nil if the tool has no role requirements. This is set internally by Server.CallTool and used by middleware like RBAC.
func ToolSchemaFromCtx ¶
ToolSchemaFromCtx extracts the tool's InputSchema from the context. Returns nil if no schema is set. Used by validation middleware.
func WithAuthInfo ¶
WithAuthInfo returns a copy of ctx with the verified caller identity attached. The Roles slice and Meta map are defensively copied to prevent mutation.
func WithMeta ¶
WithMeta returns a copy of ctx with the request's _meta attached. This is set by the dispatch layer when the client includes _meta in the request params. Handlers and middleware can inspect it via MetaFromCtx.
func WithNotificationSender ¶
func WithNotificationSender(ctx context.Context, fn NotificationSender) context.Context
WithNotificationSender attaches a notification sender to the context. Transports call this before invoking HandleMessage so that tool handlers can emit mid-execution notifications via ReportProgress.
func WithRequestID ¶
WithRequestID returns a copy of ctx with the JSON-RPC request ID attached.
func WithRequestSender ¶
func WithRequestSender(ctx context.Context, fn RequestSender) context.Context
WithRequestSender attaches a server-to-client request sender to the context. Transports call this before invoking HandleMessage so that server methods like CreateMessage can send requests to the client and await responses.
func WithRolesCtx ¶
WithRolesCtx returns a copy of ctx with the caller's roles attached.
func WithSimDepth ¶
WithSimDepth attaches the current simulation nesting depth to the context.
func WithSimulated ¶
WithSimulated marks the context as a simulation (dry-run) call. The Simulation middleware calls this before invoking the simulator so that the simulator and any code it calls can detect dry-run mode via IsSimulatedFromCtx.
Note: because Go contexts are immutable, the simulated flag is only visible to the simulator and downstream calls — middleware earlier in the chain (outer wrappers) will not see it. Outer middleware that needs to detect dry-run mode should check MetaFromCtx for the "dryRun" key instead.
func WithSubscriberID ¶
WithSubscriberID attaches a stable per-connection identifier to the context. Transports set this once per connection/session so the server can associate subscriptions and broadcast senders with a specific client.
func WithTenantID ¶
WithTenantID returns a copy of ctx with the resolved tenant ID attached. This is set by the TenantResolver during request dispatch and can be read by downstream middleware (rate limiter, audit log, cost tracking) via TenantIDFromCtx.
Types ¶
type AudioContent ¶
type AudioContent struct {
// Data is the raw audio bytes. They are base64-encoded on the wire.
Data []byte
// MimeType is the MIME type of the audio (e.g. "audio/wav").
// May be empty if the format is unspecified.
MimeType string
}
AudioContent represents a base64-encoded audio clip returned by a tool. MCP wire format: {"type":"audio","data":"<base64>","mimeType":"audio/*"}. The MimeType field indicates the audio format (e.g. "audio/wav", "audio/mpeg"). MimeType may be an empty string if the format is unknown or unspecified.
func NewAudioContent ¶
func NewAudioContent(mimeType string, data []byte) AudioContent
NewAudioContent creates an AudioContent from raw bytes and a MIME type. The bytes are stored as-is and base64-encoded when marshaled to JSON.
func (AudioContent) MarshalJSON ¶
func (c AudioContent) MarshalJSON() ([]byte, error)
MarshalJSON encodes Data as a base64 string and includes the MCP "type" discriminator.
type AuthChecker ¶
AuthChecker validates that a request context has proper authentication. It is called by handleRequest for every JSON-RPC request (except initialize and ping) after the server is initialized. If it returns a non-nil error, the request is rejected with a JSON-RPC error response using ErrCodeUnauthorized.
Implementations should inspect the context for an AuthInfo value set by the transport-level authentication middleware.
type AuthInfo ¶
type AuthInfo struct {
// Subject identifies the authenticated caller (e.g. user ID, service name).
Subject string
// Roles contains the caller's authorization roles for RBAC.
Roles []string
// Meta holds additional claims from the token (e.g. JWT claims).
// May be nil.
Meta map[string]any
}
AuthInfo represents the verified identity of an authenticated caller. It is injected into context by the authentication layer (transport HTTP middleware) after successful credential verification.
Consumers (RBAC, audit log, logging, handlers) read it via AuthInfoFromCtx.
func AuthInfoFromCtx ¶
AuthInfoFromCtx extracts the verified caller identity from the context. Returns nil if no identity is set (unauthenticated request).
type CallToolParams ¶
type CallToolParams struct {
Name string `json:"name"`
Arguments json.RawMessage `json:"arguments,omitempty"`
Task *TaskMetadata `json:"task,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
CallToolParams is the client's payload for a "tools/call" request.
type CallToolResult ¶
type CallToolResult struct {
Content []Content `json:"content"`
IsError bool `json:"isError,omitempty"`
StructuredContent any `json:"structuredContent,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
CallToolResult is the server's response to a tools/call request.
func NewAudioResult ¶
func NewAudioResult(mimeType string, data []byte) *CallToolResult
NewAudioResult creates a successful result containing a single audio clip. data is the raw audio bytes; mimeType should be e.g. "audio/wav" or "audio/mpeg".
func NewEmbeddedResourceResult ¶
func NewEmbeddedResourceResult(rc ResourceContent) *CallToolResult
NewEmbeddedResourceResult creates a successful result containing a single embedded resource.
func NewErrorResult ¶
func NewErrorResult(text string) *CallToolResult
NewErrorResult creates an error result with a single text content block. Tool errors are returned as content with IsError=true, not as protocol errors.
func NewImageResult ¶
func NewImageResult(mimeType string, data []byte) *CallToolResult
NewImageResult creates a successful result containing a single image. data is the raw image bytes; mimeType should be e.g. "image/png" or "image/jpeg".
func NewTextResult ¶
func NewTextResult(text string) *CallToolResult
NewTextResult creates a successful result with a single text content block.
func (*CallToolResult) UnmarshalJSON ¶
func (r *CallToolResult) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes a CallToolResult, handling the Content interface slice.
type CancelledParams ¶
type CancelledParams struct {
RequestID any `json:"requestId"` // can be string or number
Meta map[string]any `json:"_meta,omitempty"`
}
CancelledParams is the client's payload for the "notifications/cancelled" notification.
type ClientCaps ¶
type ClientCaps struct {
// Sampling indicates the client supports sampling/createMessage requests.
// When non-nil, the server may send LLM sampling requests to the client.
Sampling *SamplingCapability `json:"sampling,omitempty"`
// Elicitation indicates the client supports elicitation/create requests.
// When non-nil, the server may send user prompt requests to the client.
Elicitation *ElicitationCapability `json:"elicitation,omitempty"`
}
ClientCaps describes the client's declared capabilities.
type CompleteHandler ¶
type CompleteHandler func(ctx context.Context, params CompleteRequest) (*CompletionResult, error)
CompleteHandler provides argument auto-completions for a prompt or resource template. The server invokes the handler when a client sends a completion/complete request, passing the reference to the prompt or template and the partial argument value typed so far.
Implementations should return a CompletionResult with matching values. Returning nil is equivalent to returning an empty result (no suggestions). The server normalizes nil Values to an empty slice before serialization, so handlers may safely return a nil slice when there are no matches.
The server enforces the MCP-recommended limit of 100 values per response. If Values contains more than 100 items, the server truncates the slice to 100 entries and sets HasMore to true automatically. Total is preserved if the handler set it; otherwise it is set to the original (pre-truncation) length.
Like other user-provided handlers, a CompleteHandler is not wrapped with panic recovery by default. For production deployments, use a recovery middleware to prevent a panicking completer from crashing the server.
type CompleteParams ¶
type CompleteParams struct {
Ref CompletionRef `json:"ref"`
Argument CompletionArgument `json:"argument"`
Meta map[string]any `json:"_meta,omitempty"`
}
CompleteParams is the client's payload for a "completion/complete" request.
type CompleteRequest ¶
type CompleteRequest struct {
// Ref identifies the prompt or resource template being completed.
Ref CompletionRef
// Argument holds the argument name and partial value.
Argument CompletionArgument
}
CompleteRequest is the input passed to a CompleteHandler. It wraps the reference and argument from the client's request.
type CompleteResult ¶
type CompleteResult struct {
Completion CompletionResult `json:"completion"`
Meta map[string]any `json:"_meta,omitempty"`
}
CompleteResult is the server's response to a "completion/complete" request.
type CompletionArgument ¶
type CompletionArgument struct {
// Name is the argument identifier.
Name string `json:"name"`
// Value is the partial value typed so far.
Value string `json:"value"`
}
CompletionArgument holds the argument name and partial value for which the client is requesting completions.
type CompletionCapability ¶
type CompletionCapability struct{}
CompletionCapability signals that the server supports completion/complete. Per the MCP spec, the capability is an empty object when present.
type CompletionRef ¶
type CompletionRef struct {
// Type is "ref/prompt" or "ref/resource".
Type string `json:"type"`
// Name is the prompt name (for ref/prompt) or the resource URI template
// string (for ref/resource).
Name string `json:"name,omitempty"`
// URI is the resource template URI (for ref/resource).
// Some clients use "uri" instead of "name" for resource references.
URI string `json:"uri,omitempty"`
}
CompletionRef identifies the prompt or resource template being completed.
type CompletionResult ¶
type CompletionResult struct {
// Values is the list of completion suggestions. The server enforces the
// MCP-recommended limit of 100 items: if the handler returns more, the
// slice is truncated and HasMore is set to true automatically.
Values []string `json:"values"`
// Total is the total number of available completions (optional).
// When set, clients can display "showing X of Y" to the user.
// If the server truncates Values, Total is preserved when the handler
// set it explicitly; otherwise it is set to the original length.
Total int `json:"total,omitempty"`
// HasMore indicates that additional completions exist beyond the
// returned values.
HasMore bool `json:"hasMore,omitempty"`
}
CompletionResult holds the auto-completion suggestions returned by a CompleteHandler.
type Content ¶
type Content interface {
// contains filtered or unexported methods
}
Content is a sealed interface for tool result content types. Implementations: TextContent, ImageContent, AudioContent, EmbeddedResource.
func DecodeContent ¶
func DecodeContent(raw json.RawMessage) (Content, error)
DecodeContent decodes a raw JSON content block into the appropriate Content type based on the "type" discriminator field. Uses a single-pass unmarshal for efficiency.
Validation rules:
- TextContent.Text: optional field; defaults to empty string when absent.
- ImageContent/AudioContent.Data: required, must be a non-empty base64 string.
- ImageContent/AudioContent.MimeType: optional; defaults to empty string.
- ResourceContent.URI: required, must be non-empty.
- ResourceContent.Text/Blob: exactly one must be set.
type CreateMessageParams ¶
type CreateMessageParams struct {
// Messages is the conversation history to send to the LLM.
Messages []SamplingMessage `json:"messages"`
// ModelPreferences expresses optional model selection preferences.
ModelPreferences *ModelPreferences `json:"modelPreferences,omitempty"`
// SystemPrompt is an optional system prompt to prepend.
SystemPrompt string `json:"systemPrompt,omitempty"`
// IncludeContext controls how much MCP context the client should
// include. Valid values: "none", "thisServer", "allServers".
IncludeContext string `json:"includeContext,omitempty"`
// Temperature controls randomness (0–1). Optional.
Temperature *float64 `json:"temperature,omitempty"`
// MaxTokens is the maximum number of tokens to generate.
MaxTokens int `json:"maxTokens"`
// StopSequences is an optional list of sequences that stop generation.
StopSequences []string `json:"stopSequences,omitempty"`
// Metadata is additional provider-specific parameters.
Metadata map[string]any `json:"metadata,omitempty"`
// Meta holds MCP request metadata such as a progress token.
// Clients use this to correlate progress notifications with the request.
Meta map[string]any `json:"_meta,omitempty"`
}
CreateMessageParams is the server's payload for a "sampling/createMessage" request sent to the client.
type CreateMessageResult ¶
type CreateMessageResult struct {
// Role is the role of the generated message ("assistant").
Role string `json:"role"`
// Content is the generated content (text, image, etc.).
Content json.RawMessage `json:"content"`
// Model is the identifier of the model that was used.
Model string `json:"model"`
// StopReason indicates why generation stopped.
// Common values: "endTurn", "stopSequence", "maxTokens".
StopReason string `json:"stopReason,omitempty"`
}
CreateMessageResult is the client's response to a "sampling/createMessage" request.
type CreateTaskResult ¶
type CreateTaskResult struct {
Task Task `json:"task"`
Meta map[string]any `json:"_meta,omitempty"`
}
CreateTaskResult is the response to a task-augmented request (e.g., tools/call with task metadata). It wraps a Task handle.
type ElicitationCapability ¶
type ElicitationCapability struct{}
ElicitationCapability signals that the client supports elicitation/create. Per the MCP spec, the capability is an empty object when present.
type ElicitationParams ¶
type ElicitationParams struct {
// Prompt is the message to display to the user.
Prompt string `json:"prompt"`
// Type indicates the expected response type: "text", "secret", "file", etc.
Type string `json:"type,omitempty"`
// Default is an optional default value to present to the user.
Default string `json:"default,omitempty"`
// Meta holds MCP request metadata such as a progress token.
Meta map[string]any `json:"_meta,omitempty"`
}
ElicitationParams is the server's payload for an "elicitation/create" request sent to the client.
type ElicitationResult ¶
type ElicitationResult struct {
// Value is the user's input.
Value string `json:"value"`
// Cancelled indicates whether the user cancelled the prompt.
Cancelled bool `json:"cancelled,omitempty"`
}
ElicitationResult is the client's response to an "elicitation/create" request.
type EmbeddedResource ¶
type EmbeddedResource struct {
Resource ResourceContent
}
EmbeddedResource embeds a resource directly inside a tool result, as defined by the MCP spec's "resource" content type.
func NewEmbeddedResource ¶
func NewEmbeddedResource(rc ResourceContent) EmbeddedResource
NewEmbeddedResource wraps a ResourceContent as an EmbeddedResource content item.
func (EmbeddedResource) MarshalJSON ¶
func (e EmbeddedResource) MarshalJSON() ([]byte, error)
MarshalJSON marshals the embedded resource with the MCP "type" discriminator.
type GetPromptParams ¶
type GetPromptParams struct {
Name string `json:"name"`
Arguments map[string]string `json:"arguments,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
GetPromptParams is the client's payload for a "prompts/get" request.
type GetPromptResult ¶
type GetPromptResult struct {
Description string `json:"description,omitempty"`
Messages []PromptMessage `json:"messages"`
Meta map[string]any `json:"_meta,omitempty"`
}
GetPromptResult is the server's response to a "prompts/get" request.
type Icon ¶
type Icon struct {
Src string `json:"src"`
MimeType string `json:"mimeType,omitempty"`
Sizes []string `json:"sizes,omitempty"`
}
Icon represents an icon associated with an MCP server or client. Per the MCP spec, icons can be used by clients (e.g. Claude Desktop) to display a visual representation of the server.
type ImageContent ¶
type ImageContent struct {
// Data is the raw image bytes. They are base64-encoded on the wire.
Data []byte
// MimeType is the MIME type of the image (e.g. "image/png").
// May be empty if the format is unspecified.
MimeType string
}
ImageContent represents a base64-encoded image returned by a tool. The MimeType field indicates the image format (e.g. "image/png", "image/jpeg"). MimeType may be an empty string if the format is unknown or unspecified.
func NewImageContent ¶
func NewImageContent(mimeType string, data []byte) ImageContent
NewImageContent creates an ImageContent from raw bytes and a MIME type. The bytes are stored as-is and base64-encoded when marshaled to JSON.
func (ImageContent) MarshalJSON ¶
func (c ImageContent) MarshalJSON() ([]byte, error)
MarshalJSON encodes Data as a base64 string and includes the MCP "type" discriminator.
type InitializeParams ¶
type InitializeParams struct {
ProtocolVersion string `json:"protocolVersion"`
Capabilities ClientCaps `json:"capabilities"`
ClientInfo ProcessInfo `json:"clientInfo"`
Meta map[string]any `json:"_meta,omitempty"`
}
InitializeParams is the client's payload for the "initialize" request.
type InitializeResult ¶
type InitializeResult struct {
ProtocolVersion string `json:"protocolVersion"`
Capabilities ServerCapabilities `json:"capabilities"`
ServerInfo ProcessInfo `json:"serverInfo"`
Instructions string `json:"instructions,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
InitializeResult is the server's response to an "initialize" request.
type ItemFilter ¶
type ItemFilter struct {
// TenantID is the resolved tenant identifier. Set by the TenantResolver
// so the dispatch layer can inject it into context via WithTenantID.
// Empty if tenancy is not active.
TenantID string
// Tool returns true if the item should be visible to the caller.
// nil means all tools are visible.
Tool func(*Tool) bool
// Resource returns true if the item should be visible to the caller.
// nil means all resources are visible.
Resource func(*Resource) bool
// ResourceTemplate returns true if the item should be visible to the caller.
// nil means all resource templates are visible.
ResourceTemplate func(*ResourceTemplate) bool
// Prompt returns true if the item should be visible to the caller.
// nil means all prompts are visible.
Prompt func(*Prompt) bool
}
ItemFilter controls per-request visibility of server items for multi-tenant isolation. Each function returns true to allow the item, false to hide/deny it. A nil function field means "allow all" for that item type.
Callers should use the nil-safe Allow* methods rather than calling the function fields directly.
func (*ItemFilter) AllowPrompt ¶
func (f *ItemFilter) AllowPrompt(p *Prompt) (allowed bool)
AllowPrompt reports whether the filter permits the given prompt. Returns true when f is nil or f.Prompt is nil (allow-all). Panics in the filter function are recovered and treated as deny (fail-secure).
func (*ItemFilter) AllowResource ¶
func (f *ItemFilter) AllowResource(r *Resource) (allowed bool)
AllowResource reports whether the filter permits the given resource. Returns true when f is nil or f.Resource is nil (allow-all). Panics in the filter function are recovered and treated as deny (fail-secure).
func (*ItemFilter) AllowResourceTemplate ¶
func (f *ItemFilter) AllowResourceTemplate(t *ResourceTemplate) (allowed bool)
AllowResourceTemplate reports whether the filter permits the given resource template. Returns true when f is nil or f.ResourceTemplate is nil (allow-all). Panics in the filter function are recovered and treated as deny (fail-secure).
func (*ItemFilter) AllowTool ¶
func (f *ItemFilter) AllowTool(t *Tool) (allowed bool)
AllowTool reports whether the filter permits the given tool. Returns true when f is nil or f.Tool is nil (allow-all). Panics in the filter function are recovered and treated as deny (fail-secure).
type JSONRPCError ¶
type JSONRPCError struct {
Code int `json:"code"`
Message string `json:"message"`
Data any `json:"data,omitempty"`
}
JSONRPCError represents a JSON-RPC 2.0 error object.
func (*JSONRPCError) Error ¶
func (e *JSONRPCError) Error() string
Error implements the error interface for JSONRPCError.
type JSONRPCNotification ¶
type JSONRPCNotification struct {
JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
Params any `json:"params,omitempty"`
}
JSONRPCNotification is an outgoing server-to-client JSON-RPC 2.0 notification. Notifications have no "id" field and expect no response.
type JSONRPCRequest ¶
type JSONRPCRequest struct {
JSONRPC string `json:"jsonrpc"`
ID any `json:"-"`
Method string `json:"method"`
Params json.RawMessage `json:"params,omitempty"`
// contains filtered or unexported fields
}
JSONRPCRequest represents an incoming JSON-RPC 2.0 request or notification. A notification has no "id" field; use IsNotification() to distinguish.
func (*JSONRPCRequest) IsNotification ¶
func (r *JSONRPCRequest) IsNotification() bool
IsNotification reports whether this message is a notification (no "id" field).
func (*JSONRPCRequest) UnmarshalJSON ¶
func (r *JSONRPCRequest) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom unmarshaling to detect whether "id" is present. JSON-RPC 2.0 distinguishes between absent id (notification) and null id (valid request).
type JSONRPCResponse ¶
type JSONRPCResponse struct {
JSONRPC string `json:"jsonrpc"`
ID any `json:"id"`
Result any `json:"result,omitempty"`
Error *JSONRPCError `json:"error,omitempty"`
}
JSONRPCResponse represents an outgoing JSON-RPC 2.0 response. A response has either Result or Error, never both.
func NewErrorResponse ¶
func NewErrorResponse(id any, code int, msg string) *JSONRPCResponse
NewErrorResponse creates an error response with the given id, code, and message.
func NewResponse ¶
func NewResponse(id any, result any) *JSONRPCResponse
NewResponse creates a success response with the given id and result.
type Job ¶
type Job struct {
// ID is a unique identifier for this job.
ID string
// ToolName is the name of the tool that was called.
ToolName string
// Status is the current state of the job.
Status JobStatus
// Result holds the tool's output once the job is complete.
Result *CallToolResult
// Error holds an error message if the job failed.
Error string
// CreatedAt is when the job was submitted.
CreatedAt time.Time
// CompletedAt is when the job finished (zero if still running).
CompletedAt time.Time
}
Job represents an asynchronous tool execution.
type JobStatus ¶
type JobStatus string
JobStatus represents the lifecycle state of a job.
const ( // JobStatusPending means the job is queued but not yet started. JobStatusPending JobStatus = "pending" // JobStatusRunning means the job is currently executing. JobStatusRunning JobStatus = "running" // JobStatusComplete means the job finished successfully. JobStatusComplete JobStatus = "complete" // JobStatusFailed means the job finished with an error. JobStatusFailed JobStatus = "failed" // JobStatusCancelled means the job was cancelled before completion. JobStatusCancelled JobStatus = "cancelled" )
type JobStore ¶
type JobStore struct {
// contains filtered or unexported fields
}
JobStore manages the lifecycle and storage of asynchronous jobs. It is safe for concurrent use.
Warning: JobStore has no built-in eviction. Jobs are stored indefinitely. For long-running servers, callers should periodically call JobStore.Delete to remove completed or expired jobs and prevent unbounded memory growth.
func NewJobStore ¶
func NewJobStore(opts ...JobStoreOption) *JobStore
NewJobStore creates a new job store.
func (*JobStore) Cancel ¶
Cancel transitions a job to cancelled status. Only jobs in pending or running state can be cancelled. Returns [errInvalidTransition] if the job is already in a terminal state.
Note: Cancel only updates the job's status in the store. It does not stop the background goroutine executing the handler (since the context is detached via context.WithoutCancel). The goroutine will run to completion but its result will be discarded because the store will reject the subsequent Complete/Fail transition. Callers who need cooperative cancellation should use the Sandbox middleware with a timeout or implement cancellation within the handler itself.
func (*JobStore) Complete ¶
func (js *JobStore) Complete(id string, result *CallToolResult) error
Complete transitions a job from running to completed status with the given result. Returns [errInvalidTransition] if the job is not in running state. Note: The store does not deep-copy StructuredContent. If you set StructuredContent, treat it as immutable after submission to avoid exposing shared mutable state.
func (*JobStore) Delete ¶
Delete removes a job from the store. Returns [errJobNotFound] if the job does not exist.
func (*JobStore) Fail ¶
Fail transitions a job from running to failed status with the given error message. Returns [errInvalidTransition] if the job is not in running state.
func (*JobStore) Get ¶
Get returns a copy of the job to prevent data races. Note: The Content slice is deep-copied, but StructuredContent is not. If StructuredContent holds a mutable reference (map, slice, pointer), callers may observe shared state. Treat StructuredContent as immutable after submission.
func (*JobStore) List ¶
List returns all jobs. The returned slice is a snapshot. Note: The Content slice is deep-copied, but StructuredContent is not. If StructuredContent holds a mutable reference (map, slice, pointer), callers may observe shared state. Treat StructuredContent as immutable after submission.
func (*JobStore) MarkRunning ¶
MarkRunning transitions a job from pending to running. Returns [errInvalidTransition] if the job is not in pending state.
type LifespanFunc ¶
LifespanFunc is a lifecycle hook called by Server.Start before the server begins handling requests. It receives the base context and the server instance, and returns an enriched context that is passed to all handlers. The returned cleanup function is called during shutdown to release resources.
Use this to initialize shared resources (database connections, caches, etc.) that tool handlers need via context values.
Example:
finemcp.WithLifespan(func(ctx context.Context, s *finemcp.Server) (context.Context, func(), error) {
db, err := sql.Open("postgres", dsn)
if err != nil {
return nil, nil, err
}
ctx = context.WithValue(ctx, dbKey, db)
return ctx, func() { db.Close() }, nil
})
type ListParams ¶
type ListParams struct {
Cursor string `json:"cursor,omitempty"`
Limit int `json:"limit,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
ListParams contains pagination parameters for any list request (tools/list, resources/list, prompts/list, resources/templates/list).
Cursor is an opaque server-defined token identifying the starting position for the page. Limit is the maximum number of items to return per page (default 50; clamped to 1000).
Backward compatibility: when both Cursor and Limit are omitted or zero-valued (e.g., {} or null params), the server returns the full unpaginated list. To request the first page with the default size, send {"limit": 50} explicitly, or any non-zero limit without a cursor.
When pagination is active, the server returns a window of items starting at the given cursor, limited to at most Limit items, along with a nextCursor in the response when more items are available.
type ListPromptsResult ¶
type ListPromptsResult struct {
Prompts []PromptInfo `json:"prompts"`
NextCursor string `json:"nextCursor,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
ListPromptsResult is the server's response to a "prompts/list" request.
type ListResourceTemplatesResult ¶
type ListResourceTemplatesResult struct {
ResourceTemplates []ResourceTemplateInfo `json:"resourceTemplates"`
NextCursor string `json:"nextCursor,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
ListResourceTemplatesResult is the server's response to a "resources/templates/list" request.
type ListResourcesResult ¶
type ListResourcesResult struct {
Resources []ResourceInfo `json:"resources"`
NextCursor string `json:"nextCursor,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
ListResourcesResult is the server's response to a "resources/list" request.
type ListRootsResult ¶
type ListRootsResult struct {
Roots []RootInfo `json:"roots"`
NextCursor string `json:"nextCursor,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
ListRootsResult is the server's response to a "roots/list" request.
type ListTasksResult ¶
type ListTasksResult struct {
Tasks []Task `json:"tasks"`
NextCursor string `json:"nextCursor,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
ListTasksResult is the response for tasks/list.
type ListToolsResult ¶
type ListToolsResult struct {
Tools []ToolInfo `json:"tools"`
NextCursor string `json:"nextCursor,omitempty"`
Meta map[string]any `json:"_meta,omitempty"`
}
ListToolsResult is the server's response to a "tools/list" request.
type LogHandler ¶
LogHandler is called when the client sends a logging/setLevel request. The handler receives the requested log level and can adjust logging behavior.
type LogLevel ¶
type LogLevel string
LogLevel represents the logging level for the server. Values follow RFC 5424 (syslog) severity levels as required by the MCP spec.
const ( LogLevelDebug LogLevel = "debug" // RFC 5424 severity 7 LogLevelInfo LogLevel = "info" // RFC 5424 severity 6 LogLevelNotice LogLevel = "notice" // RFC 5424 severity 5 LogLevelWarning LogLevel = "warning" // RFC 5424 severity 4 LogLevelError LogLevel = "error" // RFC 5424 severity 3 LogLevelCritical LogLevel = "critical" // RFC 5424 severity 2 LogLevelAlert LogLevel = "alert" // RFC 5424 severity 1 LogLevelEmergency LogLevel = "emergency" // RFC 5424 severity 0 )
LogLevel constants follow the RFC 5424 syslog severity levels as required by the MCP spec, ordered from least severe (debug) to most severe (emergency).
type LogMessageParams ¶
type LogMessageParams struct {
Level LogLevel `json:"level"`
Logger string `json:"logger,omitempty"`
Data any `json:"data"`
}
LogMessageParams is the server's payload for the "notifications/message" notification.
type LoggingCapability ¶
type LoggingCapability struct{}
LoggingCapability signals that the server supports logging/setLevel and may emit notifications/message notifications. Per the MCP spec, the capability is an empty object when present.
type MergeFunc ¶
MergeFunc receives the results of all parallel branches (keyed by handler name) and produces a single merged output. It is called in the goroutine that invoked the composed handler.
type Middleware ¶
type Middleware func(ToolHandler) ToolHandler
Middleware wraps a ToolHandler, adding cross-cutting behaviour (logging, recovery, auth, etc.) without modifying the handler itself.
Middleware is applied in registration order: the first middleware added via Server.Use is the outermost wrapper (executes first on the way in, last on the way out).
server.Use(logging, recovery) // call order: logging → recovery → handler → recovery → logging
type ModelHint ¶
type ModelHint struct {
// Name is a substring or full model identifier (e.g. "claude-4-sonnet").
Name string `json:"name,omitempty"`
}
ModelHint is a partial or full model name hint for model selection.
type ModelPreferences ¶
type ModelPreferences struct {
// Hints is an ordered list of model name hints (most preferred first).
// Each hint may contain a partial or full model name.
Hints []ModelHint `json:"hints,omitempty"`
// CostPriority indicates the relative importance of low cost (0–1).
// A nil value means unset; 0.0 is a valid explicit preference.
CostPriority *float64 `json:"costPriority,omitempty"`
// SpeedPriority indicates the relative importance of low latency (0–1).
// A nil value means unset; 0.0 is a valid explicit preference.
SpeedPriority *float64 `json:"speedPriority,omitempty"`
// IntelligencePriority indicates the relative importance of high
// capability (0–1). A nil value means unset; 0.0 is a valid explicit preference.
IntelligencePriority *float64 `json:"intelligencePriority,omitempty"`
}
ModelPreferences expresses the server's model selection preferences. Clients use these as hints when choosing which model to sample with.
type NamedHandler ¶
type NamedHandler struct {
Name string
Handler ToolHandler
}
NamedHandler pairs a handler with a name used as the key in the parallel result map. Names must be unique within a Parallel call.
type NotificationHandlerFunc ¶
type NotificationHandlerFunc func(ctx context.Context, params json.RawMessage)
NotificationHandlerFunc is called when a JSON-RPC notification with the registered method name is received. The params argument is the raw JSON from the notification's "params" field (nil when absent).
Handlers are called synchronously in registration order on the dispatcher goroutine. A slow handler blocks processing of subsequent handlers and the dispatch goroutine itself. If your handler performs I/O or heavy computation, launch a goroutine:
s.OnNotification("heavy/work", func(ctx context.Context, params json.RawMessage) {
go processAsync(ctx, params) // don't block the dispatch path
})
The context may be cancelled during handler execution. Long-running handlers should check ctx.Done() periodically and return early. Cancellation is only enforced between handlers, not mid-execution.
A panic in a handler is recovered — it does not crash the server or prevent subsequent handlers from running. If a NotificationPanicHandler is configured via WithNotificationPanicHandler, it is called with the recovered value and method name.
The handler function is retained for the lifetime of the server (or until Server.RemoveNotificationHandlers is called). Avoid capturing large objects in handler closures. If the handler needs access to large or changing state, fetch it on demand:
s.OnNotification("event", func(ctx context.Context, params json.RawMessage) {
data := getCurrentData() // fetch on-demand, don't capture
// ...
})
type NotificationPanicHandler ¶
NotificationPanicHandler is called when a notification handler panics. The method is the notification method name and recovered is the value returned by recover(). Implementations must not panic.
The handler runs synchronously on the dispatch goroutine. Keep it fast — avoid blocking I/O. For async error reporting, launch a goroutine:
func asyncPanicHandler(method string, recovered any) {
go uploadToErrorService(method, recovered)
}
The recovered value may contain attacker-controlled data if the panicking handler used unsanitized input. Implementations should sanitize before logging to prevent log injection:
func safePanicHandler(method string, recovered any) {
log.Printf("panic in %s: %T", method, recovered) // log type, not raw value
}
type NotificationSender ¶
type NotificationSender func(n *JSONRPCNotification)
NotificationSender is a function that transports implement to send server-side notifications (like notifications/progress) back to the client.
func NotificationSenderFromCtx ¶
func NotificationSenderFromCtx(ctx context.Context) NotificationSender
NotificationSenderFromCtx extracts the NotificationSender from the context. Returns nil if the transport does not support server-side notifications.
type ParallelResult ¶
type ParallelResult struct {
// Output holds the raw bytes returned by the branch handler.
// If the output is valid JSON it is embedded verbatim; otherwise it is
// encoded as a JSON string (via toJSONValue).
Output json.RawMessage `json:"output,omitempty"`
Error string `json:"error,omitempty"`
}
ParallelResult holds the output or error for a single branch of a parallel composition.
type PendingRequests ¶
type PendingRequests struct {
// contains filtered or unexported fields
}
PendingRequests tracks in-flight server-to-client requests, correlating outbound requests with their responses by JSON-RPC ID. Transports embed this to implement the RequestSender callback.
Usage in a transport:
- Create a PendingRequests via NewPendingRequests(writeFn).
- Pass pr.Send as the RequestSender to WithRequestSender.
- When reading messages from the client, check pr.IsResponse(data) and call pr.Deliver(data) for responses; forward non-responses to HandleMessage.
- Call pr.CloseAll() on transport shutdown.
func NewPendingRequests ¶
func NewPendingRequests(writeFn func(data []byte) error) *PendingRequests
NewPendingRequests creates a PendingRequests that writes outgoing requests via writeFn. The function must be safe for concurrent use.
func (*PendingRequests) CloseAll ¶
func (pr *PendingRequests) CloseAll()
CloseAll cancels all pending requests. Called on transport shutdown. After CloseAll, Send returns an error immediately.
func (*PendingRequests) Deliver ¶
func (pr *PendingRequests) Deliver(data []byte) bool
Deliver routes a client response to the pending request matching its ID. Returns true if the response was delivered, false if no pending request matches (e.g., the caller timed out already or the response is unexpected).
func (*PendingRequests) Send ¶
func (pr *PendingRequests) Send(ctx context.Context, method string, params any) (*JSONRPCResponse, error)
Send implements the RequestSender signature. It assigns a unique ID to the request, writes it to the client, and blocks until the client responds or the context expires.
type ProcessInfo ¶
type ProcessInfo struct {
Name string `json:"name"`
Version string `json:"version"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
WebsiteURL string `json:"websiteUrl,omitempty"`
Icons []Icon `json:"icons,omitempty"`
}
ProcessInfo identifies an MCP endpoint (client or server).
type ProgressParams ¶
type ProgressParams struct {
// ProgressToken correlates the notification with the originating request.
// When the client sends _meta.progressToken in the request, the server
// uses that value here; otherwise it defaults to the JSON-RPC request ID.
ProgressToken any `json:"progressToken"`
// Progress is the current progress value (e.g. number of items processed).
Progress float64 `json:"progress"`
// Total is the total expected value. When > 0, clients can show a percentage.
// Zero means indeterminate progress.
Total float64 `json:"total,omitempty"`
// Content holds optional content blocks embedded in this progress notification.
// Streaming-capable servers populate this field to allow clients to surface
// partial tool-result content before the final tools/call response arrives.
// This field is omitted by servers that do not support streaming; existing
// progress consumers are unaffected by its presence or absence.
Content []json.RawMessage `json:"content,omitempty"`
}
ProgressParams is the server's payload for the "notifications/progress" notification.
type ProgressReporter ¶
type ProgressReporter func(progress, total float64)
ProgressReporter is a function tool handlers call to emit a progress notification. progress is the current value; total is the expected final value (0 = indeterminate).
func ProgressReporterFromCtx ¶
func ProgressReporterFromCtx(ctx context.Context) ProgressReporter
ProgressReporterFromCtx extracts the ProgressReporter from the context. Returns nil if no reporter is set (progress reporting is a no-op in that case).
type Prompt ¶
type Prompt struct {
// Name is the unique identifier for this prompt.
Name string
// Description is an optional human-readable description.
Description string
// Arguments defines the expected parameters for this prompt.
Arguments []PromptArgument
// Handler generates the prompt messages.
Handler PromptHandler
// Completer provides argument auto-completions for this prompt.
// When nil, the server returns an empty completion result.
Completer CompleteHandler
}
Prompt represents a registered MCP prompt template.
func NewPrompt ¶
func NewPrompt(name string, handler PromptHandler, opts ...PromptOption) (*Prompt, error)
NewPrompt creates a new Prompt with the given name, handler, and options.
type PromptArgument ¶
type PromptArgument struct {
// Name is the argument identifier.
Name string `json:"name"`
// Description is an optional human-readable description.
Description string `json:"description,omitempty"`
// Required indicates whether this argument must be provided.
Required bool `json:"required,omitempty"`
}
PromptArgument describes a single argument accepted by a prompt.
type PromptCapability ¶
type PromptCapability struct {
// ListChanged indicates whether the server will emit prompts/list_changed notifications.
ListChanged bool `json:"listChanged,omitempty"`
}
PromptCapability describes the server's prompt-related capabilities.
type PromptHandler ¶
PromptHandler generates prompt messages for the given arguments. It receives the context and a map of argument values, and returns a slice of PromptMessage items.
type PromptInfo ¶
type PromptInfo struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Arguments []PromptArgument `json:"arguments,omitempty"`
}
PromptInfo is the wire representation of a prompt in a prompts/list response.
type PromptMessage ¶
type PromptMessage struct {
// Role is the speaker role: "user" or "assistant".
Role string `json:"role"`
// Content is the message content.
Content Content `json:"content"`
}
PromptMessage represents a single message in a prompt's output.
func NewAssistantMessage ¶
func NewAssistantMessage(text string) PromptMessage
NewAssistantMessage creates a PromptMessage with role "assistant" and text content.
func NewUserMessage ¶
func NewUserMessage(text string) PromptMessage
NewUserMessage creates a PromptMessage with role "user" and text content.
func (*PromptMessage) UnmarshalJSON ¶
func (m *PromptMessage) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes a PromptMessage, handling the Content interface field.
type PromptOption ¶
type PromptOption func(*Prompt)
PromptOption is a functional option for configuring a Prompt.
func WithCompleter ¶
func WithCompleter(handler CompleteHandler) PromptOption
WithCompleter attaches a CompleteHandler to a Prompt. When a client sends completion/complete for this prompt, the handler is invoked with the argument details.
func WithPromptArguments ¶
func WithPromptArguments(args ...PromptArgument) PromptOption
WithPromptArguments sets the prompt's expected arguments. The provided slice is copied to avoid aliasing with the caller's data.
func WithPromptDescription ¶
func WithPromptDescription(desc string) PromptOption
WithPromptDescription sets the prompt's human-readable description.
type ReadResourceParams ¶
type ReadResourceParams struct {
URI string `json:"uri"`
Meta map[string]any `json:"_meta,omitempty"`
}
ReadResourceParams is the client's payload for a "resources/read" request.
type ReadResourceResult ¶
type ReadResourceResult struct {
Contents []ResourceContent `json:"contents"`
Meta map[string]any `json:"_meta,omitempty"`
}
ReadResourceResult is the server's response to a "resources/read" request.
func ReadResourceResultFromText ¶
func ReadResourceResultFromText(uri, text string) *ReadResourceResult
ReadResourceResultFromText is a convenience for returning a single text resource.
func (ReadResourceResult) MarshalJSON ¶
func (r ReadResourceResult) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler. No custom logic needed, but having the method makes the intent explicit and prevents accidental breakage.
type RequestSender ¶
RequestSender is a function that transports implement to send a JSON-RPC request from the server to the client and wait for the client's response. This enables server-initiated requests such as sampling/createMessage.
The transport must:
- Assign an "id" to the outgoing request.
- Write the request to the client.
- Block until the client sends a JSON-RPC response with the matching "id".
- Return the response, or an error if the context expires / transport fails.
The context controls the deadline for the round-trip. Implementations should select on ctx.Done() while waiting for the client response.
func RequestSenderFromCtx ¶
func RequestSenderFromCtx(ctx context.Context) RequestSender
RequestSenderFromCtx extracts the RequestSender from the context. Returns nil if the transport does not support server-to-client requests.
type Resource ¶
type Resource struct {
// URI is the unique identifier for this resource (e.g. "file:///etc/hosts").
URI string
// Name is a human-readable name for the resource.
Name string
// Description is an optional human-readable description.
Description string
// MimeType is the MIME type of the resource content (e.g. "text/plain").
MimeType string
// Handler reads the resource content.
Handler ResourceHandler
}
Resource represents a registered MCP resource.
func NewResource ¶
func NewResource(uri, name string, handler ResourceHandler, opts ...ResourceOption) (*Resource, error)
NewResource creates a new Resource with the given URI, name, handler, and options.
type ResourceCapability ¶
type ResourceCapability struct {
// Subscribe indicates whether the server supports resource subscriptions.
Subscribe bool `json:"subscribe,omitempty"`
// ListChanged indicates whether the server will emit resources/list_changed notifications.
ListChanged bool `json:"listChanged,omitempty"`
}
ResourceCapability describes the server's resource-related capabilities.
type ResourceContent ¶
type ResourceContent struct {
// URI is the resource URI this content belongs to.
URI string `json:"uri"`
// MimeType is the MIME type of this content.
MimeType string `json:"mimeType,omitempty"`
// Text holds the text content (mutually exclusive with Blob).
Text *string `json:"text,omitempty"`
// Blob holds base64-encoded binary content (mutually exclusive with Text).
Blob *string `json:"blob,omitempty"`
}
ResourceContent represents the content of a resource. Exactly one of Text or Blob must be set.
func NewBlobResourceContent ¶
func NewBlobResourceContent(uri string, data []byte) ResourceContent
NewBlobResourceContent creates a binary resource content item. The data is base64-encoded automatically.
func NewTextResourceContent ¶
func NewTextResourceContent(uri, text string) ResourceContent
NewTextResourceContent creates a text resource content item.
func (ResourceContent) MarshalJSON ¶
func (c ResourceContent) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler for ResourceContent. It enforces that exactly one of Text or Blob is present in the output.
func (ResourceContent) Validate ¶
func (c ResourceContent) Validate() error
Validate checks that the ResourceContent is well-formed: URI must be non-empty and exactly one of Text or Blob must be set.
type ResourceHandler ¶
type ResourceHandler func(ctx context.Context, uri string) ([]ResourceContent, error)
ResourceHandler reads a resource identified by its URI. It receives the context and the resource URI, and returns a slice of ResourceContent items (text or blob).
type ResourceInfo ¶
type ResourceInfo struct {
URI string `json:"uri"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
MimeType string `json:"mimeType,omitempty"`
}
ResourceInfo is the wire representation of a resource in a resources/list response.
type ResourceOption ¶
type ResourceOption func(*Resource)
ResourceOption is a functional option for configuring a Resource.
func WithResourceDescription ¶
func WithResourceDescription(desc string) ResourceOption
WithResourceDescription sets the resource's human-readable description.
func WithResourceMimeType ¶
func WithResourceMimeType(mime string) ResourceOption
WithResourceMimeType sets the resource's MIME type.
type ResourceTemplate ¶
type ResourceTemplate struct {
// URITemplate is an RFC 6570 URI template.
URITemplate string
// Name is a human-readable name for the template.
Name string
// Description is an optional human-readable description.
Description string
// MimeType is the MIME type of the resource content.
MimeType string
// Handler reads the resource; the URI parameter is the expanded template.
Handler ResourceHandler
// Completer provides argument auto-completions for this template.
// When nil, the server returns an empty completion result.
Completer CompleteHandler
// contains filtered or unexported fields
}
ResourceTemplate represents a URI-template resource that can be parameterized at read time (e.g. "file:///logs/{date}.log").
When a client sends a resources/read request and no static resource matches the URI, the server tries each registered template in lexicographic URITemplate order and invokes the first matching handler with the concrete URI. Overlapping templates are not recommended; the winner depends on alphabetic order, which may be surprising.
func NewResourceTemplate ¶
func NewResourceTemplate(uriTemplate, name string, handler ResourceHandler, opts ...ResourceTemplateOption) (*ResourceTemplate, error)
NewResourceTemplate creates a new ResourceTemplate with the given URI template, name, handler, and options. It validates the template syntax at creation time, returning errTemplateInvalid for malformed or unsupported templates.
type ResourceTemplateInfo ¶
type ResourceTemplateInfo struct {
URITemplate string `json:"uriTemplate"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
MimeType string `json:"mimeType,omitempty"`
}
ResourceTemplateInfo is the wire representation in a resources/templates/list response.
type ResourceTemplateOption ¶
type ResourceTemplateOption func(*ResourceTemplate)
ResourceTemplateOption is a functional option for configuring a ResourceTemplate.
func WithTemplateCompleter ¶
func WithTemplateCompleter(handler CompleteHandler) ResourceTemplateOption
WithTemplateCompleter attaches a CompleteHandler to a ResourceTemplate. When a client sends completion/complete for this template, the handler is invoked with the argument details.
func WithTemplateDescription ¶
func WithTemplateDescription(desc string) ResourceTemplateOption
WithTemplateDescription sets the template's human-readable description.
func WithTemplateMimeType ¶
func WithTemplateMimeType(mime string) ResourceTemplateOption
WithTemplateMimeType sets the template's MIME type.
type ResourceUpdatedParams ¶
type ResourceUpdatedParams struct {
URI string `json:"uri"`
}
ResourceUpdatedParams is the server's payload for the "notifications/resources/updated" notification.
type Root ¶
type Root struct {
// URI is the unique identifier for this root (e.g. "file:///workspace/project").
// Must not be empty.
URI string
// Name is an optional human-readable name for the root (e.g. "Project Name").
// May be empty.
Name string
}
Root represents a workspace root directory that the server is aware of. Roots provide context about the server's workspace boundaries.
type RootOption ¶
type RootOption func(*Root)
RootOption is a functional option for configuring a Root.
func WithRootName ¶
func WithRootName(name string) RootOption
WithRootName sets the root's human-readable name.
type SamplingCapability ¶
type SamplingCapability struct{}
SamplingCapability signals that the client supports sampling/createMessage. Per the MCP spec, the capability is an empty object when present.
type SamplingMessage ¶
type SamplingMessage struct {
// Role is the speaker role: "user" or "assistant".
Role string `json:"role"`
// Content is the message content (text, image, or audio).
Content Content `json:"content"`
}
SamplingMessage represents a single message in a sampling request or response. It mirrors the MCP SamplingMessage schema.
func (SamplingMessage) MarshalJSON ¶
func (m SamplingMessage) MarshalJSON() ([]byte, error)
MarshalJSON marshals a SamplingMessage, delegating content serialization to the Content interface implementation.
func (*SamplingMessage) UnmarshalJSON ¶
func (m *SamplingMessage) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes a SamplingMessage, using DecodeContent for the polymorphic Content field.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the core MCP server that manages tool registration and dispatch. It is transport-agnostic; transports (stdio, HTTP/SSE) are layered on top.
func NewServer ¶
func NewServer(name, version string, opts ...ServerOption) *Server
NewServer creates a new MCP server with the given implementation name, version, and options.
func (*Server) AddSender ¶
func (s *Server) AddSender(id string, sender NotificationSender) error
AddSender registers a connection's NotificationSender for broadcasting list-changed events. It returns an error if id is empty, sender is nil, or a sender is already registered under id.
func (*Server) AddSessionTool ¶
AddSessionTool registers a tool that is visible only to the given session. The sessionID should match the SubscriberID used by the transport for that connection.
The ctx parameter is used for tenant-level validation: when a TenantResolver is active, the tool is checked against the resolved tenant's filter before registration. Pass context.Background() if no tenant filtering is needed.
Session tools overlay the global tool registry: if a session tool has the same name as a global tool, the session tool takes priority for that session. When this occurs, the server's SessionToolShadowCallback (if configured via OnSessionToolShadow) is invoked.
After a successful add, a notifications/tools/list_changed notification is sent to the affected session only (other sessions are not affected).
Returns an error if:
- the context is cancelled,
- the session has been closed (disconnected),
- the session ID is empty,
- the tool is nil/invalid or its name fails validation,
- a session tool with the same name is already registered,
- the per-session tool limit is exceeded,
- the tenant filter rejects the tool.
Safe for concurrent use.
func (*Server) CallTool ¶
CallTool looks up a tool by name and executes its handler. Session-specific tools take priority over global tools for the calling session (identified by SubscriberIDFromCtx). Returns errToolNotFound if no tool with the given name is registered, or if a TenantResolver is active and the tool is filtered out for the current tenant (indistinguishable from not found to prevent enumeration).
func (*Server) CreateMessage ¶
func (s *Server) CreateMessage(ctx context.Context, params CreateMessageParams) (*CreateMessageResult, error)
CreateMessage sends a sampling/createMessage request to the client and blocks until the client responds with an LLM-generated message.
This is a server-initiated request: the server asks the client to perform LLM inference on its behalf. The client must have declared sampling support in its capabilities during initialization.
The context controls the deadline for the entire round-trip. Tool handlers call this method when they need the LLM to make a decision mid-execution.
Prerequisites:
- The server must be initialized (initialize handshake completed).
- The client must have declared sampling capability (ClientCaps.Sampling != nil).
- The transport must provide a RequestSender via context.
Like other user-facing methods, CreateMessage is not wrapped with panic recovery by default. For production deployments, use a recovery middleware.
func (*Server) ElicitUser ¶
func (s *Server) ElicitUser(ctx context.Context, params ElicitationParams) (*ElicitationResult, error)
ElicitUser sends an elicitation/create request to the client and blocks until the user responds with input.
This is a server-initiated request: the server asks the client to prompt the user for input on its behalf. The client must have declared elicitation support in its capabilities during initialization.
The context controls the deadline for the entire round-trip.
Prerequisites:
- The server must be initialized (initialize handshake completed).
- The client must have declared elicitation capability (ClientCaps.Elicitation != nil).
- The transport must provide a RequestSender via context.
func (*Server) GetPrompt ¶
func (s *Server) GetPrompt(ctx context.Context, name string, args map[string]string) (*GetPromptResult, error)
GetPrompt looks up a prompt by name and invokes its handler. Returns errPromptNotFound if no prompt with the given name is registered or if a TenantResolver is active and the prompt is filtered out for the current tenant (indistinguishable from not found).
Security note: The maxPromptMessages limit (1000) is enforced AFTER the handler returns. Prompt handlers are trusted code and must not allocate excessive resources. This limit protects against accidental bugs in handlers, not malicious code. Handlers with prompt registration capability are part of the server's trusted computing base.
func (*Server) HandleMessage ¶
HandleMessage is the single entry point for all incoming JSON-RPC messages. It parses the raw bytes, routes to the correct method handler, and returns a JSON-RPC response. For notifications it returns nil (no response required). Protocol-level errors (bad JSON, unknown method) are returned as error responses, never as Go errors. The returned error is reserved for truly unrecoverable issues.
func (*Server) ListPrompts ¶
ListPrompts returns a snapshot of all registered prompts, sorted by name. Sorting ensures deterministic ordering for cursor-based pagination.
func (*Server) ListResourceTemplates ¶
func (s *Server) ListResourceTemplates() []*ResourceTemplate
ListResourceTemplates returns a snapshot of all registered resource templates, sorted by URI template. Sorting ensures deterministic ordering for cursor-based pagination.
func (*Server) ListResources ¶
ListResources returns a snapshot of all registered resources, sorted by URI. Sorting ensures deterministic ordering for cursor-based pagination.
func (*Server) ListTools ¶
ListTools returns a snapshot of all registered tools, sorted by name. The returned slice is a copy; mutating it does not affect the server. Sorting ensures deterministic ordering for cursor-based pagination.
func (*Server) NegotiatedVersion ¶
NegotiatedVersion returns the protocol version agreed upon during the initialize handshake. Returns "" if the handshake has not completed.
func (*Server) NotificationStats ¶
NotificationStats returns a point-in-time snapshot of registered notification handler counts keyed by method name. The snapshot is consistent (all counts from the same instant) but may become stale if handlers are added or removed after the call returns. The returned map is a copy and safe to mutate. Useful for debugging and monitoring.
Map iteration order is non-deterministic per Go semantics.
This is a server-wide view: in multi-tenant deployments the result includes methods from all tenants. Restrict access to trusted operators.
Allocates O(N) memory where N is the number of registered methods. Not intended for hot-path use.
func (*Server) NotifyPromptsListChanged ¶
func (s *Server) NotifyPromptsListChanged()
NotifyPromptsListChanged broadcasts notifications/prompts/list_changed to all connected clients.
func (*Server) NotifyResourceUpdated ¶
NotifyResourceUpdated notifies all subscribed clients that a resource has changed.
func (*Server) NotifyResourcesListChanged ¶
func (s *Server) NotifyResourcesListChanged()
NotifyResourcesListChanged broadcasts notifications/resources/list_changed to all connected clients.
func (*Server) NotifyRootsListChanged ¶
func (s *Server) NotifyRootsListChanged()
NotifyRootsListChanged broadcasts notifications/roots/list_changed to all connected clients.
func (*Server) NotifyToolsListChanged ¶
func (s *Server) NotifyToolsListChanged()
NotifyToolsListChanged broadcasts notifications/tools/list_changed to all connected clients.
func (*Server) OnNotification ¶
func (s *Server) OnNotification(method string, handler NotificationHandlerFunc)
OnNotification registers a handler for a JSON-RPC notification method. Multiple handlers can be registered for the same method — they are called in registration order. Handlers registered for built-in methods (e.g. "notifications/initialized", "notifications/cancelled") run after the server's built-in processing for that method.
Panics if method is empty, contains invalid characters, handler is nil, or the handler limit is exceeded.
Method names are validated for MCP protocol compliance. Do not use method names in file paths, shell commands, or SQL queries without additional sanitization.
Safe for concurrent use.
Example ¶
server := NewServer("myserver", "1.0")
// Register a handler for custom notifications.
server.OnNotification("custom/event", func(ctx context.Context, params json.RawMessage) {
var data map[string]any
if err := json.Unmarshal(params, &data); err != nil {
return
}
fmt.Printf("event: %v\n", data["type"])
})
// Multiple handlers for the same method run in registration order.
server.OnNotification("custom/event", func(ctx context.Context, params json.RawMessage) {
fmt.Println("second handler")
})
// Check registered handlers.
stats := server.NotificationStats()
fmt.Printf("handlers for custom/event: %d\n", stats["custom/event"])
Output: handlers for custom/event: 2
func (*Server) OnSessionToolShadow ¶
func (s *Server) OnSessionToolShadow(cb SessionToolShadowCallback)
OnSessionToolShadow registers a callback that is invoked when a session tool shadows a global tool with the same name. This is informational only; the registration proceeds regardless. Set to nil to disable.
The callback must be safe for concurrent use and should return quickly.
Safe to call concurrently; uses atomic storage internally.
func (*Server) ReadResource ¶
ReadResource looks up a resource by URI and invokes its handler. Returns errResourceNotFound if no resource or matching template with the given URI is registered, or if a TenantResolver is active and the item is filtered out for the current tenant (indistinguishable from not found).
func (*Server) RegisterPrompt ¶
RegisterPrompt adds a prompt to the server's registry. Returns an error if the prompt is nil, has missing required fields, or a prompt with the same name already exists.
func (*Server) RegisterResource ¶
RegisterResource adds a resource to the server's registry. Returns an error if the resource is nil, has missing required fields, or a resource with the same URI already exists.
func (*Server) RegisterResourceTemplate ¶
func (s *Server) RegisterResourceTemplate(t *ResourceTemplate) error
RegisterResourceTemplate adds a resource template to the server's registry. Returns an error if the template is nil, has a malformed URI template, or a template with the same URI already exists.
func (*Server) RegisterRoot ¶
RegisterRoot adds a root to the server's registry. Returns an error if the root is nil, URI is empty, or the URI is already registered.
func (*Server) RegisterTool ¶
RegisterTool adds a tool to the server's registry. The tool must not be nil, its name must be a valid MCP tool name (non-empty, ≤128 characters, only [A-Za-z0-9_\-.] allowed), and its Handler must not be nil.
Returns:
- errToolNil if tool is nil
- errToolNameEmpty, errToolNameTooLong, or errToolNameChars if the name is invalid
- errToolHandlerNil if the handler is nil
- errToolAlreadyExists if a tool with the same name is already registered
On success a notifications/tools/list_changed notification is broadcast to all connected clients.
func (*Server) RegisterTools ¶
RegisterTools registers multiple tools atomically and broadcasts a single notifications/tools/list_changed to all connected clients. Returns a validation or duplicate error on the first failing tool; on error, no tools from the batch are registered (all-or-nothing).
func (*Server) RemoveNotificationHandlers ¶
RemoveNotificationHandlers removes all handlers registered for the given notification method. Returns the number of handlers that were removed. This is useful for per-session cleanup patterns where handlers are registered and later torn down.
Removal is not retroactive: handlers for in-flight notifications that acquired the handler list before removal will still complete. For strict cleanup guarantees, cancel the session context before calling RemoveNotificationHandlers so that in-flight handlers observe cancellation.
Returns 0 for empty or oversized method names (which could never have been registered via Server.OnNotification).
Safe for concurrent use.
func (*Server) RemoveSender ¶
RemoveSender removes a connection's NotificationSender.
func (*Server) RemoveSessionTool ¶
RemoveSessionTool removes a session-specific tool by name. Returns errSessionToolNotFound if no such session tool exists.
After a successful removal, a notifications/tools/list_changed notification is sent to the affected session only.
Safe for concurrent use.
func (*Server) RemoveSessionTools ¶
RemoveSessionTools removes all session-specific tools for the given session and marks the session as closed. Subsequent AddSessionTool calls for this session will return errSessionClosed.
This should be called by transports when a client disconnects. It is safe to call even if the session has no tools.
Unlike Add/Remove, this does NOT send a list_changed notification since the session is being torn down.
Safe for concurrent use.
func (*Server) RemoveTool ¶
RemoveTool removes a tool from the server's registry. Returns errToolNotFound if no tool with the given name is registered. After a successful removal, a notifications/tools/list_changed notification is broadcast to all connected clients.
func (*Server) SendLogMessage ¶
SendLogMessage sends a notifications/message notification to the client with the provided log level and message data. Returns errNotInitialized if the handshake hasn't completed, since the protocol version and client capabilities are unknown until then.
func (*Server) SessionTools ¶
SessionTools returns a snapshot of tools registered for the given session, sorted by name. Does not include global tools. Returns nil if the session has no session-specific tools.
func (*Server) SetAuthChecker ¶
func (s *Server) SetAuthChecker(checker AuthChecker)
SetAuthChecker registers a protocol-level authentication checker. The checker is called for ALL JSON-RPC requests (except initialize and ping) after JSON-RPC parsing but before method routing. If it returns an error, the request is rejected with a JSON-RPC error response (code -32001).
This provides defense-in-depth: the HTTP middleware layer rejects unauthenticated connections, while the auth checker ensures every protocol message is associated with a verified identity.
Safe to call concurrently; uses atomic storage internally.
Usage:
server.SetAuthChecker(middleware.RequireAuth())
func (*Server) SetLogHandler ¶
func (s *Server) SetLogHandler(handler LogHandler)
SetLogHandler registers a handler for logging/setLevel requests. The handler is called when clients send logging/setLevel requests.
func (*Server) SetTenantResolver ¶
func (s *Server) SetTenantResolver(resolver TenantResolver)
SetTenantResolver registers a tenant resolution hook for multi-tenant isolation. The resolver is called for ALL JSON-RPC requests (except initialize and ping) after authentication but before method routing. If it returns an error, the request is rejected with a JSON-RPC error (code -32002).
This provides multi-tenant isolation: each request is associated with a tenant, and only that tenant's permitted tools, resources, and prompts are visible through list operations and accessible through call/read/get operations.
Safe to call concurrently; uses atomic storage internally.
Usage:
server.SetTenantResolver(middleware.NewTenantResolver(
middleware.TenantFromAuthSubject(),
middleware.NewStaticTenantStore(configs),
))
func (*Server) Shutdown ¶
Shutdown gracefully stops the server by waiting for in-flight requests to complete. If the context expires before all requests finish, it returns the context error.
Usage:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Println("shutdown timed out:", err)
}
func (*Server) Start ¶
Start runs the server's lifespan hook (if configured) and calls runFn. The lifespan hook is called before runFn to initialize shared resources; its cleanup function runs after runFn returns.
If no lifespan hook is configured, Start simply calls runFn(ctx).
This is the recommended way to run a transport with lifespan support:
server := finemcp.NewServer("app", "1.0",
finemcp.WithLifespan(func(ctx context.Context, s *finemcp.Server) (context.Context, func(), error) {
db, err := sql.Open("postgres", dsn)
if err != nil {
return nil, nil, err
}
return context.WithValue(ctx, dbKey, db), func() { db.Close() }, nil
}),
)
err := server.Start(ctx, func(ctx context.Context) error {
return transport.StartStreamable(ctx, server, ":8080")
})
func (*Server) Subscribe ¶
func (s *Server) Subscribe(subscriberID, uri string, sender NotificationSender) error
Subscribe adds a client's subscription to a specific resource URI. It returns [errSubscriptionsDisabled] if the server was not configured with WithResourceSubscriptions.
func (*Server) Unsubscribe ¶
Unsubscribe removes a client's subscription to a specific resource URI.
func (*Server) UnsubscribeAll ¶
UnsubscribeAll removes all subscriptions for a specific client connection. This should be called by transports when a client disconnects.
func (*Server) Use ¶
func (s *Server) Use(mw ...Middleware)
Use appends one or more middleware to the server's chain. Middleware are applied in the order they are added. Must be called before serving requests; not safe for concurrent use with CallTool.
type ServerCapabilities ¶
type ServerCapabilities struct {
Tools *ToolCapability `json:"tools,omitempty"`
Resources *ResourceCapability `json:"resources,omitempty"`
Prompts *PromptCapability `json:"prompts,omitempty"`
Tasks *TaskCapability `json:"tasks,omitempty"`
Completions *CompletionCapability `json:"completions,omitempty"`
Logging *LoggingCapability `json:"logging,omitempty"`
}
ServerCapabilities advertises what the server supports.
type ServerOption ¶
type ServerOption func(*Server)
ServerOption is a functional option for configuring a Server.
func WithIcons ¶
func WithIcons(icons ...Icon) ServerOption
WithIcons sets the server's icons. These are included in the serverInfo of the initialize response and can be used by clients (e.g. Claude Desktop) to display a visual representation of the server.
Panics if any icon has a Src URL with an unsafe scheme (only http, https, and data are allowed). Relative URLs and protocol-relative URLs are rejected. Data URLs must use an image/* MIME type.
func WithInstructions ¶
func WithInstructions(instructions string) ServerOption
WithInstructions sets optional instructions for the client. These are included in the initialize response and can guide client behavior.
Panics if the instructions string exceeds 100 KB.
func WithLifespan ¶
func WithLifespan(fn LifespanFunc) ServerOption
WithLifespan registers a lifecycle hook that is called by Server.Start before the server begins handling requests. The hook can initialize shared resources and enrich the context. The returned cleanup function is called during shutdown.
func WithMaxHandlersPerNotification ¶
func WithMaxHandlersPerNotification(n int) ServerOption
WithMaxHandlersPerNotification sets the maximum number of handlers that can be registered for a single notification method via OnNotification. The default is DefaultMaxHandlersPerMethod (100).
func WithMaxNotificationMethods ¶
func WithMaxNotificationMethods(n int) ServerOption
WithMaxNotificationMethods sets the maximum number of distinct notification methods that can have handlers registered via OnNotification. The default is DefaultMaxNotificationMethods (1000). Prevents unbounded memory growth from excessive handler registrations.
func WithMaxSessionTools ¶
func WithMaxSessionTools(n int) ServerOption
WithMaxSessionTools sets the maximum number of tools a single session can register via AddSessionTool. The default is DefaultMaxSessionTools (100). Use this to tune the limit for your deployment — lower values reduce memory exposure from misbehaving clients.
func WithMaxSessions ¶
func WithMaxSessions(n int) ServerOption
WithMaxSessions sets the maximum number of concurrent sessions that can register session tools. The default is DefaultMaxSessions (10,000). Prevents unbounded memory growth from rogue transport connections.
func WithNotificationPanicHandler ¶
func WithNotificationPanicHandler(h NotificationPanicHandler) ServerOption
WithNotificationPanicHandler registers a callback that is invoked whenever a notification handler panics. Without this option, panics are recovered and silently discarded. The callback receives the notification method name and the recovered value.
func WithResourceSubscriptions ¶
func WithResourceSubscriptions() ServerOption
WithResourceSubscriptions enables support for resource subscriptions. When enabled, the server advertises the "subscribe" capability, allowing clients to subscribe to resource updates.
func WithServerDescription ¶
func WithServerDescription(desc string) ServerOption
WithServerDescription sets the server's human-readable description. This is included in the serverInfo of the initialize response.
func WithServerTitle ¶
func WithServerTitle(title string) ServerOption
WithServerTitle sets the server's display name. This is included in the serverInfo of the initialize response and can be used by clients for display purposes.
func WithStreamBufferSize ¶
func WithStreamBufferSize(n int) ServerOption
WithStreamBufferSize sets the number of content chunks that a ToolStream can buffer before Send blocks, providing backpressure to the tool handler. The default is DefaultStreamBufferSize (16). Use a larger value for tools that produce many small chunks rapidly.
func WithSupportedVersions ¶
func WithSupportedVersions(versions ...string) ServerOption
WithSupportedVersions overrides the default set of MCP protocol versions that the server accepts during the initialize handshake. Versions must be in descending chronological order (latest first). The first entry is the server's preferred version and is returned when the client requests an unsupported version.
Panics if no versions are provided — at least one version is required. Panics if versions are not in descending order (YYYY-MM-DD strings). If not set, the server defaults to DefaultSupportedVersions().
func WithTaskStore ¶
func WithTaskStore(ts *TaskStore) ServerOption
WithTaskStore enables spec-compliant task support (tasks/get, tasks/result, tasks/cancel, tasks/list) and allows task-augmented tools/call requests. Panics if ts is nil.
func WithWebsiteURL ¶
func WithWebsiteURL(url string) ServerOption
WithWebsiteURL sets the server's website URL. This is included in the serverInfo of the initialize response.
type SessionToolShadowCallback ¶
type SessionToolShadowCallback func(sessionID, toolName string)
SessionToolShadowCallback is called when a session tool shadows a global tool with the same name. This is informational — the registration proceeds regardless. Implementations should be lightweight and safe for concurrent use.
type SetLevelParams ¶
type SetLevelParams struct {
Level LogLevel `json:"level"`
}
SetLevelParams is the client's payload for the "logging/setLevel" request.
type SetLevelResult ¶
type SetLevelResult struct{}
SetLevelResult is the server's response to a "logging/setLevel" request.
type SimulatorFunc ¶
SimulatorFunc is the function signature for a custom dry-run handler. It receives the same (ctx, input) as the real tool handler and should return a representative output describing what the tool would do.
A SimulatorFunc MUST NOT perform real side effects (e.g., database writes, HTTP calls to external services, file deletions). It must be safe for concurrent use — the server may invoke the same simulator from multiple goroutines simultaneously. Avoid mutable state or protect it with appropriate synchronization.
See middleware.Simulation and WithSimulator.
func ToolSimulatorFromCtx ¶
func ToolSimulatorFromCtx(ctx context.Context) SimulatorFunc
ToolSimulatorFromCtx extracts the tool's SimulatorFunc from the context. Returns nil if the tool has no custom simulator.
type StreamChunkData ¶
type StreamChunkData struct {
// Content is the JSON-encoded content chunk (e.g. TextContent, ImageContent).
Content json.RawMessage `json:"content"`
// Sequence is the 1-based ordinal of this chunk within the stream.
Sequence int64 `json:"sequence"`
}
StreamChunkData is the payload carried in the "data" field of a streaming progress notification. Clients that understand streaming read content chunks from this field; non-streaming clients simply ignore the extra field.
type SubscribeParams ¶
type SubscribeParams struct {
URI string `json:"uri"`
Meta map[string]any `json:"_meta,omitempty"`
}
SubscribeParams is the client's payload for "resources/subscribe" and "resources/unsubscribe" requests.
type Task ¶
type Task struct {
// TaskID is the unique identifier for this task.
TaskID string `json:"taskId"`
// Status is the current task state.
Status TaskStatus `json:"status"`
// StatusMessage is an optional human-readable message describing the
// current task state (e.g., error details for failed, reason for cancelled).
StatusMessage *string `json:"statusMessage,omitempty"`
// CreatedAt is an ISO 8601 timestamp when the task was created.
CreatedAt string `json:"createdAt"`
// LastUpdatedAt is an ISO 8601 timestamp when the task was last updated.
LastUpdatedAt string `json:"lastUpdatedAt"`
// TTL is the actual retention duration from creation in milliseconds.
// nil means unlimited retention.
TTL *int `json:"ttl"`
// PollInterval is the suggested polling interval in milliseconds.
PollInterval *int `json:"pollInterval,omitempty"`
}
Task is the MCP spec-compliant representation of an asynchronous task. It is returned in responses for tasks/get, tasks/cancel, tasks/list, and as part of CreateTaskResult for task-augmented tools/call.
type TaskCapability ¶
type TaskCapability struct {
// List indicates whether the server supports tasks/list.
List any `json:"list,omitempty"`
// Cancel indicates whether the server supports tasks/cancel.
Cancel any `json:"cancel,omitempty"`
// Requests specifies which request types can be augmented with tasks.
Requests *TaskRequestsCapability `json:"requests,omitempty"`
}
TaskCapability describes the server's task-related capabilities.
type TaskIdParams ¶
type TaskIdParams struct {
TaskID string `json:"taskId"`
Meta map[string]any `json:"_meta,omitempty"`
}
TaskIdParams is the wire format for requests that take a taskId (tasks/get, tasks/result, tasks/cancel).
type TaskMetadata ¶
type TaskMetadata struct {
TTL *int `json:"ttl,omitempty"`
}
TaskMetadata holds the parameters for creating a task, sent by the client in the "task" field of a task-augmented request.
type TaskOptions ¶
type TaskOptions struct {
TTL *int // retention duration in milliseconds; nil for unlimited
PollInterval *int // suggested polling interval in milliseconds
OwnerID string // session/connection that owns this task; used for access control
}
TaskOptions controls task creation behavior.
type TaskRequestsCapability ¶
type TaskRequestsCapability struct {
Tools *TaskToolsCapability `json:"tools,omitempty"`
}
TaskRequestsCapability describes which request types support task augmentation.
type TaskStatus ¶
type TaskStatus string
TaskStatus represents the lifecycle state of a task per the MCP specification.
const ( // TaskStatusWorking means the request is currently being processed. TaskStatusWorking TaskStatus = "working" // TaskStatusInputRequired means the task is waiting for input // (e.g., elicitation or sampling). TaskStatusInputRequired TaskStatus = "input_required" // TaskStatusCompleted means the request completed successfully and // results are available via tasks/result. TaskStatusCompleted TaskStatus = "completed" // TaskStatusFailed means the request did not complete successfully. TaskStatusFailed TaskStatus = "failed" // TaskStatusCancelled means the request was cancelled before completion. TaskStatusCancelled TaskStatus = "cancelled" )
type TaskStore ¶
type TaskStore struct {
// contains filtered or unexported fields
}
TaskStore manages the lifecycle and storage of spec-compliant MCP tasks. It is safe for concurrent use.
Warning: TaskStore has no built-in eviction. Tasks are stored indefinitely unless manually deleted via TaskStore.Delete. For long-running servers, callers should periodically delete completed/expired tasks.
func NewTaskStore ¶
func NewTaskStore(opts ...TaskStoreOption) *TaskStore
NewTaskStore creates a new task store.
func (*TaskStore) Cancel ¶
Cancel transitions a working task to cancelled. If a cancel function was registered (e.g., from a background goroutine), it is called to abort the in-flight work. Returns the updated task copy.
func (*TaskStore) Complete ¶
func (ts *TaskStore) Complete(id string, result *CallToolResult) error
Complete transitions a task from working to completed with the given result.
func (*TaskStore) Fail ¶
Fail transitions a task from working to failed with the given error message.
func (*TaskStore) GenerateID ¶
GenerateID returns a unique, cryptographically random task ID. The format is "task-" followed by 32 hex characters (128 bits of entropy). Safe for concurrent use.
func (*TaskStore) GetResult ¶
func (ts *TaskStore) GetResult(id string) (*CallToolResult, error)
GetResult returns the result of a completed task. Returns errTaskNotCompleted if the task is not in completed state.
func (*TaskStore) List ¶
List returns all tasks sorted by task ID (lexicographic order). Each task is a copy.
func (*TaskStore) ListByOwner ¶
ListByOwner returns tasks visible to the given owner, sorted by task ID. When ownerID is empty every task is returned (no filtering). A task is visible if it has no owner or its owner matches ownerID. Each task is a copy.
func (*TaskStore) SubmitWithOptions ¶
func (ts *TaskStore) SubmitWithOptions(id string, opts TaskOptions) (*Task, error)
SubmitWithOptions creates a new working task with the given options.
type TaskStoreOption ¶
type TaskStoreOption func(*TaskStore)
TaskStoreOption configures a TaskStore.
func WithMaxTasks ¶
func WithMaxTasks(n int) TaskStoreOption
WithMaxTasks sets the maximum number of tasks the store will hold. When the limit is reached, new submissions are rejected with an error. A value of 0 (the default) means unlimited.
type TaskToolsCapability ¶
type TaskToolsCapability struct {
Call any `json:"call,omitempty"`
}
TaskToolsCapability describes task support for tool-related requests.
type TenantResolver ¶
type TenantResolver func(ctx context.Context) (*ItemFilter, error)
TenantResolver resolves the request context into an ItemFilter that controls what the caller can see and access. It is called once per request by the dispatch layer, after authentication but before method routing.
The resolver should:
- Extract a tenant identifier from the context (e.g. from AuthInfo).
- Look up the tenant's configuration (allowed tools, resources, etc.).
- Return an *ItemFilter. Return nil to allow everything (no filtering).
If the resolver returns a non-nil error, the request is rejected with a JSON-RPC error response using ErrCodeTenantRequired (-32002). Error messages are scrubbed to a generic "tenant identification required" to prevent enumeration of valid tenant IDs.
The resolver must be safe for concurrent use from multiple goroutines.
type TextContent ¶
type TextContent struct {
Text string `json:"text"`
}
TextContent represents text provided to or from an LLM.
func (TextContent) MarshalJSON ¶
func (c TextContent) MarshalJSON() ([]byte, error)
MarshalJSON includes the "type" discriminator required by MCP wire format.
type Tool ¶
type Tool struct {
Name string
Description string
Handler ToolHandler
Simulator SimulatorFunc // optional dry-run handler for simulation middleware
Roles []string
InputSchema any
Annotations *ToolAnnotations // optional MCP tool annotations
SkipValidation bool // when true, validation middleware skips this tool
}
Tool is a registered MCP tool that the server exposes to clients. Create tools via NewTool or NewTypedTool; do not construct directly.
func NewTool ¶
func NewTool(name string, handler ToolHandler, opts ...ToolOption) (*Tool, error)
NewTool creates a Tool with the given name, handler, and options. The name must be 1–128 characters and may contain A–Z, a–z, 0–9, _, -, and . Returns an error if the name is invalid or the handler is nil. For strongly typed inputs/outputs, use NewTypedTool instead.
func NewTypedTool ¶
func NewTypedTool[In any, Out any](name string, handler TypedHandler[In, Out], opts ...ToolOption) (*Tool, error)
NewTypedTool creates a tool with a strongly typed handler. Input is automatically deserialized from JSON; output is serialized to JSON. A JSON Schema is auto-generated from the In type's struct fields and tags.
This is the recommended way to create tools — it provides compile-time type safety, removes JSON boilerplate, and auto-documents the input schema.
The auto-generated schema uses struct tags to control output:
- json:"name" → property name
- json:",omitempty" → marks the field as optional
- json:"-" → skips the field
- description:"..." → adds a "description" to the property
If WithInputSchema is also passed, it overrides the auto-generated schema.
Usage:
type GreetInput struct {
Name string `json:"name" description:"Name to greet"`
}
tool, err := finemcp.NewTypedTool("greet",
func(_ context.Context, in GreetInput) (string, error) {
return fmt.Sprintf("Hello, %s!", in.Name), nil
},
finemcp.WithDescription("Greets someone"),
)
type ToolAnnotations ¶
type ToolAnnotations struct {
// ReadOnlyHint indicates the tool does not modify any external state.
// A true value signals that the tool is safe to call speculatively.
ReadOnlyHint *bool `json:"readOnlyHint,omitempty"`
// DestructiveHint indicates the tool may perform irreversible operations
// (e.g., deleting data). Clients may use this to add confirmation prompts.
// Only meaningful when ReadOnlyHint is false or nil.
DestructiveHint *bool `json:"destructiveHint,omitempty"`
// IdempotentHint indicates that calling the tool repeatedly with the
// same arguments produces the same result. Clients may use this to
// enable automatic retries.
IdempotentHint *bool `json:"idempotentHint,omitempty"`
// Title is an optional human-readable title for the tool, used for
// display purposes (e.g., UI labels).
//
// This field is a common extension adopted by several MCP SDKs,
// complementing the base readOnlyHint/destructiveHint/idempotentHint
// triple defined in the MCP spec.
Title string `json:"title,omitempty"`
// OpenWorldHint indicates whether the tool accepts additional properties
// beyond those defined in its input schema. Default interpretation when
// nil is false (closed schema).
//
// This field is a common extension adopted by several MCP SDKs;
// it is not part of the base MCP 2025-11-25 annotations specification.
OpenWorldHint *bool `json:"openWorldHint,omitempty"`
}
ToolAnnotations contains optional hints that describe a tool's behavior to clients without affecting server-side execution. All fields use *bool so that nil ("unknown") is distinguishable from an explicit false.
Per MCP spec 2025-11-25, these are hints only — clients SHOULD NOT rely on them for correctness or security. Servers SHOULD set them accurately when the tool's behavior is known.
Note on contradictory hints: the library does not reject semantically conflicting combinations (e.g., ReadOnlyHint=true + DestructiveHint=true). It is the caller's responsibility to set consistent values; clients may exhibit undefined behavior when receiving contradictory hints.
type ToolCapability ¶
type ToolCapability struct {
// ListChanged indicates whether the server will emit tools/list_changed notifications.
ListChanged bool `json:"listChanged,omitempty"`
}
ToolCapability describes the server's tool-related capabilities.
type ToolHandler ¶
ToolHandler is a low-level tool handler that receives the raw JSON-encoded input bytes and returns raw JSON-encoded output bytes. Use NewTypedTool for a typed variant that handles JSON marshaling automatically.
func FanOutFanIn ¶
func FanOutFanIn(merge MergeFunc, handlers ...NamedHandler) ToolHandler
FanOutFanIn returns a ToolHandler that fans the input out to all named handlers concurrently, then passes all results through a merge function that produces the final output.
Like Parallel, all branches run to completion before the merge function is called. The merge function receives every branch's result (including errors) and decides how to combine them. If a handler panics, the panic is recovered and converted to an error for that branch. If the merge function panics, the panic is recovered and returned as an error.
All branches receive the same input slice. Handlers MUST NOT mutate the input bytes, as this would cause data races between goroutines.
At least one handler is required; FanOutFanIn panics otherwise.
Example:
merge := func(ctx context.Context, results map[string]ParallelResult) ([]byte, error) {
// combine results from all APIs
return json.Marshal(combined)
}
composed, _ := NewTool("unified_search",
FanOutFanIn(merge,
NamedHandler{Name: "api_a", Handler: apiA},
NamedHandler{Name: "api_b", Handler: apiB},
),
WithDescription("Query multiple APIs and merge results"),
)
func Parallel ¶
func Parallel(handlers ...NamedHandler) ToolHandler
Parallel returns a ToolHandler that executes all named handlers concurrently on the same input. The result is a JSON object mapping each name to its ParallelResult (output or error).
All branches run to completion — errors in one branch do not cancel others. If every branch fails, the composed handler returns an error. If a handler panics, the panic is recovered and converted to an error for that branch.
All branches receive the same input slice. Handlers MUST NOT mutate the input bytes, as this would cause data races between goroutines.
At least one handler is required; Parallel panics otherwise.
Example:
composed, _ := NewTool("multi_check",
Parallel(
NamedHandler{Name: "spell", Handler: spellCheck},
NamedHandler{Name: "grammar", Handler: grammarCheck},
),
WithDescription("Run spell and grammar checks concurrently"),
)
func Pipeline ¶
func Pipeline(first, second ToolHandler, rest ...ToolHandler) ToolHandler
Pipeline returns a ToolHandler that chains handlers sequentially. The output of each handler becomes the input of the next. Execution stops at the first error (fail-fast). If a handler panics, the panic is recovered and returned as an error, preventing execution of subsequent handlers.
At least two handlers are required; Pipeline panics otherwise.
Example:
fetch := fetchHandler()
transform := transformHandler()
validate := validateHandler()
composed, _ := NewTool("etl",
Pipeline(fetch, transform, validate),
WithDescription("Fetch → Transform → Validate"),
)
type ToolInfo ¶
type ToolInfo struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
InputSchema any `json:"inputSchema"`
Annotations *ToolAnnotations `json:"annotations,omitempty"`
}
ToolInfo is the wire representation of a tool in a tools/list response.
type ToolOption ¶
type ToolOption func(*Tool)
ToolOption is a functional option for configuring a Tool.
func WithAnnotations ¶
func WithAnnotations(a ToolAnnotations) ToolOption
WithAnnotations sets the full ToolAnnotations struct on the tool. Use this when you need to set multiple annotations at once.
func WithDescription ¶
func WithDescription(desc string) ToolOption
WithDescription sets the tool's human-readable description.
func WithDestructive ¶
func WithDestructive() ToolOption
WithDestructive marks the tool as destructive (may perform irreversible operations). Convenience shorthand for setting DestructiveHint = true.
func WithIdempotent ¶
func WithIdempotent() ToolOption
WithIdempotent marks the tool as idempotent (same input → same result). Convenience shorthand for setting IdempotentHint = true.
func WithInputSchema ¶
func WithInputSchema(schema any) ToolOption
WithInputSchema sets the JSON Schema defining the tool's expected input parameters. Accepts map[string]any, json.RawMessage, or any type that marshals to valid JSON Schema.
func WithOpenWorld ¶
func WithOpenWorld() ToolOption
WithOpenWorld marks the tool as accepting additional properties beyond those defined in its input schema.
func WithReadOnly ¶
func WithReadOnly() ToolOption
WithReadOnly marks the tool as read-only (does not modify external state). Convenience shorthand for setting ReadOnlyHint = true.
func WithRoles ¶
func WithRoles(roles ...string) ToolOption
WithRoles sets the roles required to execute this tool. Empty strings are silently filtered out. Roles are case-sensitive.
func WithSimulator ¶
func WithSimulator(fn SimulatorFunc) ToolOption
WithSimulator registers a custom dry-run handler for the tool. When the Simulation middleware is active and the client sends _meta.dryRun: true, this function is called instead of the real handler.
The simulator MUST NOT perform real side effects. It should return output in the same format the real handler uses (typically JSON) so that callers can parse it consistently. The simulator must be safe for concurrent use — see SimulatorFunc for details.
func WithTitle ¶
func WithTitle(title string) ToolOption
WithTitle sets the human-readable title annotation for display purposes.
func WithValidation ¶
func WithValidation(enabled bool) ToolOption
WithValidation controls whether input validation is enabled for this tool. By default validation is enabled (when the Validation middleware is in the chain). Pass false to skip validation for tools that accept arbitrary JSON.
type ToolStream ¶
type ToolStream struct {
// contains filtered or unexported fields
}
ToolStream delivers incremental content chunks to the client during tool execution via notifications/progress. Tool handlers obtain a stream from context using StreamFromCtx and call ToolStream.Send or ToolStream.SendText to push chunks; the final result is still returned normally from the handler.
Streaming is supported on stdio, WebSocket, SSE, and Streamable HTTP transports — all of which inject a NotificationSender into the context. Plain HTTP is the only transport where StreamFromCtx returns nil, as it has no persistent server-to-client channel.
Backpressure: Send blocks when the internal buffer is full. The buffer size defaults to DefaultStreamBufferSize (16) and can be changed with WithStreamBufferSize. Context cancellation unblocks a waiting Send.
Example:
tool, _ := finemcp.NewTool("tail-logs", func(ctx context.Context, input []byte) ([]byte, error) {
stream := finemcp.StreamFromCtx(ctx)
if stream == nil {
return []byte("streaming not supported"), nil
}
for line := range logLines(ctx) {
if err := stream.SendText(line); err != nil {
return nil, err
}
}
return []byte(`{"done":true}`), nil
})
func StreamFromCtx ¶
func StreamFromCtx(ctx context.Context) *ToolStream
StreamFromCtx extracts the ToolStream for the current tool call. Returns nil only for plain HTTP transport, which has no persistent server-to-client notification channel. Stdio, WebSocket, SSE, and Streamable HTTP all inject a NotificationSender and return a valid stream. Tool handlers should check for nil and fall back to returning the full result when streaming is unavailable.
func (*ToolStream) Send ¶
func (s *ToolStream) Send(c Content) error
Send delivers a content chunk to the client. It blocks if the internal buffer is full, providing backpressure to the tool handler. Returns nil on success, ErrStreamClosed if the stream was closed, or a context error if the context was cancelled.
The sequence number is assigned by the drain goroutine at dispatch time, so ToolStream.Sequence accurately reflects only the chunks that were actually delivered (not those dropped due to close or cancellation).
Send is safe for concurrent use by multiple goroutines.
func (*ToolStream) SendText ¶
func (s *ToolStream) SendText(text string) error
SendText is a convenience that sends a TextContent chunk.
func (*ToolStream) Sequence ¶
func (s *ToolStream) Sequence() int64
Sequence returns the number of chunks actually dispatched to the client. This can be used by the handler to track progress or include the count in the final result. The count only includes chunks that were dequeued and sent by the drain goroutine, not chunks still buffered or dropped.
type TypedHandler ¶
TypedHandler is a tool handler with strongly typed input and output. The framework automatically deserializes JSON input into In and serializes Out back to JSON, eliminating manual json.Unmarshal/Marshal boilerplate.
Example:
func greet(_ context.Context, in GreetInput) (string, error) {
return fmt.Sprintf("Hello, %s!", in.Name), nil
}
Source Files
¶
- async.go
- completion.go
- compose.go
- content.go
- context.go
- dispatch.go
- doc.go
- elicitation.go
- jsonrpc.go
- logging.go
- middleware.go
- notification_handler.go
- pending.go
- progress.go
- prompt.go
- protocol.go
- resource.go
- result.go
- roots.go
- sampling.go
- schema.go
- serve.go
- server.go
- session_tools.go
- stream.go
- task.go
- tool.go
- tool_validator.go
- typed_tool.go
- uritemplate.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package client provides a transport-agnostic MCP client SDK.
|
Package client provides a transport-agnostic MCP client SDK. |
|
transport/http
Package http provides a simple HTTP request-response transport for MCP.
|
Package http provides a simple HTTP request-response transport for MCP. |
|
transport/stdio
Package stdio provides a client-side stdio transport for MCP.
|
Package stdio provides a client-side stdio transport for MCP. |
|
transport/streamable
Package streamable provides a client-side Streamable HTTP transport for MCP.
|
Package streamable provides a client-side Streamable HTTP transport for MCP. |
|
transport/ws
Package ws provides a client-side WebSocket transport for MCP.
|
Package ws provides a client-side WebSocket transport for MCP. |
|
Package clienttest provides test helpers for code that uses the finemcp client SDK.
|
Package clienttest provides test helpers for code that uses the finemcp client SDK. |
|
cmd
|
|
|
finemcp
command
Command finemcp is the unified CLI for the FineMCP SDK.
|
Command finemcp is the unified CLI for the FineMCP SDK. |
|
examples
|
|
|
01-server/basic
command
Example: Basic MCP Server
|
Example: Basic MCP Server |
|
01-server/options
command
Example: Server Options
|
Example: Server Options |
|
02-tools/annotations
command
Example: Tool Annotations
|
Example: Tool Annotations |
|
02-tools/raw
command
Example: Raw Tool Handler
|
Example: Raw Tool Handler |
|
02-tools/session-tools
command
Example: Session-Scoped Tools
|
Example: Session-Scoped Tools |
|
02-tools/typed
command
Example: Typed Tools
|
Example: Typed Tools |
|
03-streaming
command
Example: Streaming Tool Responses
|
Example: Streaming Tool Responses |
|
04-resources/static
command
Example: Static Resources
|
Example: Static Resources |
|
04-resources/subscriptions
command
Example: Resource Subscriptions
|
Example: Resource Subscriptions |
|
04-resources/template
command
Example: Resource Templates
|
Example: Resource Templates |
|
05-prompts/basic
command
Example: Prompts
|
Example: Prompts |
|
05-prompts/completion
command
Example: Prompt Completion
|
Example: Prompt Completion |
|
06-sampling
command
Example: Sampling (Server-Initiated LLM Requests)
|
Example: Sampling (Server-Initiated LLM Requests) |
|
07-roots
command
Example: Roots
|
Example: Roots |
|
08-elicitation
command
Example: Elicitation (Server-Initiated User Prompts)
|
Example: Elicitation (Server-Initiated User Prompts) |
|
09-progress
command
Example: Progress Reporting
|
Example: Progress Reporting |
|
10-logging
command
Example: Server Logging
|
Example: Server Logging |
|
11-completion
command
Example: Auto-Completion
|
Example: Auto-Completion |
|
12-transports/http
command
Example: HTTP Transport
|
Example: HTTP Transport |
|
12-transports/sse
command
Example: SSE (Server-Sent Events) Transport
|
Example: SSE (Server-Sent Events) Transport |
|
12-transports/stdio
command
Example: Stdio Transport
|
Example: Stdio Transport |
|
12-transports/streamable
command
Example: Streamable HTTP Transport
|
Example: Streamable HTTP Transport |
|
12-transports/websocket
command
Example: WebSocket Transport
|
Example: WebSocket Transport |
|
13-middleware/async
command
Example: Async Middleware
|
Example: Async Middleware |
|
13-middleware/auditlog
command
Example: Audit Log Middleware
|
Example: Audit Log Middleware |
|
13-middleware/auth
command
Example: Authentication Middleware
|
Example: Authentication Middleware |
|
13-middleware/cache
command
Example: Cache Middleware
|
Example: Cache Middleware |
|
13-middleware/circuitbreaker
command
Example: Circuit Breaker Middleware
|
Example: Circuit Breaker Middleware |
|
13-middleware/costtracking
command
Example: Cost Tracking Middleware
|
Example: Cost Tracking Middleware |
|
13-middleware/logging
command
Example: Logging Middleware
|
Example: Logging Middleware |
|
13-middleware/multitenant
command
Example: Multi-Tenant Middleware
|
Example: Multi-Tenant Middleware |
|
13-middleware/otel
command
Example: OpenTelemetry Middleware
|
Example: OpenTelemetry Middleware |
|
13-middleware/ratelimit
command
Example: Rate Limit Middleware
|
Example: Rate Limit Middleware |
|
13-middleware/rbac
command
Example: RBAC Middleware
|
Example: RBAC Middleware |
|
13-middleware/recovery
command
Example: Recovery Middleware
|
Example: Recovery Middleware |
|
13-middleware/retry
command
Example: Retry Middleware
|
Example: Retry Middleware |
|
13-middleware/sandbox
command
Example: Sandbox Middleware
|
Example: Sandbox Middleware |
|
13-middleware/simulation
command
Example: Simulation Middleware
|
Example: Simulation Middleware |
|
13-middleware/validation
command
Example: Validation Middleware
|
Example: Validation Middleware |
|
14-testing
Package testing demonstrates how to use the mcptest package for in-process MCP server testing without a real network connection.
|
Package testing demonstrates how to use the mcptest package for in-process MCP server testing without a real network connection. |
|
15-content-types
command
Example: Content Types
|
Example: Content Types |
|
16-composition
command
Example: Tool Composition
|
Example: Tool Composition |
|
17-embedding
command
Example: Embedding MCP in an Existing HTTP Server
|
Example: Embedding MCP in an Existing HTTP Server |
|
18-example-apps/notes
command
Example: Notes App
|
Example: Notes App |
|
18-example-apps/smartwiki
command
Example: SmartWiki — Full-Featured Multi-Tenant Knowledge Base
|
Example: SmartWiki — Full-Featured Multi-Tenant Knowledge Base |
|
Package mcptest provides test helpers for MCP servers built with finemcp.
|
Package mcptest provides test helpers for MCP servers built with finemcp. |
|
Package middleware provides tool-level and transport-level middleware for finemcp MCP servers.
|
Package middleware provides tool-level and transport-level middleware for finemcp MCP servers. |
|
Package transport provides MCP transport implementations for finemcp.
|
Package transport provides MCP transport implementations for finemcp. |
