Documentation
¶
Index ¶
- Constants
- Variables
- func DefaultProtocolVersion(configured string) string
- func IsSupportedProtocolVersion(version string) bool
- func RecoverDispatch(reqID any, site, toolHint string, sink PanicResponseSink)
- func WithNotifier(ctx context.Context, n Notifier) context.Context
- func WithProgressToken(ctx context.Context, token ProgressToken) context.Context
- type AuditLogMode
- type AuditLogger
- type InitializeParams
- type InvalidParamsError
- type Notifier
- type PanicResponseSink
- type ProgressGate
- type ProgressToken
- type Prompt
- type PromptArgument
- type PromptMessage
- type PromptMessagePart
- type RPCError
- type Request
- type RequestMeta
- type Resource
- type ResourceContents
- type ResourceProvider
- type ResourceTemplate
- type ResourceUpdateDelta
- type Response
- type RiskClass
- type RiskRateLimits
- type Server
- func (s *Server) AddNotifier(n Notifier) func()
- func (s *Server) AllowProgress(token any, progress float64) bool
- func (s *Server) ClientInfo() (name, version string)
- func (s *Server) ConfigureRiskRateLimits(limits RiskRateLimits)
- func (s *Server) ConfigureToolLimits(ratePerMinute int)
- func (s *Server) DispatchMessage(ctx context.Context, msg []byte) ([]byte, error)
- func (s *Server) HandleWithRecover(ctx context.Context, req Request, site string) (resp Response)
- func (s *Server) HasResourceSubscription(uri string) bool
- func (s *Server) InFlightToolCalls() int
- func (s *Server) InflightCount() int
- func (s *Server) MarkInitialized(protocolVersion, clientName, clientVersion string)
- func (s *Server) Notify(method string, params any) error
- func (s *Server) NotifyResourceUpdated(uri string, delta ResourceUpdateDelta)
- func (s *Server) NotifyResourcesListChanged()
- func (s *Server) Run(ctx context.Context, r io.Reader, w io.Writer) (retErr error)
- func (s *Server) SetAdvertisedTools(advertised []ToolDescriptor)
- func (s *Server) SetNotifier(n Notifier)
- type Tool
- type ToolCallParams
- type ToolDescriptor
- type ToolHandler
- type UnknownToolError
Constants ¶
const ( RPCCodeSessionInvalid = -32001 RPCCodeServerNotInitialized = -32002 RPCCodeOriginNotAllowed = -32010 RPCCodeHostNotAllowed = -32011 RPCCodeRateLimited = -32012 RPCCodeRequestTooLarge = -32013 RPCCodeSessionPrincipal = -32014 RPCCodeMethodNotAllowed = -32015 RPCCodeUnauthenticated = -32020 RPCCodeForbidden = -32021 )
JSON-RPC error codes used by this server. The standard codes (-32600..-32603, -32700) come from the spec; the server-specific codes below occupy the implementation-defined range for session, transport, and authorization failures.
const DefaultToolsListPageSize = 80
DefaultToolsListPageSize is the page size used for paginated tools/list responses when the client does not request a specific cursor page.
const RiskHighMask = RiskBilling | RiskAdmin | RiskPermissionChange | RiskExternalSideEffect | RiskDestructive
RiskHighMask is retained as metadata for clients that want to visually distinguish billing, admin, external-side-effect, and destructive tools.
const ServerInstructions = `` /* 220-byte string literal not displayed */
ServerInstructions is returned in the initialize response to teach MCP clients how to use the one-user/full-access product path.
Variables ¶
var SupportedProtocolVersions = []string{
"2025-11-25",
"2025-06-18",
"2025-03-26",
"2024-11-05",
}
SupportedProtocolVersions lists MCP protocol versions this server can negotiate, newest first. The first entry is returned as the default when the client does not send a protocolVersion unless an operator configures a per-server default. When a client requests an unsupported version, we echo back the newest supported version — clients that cannot downgrade will treat that as an error and disconnect, which is the spec-compliant behaviour.
Functions ¶
func DefaultProtocolVersion ¶
DefaultProtocolVersion returns configured when it is a supported version, otherwise the newest supported version. Used to pick the version advertised when a client's initialize omits protocolVersion.
func IsSupportedProtocolVersion ¶
IsSupportedProtocolVersion reports whether version (trimmed) is one of the MCP protocol versions this server can negotiate.
func RecoverDispatch ¶
func RecoverDispatch(reqID any, site, toolHint string, sink PanicResponseSink)
RecoverDispatch is the deferred function that wraps a tool dispatch goroutine. It recovers a panic, emits a structured log event, and (when a panic was caught) hands a stable JSON-RPC tool-error envelope to sink. No-op when the dispatch returns normally.
Usage at the tool-dispatch site:
defer mcp.RecoverDispatch(reqID, "stdio_tool_dispatch", toolName, sink) resp := s.handle(ctx, r) ...
recover() works here because RecoverDispatch IS the deferred function — `defer fn(...)` calls fn at defer-pop time, and recover() inside fn sees the panic. Wrapping this in an IIFE at the call site (`defer func(){ RecoverDispatch(...) }()`) would break that invariant.
func WithNotifier ¶
WithNotifier returns a child context carrying n as the calling peer's Notifier. The stdio loop calls this once per session after AddNotifier so the resources/subscribe handler attributes the subscription correctly. Passing a nil Notifier yields the parent context unchanged.
func WithProgressToken ¶
func WithProgressToken(ctx context.Context, token ProgressToken) context.Context
WithProgressToken attaches the client-supplied progressToken (if any) to ctx so downstream tool handlers can emit notifications/progress keyed off the same value.
Types ¶
type AuditLogMode ¶ added in v0.4.0
type AuditLogMode string
AuditLogMode selects which tool invocations the AuditLogger records.
const ( AuditLogModeOff AuditLogMode = "off" AuditLogModeSideEffectsOnly AuditLogMode = "side_effects_only" AuditLogModeAll AuditLogMode = "all" )
Audit log modes: Off disables the logger, SideEffectsOnly records only write/high-risk tools, and All records every tool call.
type AuditLogger ¶ added in v0.4.0
type AuditLogger struct {
// contains filtered or unexported fields
}
AuditLogger appends JSON-lines audit records for tool invocations to a local file, rotating it once it exceeds maxAuditLogBytes. It records only a redacted workspace-ID suffix, never the full ID. A nil *AuditLogger is a valid no-op receiver.
func NewAuditLogger ¶ added in v0.4.0
func NewAuditLogger(path string, mode AuditLogMode, workspaceID string) (*AuditLogger, error)
NewAuditLogger returns an AuditLogger writing to path in the given mode, recording only a redacted suffix of workspaceID. It returns (nil, nil) when path is empty or mode is off, so callers can treat the result as an always-valid (possibly no-op) logger.
func (*AuditLogger) Close ¶ added in v0.4.0
func (l *AuditLogger) Close() error
Close releases any resources held by the logger. The file-per-record design keeps no open handle, so Close is currently a no-op that satisfies io.Closer.
func (*AuditLogger) Record ¶ added in v0.4.0
func (l *AuditLogger) Record(descriptor ToolDescriptor, args map[string]any, result, errorCode string) error
Record writes an audit entry for a tool invocation with no confirmation metadata. It is a thin wrapper over RecordWithConfirmation.
func (*AuditLogger) RecordWithConfirmation ¶ added in v0.4.0
func (l *AuditLogger) RecordWithConfirmation(descriptor ToolDescriptor, args map[string]any, result, errorCode string, confirmation map[string]any) error
RecordWithConfirmation appends one audit record for the given tool, filtering by mode (side-effects-only skips non-write, non-high-risk tools). It captures only the descriptor's allow-listed AuditKeys from args, the dry-run flag, and any high-risk confirmation metadata. A nil logger or off mode is a no-op.
type InitializeParams ¶
type InitializeParams struct {
ProtocolVersion string `json:"protocolVersion,omitempty"`
Capabilities map[string]any `json:"capabilities,omitempty"`
ClientInfo map[string]any `json:"clientInfo,omitempty"`
Meta *RequestMeta `json:"_meta,omitempty"`
}
InitializeParams is the params payload of an MCP initialize request: the client's requested protocol version, advertised capabilities, and client info, plus optional _meta.
type InvalidParamsError ¶
InvalidParamsError is returned by the tools/call dispatch when a tool's input arguments fail runtime JSON-schema validation. The dispatch translates it into a JSON-RPC -32602 (invalid params) response, with Pointer exposed under error.data.pointer so clients can locate the offending field.
Pointer is an RFC 6901 JSON Pointer (e.g. "/workspace_id"). An empty pointer means the root value itself was rejected.
func (*InvalidParamsError) Error ¶
func (e *InvalidParamsError) Error() string
type Notifier ¶
Notifier delivers server-initiated notifications (e.g. tools/list_changed) to the connected client. The stdio transport implements this by writing through the shared JSON encoder.
type PanicResponseSink ¶
type PanicResponseSink func(Response)
PanicResponseSink receives the JSON-RPC response built from a recovered panic. Callers supply a sink that pushes the response onto the wire (writeResponse for stdio; embedders supply their own).
type ProgressGate ¶ added in v0.2.0
ProgressGate decides whether a notifications/progress for a token at a given progress value may be sent. *Server implements it; Service.EmitProgress consults it so non-increasing or flooding progress is dropped at the source.
type ProgressToken ¶
type ProgressToken = any
ProgressToken is the opaque client-supplied token echoed back on every notifications/progress. Either a string or a number per the MCP spec.
func ProgressTokenFromContext ¶
func ProgressTokenFromContext(ctx context.Context) (ProgressToken, bool)
ProgressTokenFromContext returns the progressToken supplied in the current tools/call _meta, or (nil, false) when the client did not opt in.
type Prompt ¶
type Prompt struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Arguments []PromptArgument `json:"arguments,omitempty"`
Messages []PromptMessage `json:"messages"`
}
Prompt is a registered prompt template with canned messages whose bodies may contain `{{name}}` placeholders substituted at prompts/get time.
type PromptArgument ¶
type PromptArgument struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Required bool `json:"required,omitempty"`
}
PromptArgument describes one substitution variable a prompt accepts.
type PromptMessage ¶
type PromptMessage struct {
Role string `json:"role"`
Content PromptMessagePart `json:"content"`
}
PromptMessage is one turn in a prompt's canned message sequence. Role is typically "user" or "assistant"; content mirrors the MCP content-part shape.
type PromptMessagePart ¶
PromptMessagePart is a single content part inside a PromptMessage. Only text content is supported in this server; clients that want images or resource links can request a richer prompt via a follow-up tool call.
type RPCError ¶
type RPCError struct {
Code int `json:"code"`
Message string `json:"message"`
Data map[string]any `json:"data,omitempty"`
}
RPCError is the JSON-RPC 2.0 error object carried in Response.Error. Data holds optional machine-readable details (e.g. a JSON Pointer for invalid params).
type Request ¶
type Request struct {
JSONRPC string `json:"jsonrpc"`
ID any `json:"id,omitempty"`
Method string `json:"method"`
Params any `json:"params,omitempty"`
}
Request is a decoded JSON-RPC 2.0 request or notification on the stdio transport. A nil ID marks a notification (no response is written).
type RequestMeta ¶
type RequestMeta struct {
ProgressToken any `json:"progressToken,omitempty"`
}
RequestMeta is the MCP _meta object that can attach side-channel hints to any request. progressToken is the only field used today — clients supply one to opt into notifications/progress from long-running tool handlers.
type Resource ¶
type Resource struct {
URI string `json:"uri"`
Name string `json:"name"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
MimeType string `json:"mimeType,omitempty"`
}
Resource describes a concrete, static MCP resource. Dynamic (parametric) resources should be surfaced via ResourceTemplate instead.
type ResourceContents ¶
type ResourceContents struct {
URI string `json:"uri"`
MimeType string `json:"mimeType,omitempty"`
Text string `json:"text,omitempty"`
Blob string `json:"blob,omitempty"`
}
ResourceContents is one chunk of resource body. Text and Blob are mutually exclusive — text/* content uses Text, binary content uses base64 in Blob.
type ResourceProvider ¶
type ResourceProvider interface {
ListResources(ctx context.Context) ([]Resource, error)
ListResourceTemplates(ctx context.Context) ([]ResourceTemplate, error)
ReadResource(ctx context.Context, uri string) ([]ResourceContents, error)
}
ResourceProvider backs the MCP resources/* method family. Implementations live outside the protocol core (tools.Service implements it for Clockify). A nil ResourceProvider on Server means the resources capability is off.
type ResourceTemplate ¶
type ResourceTemplate struct {
URITemplate string `json:"uriTemplate"`
Name string `json:"name"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
MimeType string `json:"mimeType,omitempty"`
}
ResourceTemplate describes a parametric MCP resource using RFC 6570 URI template syntax — e.g. `clockify://workspace/{workspaceId}/entry/{entryId}`.
type ResourceUpdateDelta ¶
type ResourceUpdateDelta struct {
// Format is one of FormatNone / FormatMerge / FormatFull /
// FormatDeleted. Empty means do not emit a delta envelope — legacy
// payload shape {"uri": "..."} is used.
Format string
// Patch is the wire-format payload for FormatMerge / FormatFull. It
// is emitted verbatim under the "patch" key. Pre-decoded (already
// a Go value) so marshalling the notification doesn't require a
// re-parse step.
Patch any
}
ResourceUpdateDelta carries the optional delta envelope the server can attach to a notifications/resources/updated payload. When Format is empty the legacy payload shape is emitted ({"uri": ...}); otherwise the envelope is merged into the notification params so MCP clients can apply a minimal JSON Merge Patch (RFC 7396) against their cached resource state instead of re-fetching the whole document.
Format values are defined in internal/jsonmergepatch (FormatNone / FormatMerge / FormatFull / FormatDeleted). The protocol core does not interpret them; it passes the envelope through to the notifier. Format validation and payload shape are the tools-layer caller's responsibility.
This extension is additive and backwards compatible: clients that only read the `uri` field keep working. No MCP protocol version bump is required.
type Response ¶
type Response struct {
JSONRPC string `json:"jsonrpc"`
ID any `json:"id,omitempty"`
Method string `json:"method,omitempty"`
Result any `json:"result,omitempty"`
Error *RPCError `json:"error,omitempty"`
}
Response is a JSON-RPC 2.0 response (or notification, when Method is set and ID is empty). Exactly one of Result or Error is populated for a reply.
type RiskClass ¶
type RiskClass uint32
RiskClass categorises tools beyond the three MCP boolean hints. It is a bitmask so a tool can carry multiple attributes (for example a billing action that also triggers an external side effect). Consumers can pattern-match against bits for logging, filtering, or UX hints.
const ( RiskRead RiskClass = 1 << iota // safe, idempotent reads RiskWrite // ordinary mutating writes RiskSensitiveRead // reads users, invoices, balances, webhooks, or similar sensitive state RiskBilling // touches invoices / payments RiskAdmin // workspace-admin scope (deactivate, group/user mgmt) RiskPermissionChange // role / permission changes RiskExternalSideEffect // triggers outbound delivery (email, webhook test) RiskDestructive // irreversible delete-style operations )
Risk-class bits. Each value occupies one bit so a tool's RiskClass can combine several attributes; see RiskHighMask for the high-risk subset.
func (RiskClass) IsHighRisk ¶
IsHighRisk reports whether any high-risk metadata bit is set.
type RiskRateLimits ¶ added in v0.4.0
type RiskRateLimits struct {
ReadPerMinute int
WritePerMinute int
BillingAdminPerMinute int
DestructivePerMinute int
}
RiskRateLimits configures per-minute invocation ceilings for tools grouped by risk tier. A zero or negative value for any field disables the limit for that tier.
type Server ¶
type Server struct {
Version string
ToolTimeout time.Duration // per-call timeout; 0 = default 45s
// DefaultProtocolVersion is used only when initialize omits
// params.protocolVersion. Empty or unsupported values fall back to
// SupportedProtocolVersions[0]; explicit supported client requests still win.
DefaultProtocolVersion string
// ResourceProvider backs resources/* method handlers. nil disables the
// resources capability (server omits it from initialize.result.capabilities).
ResourceProvider ResourceProvider
// MaxInFlightToolCalls bounds the number of concurrently-running
// tools/call goroutines spawned by the stdio dispatch loop.
// Acquired before the goroutine is created so bursty input cannot
// amplify goroutine count. 0 = unlimited.
MaxInFlightToolCalls int
MaxMessageSize int64
// MaxToolResultBytes caps a successful tools/call result before it is
// placed in the MCP content envelope. 0 disables the cap.
MaxToolResultBytes int
// AuditLogger optionally appends local redacted JSONL records for tool
// calls. Nil disables durable audit logging.
AuditLogger *AuditLogger
// ConfirmationStore issues short-lived local confirmation tokens for
// high-risk tool dry-runs. Nil leaves confirmation enforcement disabled
// for tests and embedders that have not opted in.
ConfirmationStore *safety.TokenStore
// WorkspaceIDForSafety binds confirmation tokens to the pinned workspace
// without exposing the ID in the token.
WorkspaceIDForSafety string
// ConfirmationMode is "required" by default when ConfirmationStore is set.
// "disabled_for_local_dev" bypasses enforcement for explicit local tests.
ConfirmationMode string
// EnforceAdvertisedTools makes SetAdvertisedTools an authorization
// boundary for tools/call. Leave false for explicit full-registry modes.
EnforceAdvertisedTools bool
// StaticToolList keeps tools.listChanged out of initialize for products
// that load their complete registry at startup and never mutate tool
// availability during a session.
StaticToolList bool
// ToolsListPageSize controls cursor pagination for tools/list. Values <= 0
// use DefaultToolsListPageSize; set a larger value in tests or embedders
// that intentionally need the complete advertised surface in one response.
ToolsListPageSize int
// contains filtered or unexported fields
}
Server is the MCP protocol engine for the stdio transport. It holds the tool registry, optional resource/prompt providers, per-call concurrency and size limits, rate limits, and the audit logger, and drives the JSON-RPC read/dispatch/write loop. Configure exported fields before Run; the unexported state is managed internally and guarded by mu.
func NewServer ¶
func NewServer(version string, descriptors []ToolDescriptor) *Server
NewServer builds a Server with the given version string and tool registry, indexing the descriptors by tool name and wiring default internal state (in-flight tracking, prompt registry). Configure the exported policy fields on the returned Server before calling Run.
func (*Server) AddNotifier ¶
AddNotifier registers a notification sink and returns a function that removes it. Multiple notifiers can coexist; Notify fans out to all of them.
func (*Server) AllowProgress ¶ added in v0.2.0
AllowProgress reports whether a progress notification for token at the given progress value should be emitted. It returns false when the token is not registered (the call finished or was cancelled), when progress does not strictly increase, or when the per-second flood cap is exceeded.
func (*Server) ClientInfo ¶
ClientInfo returns the client name and version sent during initialize.
func (*Server) ConfigureRiskRateLimits ¶ added in v0.4.0
func (s *Server) ConfigureRiskRateLimits(limits RiskRateLimits)
ConfigureRiskRateLimits installs per-risk-tier rate limiting for tool calls, replacing any previously configured limiter. Call before Run.
func (*Server) ConfigureToolLimits ¶ added in v0.2.0
ConfigureToolLimits installs the optional per-process tool-invocation rate limiter when ratePerMinute > 0. The per-risk-family concurrency caps are installed unconditionally by NewServer and are intentionally not touched here, so a Server always serializes high-risk writes even when rate limiting is disabled (CLOCKIFY_TOOL_RATE_LIMIT_PER_MINUTE defaults to 0).
func (*Server) DispatchMessage ¶
DispatchMessage parses a single JSON-RPC message from raw bytes, invokes the central handler, and returns the serialized response. It is intended for embedders that own their own concurrency model and framing.
Parse and validation errors are converted to JSON-RPC error responses mirroring the stdio loop. A notification (no id, no result, no error) returns (nil, nil); the caller must skip sending on the wire in that case.
This method does NOT apply the stdio dispatch-layer toolCallSem. Callers that need backpressure on tools/call must implement their own bound.
func (*Server) HandleWithRecover ¶
HandleWithRecover invokes handle with structured panic recovery. Used by embedders whose dispatch goroutines do not own a higher- level recovery wrapper — stdio's loop has its own RecoverDispatch deferred at the goroutine boundary in Run.
site is the metric/log label that lets operators distinguish where a panic originated. Returns the stable JSON-RPC tool-error response when a panic was recovered; otherwise the handler's normal Response.
Why a named-return wrapper: recover() only sees the panic when called by the deferred function directly; the sink callback then writes the panic envelope into the named return variable so the caller observes the structured response rather than the zero value. RecoverDispatch handles metric increment + slog event.
func (*Server) HasResourceSubscription ¶
HasResourceSubscription reports whether any client is currently subscribed to uri. The tool layer calls this before re-reading a resource in emitResourceUpdate so unsubscribed mutations don't pay for a redundant ReadResource round-trip. Coarse by design — it answers "does anyone want this URI?" so the read is skipped when nobody does; the per-stream filter that prevents cross-talk happens inside NotifyResourceUpdated.
func (*Server) InFlightToolCalls ¶
InFlightToolCalls reports the current depth of the stdio dispatch semaphore. Returns 0 when the semaphore is disabled.
func (*Server) InflightCount ¶
InflightCount returns the number of tracked in-flight tools/call requests. Used by tests to verify the map is cleaned up.
func (*Server) MarkInitialized ¶
MarkInitialized seeds a freshly-built Server with the negotiated state it would normally obtain from a live `initialize` exchange. Tests and embedders use this to skip the handshake; idempotent — calling it twice with the same values is a no-op.
protocolVersion may be empty (pre-2025-03-26 client); ClientInfo fields are best-effort. The initialized flag is set unconditionally because the caller's contract is that the server is ready to dispatch tool calls; lacking protocolVersion just means the negotiated-version check degrades to "accept any supported version".
func (*Server) Notify ¶
Notify forwards a server-initiated notification through all registered notifiers. Returns nil when no notifiers are installed.
func (*Server) NotifyResourceUpdated ¶
func (s *Server) NotifyResourceUpdated(uri string, delta ResourceUpdateDelta)
NotifyResourceUpdated publishes notifications/resources/updated to every notifier that called resources/subscribe for uri. Tool handlers call this after a mutation that invalidates a cached resource view. Safe to call before any notifier is wired — the call silently no-ops when nothing is subscribed.
Subscription scope is per-notifier; a peer that did NOT subscribe to uri never receives the notification. tools/list_changed continues to fan out broadcast through Server.Notify; only resources/updated takes this per-URI path.
When delta.Format is non-empty the notification params include the envelope:
{
"uri": "clockify://workspace/ws/entry/id",
"format": "merge",
"patch": { "description": "new text", "billable": true }
}
Empty delta preserves the legacy payload shape {"uri": "..."} so existing clients and tests remain unchanged.
func (*Server) NotifyResourcesListChanged ¶ added in v0.2.0
func (s *Server) NotifyResourcesListChanged()
NotifyResourcesListChanged emits notifications/resources/list_changed to every registered notifier. The one-user server calls this when the set of available resources changes (a demo-run resource is added) so the advertised resources.listChanged capability is truthful. No-op when resources are off.
func (*Server) Run ¶
Run processes newline-delimited JSON-RPC requests from r and writes responses to w. The reader must reach EOF when the stdio session ends; a reader that signals logical end-of-input without EOF can leave the scan goroutine blocked in Read. Scanner errors are returned on the EOF path.
func (*Server) SetAdvertisedTools ¶ added in v0.3.0
func (s *Server) SetAdvertisedTools(advertised []ToolDescriptor)
SetAdvertisedTools limits tools/list to descriptors in advertised. When EnforceAdvertisedTools is true, this set is also the callable boundary. Passing nil advertises every loaded tool.
func (*Server) SetNotifier ¶
SetNotifier installs a single notification sink, removing any previously installed via SetNotifier. The stdio loop uses this for the per-session encoder notifier.
type Tool ¶
type Tool struct {
Name string `json:"name"`
Title string `json:"title,omitempty"`
Description string `json:"description"`
InputSchema map[string]any `json:"inputSchema,omitempty"`
OutputSchema map[string]any `json:"outputSchema,omitempty"`
Annotations map[string]any `json:"annotations,omitempty"`
}
Tool is the wire representation of a single entry in a tools/list result: its name, optional title, description, input/output JSON schemas, and annotations (e.g. read-only or destructive hints).
type ToolCallParams ¶
type ToolCallParams struct {
Name string `json:"name"`
Arguments map[string]any `json:"arguments,omitempty"`
Meta *RequestMeta `json:"_meta,omitempty"`
}
ToolCallParams is the params payload of a tools/call request: the tool Name and its Arguments map, plus optional _meta (e.g. a progressToken).
type ToolDescriptor ¶
type ToolDescriptor struct {
Tool Tool
Handler ToolHandler
ReadOnlyHint bool
DestructiveHint bool
IdempotentHint bool
// AdvertiseOutputSchema controls whether Tool.OutputSchema appears in
// tools/list responses. Default false: server-side validation still uses
// the schema, but it is omitted from the wire to shrink tools/list.
AdvertiseOutputSchema bool
// Tiers lists advertised toolset tiers this descriptor belongs to. Tier
// names: "default" (everyday surface), "core", "business", "admin".
// The "all" tier is implicit: every descriptor belongs to it.
Tiers []string
// RiskClass is the structured risk taxonomy; defaults are derived from
// the boolean hints in normalizeDescriptors when this field is zero.
// Tier-2 tools that need finer granularity than read/write/destructive
// (billing, admin, permission_change, external_side_effect) override it
// in internal/tools/risk_overrides.go.
RiskClass RiskClass
// AuditKeys names non-secret arguments that may be copied into the optional
// local JSONL audit log.
AuditKeys []string
// SafetyRequirementFunc can refine confirmation policy from call
// arguments, primarily for raw method/path fallback tools.
SafetyRequirementFunc func(args map[string]any) safety.Requirement
// CentralDryRunPreview lets dispatch answer dry_run:true for high-risk
// tools that do not need handler-specific preview enrichment.
CentralDryRunPreview bool
// SafetyExemption documents a high-risk descriptor that is deliberately
// safe without central confirmation.
SafetyExemption string
}
ToolDescriptor is a registry entry binding a Tool's wire metadata to its Handler and the server-side policy that governs it: MCP boolean hints, the structured RiskClass, audit keys, confirmation/dry-run policy, and the advertised toolset tiers it belongs to.
type ToolHandler ¶
ToolHandler executes a single tool call: it receives the request context and the decoded arguments map and returns the tool result (typically a *tools.ToolResult) or an error for runtime/protocol failures.
type UnknownToolError ¶
type UnknownToolError struct {
Name string
}
UnknownToolError is returned by tool dispatch when a tools/call names a tool that is not in the registry. The dispatch maps it to a JSON-RPC method-not- found style error so clients can distinguish it from argument failures.
func (*UnknownToolError) Error ¶
func (e *UnknownToolError) Error() string