mcp

package module
v0.32.4 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 33 Imported by: 7

README

MCP Server Library for Go

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

Features

  • HTTP & Stdio Transports: Serve the same tools over HTTP or newline-delimited JSON-RPC on stdin/stdout, and consume remote servers over either
  • Simple API: Fluent interface for defining tools and parameters
  • Type Safety: Strongly typed parameter access with automatic conversion
  • Rich Responses: Support for text, image, audio, resource, and structured content
  • Resources: Serve addressable data by URI (resources/list, resources/read, resource templates), including per-user/session resources via ResourceProvider
  • MCP Apps: Link a tool to an interactive HTML UI resource (SEP-1865), with CSP/permission metadata, extension capability negotiation, and host/view auto-resize via containerDimensions
  • Prompts: Reusable message templates with arguments (prompts/list, prompts/get), including per-user/session prompts via PromptProvider
  • Skills: Agent Skills directories served per SEP-2640 (skills/list, skills/get): every skill file is an ordinary skill:// resource with digests, frontmatter served verbatim from the SKILL.md; per-user/session skills via a SkillProvider on the request context
  • ListChanged Notifications: Push-based tool/resource/prompt refresh over HTTP (SSE) and stdio, with automatic propagation through federated servers
  • TOON Support: Compact, human-readable JSON encoding for LLM prompts
  • Thread Safe: Concurrent request handling with mutex protection
  • Remote Servers: Connect to and proxy remote MCP servers with authentication
  • Remote Search: Delegate tool_search to remote servers to discover hidden tools
  • Parallel Tool Calls: Execute multiple tools concurrently and collect all results in one call
  • Searchable Tools: Reduce context window usage with on-demand tool discovery
  • Dynamic Tool Providers: Load tools from external sources (databases, scripts, APIs)
  • Per-User Remote Servers: Request-scoped RemoteProvider for federating remote MCP servers with per-user auth, filtering, and caching
  • Provider Composition: Combine providers with MultiProvider using clear miss/error semantics
  • Streamed Responses: Long-running tools/call, resources/read and prompts/get switch to an SSE stream with keep-alives, so proxies with read timeouts (Cloudflare, nginx, load balancers) don't cut them off; fast calls stay plain JSON
  • Header Routing: x-mcp-header tool parameters mirrored to Mcp-Param-* HTTP headers (HTTPHeader() option), validated by the server and sent automatically by the client
  • MCP Compliant: Full support for protocol versions 2024-11-05 through 2026-07-28, on both server and client, negotiating the highest version both sides support

Installation

go get github.com/paularlott/mcp

Quick Start

package main

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

    "github.com/paularlott/mcp"
)

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

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

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

Transports

The same server and its tools can be served over two transports.

HTTP

Mount the server as an http.Handler (as in Quick Start above):

http.HandleFunc("/mcp", server.HandleRequest)

A request from a client that accepts text/event-stream and runs longer than 2 seconds is answered as an SSE stream with a keep-alive comment every 15 seconds; anything faster is a normal JSON response. Tune or disable it with:

server.SetResponseStreaming(5*time.Second, 20*time.Second) // delay, keep-alive
server.SetResponseStreaming(-1, 0)                          // always JSON

The client handles both response forms transparently.

Stdio

Serve the MCP protocol over stdin/stdout (newline-delimited JSON-RPC 2.0) — the transport a host launches as a subprocess. ServeStdio blocks until stdin reaches EOF; keep stdout for protocol frames only and send logs to stderr:

server := mcp.NewServer("my-server", "1.0.0")
// ... RegisterTool(...) as usual ...
if err := server.ServeStdio(context.Background()); err != nil {
    log.Fatal(err)
}

Use ServeStream(ctx, in, out) to serve over any pair of streams (for example an in-process pipe) rather than the process's own stdio.

A client connects to a stdio server by launching it as a subprocess:

client, err := mcp.NewStdioClient("my-server-binary", []string{"--flag"}, "")
if err != nil {
    log.Fatal(err)
}
defer client.Close()

tools, _ := client.ListTools(ctx)
resp, _ := client.CallTool(ctx, "greet", map[string]any{"name": "Ada"})

NewStdioClient accepts options such as WithClientStderr, WithClientEnv, WithClientExtraEnv, and WithClientDir. WithClientEnv replaces the child's whole environment, while WithClientExtraEnv adds or overrides individual KEY=VALUE variables on top of the inherited parent environment (so PATH, HOME, etc. are preserved). To talk to a server over streams you already hold, use NewStreamClient(in, out, namespace). The stdio transport is built on the paularlott/jsonrpc package. The client API (ListTools, CallTool, namespacing, filtering) is identical across HTTP and stdio.

CallToolsParallel and ExecuteDiscoveredToolsParallel send every call as a single JSON-RPC batch over the stdio transport (one round-trip instead of one per call), falling back to concurrent individual calls over HTTP. Either way, results are always returned in call order.

Documentation

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

Get Started
  • Tool Providers - Dynamic tool loading, per-request providers, visibility control, and show-all mode
  • Tool Discovery - Searchable tools and context window optimization
How-To Guides
  • Remote Servers - Connecting and proxying remote MCP servers, parallel tool calls
  • Resources - Serving addressable data by URI, resource templates, and per-user/session resources
  • Prompts - Reusable message templates with arguments, and per-user/session prompts
  • Skills - Serving Agent Skills directories (skills/list, skills/get, skill:// resources) per SEP-2640, statically or per-request via SkillProvider
  • Notifications - Push-based list refresh (listChanged) over HTTP and stdio, with federation propagation
  • Protocol Support - Supported protocol versions (2024-11-05 through 2026-07-28), version negotiation, streamed responses, x-mcp-header, and pagination
  • Sessions - Optional session management (MCP 2025-11-25)
  • Response Types - Text, images, audio, and structured responses
  • Error Handling - Structured error patterns and best practices
  • Thread Safety & Concurrency - Safe concurrent usage patterns
  • MCP Apps - Interactive UI resources linked to tools (SEP-1865), CSP metadata, and extension capability negotiation

Tool Discovery Mode

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

Header-Based Mode Selection

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

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

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

Or via query parameter: /mcp?show_all=true

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

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

Discoverable Tools

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

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

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

Examples

See the examples/ directory for complete, runnable examples:

Testing

Run tests to ensure everything works:

go test ./...

View specific test categories:

# Provider tests
go test -run TestAddRemoveProviders -v

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

# Full test suite
go test -v

Documentation

Index

Constants

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

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

	// DefaultOAuthRefreshTimeout is the default timeout for OAuth token refresh operations
	DefaultOAuthRefreshTimeout = 30 * time.Second
)
View Source
const (
	NotificationToolsChanged     = "notifications/tools/listChanged"
	NotificationResourcesChanged = "notifications/resources/listChanged"
	NotificationPromptsChanged   = "notifications/prompts/listChanged"
)

MCP notification method names for list-change signalling.

View Source
const (
	// DefaultStreamingDelay is how long a streamable request may run before
	// its response switches from application/json to an SSE stream.
	DefaultStreamingDelay = 2 * time.Second

	// DefaultStreamingKeepAlive is the interval between SSE keep-alive
	// comments on a streamed response. Well under common intermediary idle
	// timeouts (Cloudflare ~100s, nginx proxy_read_timeout 60s).
	DefaultStreamingKeepAlive = 15 * time.Second
)
View Source
const (
	// ErrorCodeParseError indicates invalid JSON was received by the server.
	// Use when the request body cannot be parsed as JSON.
	ErrorCodeParseError = -32700

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

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

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

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

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

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

	// ErrorCodeHeaderMismatch indicates a Modern-era (protocol revision
	// 2026-07-28+) request's mirrored HTTP headers (MCP-Protocol-Version,
	// Mcp-Method, Mcp-Name, Mcp-Param-*) don't match the corresponding values
	// in the JSON-RPC request body, or a required header is missing.
	ErrorCodeHeaderMismatch = -32020

	// ErrorCodeMissingRequiredClientCapability indicates a Modern-era request
	// needs a capability the client didn't declare in its per-request
	// io.modelcontextprotocol/clientCapabilities metadata.
	ErrorCodeMissingRequiredClientCapability = -32021

	// ErrorCodeUnsupportedProtocolVersion indicates the requested protocol
	// version (Modern or Legacy) isn't one this server implements. The
	// error's data.supported field lists the versions it does support.
	ErrorCodeUnsupportedProtocolVersion = -32022
)

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

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

Discovery tool names

View Source
const DefaultRemoteSkillsCacheTTL = time.Minute

DefaultRemoteSkillsCacheTTL is how long a federated skills listing is cached when a target's TTL is zero. Negative disables caching, matching the tool-list rules.

View Source
const DefaultRemoteToolCacheMaxEntries = 1024

DefaultRemoteToolCacheMaxEntries bounds the number of distinct cache keys a RemoteProvider keeps remote listings (tool lists, skills lists) for. It exists so a CacheKey that embeds a per-user/per-tenant identifier cannot grow the cache without limit. Override with WithMaxCacheEntries.

View Source
const DefaultRemoteToolCacheTTL = 60 * time.Second

DefaultRemoteToolCacheTTL is the default lifetime for cached remote tool lists when a RemoteProviderConfig does not specify CacheTTL.

View Source
const DefaultRemoteToolListTimeout = 10 * time.Second

DefaultRemoteToolListTimeout bounds how long a single remote server's tools/list call may take before RemoteProvider gives up on it for this request. A zero RemoteProviderConfig.ListTimeout uses this default; a negative ListTimeout disables the bound (waits as long as the caller's context allows). This exists so one unresponsive server cannot hang GetTools indefinitely — without it, a hung server would delay (or, before GetTools ran servers concurrently, block) every other server's tools too.

View Source
const (
	// MCPProtocolVersionModern is the current Modern-era protocol revision.
	MCPProtocolVersionModern = "2026-07-28"
)

Support for MCP protocol revision 2026-07-28 (the "Modern" era): a stateless, per-request model that replaces the initialize handshake (the "Legacy" era, 2024-11-05..2025-11-25) with protocol version, client identity, and capabilities carried on every request's _meta.

A Server implements both eras simultaneously ("Dual-era"): a request is routed to the Modern path only when it carries a Modern signal (the Mcp-Method header on HTTP, or io.modelcontextprotocol/protocolVersion in _meta on any transport); otherwise it falls through to the existing Legacy code, completely unchanged. See https://modelcontextprotocol.io/specification/2026-07-28 and docs/guides/protocol-support.md for the full picture.

Known gaps, deliberately out of scope for this pass (see the guide):

  • MRTR (server-initiated sampling/elicitation/roots) — this library implements none of these in either era, so there is nothing to migrate.
  • stdio does not implement subscriptions/listen: doing so correctly needs the calling request's own JSON-RPC id (to use as the subscription id) and a way to cancel a still-open subscription on an inbound notifications/cancelled — neither is something the underlying jsonrpc package's Handler signature exposes today, and stdio's existing connection-scoped notification delivery (every connected client already receives every listChanged notification, regardless of era) means nothing is functionally lost by not having it. A stdio client that calls it gets a standard, honest "Method not found" (-32601) — see TestStdioSubscriptionsListenNotSupported — rather than a silent or partial implementation.
View Source
const ShowAllHeader = "X-MCP-Show-All"

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

View Source
const ShowAllQueryParam = "show_all"

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

View Source
const SkillsExtensionID = "io.modelcontextprotocol/skills"

SkillsExtensionID is the extension capability a server declares to advertise skills support, negotiated via the capabilities.extensions mechanism (SEP-1724).

View Source
const UIAppMimeType = "text/html;profile=mcp-app"

UIAppMimeType is the MIME type MCP Apps UI resources MUST use.

View Source
const UIAppsExtensionID = "io.modelcontextprotocol/ui"

UIAppsExtensionID is the extension identifier clients and servers use to negotiate MCP Apps support via the capabilities.extensions mechanism (SEP-1724), e.g. capabilities.extensions["io.modelcontextprotocol/ui"].

Variables

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

DefaultNamespaceSeparator is the default separator used for namespacing tool names. Uses "__" by default for broad client compatibility (some clients such as AntiGravity and PhpStorm reject tool names containing dots even though the MCP spec allows them).

Functions

func ExtensionCapability added in v0.27.0

func ExtensionCapability(clientCapabilities map[string]any, extensionID string) (settings map[string]any, ok bool)

ExtensionCapability extracts a named extension's settings object from a raw capabilities map as received in an initialize request's capabilities field (capabilities.extensions[extensionID]), per the SEP-1724 extensions mechanism. ok is false if the extension was not declared.

func GenerateSigningKey added in v0.6.6

func GenerateSigningKey() ([]byte, error)

GenerateSigningKey creates a cryptographically secure random signing key

func GetShowAllFromRequest added in v0.10.0

func GetShowAllFromRequest(r *http.Request) bool

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

func GetShowAllTools added in v0.10.0

func GetShowAllTools(ctx context.Context) bool

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

func MatchResourceTemplate added in v0.21.0

func MatchResourceTemplate(template, uri string) (map[string]string, error)

MatchResourceTemplate extracts the {var} values from uri against an RFC 6570 level-1 URI template. It is intended for ResourceProvider implementations and advanced uses that need to parse their own template URIs; handlers registered via Server.RegisterResourceTemplate receive the variables already extracted on the ResourceRequest.

Returns the variables and nil on a match, or (nil, error) if uri does not match the template.

func NewToolError

func NewToolError(code int, message string, data any) error

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

Example:

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

func NewToolErrorInternal

func NewToolErrorInternal(message string) error

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

func NewToolErrorInvalidParams

func NewToolErrorInvalidParams(message string) error

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

func RegisterOAuthClient added in v0.13.0

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

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

func SkillPromptLine added in v0.28.0

func SkillPromptLine(namespace string, skill Skill) string

SkillPromptLine renders one skill as a prompt line for a chat model: "- namespace/name: description (uri)", or without the namespace prefix when empty. The name falls back to the URI path when the frontmatter lacks one. The description is what lets the model decide a skill is relevant before spending a read on it.

name, description, and uri may originate from a remote MCP server's own skills/list response, so every field is flattened to a single line first: otherwise an embedded newline lets a malicious remote close out this bullet (or a caller's surrounding block markers) and inject standalone text into whatever prompt role the caller merges these lines into.

func SupportsUIApps added in v0.27.0

func SupportsUIApps(clientCapabilities map[string]any) (mimeTypes []string, ok bool)

SupportsUIApps reports whether clientCapabilities declares support for the MCP Apps extension (UIAppsExtensionID), and if so, the resource MIME types it accepts. Use it to decide whether to register UI-linked tools, or fall back to a text-only tool for hosts that don't support MCP Apps:

if mimeTypes, ok := mcp.SupportsUIApps(server.ClientCapabilities()); ok && slices.Contains(mimeTypes, mcp.UIAppMimeType) {
	server.RegisterTool(mcp.NewTool("get_weather", "...").UIResource("ui://weather/dashboard"), handler)
} else {
	server.RegisterTool(mcp.NewTool("get_weather", "..."), handler)
}

func ToolIsApp added in v0.28.0

func ToolIsApp(tool MCPTool) bool

ToolIsApp reports whether a tool descriptor is an MCP Apps view: a tool linked to a companion UI resource via _meta.ui.resourceUri. Federating such a tool re-serves its view under a namespace the view's own code doesn't know (its in-page JS calls bare, host-agnostic names), so a federating server that excludes apps skips them entirely — see RemoteServerEntry.ExcludeApps.

func ValidateNamespace added in v0.28.0

func ValidateNamespace(namespace string) error

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

Example:

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

ValidateNamespace reports whether a federation namespace is usable. A namespace containing the namespace separator itself is rejected: it makes every namespaced tool name ambiguous ("a__b__tool" could belong to server "a" or server "a__b"), and no dispatcher can resolve that. Hosts taking namespaces from user input should call this and reject at the boundary; the client constructors enforce the same rule as a panic (a bad namespace is a programmer error the same way an invalid UI visibility is).

func WithPromptProviders added in v0.21.0

func WithPromptProviders(ctx context.Context, providers ...PromptProvider) context.Context

WithPromptProviders returns a context with the given prompt providers attached. Multiple providers can be attached; all are queried. Providers are consulted in order and the first one that handles a prompt wins.

This is the prompt equivalent of WithToolProviders / WithResourceProviders.

func WithResourceProviders added in v0.21.0

func WithResourceProviders(ctx context.Context, providers ...ResourceProvider) context.Context

WithResourceProviders returns a context with the given resource providers attached. Multiple providers can be attached; all are queried. Providers are consulted in order and the first one that handles a URI wins.

This is the resource equivalent of WithToolProviders. Use it in request middleware to inject per-user or per-session resources:

func handler(w http.ResponseWriter, r *http.Request) {
    user := currentUser(r)
    ctx := mcp.WithResourceProviders(r.Context(), &UserResourceProvider{user: user})
    server.HandleRequest(w, r.WithContext(ctx))
}

func WithShowAllFromRequest added in v0.10.0

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

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

func WithShowAllTools added in v0.10.0

func WithShowAllTools(ctx context.Context) context.Context

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

func WithSkillProviders added in v0.28.0

func WithSkillProviders(ctx context.Context, providers ...SkillProvider) context.Context

WithSkillProviders returns a context with the given skill providers attached. Multiple providers can be attached; all are queried, and the static registry wins URI collisions (provider entries are appended only for URIs it does not already serve).

This is the skills equivalent of WithToolProviders / WithResourceProviders. Use it in request middleware to inject per-user or per-session skills:

func handler(w http.ResponseWriter, r *http.Request) {
    user := currentUser(r)
    ctx := mcp.WithSkillProviders(r.Context(), &UserSkillProvider{user: user})
    server.HandleRequest(w, r.WithContext(ctx))
}

func WithToolProviders added in v0.9.0

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

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

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

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

A per-request memo is also installed so providers can cache expensive, request-scoped work (such as resolving a user's remote servers) across the multiple times the server queries providers while handling one request.

Types

type AuthProvider

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

AuthProvider is the interface for MCP client authentication.

type AuthResolver added in v0.19.0

type AuthResolver func(ctx context.Context) (AuthProvider, error)

AuthResolver lazily resolves the auth provider for a remote server for the current request. It is only called when the provider actually needs to talk to the server (listing or calling a tool), so per-user token lookups are not performed for servers that are never touched.

type BearerTokenAuth

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

BearerTokenAuth implements simple static bearer token authentication.

func NewBearerTokenAuth

func NewBearerTokenAuth(token string) *BearerTokenAuth

func (*BearerTokenAuth) GetAuthHeader

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

type Client

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

Client represents an MCP client for connecting to remote servers

func NewClient

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

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

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

func NewClientWithPool added in v0.9.5

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

func NewStdioClient added in v0.20.0

func NewStdioClient(command string, args []string, namespace string, opts ...StdioClientOption) (*Client, error)

NewStdioClient launches command (with args) as an MCP server speaking newline-delimited JSON-RPC over its stdin/stdout, and returns a client connected to it. Call Close to shut the child process down.

The namespace behaves as for NewClient: when non-empty it is prefixed to tool names (e.g. namespace "fs" exposes tool "read" as "fs__read").

func NewStreamClient added in v0.20.0

func NewStreamClient(in io.Reader, out io.Writer, namespace string) *Client

NewStreamClient returns an MCP client that speaks newline-delimited JSON-RPC over the given streams: it writes requests to out and reads responses from in. Use it to connect to a server exposed via Server.ServeStream (for example over an in-process pipe), or any transport you manage yourself. Close stops the client's reader.

func (*Client) BaseURL added in v0.27.0

func (c *Client) BaseURL() string

BaseURL returns the remote server's endpoint URL this client connects to. Unlike Namespace (which callers may leave empty, and which two different remote servers may share no such uniqueness guarantee exists for), this is a stable, unique-per-remote-server identifier — used by Server.ToolSource and Server.ReadResourceFrom to tell which federated server a tool or resource actually came from.

func (*Client) CallTool

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

func (*Client) CallToolsParallel added in v0.15.0

func (c *Client) CallToolsParallel(ctx context.Context, calls []ToolCall) []ParallelToolResult

CallToolsParallel executes multiple tools concurrently and returns results in the same order as the input. Over a transport with native batch support (currently the stdio transport, backed by jsonrpc.Client.CallBatch), all calls are sent as a single wire-level batch instead of one round-trip each; otherwise they run as concurrent individual calls.

func (*Client) Close added in v0.20.0

func (c *Client) Close() error

Close releases resources held by the client's transport. For the default HTTP transport it stops the notification reader; for a stdio subprocess transport it shuts the child process down.

func (*Client) DeclareExtension added in v0.27.0

func (c *Client) DeclareExtension(id string, settings map[string]any)

DeclareExtension advertises this client's support for an MCP extension (per SEP-1724) to every server it talks to, under capabilities.extensions[id] on Legacy's initialize and _meta.clientCapabilities.extensions[id] on every Modern request. Call it during setup, before Initialize — a remote server that conditionally attaches extension-specific data (e.g. only linking a tool to its MCP Apps UI resource for clients that declared support) otherwise has no way to know this client can use it, and quietly falls back to a plain response instead. For example, a client rendering MCP Apps views declares:

client.DeclareExtension(mcp.UIAppsExtensionID, map[string]any{
	"mimeTypes": []string{mcp.UIAppMimeType},
})

This is the client-side counterpart of Server.DeclareExtension.

func (*Client) EnableNotifications added in v0.21.0

func (c *Client) EnableNotifications() *Client

EnableNotifications opts the HTTP client into receiving server-pushed notifications over a long-lived SSE stream. When enabled, the client opens a background GET event-stream connection after Initialize, invalidates its tool cache on notifications/tools/listChanged, and fires any On*Changed callbacks.

Notifications are off by default: a long-lived connection is only wanted when the caller intends to consume change events, and it must be released with Client.Close. stdio clients always receive notifications (no opt-in needed) because their transport is already a persistent connection.

Returns the client for chaining. Safe to call before or after Initialize.

func (*Client) ExecuteDiscoveredTool added in v0.8.0

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

ExecuteDiscoveredTool executes a tool by name using the execute_tool MCP tool. This is the always-safe way to call tools returned by ToolSearch. Tools may also be callable directly via CallTool when they were exposed in tools/list.

func (*Client) ExecuteDiscoveredToolsParallel added in v0.15.0

func (c *Client) ExecuteDiscoveredToolsParallel(ctx context.Context, calls []ToolCall) []ParallelToolResult

ExecuteDiscoveredToolsParallel executes multiple discovered tools concurrently and returns results in the same order as the input. It has the same batch-transport behaviour as CallToolsParallel.

func (*Client) GetPrompt added in v0.21.0

func (c *Client) GetPrompt(ctx context.Context, name string, args map[string]string) (*PromptResponse, error)

GetPrompt renders a prompt by name with the given string arguments via prompts/get.

func (*Client) GetSkill added in v0.28.0

func (c *Client) GetSkill(ctx context.Context, uri string) (*Skill, error)

GetSkill fetches one skill's entry by URI via skills/get. The entry carries metadata and digests; read the content itself with ReadResource on any listed resource URI.

func (*Client) Initialize

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

Initialize connects to the remote server, transparently detecting whether it speaks the Modern (protocol revision 2026-07-28+, stateless per-request) or Legacy (initialize handshake) era, per the spec's backward-compatibility algorithm: attempt a Modern server/discover call first, and fall back to the Legacy initialize handshake below if that doesn't succeed. Every other Client method is unaffected by which era was detected — they all still just call sendRequest, which applies the right wire shape internally.

func (*Client) Instructions added in v0.27.0

func (c *Client) Instructions() string

Instructions returns the instructions the remote server returned during initialize, or "" if the server set none or the client hasn't been initialized yet (Initialize is called automatically by most Client methods).

func (*Client) ListPrompts added in v0.21.0

func (c *Client) ListPrompts(ctx context.Context) ([]MCPPrompt, error)

ListPrompts retrieves the list of prompts from the remote server via prompts/list. Prompts are not cached: each call performs a fresh request.

func (*Client) ListResourceTemplates added in v0.21.0

func (c *Client) ListResourceTemplates(ctx context.Context) ([]MCPResourceTemplate, error)

ListResourceTemplates retrieves the resource templates exposed via resources/templates/list from the remote server.

func (*Client) ListResources added in v0.21.0

func (c *Client) ListResources(ctx context.Context) ([]MCPResource, error)

ListResources retrieves the list of resources from the remote server via resources/list. Unlike tools, resources are not cached: each call performs a fresh request, since resource sets can change between calls.

func (*Client) ListSkills added in v0.28.0

func (c *Client) ListSkills(ctx context.Context) ([]Skill, error)

ListSkills fetches the server's skills/list.

func (*Client) ListTools

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

ListTools retrieves tools from the remote server

func (*Client) Namespace added in v0.8.0

func (c *Client) Namespace() string

Namespace returns the namespace for this client's tools.

func (*Client) OnPromptsChanged added in v0.21.0

func (c *Client) OnPromptsChanged(fn func()) *Client

OnPromptsChanged registers a callback for notifications/prompts/listChanged.

func (*Client) OnResourcesChanged added in v0.21.0

func (c *Client) OnResourcesChanged(fn func()) *Client

OnResourcesChanged registers a callback for notifications/resources/listChanged.

func (*Client) OnToolsChanged added in v0.21.0

func (c *Client) OnToolsChanged(fn func()) *Client

OnToolsChanged registers a callback fired whenever a notifications/tools/listChanged arrives from the server (HTTP SSE or stdio). The client also invalidates its own tool cache automatically; use this to trigger application-level refreshes (e.g. re-pulling for a UI). Returns the client for chaining.

func (*Client) ProtocolVersion added in v0.27.0

func (c *Client) ProtocolVersion() string

ProtocolVersion returns the protocol revision actually in effect with this server (e.g. "2025-06-18" for a Legacy server, or MCPProtocolVersionModern once Modern era is confirmed), or "" if the client hasn't been initialized yet (Initialize is called automatically by most Client methods).

func (*Client) ReadResource added in v0.21.0

func (c *Client) ReadResource(ctx context.Context, uri string) (*ResourceResponse, error)

ReadResource reads a resource by URI from the remote server via resources/read.

func (*Client) RefreshToolCache

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

RefreshToolCache explicitly refreshes the tool cache

func (*Client) ToolSearch added in v0.8.0

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

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

func (*Client) WithToolFilter added in v0.9.9

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

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

type ClientOption added in v0.27.1

type ClientOption func(*Client)

ClientOption customises a Client at construction time. Applied inside NewClient/NewClientWithPool before the client is returned, so anything an option sets is safe to read lock-free afterwards.

func WithClientRequestHeaders added in v0.27.1

func WithClientRequestHeaders(headers map[string]string) ClientOption

WithClientRequestHeaders returns a ClientOption that adds the given headers to every HTTP request the client makes — the JSON-RPC POSTs and the notification event-stream GET alike. Headers the transport manages itself (Content-Type, Accept, Authorization, Mcp-Session-Id, ...) are set after these, so they win any collision. Useful for gateways keyed on request headers, e.g. a proxy forwarding an "X-MCP-Show-All: true" mode header.

type Icon added in v0.27.0

type Icon struct {
	// Src is the icon's location: an https:// URL or a data: URI. Consumers
	// MUST reject any other scheme (e.g. javascript:, file:, ftp:).
	Src string `json:"src"`
	// MimeType is the icon's media type, useful when it can't be inferred
	// from Src (e.g. a data: URI or a generic-looking URL).
	MimeType string `json:"mimeType,omitempty"`
	// Sizes lists size hints such as "48x48", or "any" for a scalable format
	// like SVG.
	Sizes []string `json:"sizes,omitempty"`
	// Theme requests this icon be preferred for a specific host theme:
	// "light" or "dark". Omit it for a theme-neutral icon.
	Theme string `json:"theme,omitempty"`
}

Icon is a visual identifier attachable to a tool, prompt, resource, or a server/client's own identity (an "Implementation"), per the MCP spec's generic icons convention.

This library only carries icon metadata on the wire — it does not fetch, cache, decode, or render icon bytes. Consumers that do render icons are responsible for the spec's security precautions (treat Src and any fetched bytes as untrusted, require an https:// or data: URI, reject unsafe schemes and cross-origin redirects, fetch without credentials, verify content type from magic bytes, and guard against oversized images).

type JWTSessionManager added in v0.6.6

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

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

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

func NewJWTSessionManager added in v0.6.6

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

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

func NewJWTSessionManagerWithAutoKey added in v0.9.1

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

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

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

func (*JWTSessionManager) CreateSession added in v0.6.6

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

CreateSession generates a new JWT session token

func (*JWTSessionManager) DeleteSession added in v0.6.6

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

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

func (*JWTSessionManager) GetShowAll added in v0.10.0

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

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

func (*JWTSessionManager) ValidateSession added in v0.6.6

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

ValidateSession validates a JWT session token

type MCPError

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

type MCPNotification added in v0.21.0

type MCPNotification struct {
	JSONRPC string `json:"jsonrpc"`
	Method  string `json:"method"`
	Params  any    `json:"params,omitempty"`
}

MCPNotification is a JSON-RPC 2.0 notification — a message that carries no "id" member. Unlike MCPRequest (whose ID field has no omitempty and would serialize as "id":null), this struct makes it structurally impossible to emit an "id" field, conforming to the JSON-RPC 2.0 spec which requires that notifications omit "id" entirely.

type MCPPrompt added in v0.21.0

type MCPPrompt struct {
	Name        string              `json:"name"`
	Description string              `json:"description,omitempty"`
	Arguments   []MCPPromptArgument `json:"arguments,omitempty"`
	Icons       []Icon              `json:"icons,omitempty"`
}

MCPPrompt describes a prompt exposed via prompts/list. A prompt is a reusable message template with named arguments that produces messages for the model.

type MCPPromptArgument added in v0.21.0

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

MCPPromptArgument describes one argument a prompt accepts.

type MCPRequest

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

MCP Protocol types

type MCPResource added in v0.21.0

type MCPResource struct {
	URI         string         `json:"uri"`
	Name        string         `json:"name"`
	Description string         `json:"description,omitempty"`
	MimeType    string         `json:"mimeType,omitempty"`
	Meta        map[string]any `json:"_meta,omitempty"` // Extension metadata, e.g. MCP Apps' ui hints
	Icons       []Icon         `json:"icons,omitempty"`
}

MCPResource describes a static resource exposed via resources/list. A resource is data the server can serve to clients by URI, such as a file, a configuration document, or a database record.

type MCPResourceTemplate added in v0.21.0

type MCPResourceTemplate struct {
	URITemplate string         `json:"uriTemplate"`
	Name        string         `json:"name"`
	Description string         `json:"description,omitempty"`
	MimeType    string         `json:"mimeType,omitempty"`
	Meta        map[string]any `json:"_meta,omitempty"` // Extension metadata, e.g. MCP Apps' ui hints
	Icons       []Icon         `json:"icons,omitempty"`
}

MCPResourceTemplate describes a parameterized resource exposed via resources/templates/list. The URITemplate may contain {var} placeholders (RFC 6570 level 1) that clients expand to concrete URIs and then read.

type MCPResponse

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

type MCPTool

type MCPTool struct {
	Name         string         `json:"name"`
	Description  string         `json:"description"`
	InputSchema  any            `json:"inputSchema"`
	OutputSchema any            `json:"outputSchema,omitempty"`
	Meta         map[string]any `json:"_meta,omitempty"` // Extension metadata, e.g. MCP Apps' ui.resourceUri
	Icons        []Icon         `json:"icons,omitempty"`
	Keywords     []string       `json:"-"` // For discovery search, not serialized to clients
	Visibility   ToolVisibility `json:"-"` // Native or Discoverable
}

type MultiProvider added in v0.19.0

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

MultiProvider combines multiple ToolProviders into a single ToolProvider.

Composition semantics:

  • GetTools aggregates the tools from every provider in order. To stay transparent with the server's own list path (listToolsFromProviders), a provider whose GetTools returns an error is skipped rather than failing the whole set, so one broken provider never hides the others' tools. GetTools therefore does not surface provider errors. Duplicate tool names are NOT de-duplicated here; the server's list/search logic already de-duplicates by name.

  • ExecuteTool dispatches to each provider in order using the "skip on miss, abort on real error, first success wins" contract: 1. A provider that does not handle the tool signals a miss by returning (nil, nil) or (nil, ErrUnknownTool). The next provider is tried. 2. A provider that returns any other error aborts dispatch and that error is returned to the caller. 3. The first provider that returns a non-nil result wins. If no provider handles the tool, ExecuteTool returns ErrUnknownTool — the same miss signal as every other provider, so the server (which routes by the provider's own listing, see providerForTool) and any other dispatcher treat a MultiProvider exactly like a plain one.

MultiProvider is safe for concurrent use if its underlying providers are.

func NewMultiProvider added in v0.19.0

func NewMultiProvider(providers ...ToolProvider) *MultiProvider

NewMultiProvider combines the given providers into a single ToolProvider. Nil providers are skipped. If no non-nil providers are supplied, nil is returned so callers can attach the result with WithToolProviders without a guard (attaching a nil provider is a no-op-safe pattern callers should still check for).

func (*MultiProvider) ExecuteTool added in v0.19.0

func (p *MultiProvider) ExecuteTool(ctx context.Context, name string, params map[string]any) (*ToolResponse, error)

ExecuteTool dispatches the call to the first provider that handles the tool. See the MultiProvider type docs for the full skip/abort/first-success contract. A total miss returns ErrUnknownTool, like every other provider's miss.

func (*MultiProvider) GetTools added in v0.19.0

func (p *MultiProvider) GetTools(ctx context.Context) ([]MCPTool, error)

GetTools returns the aggregated tools from all providers in order. A provider whose GetTools returns an error is skipped (matching the server's list path), so GetTools itself never returns an error.

type OAuth2Auth

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

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

func NewOAuth2Auth

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

NewOAuth2Auth creates an OAuth2 provider using the client credentials flow.

func NewOAuth2RefreshTokenAuth added in v0.13.0

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

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

func (*OAuth2Auth) GetAuthHeader

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

type OAuthMeta added in v0.13.0

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

OAuthMeta holds the OAuth2 server metadata discovered via RFC 8414.

func DiscoverOAuthMeta added in v0.13.0

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

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

type Option

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

Option interface for parameter options

func HTTPHeader added in v0.30.0

func HTTPHeader(name string) Option

HTTPHeader marks a string, integer or boolean parameter with the 2026-07-28 "x-mcp-header" annotation: clients calling the tool over Streamable HTTP mirror the argument's value into an "Mcp-Param-<name>" header, so load balancers and gateways can route on it without parsing the body, and the server rejects a call whose header does not match the argument. name must be a valid HTTP header token, unique (case-insensitively) within the tool; RegisterTool panics otherwise. The option is ignored on other types.

func Required

func Required() Option

type OriginValidator added in v0.27.0

type OriginValidator func(origin string) bool

OriginValidator reports whether origin — the exact value of an incoming request's Origin header — may access this server. Set via Server.SetOriginValidator; see Server.AllowOrigins for the common case of just adding specific origins on top of the default policy rather than replacing it outright.

type ParallelToolResult added in v0.15.0

type ParallelToolResult struct {
	Name     string
	Response *ToolResponse
	Err      error
}

ParallelToolResult holds the result of a single tool call from a parallel execution.

type Parameter

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

Parameter interface for all parameter types

func Boolean

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

Boolean creates a boolean parameter

func BooleanArray added in v0.9.0

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

BooleanArray creates a boolean array parameter

func Integer added in v0.16.0

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

Integer creates an integer parameter (whole numbers only). Emitted as JSON Schema {"type": "integer"}.

func IntegerArray added in v0.16.0

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

IntegerArray creates an integer array parameter (whole numbers only). Emitted as JSON Schema {"type": "array", "items": {"type": "integer"}}.

func Number

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

Number creates a number parameter (integer or float). Emitted as JSON Schema {"type": "number"}.

func NumberArray

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

NumberArray creates a number array parameter (integers or floats). Emitted as JSON Schema {"type": "array", "items": {"type": "number"}}.

func Object

func Object(name, description string, propertiesAndOptions ...any) Parameter

Object creates an object parameter with properties

func ObjectArray

func ObjectArray(name, description string, propertiesAndOptions ...any) Parameter

ObjectArray creates an array of objects parameter

func Output

func Output(parameters ...Parameter) Parameter

func String

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

String creates a string parameter

func StringArray

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

StringArray creates a string array parameter

type PromptBuilder added in v0.21.0

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

PromptBuilder is a fluent builder for a prompt. A prompt is a reusable, named message template with declared arguments that the client fills in; the server renders it into one or more messages via prompts/get. Register it with Server.RegisterPrompt.

func NewPrompt added in v0.21.0

func NewPrompt(name, description string) *PromptBuilder

NewPrompt creates a prompt descriptor. Chain Argument calls to declare the arguments the prompt accepts:

p := mcp.NewPrompt("code_review", "Review code").
    Argument("code", "The code to review", true)

func (*PromptBuilder) Argument added in v0.21.0

func (p *PromptBuilder) Argument(name, description string, required bool) *PromptBuilder

Argument declares an argument the prompt accepts.

func (*PromptBuilder) Arguments added in v0.21.0

func (p *PromptBuilder) Arguments() []MCPPromptArgument

Arguments returns the prompt's declared arguments.

func (*PromptBuilder) Description added in v0.21.0

func (p *PromptBuilder) Description() string

Description returns the prompt's description.

func (*PromptBuilder) Icons added in v0.27.0

func (p *PromptBuilder) Icons(icons ...Icon) *PromptBuilder

Icons attaches visual identifiers to the prompt's prompts/list descriptor. See Icon for the shape and the security precautions consumers must apply.

func (*PromptBuilder) Name added in v0.21.0

func (p *PromptBuilder) Name() string

Name returns the prompt's name.

func (*PromptBuilder) ToMCPPrompt added in v0.21.0

func (p *PromptBuilder) ToMCPPrompt() MCPPrompt

ToMCPPrompt converts the builder to an MCPPrompt descriptor.

type PromptHandler added in v0.21.0

type PromptHandler func(ctx context.Context, req *PromptRequest) (*PromptResponse, error)

PromptHandler returns the rendered messages for a prompt, given its arguments. Build the response with the NewPromptResponse* constructors.

type PromptMessage added in v0.21.0

type PromptMessage struct {
	Role    PromptMessageRole    `json:"role"`
	Content PromptMessageContent `json:"content"`
}

PromptMessage is a single message in a prompt response.

func NewPromptTextMessage added in v0.21.0

func NewPromptTextMessage(role PromptMessageRole, text string) PromptMessage

NewPromptTextMessage builds a single-content text message with the given role.

type PromptMessageContent added in v0.21.0

type PromptMessageContent = ToolContent

PromptMessageContent is the content block of a prompt message. It is the same shape as the content block used by tool responses (text, image, audio, or an embedded resource), so the ToolContent constructors can be reused.

type PromptMessageRole added in v0.21.0

type PromptMessageRole string

PromptMessageRole is the role of a message within a prompt response.

const (
	// PromptRoleUser marks a message from the user.
	PromptRoleUser PromptMessageRole = "user"
	// PromptRoleAssistant marks a message from the assistant.
	PromptRoleAssistant PromptMessageRole = "assistant"
)

type PromptProvider added in v0.21.0

type PromptProvider interface {
	// GetPrompts returns the prompt descriptors this provider exposes for the
	// request. The context carries tenant/user/session information for filtering.
	GetPrompts(ctx context.Context) ([]MCPPrompt, error)

	// GetPrompt renders a prompt by name with the given arguments.
	//
	// Miss contract: if this provider does not handle the named prompt, return
	// (nil, ErrUnknownPrompt). Any other non-nil error aborts dispatch and is
	// returned to the caller, so only use it for genuine failures, not misses.
	GetPrompt(ctx context.Context, name string, args map[string]string) (*PromptResponse, error)
}

PromptProvider is the interface that providers implement to expose prompts scoped to a request — for example per-user or per-session prompts.

It is the prompt analogue of ToolProvider and ResourceProvider: attach instances to the request context with WithPromptProviders and the server merges them with any statically-registered prompts when serving prompts/list and prompts/get.

func GetPromptProviders added in v0.21.0

func GetPromptProviders(ctx context.Context) []PromptProvider

GetPromptProviders returns the prompt providers from the context, or nil if none are attached.

type PromptRequest added in v0.21.0

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

PromptRequest provides typed access to a prompt's arguments. All prompt arguments are strings. Use String to retrieve an argument (returning ErrUnknownParameter if absent) or StringOr for a default.

func NewPromptRequest added in v0.21.0

func NewPromptRequest(args map[string]string) *PromptRequest

NewPromptRequest creates a PromptRequest from a string argument map.

func (*PromptRequest) Args added in v0.21.0

func (r *PromptRequest) Args() map[string]string

Args returns all arguments as a map. The returned map may be empty but is never nil when obtained from a handler invocation.

func (*PromptRequest) String added in v0.21.0

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

String returns a string argument by name. Returns ErrUnknownParameter if the argument was not provided.

func (*PromptRequest) StringOr added in v0.21.0

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

StringOr returns a string argument or defaultValue if not provided.

type PromptResponse added in v0.21.0

type PromptResponse struct {
	Description string          `json:"description,omitempty"`
	Messages    []PromptMessage `json:"messages"`
}

PromptResponse is the result of prompts/get.

func NewPromptResponseMessages added in v0.21.0

func NewPromptResponseMessages(messages ...PromptMessage) *PromptResponse

NewPromptResponseMessages builds a prompt response from the given messages. Use this when a prompt renders multiple messages or non-user roles.

func NewPromptResponseText added in v0.21.0

func NewPromptResponseText(text string) *PromptResponse

NewPromptResponseText builds a prompt response containing a single user text message. This is the common case where the prompt renders one block of text.

type ProvidedResources added in v0.21.0

type ProvidedResources struct {
	Resources []MCPResource         // Static resources surfaced via resources/list
	Templates []MCPResourceTemplate // Parameterized templates surfaced via resources/templates/list
}

ProvidedResources is the set of descriptors a ResourceProvider exposes for a request. Either slice may be empty.

type ProviderFuncs added in v0.19.0

type ProviderFuncs struct {
	GetToolsFunc    func(ctx context.Context) ([]MCPTool, error)
	ExecuteToolFunc func(ctx context.Context, name string, params map[string]any) (*ToolResponse, error)
}

ProviderFuncs adapts plain functions to the ToolProvider interface, so a provider can be defined inline without a dedicated type.

p := &mcp.ProviderFuncs{
    GetToolsFunc: func(ctx context.Context) ([]mcp.MCPTool, error) { ... },
    ExecuteToolFunc: func(ctx context.Context, name string, params map[string]any) (*mcp.ToolResponse, error) { ... },
}

A nil GetToolsFunc yields no tools; a nil ExecuteToolFunc reports the tool as not handled (returns nil, ErrUnknownTool).

func (*ProviderFuncs) ExecuteTool added in v0.19.0

func (p *ProviderFuncs) ExecuteTool(ctx context.Context, name string, params map[string]any) (*ToolResponse, error)

ExecuteTool calls ExecuteToolFunc, or reports the tool as not handled if it is unset.

func (*ProviderFuncs) GetTools added in v0.19.0

func (p *ProviderFuncs) GetTools(ctx context.Context) ([]MCPTool, error)

GetTools calls GetToolsFunc, or returns nil if it is unset.

type RemoteProvider added in v0.19.0

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

RemoteProvider is a request-scoped ToolProvider that exposes tools from one or more remote MCP servers. It is intended to be created once and reused for the lifetime of the process: it resolves the per-request server set from the context, so a single instance safely serves many users without leaking tools between them. Reusing one instance also lets its tool-list cache persist across requests.

provider := mcp.NewRemoteProvider(func(ctx context.Context) ([]mcp.RemoteProviderConfig, error) {
    user := userFromContext(ctx)
    return loadServersForUser(user), nil
})
// per request:
ctx := mcp.WithToolProviders(r.Context(), provider)
server.HandleRequest(w, r.WithContext(ctx))

func NewRemoteProvider added in v0.19.0

func NewRemoteProvider(resolve RemoteProviderResolver, opts ...RemoteProviderOption) *RemoteProvider

NewRemoteProvider creates a remote tool provider driven by the given resolver. Create it once and reuse it across requests.

func (*RemoteProvider) ExecuteTool added in v0.19.0

func (p *RemoteProvider) ExecuteTool(ctx context.Context, name string, params map[string]any) (*ToolResponse, error)

ExecuteTool dispatches a namespaced tool call to the owning remote server. Returns ErrUnknownTool when the tool is not a namespaced tool belonging to one of this request's servers, so other providers can handle it.

func (*RemoteProvider) GetResources added in v0.28.0

func (p *RemoteProvider) GetResources(ctx context.Context) (*ProvidedResources, error)

GetResources returns the resources and resource templates exposed by all of the current request's remote servers, so a federated tool's linked MCP Apps ui:// resource (or any other resource a remote exposes) is reachable via resources/list and resources/read the same way a native tool's would be — without this, RemoteProvider's caller can dispatch a federated tool call but has no way to serve the ui:// view it renders, since a request-scoped remote server has no other route into Server.ReadResource's fan-out (that fan-out only covers servers registered process-lifetime via Server.RegisterRemoteServer/ReplaceRemoteServers, not ones resolved per request here).

Like GetTools, servers are queried concurrently and a server that fails is skipped (and reported via WithOnServerError) rather than failing the whole call. Unlike tools, remote resources are not namespaced: a federated server's resource URIs (e.g. a ui:// MCP Apps view) are opaque and surfaced as-is, matching Server.ReadResource's own remote fan-out.

func (*RemoteProvider) GetTools added in v0.19.0

func (p *RemoteProvider) GetTools(ctx context.Context) ([]MCPTool, error)

GetTools returns the tools for all of the current request's remote servers, applying each server's visibility, keywords and tool filter. Servers are queried concurrently and each is bounded by its ListTimeout, so one slow or unresponsive remote cannot delay or block the others. Servers that fail to respond are skipped so one bad remote does not break the whole list; if WithOnServerError was set, it is called for each skipped server so the host can log it and/or track its health.

func (*RemoteProvider) InvalidateAllCache added in v0.19.0

func (p *RemoteProvider) InvalidateAllCache()

InvalidateAllCache clears every cached remote tool list.

func (*RemoteProvider) InvalidateCache added in v0.19.0

func (p *RemoteProvider) InvalidateCache(cacheKey string)

InvalidateCache removes the cached tool list for a single server. The key must match the server's CacheKey (or, when CacheKey is unset, Name + "\x00" + URL). Call this when a server's configuration or tool set changes.

func (*RemoteProvider) ListSkills added in v0.28.0

func (p *RemoteProvider) ListSkills(ctx context.Context) ([]Skill, error)

ListSkills implements SkillProvider: every resolved remote server's skills, re-published under skill://<namespace>/… URIs — the spec-sanctioned rewrite, identical in shape to a server's registered skills federation (see Server.RegisterRemoteServer with WithRemoteSkillsFederation): manifests rewritten to the same root, digests untouched, and reads routed back to the owning server with the namespace stripped (see ReadResource). Listing and caching run through the same shared machinery as the registered path.

Listings are cached per server under the same cache-key and bound rules as tool lists (CacheTTL zero uses DefaultRemoteSkillsCacheTTL; negative disables caching), so prompts and listings cost at most one hit per server per TTL. A server that fails to list is reported and skipped, never fatal to the rest.

func (*RemoteProvider) ReadResource added in v0.28.0

func (p *RemoteProvider) ReadResource(ctx context.Context, uri string) (*ResourceResponse, error)

ReadResource fans a resources/read out to all of the current request's remote servers, in resolver order, and returns the first hit — mirroring Server.ReadResource's own remote fan-out (see resources.go), since a federated server's resource URIs are opaque and not namespaced by server the way tool names are. One exception: a namespaced skill URI (skill://<ns>/…) published by RemoteProvider.ListSkills routes to the one server named by the namespace, with the segment stripped back to the remote's own URI, and the response echoes the namespaced URI the caller asked for. Returns ErrUnknownResource if no server has the resource; when one or more servers failed outright (rather than answering not-found), the returned error still wraps ErrUnknownResource but names each failing server, per the ResourceProvider miss contract.

type RemoteProviderConfig added in v0.19.0

type RemoteProviderConfig struct {
	// Name is the namespace applied to the server's tool names (e.g. a Name of
	// "github" exposes the remote tool "list_repos" as "github__list_repos").
	// It must be unique within a single resolver result.
	Name string

	// URL is the remote MCP server endpoint.
	URL string

	// Auth is a static auth provider for the server. Ignored when AuthFunc is set.
	// May be nil for unauthenticated servers.
	Auth AuthProvider

	// AuthFunc lazily resolves auth for the current request. Takes precedence
	// over Auth. Use this for per-user credentials (e.g. OAuth tokens looked up
	// from a store) so the lookup only happens when the server is used.
	AuthFunc AuthResolver

	// Visibility controls whether the server's tools appear in tools/list
	// (ToolVisibilityNative) or are only reachable via tool_search
	// (ToolVisibilityDiscoverable).
	Visibility ToolVisibility

	// ToolFilter optionally restricts which tools are exposed. It receives the
	// original (un-namespaced) tool name and returns true to include it. Applied
	// on both the list and call paths. Nil means expose all tools.
	ToolFilter ToolFilterFunc

	// CacheTTL is how long this server's tool list is cached. Zero uses
	// DefaultRemoteToolCacheTTL. Negative disables caching.
	CacheTTL time.Duration

	// ListTimeout bounds how long this server's tools/list call may take
	// before GetTools treats it as failed and skips it. Zero uses
	// DefaultRemoteToolListTimeout; negative disables the bound (waits as
	// long as the caller's context allows). Only applies to tools/list —
	// ExecuteTool has no default timeout (see CallTimeout), since tool calls
	// (unlike listing) may legitimately run long.
	ListTimeout time.Duration

	// CallTimeout optionally bounds how long a single ExecuteTool call to
	// this server may take. Unlike ListTimeout, the zero value here means no
	// bound at all — waits as long as the caller's context allows — because a
	// tool call may legitimately run long and a default cap here would risk
	// silently breaking one. Set this explicitly if you want tool calls to a
	// specific server bounded (e.g. because you know its tools are quick, or
	// because you want ExecuteTool to hand a hung server's failure to your
	// OnServerError hook promptly instead of waiting on the caller's own
	// context, which may have no deadline).
	CallTimeout time.Duration

	// CacheKey overrides the cache key for this server's tool list. Defaults to
	// Name + "\x00" + URL. Set this to include a user/tenant identifier when tool
	// catalogs differ per user and must not be shared.
	//
	// The cache is bounded: it holds at most a fixed number of entries (see
	// WithMaxCacheEntries / DefaultRemoteToolCacheMaxEntries) and evicts the
	// least-recently-used entry when full, so a per-user CacheKey cannot grow
	// memory without limit. For very large user populations you may still want a
	// shorter CacheTTL or a larger max so active users are not evicted too soon.
	CacheKey string

	// HTTPPool optionally provides a custom HTTP pool (e.g. for self-signed
	// internal services). Nil uses the default secure pool.
	HTTPPool pool.HTTPPool

	// Keywords are extra search keywords attached to this server's tools. The
	// server namespace and "remote" are always included.
	Keywords []string
}

RemoteProviderConfig describes a single remote MCP server that a RemoteProvider should expose for the current request. The consumer owns "which servers does this user have and how do they authenticate"; the library owns fetching, caching, namespacing, visibility, filtering and dispatch.

type RemoteProviderOption added in v0.19.0

type RemoteProviderOption func(*remoteProviderOptions)

RemoteProviderOption configures a RemoteProvider.

func WithMaxCacheEntries added in v0.19.0

func WithMaxCacheEntries(n int) RemoteProviderOption

WithMaxCacheEntries bounds how many distinct cache keys the provider keeps tool lists for. Once exceeded, the least-recently-used entry is evicted. This keeps memory bounded even when CacheKey embeds a per-user/per-tenant id. A value <= 0 uses DefaultRemoteToolCacheMaxEntries.

func WithOnServerError added in v0.26.0

func WithOnServerError(fn func(cfg RemoteProviderConfig, err error)) RemoteProviderOption

WithOnServerError registers a callback invoked whenever a remote server could not be reached or misbehaved — a failed tools/list (GetTools skips the server but does not fail the request), or a genuine transport/protocol failure calling a tool (a *ToolError, meaning the server responded with its own application-level error, does NOT trigger this — that is not a health problem). fn is called synchronously from whichever request goroutine hit the failure and may be called concurrently for different servers; keep it fast and non-blocking (e.g. update in-memory state, log, or send on a channel) rather than doing I/O inline. Use it to log failures and/or drive a health-tracking / background-retry system: nothing else in RemoteProvider surfaces skipped-server failures anywhere.

type RemoteProviderResolver added in v0.19.0

type RemoteProviderResolver func(ctx context.Context) ([]RemoteProviderConfig, error)

RemoteProviderResolver returns the set of remote servers available for the current request. It is called on every list/search/execute that reaches the provider, so it should read request-scoped information (user, tenant) from the context. Returning an error fails the operation; returning an empty slice simply exposes no remote tools.

type RemoteServerEntry added in v0.12.11

type RemoteServerEntry struct {
	Client       *Client
	Visibility   ToolVisibility
	RemoteSearch bool // Delegate tool_search to this remote server
	// ExcludeApps skips the remote's MCP Apps tools (any tool whose
	// _meta.ui links it to a ui:// resource): they are absent from
	// tools/list and tool_search, and not callable through this server.
	// An app view speaks bare, host-agnostic tool names, so re-serving it
	// under a federation namespace breaks its in-page calls to its own
	// tools — a federating server that renders no views of its own should
	// always set this.
	ExcludeApps bool
	// FederateSkills serves the remote's skills through this server's
	// skills/list and skills/get under skill://<namespace>/… URIs, with file
	// reads routed back to the owning server. See [WithRemoteSkillsFederation].
	FederateSkills bool
}

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

type RemoteServerOption added in v0.17.0

type RemoteServerOption func(*remoteServerOptions)

RemoteServerOption configures options when registering a remote server.

func WithRemoteExcludeApps added in v0.28.0

func WithRemoteExcludeApps() RemoteServerOption

WithRemoteExcludeApps skips the remote's MCP Apps tools (any tool whose _meta.ui links it to a ui:// resource) when federating it onto this server: absent from tools/list and tool_search, and not callable. See RemoteServerEntry.ExcludeApps for why a federating server that renders no views of its own should always set this.

func WithRemoteSearch added in v0.17.0

func WithRemoteSearch() RemoteServerOption

WithRemoteSearch enables delegating tool_search to this remote server. Results from the remote are prefixed with the server's namespace.

func WithRemoteSkillsFederation added in v0.28.0

func WithRemoteSkillsFederation() RemoteServerOption

WithRemoteSkillsFederation serves the remote's skills through this server's skills/list and skills/get: every URI is published with the server's namespace as the first path segment (skill://<ns>/<skill-path>/ SKILL.md), the manifest's resource URIs are rewritten to match, and file reads route back to the owning server with the namespace stripped. The rewrite is the one the skills spec sanctions: relative references inside a SKILL.md resolve against the skill's root, so every supporting-file read stays inside the rewritten namespace, and digests are computed over bytes, so they survive it.

type RemoteSkillsResult added in v0.28.0

type RemoteSkillsResult struct {
	Namespace string
	Skills    []Skill
}

RemoteSkillsResult is one source's listing, namespace attached.

type RemoteSkillsSource added in v0.28.0

type RemoteSkillsSource struct {
	Namespace string
	Client    *Client
	CacheKey  string
}

RemoteSkillsSource is one remote server whose skills feed a chat-side listing: Namespace labels its skills in prompt lines, Client is the connection to fetch through, and CacheKey overrides the cache identity (default: the namespace) for callers whose sources are scoped more finely — per user, say.

type ResourceBuilder added in v0.21.0

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

ResourceBuilder is a fluent builder for a static resource. A static resource has a fixed URI, appears in resources/list, and is read verbatim by resources/read. Register it with Server.RegisterResource.

func NewResource added in v0.21.0

func NewResource(uri, name, description, mimeType string) *ResourceBuilder

NewResource creates a static resource descriptor.

  • uri is the resource's absolute URI (e.g. "config://app").
  • name is a short human-readable identifier.
  • description is optional explanatory text shown to the model/client.
  • mimeType is optional (e.g. "application/json"); pass "" to omit.

func (*ResourceBuilder) Description added in v0.21.0

func (r *ResourceBuilder) Description() string

Description returns the resource's description.

func (*ResourceBuilder) Icons added in v0.27.0

func (r *ResourceBuilder) Icons(icons ...Icon) *ResourceBuilder

Icons attaches visual identifiers to the resource's resources/list descriptor. See Icon for the shape and the security precautions consumers must apply.

func (*ResourceBuilder) Meta added in v0.27.0

func (r *ResourceBuilder) Meta(key string, value any) *ResourceBuilder

Meta attaches an arbitrary field to the resource's _meta object, serialized on its resources/list descriptor. See ResourceBuilder.UIMeta for the MCP Apps case.

func (*ResourceBuilder) MimeType added in v0.21.0

func (r *ResourceBuilder) MimeType() string

MimeType returns the resource's MIME type (may be empty).

func (*ResourceBuilder) Name added in v0.21.0

func (r *ResourceBuilder) Name() string

Name returns the resource's name.

func (*ResourceBuilder) ToMCPResource added in v0.21.0

func (r *ResourceBuilder) ToMCPResource() MCPResource

ToMCPResource converts the builder to an MCPResource descriptor.

func (*ResourceBuilder) UIMeta added in v0.27.0

UIMeta attaches MCP Apps security/rendering hints (_meta.ui) to this resource's resources/list descriptor. These are usually only needed on the resources/read response (see NewUIResourceResponseText); set them here too if a host should see them before fetching the content.

func (*ResourceBuilder) URI added in v0.21.0

func (r *ResourceBuilder) URI() string

URI returns the resource's URI.

type ResourceContent

type ResourceContent struct {
	URI      string         `json:"uri"`
	MimeType string         `json:"mimeType,omitempty"`
	Text     string         `json:"text,omitempty"`
	Blob     string         `json:"blob,omitempty"`  // base64 encoded
	Meta     map[string]any `json:"_meta,omitempty"` // Extension metadata, e.g. MCP Apps' ui.csp
}

type ResourceHandler added in v0.21.0

type ResourceHandler func(ctx context.Context, req *ResourceRequest) (*ResourceResponse, error)

ResourceHandler returns the content of a resource.

The handler receives a *ResourceRequest: use ResourceRequest.URI for the full URI being read, and ResourceRequest.String / ResourceRequest.StringOr to read template variables extracted by the server. For a static resource there are no variables, so only URI is meaningful.

Build the response with NewResourceResponseText or NewResourceResponseBlob.

type ResourceProvider added in v0.21.0

type ResourceProvider interface {
	// GetResources returns the resources and resource templates this provider
	// exposes for the request. The context carries tenant/user/session
	// information for filtering. Return a non-nil, empty ProvidedResources if
	// the provider has nothing to expose.
	GetResources(ctx context.Context) (*ProvidedResources, error)

	// ReadResource returns the content of the resource identified by uri.
	//
	// Miss contract: if this provider does not handle the uri, return
	// (nil, ErrUnknownResource). Any other non-nil error aborts dispatch and is
	// returned to the caller, so only use it for genuine failures, not misses.
	ReadResource(ctx context.Context, uri string) (*ResourceResponse, error)
}

ResourceProvider is the interface that providers implement to expose resources scoped to a request — for example per-user or per-session data.

It is the resource analogue of ToolProvider: attach instances to the request context with WithResourceProviders and the server merges them with any statically-registered resources when serving resources/list, resources/templates/list and resources/read.

func GetResourceProviders added in v0.21.0

func GetResourceProviders(ctx context.Context) []ResourceProvider

GetResourceProviders returns the resource providers from the context, or nil if none are attached.

type ResourceRequest added in v0.21.0

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

ResourceRequest provides the URI and any expanded template variables for a resources/read call. It is the resource analogue of *ToolRequest and *PromptRequest.

func NewResourceRequest added in v0.21.0

func NewResourceRequest(uri string, vars map[string]string) *ResourceRequest

NewResourceRequest builds a ResourceRequest from a URI and an optional map of template variables. Handlers normally receive a ready-made request; this constructor exists for tests and providers that build their own.

func (*ResourceRequest) String added in v0.21.0

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

String returns a template variable by name. Returns ErrUnknownParameter if the variable is not present (for example, on a static resource, which has none).

func (*ResourceRequest) StringOr added in v0.21.0

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

StringOr returns a template variable or defaultValue if the variable is absent.

func (*ResourceRequest) URI added in v0.21.0

func (r *ResourceRequest) URI() string

URI returns the full URI being read. For a template this is the expanded URI the client requested.

func (*ResourceRequest) Vars added in v0.21.0

func (r *ResourceRequest) Vars() map[string]string

Vars returns all expanded template variables. The map is empty for static resources. The returned map is not copied; do not mutate it.

type ResourceResponse

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

func NewResourceResponseBlob

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

func NewResourceResponseText

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

func NewUIResourceResponseText added in v0.27.0

func NewUIResourceResponseText(uri, html string, meta *UIResourceMeta) *ResourceResponse

NewUIResourceResponseText builds a resources/read response for an MCP Apps UI resource. mimeType is fixed to UIAppMimeType; html must be a self-contained HTML5 document. meta may be nil to omit rendering hints and accept the host's restrictive default sandbox.

func (*ResourceResponse) WithMeta added in v0.27.0

func (rr *ResourceResponse) WithMeta(meta map[string]any) *ResourceResponse

WithMeta attaches an arbitrary _meta object to the first content entry of a resource response, returning rr for chaining. Used for extensions such as MCP Apps; see NewUIResourceResponseText for the common case.

type ResourceTemplateBuilder added in v0.21.0

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

ResourceTemplateBuilder is a fluent builder for a resource template. A resource template has a URI containing {var} placeholders (RFC 6570 level 1), appears in resources/templates/list, and is expanded by the client into a concrete URI before being read via resources/read. Register it with Server.RegisterResourceTemplate.

func NewResourceTemplate added in v0.21.0

func NewResourceTemplate(uriTemplate, name, description, mimeType string) *ResourceTemplateBuilder

NewResourceTemplate creates a parameterized resource template descriptor.

  • uriTemplate contains one or more {var} placeholders, e.g. "user://{id}". A placeholder matches one or more characters in the requested URI.
  • name, description and mimeType are as for NewResource.

func (*ResourceTemplateBuilder) Description added in v0.21.0

func (t *ResourceTemplateBuilder) Description() string

Description returns the template's description.

func (*ResourceTemplateBuilder) Icons added in v0.27.0

Icons attaches visual identifiers to the template's resources/templates/list descriptor. See Icon for the shape and the security precautions consumers must apply.

func (*ResourceTemplateBuilder) Meta added in v0.27.0

Meta attaches an arbitrary field to the template's _meta object, serialized on its resources/templates/list descriptor.

func (*ResourceTemplateBuilder) MimeType added in v0.21.0

func (t *ResourceTemplateBuilder) MimeType() string

MimeType returns the template's MIME type (may be empty).

func (*ResourceTemplateBuilder) Name added in v0.21.0

func (t *ResourceTemplateBuilder) Name() string

Name returns the template's name.

func (*ResourceTemplateBuilder) ToMCPResourceTemplate added in v0.21.0

func (t *ResourceTemplateBuilder) ToMCPResourceTemplate() MCPResourceTemplate

ToMCPResourceTemplate converts the builder to an MCPResourceTemplate descriptor.

func (*ResourceTemplateBuilder) UIMeta added in v0.27.0

UIMeta attaches MCP Apps security/rendering hints (_meta.ui) to this template's resources/templates/list descriptor.

func (*ResourceTemplateBuilder) URITemplate added in v0.21.0

func (t *ResourceTemplateBuilder) URITemplate() string

URITemplate returns the template's URI template string.

type SearchResult added in v0.9.0

type SearchResult struct {
	Name        string         `json:"name"`
	Description string         `json:"description"`
	Score       float64        `json:"score"`
	InputSchema any            `json:"inputSchema,omitempty"`
	Keywords    []string       `json:"keywords,omitempty"`
	Meta        map[string]any `json:"_meta,omitempty"` // Extension metadata, e.g. MCP Apps' ui.resourceUri
	Icons       []Icon         `json:"icons,omitempty"`
}

SearchResult represents a tool found via search

type Server

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

Server represents an MCP server instance.

Design Philosophy

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

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

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

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

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

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

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

Lifecycle: configure the server (SetInstructions, SetSessionManager, RegisterTool/RegisterTools, RegisterRemoteServer/ReplaceRemoteServers) before you start serving with HandleRequest. Each individual method is safe to call concurrently, but mutating registration while requests are in flight is discouraged: a tools/list or tools/call running concurrently with a RegisterTool may observe the tool set either before or after the change. For per-request or per-user tools, prefer ToolProvider with WithToolProviders rather than mutating the shared server.

func NewServer

func NewServer(name, version string) *Server

NewServer creates a new MCP server instance.

func (*Server) AllowOrigins added in v0.27.0

func (s *Server) AllowOrigins(origins ...string)

AllowOrigins widens the current origin validator (the default policy, unless Server.SetOriginValidator was already called) to also accept requests whose Origin header exactly matches one of origins, e.g. "https://app.example.com". Call this when real browser JavaScript needs to reach this server directly from a specific origin — see [defaultOriginValidator]'s doc comment for why most deployments don't.

func (*Server) CallTool

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

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

func (*Server) ClientCapabilities added in v0.27.0

func (s *Server) ClientCapabilities() map[string]any

ClientCapabilities returns the capabilities object (capabilities.extensions, roots, sampling, etc., as sent in initialize) declared by the most recently initialized client.

For a stdio server — one process per client connection, the common case for locally-spawned MCP servers — this reliably reflects the single connected client. An HTTP server handling multiple concurrent client sessions should not rely on this for per-request decisions: it is a single process-wide value reflecting only the most recent initialize seen across all sessions, not any particular request's caller. This is deliberately not upgraded to per-session tracking here: doing so with an in-memory map would silently misbehave in exactly the deployment this library optimizes an HTTP server for — horizontal scaling behind a load balancer with JWTSessionManager, where a later request from the same client can land on a different, stateless instance that never saw that client's initialize. If you need per-request extension awareness on HTTP, the robust option is to register UI-linked tools unconditionally (the UIAppsExtensionID cost to a non-supporting host is nil — it just ignores unknown `_meta`) rather than branching on this method. Use SupportsUIApps to interpret the MCP Apps extension's settings from the returned map.

func (*Server) DeclareExtension added in v0.27.0

func (s *Server) DeclareExtension(id string, settings map[string]any)

DeclareExtension advertises this server's support for an MCP extension (per SEP-1724) in its initialize response, under capabilities.extensions[id]. Call it during setup, before serving. For example, a server offering MCP Apps (SEP-1865) tools would declare:

server.DeclareExtension(mcp.UIAppsExtensionID, map[string]any{
	"mimeTypes": []string{mcp.UIAppMimeType},
})

func (*Server) GetPrompt added in v0.21.0

func (s *Server) GetPrompt(ctx context.Context, name string, args map[string]string) (*PromptResponse, error)

GetPrompt renders a prompt by name with the given arguments. Resolution order:

  1. Statically-registered prompts (exact name match).
  2. [PromptProvider]s on ctx, in attachment order (first hit wins).

Required arguments are validated before the handler runs. Returns ErrUnknownPrompt if nothing handles the name.

func (*Server) GetSkill added in v0.28.0

func (s *Server) GetSkill(uri string) (*Skill, bool)

GetSkill returns one skill's entry by URI: the SKILL.md URI or the root directory URI (no trailing slash). ok is false for a URI the server does not serve, which callers report as -32602 per the extension.

func (*Server) GetSkillWithContext added in v0.28.0

func (s *Server) GetSkillWithContext(ctx context.Context, uri string) (*Skill, bool)

GetSkillWithContext resolves one skill's entry by URI — the resolver behind skills/get: the static registry first, then any [SkillProvider]s on ctx. Both the SKILL.md URI and the root directory URI are accepted, per GetSkill.

func (*Server) HandleRequest

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

HandleRequest handles MCP protocol requests

func (*Server) ListPrompts added in v0.21.0

func (s *Server) ListPrompts(ctx context.Context) []MCPPrompt

ListPrompts returns all registered prompts plus any contributed by [PromptProvider]s on ctx, sorted by name. Duplicates (by name) are removed, with static registrations taking precedence.

func (*Server) ListResourceTemplates added in v0.21.0

func (s *Server) ListResourceTemplates(ctx context.Context) []MCPResourceTemplate

ListResourceTemplates returns all registered resource templates plus any contributed by [ResourceProvider]s on ctx, sorted by URITemplate. Duplicates (by URITemplate) are removed, with static registrations taking precedence.

func (*Server) ListResources added in v0.21.0

func (s *Server) ListResources(ctx context.Context) []MCPResource

ListResources returns all registered static resources plus any contributed by [ResourceProvider]s on ctx, sorted by URI. Duplicates (by URI) are removed, with static registrations taking precedence.

func (*Server) ListSkills added in v0.28.0

func (s *Server) ListSkills() []Skill

ListSkills returns the registered skills, sorted by URI.

func (*Server) ListSkillsWithContext added in v0.28.0

func (s *Server) ListSkillsWithContext(ctx context.Context) []Skill

func (*Server) ListToolsWithContext added in v0.9.0

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

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

func (*Server) NotifyPromptsChanged added in v0.21.0

func (s *Server) NotifyPromptsChanged()

NotifyPromptsChanged emits notifications/prompts/listChanged. RegisterPrompt and UnregisterPrompt emit automatically; call this for external/prompt-provider changes.

func (*Server) NotifyResourcesChanged added in v0.21.0

func (s *Server) NotifyResourcesChanged()

NotifyResourcesChanged emits notifications/resources/listChanged. Register*, UnregisterResource and RegisterResourceTemplate emit automatically; call this for external/resource-provider changes.

func (*Server) NotifyToolsChanged added in v0.21.0

func (s *Server) NotifyToolsChanged()

NotifyToolsChanged emits notifications/tools/listChanged to every connected client, signalling that its cached tool list is stale and should be re-fetched.

RegisterTool, RegisterTools and UnregisterTool emit this automatically. Call this method for changes the server cannot detect itself — for example when a ToolProvider's backing data changes, or when tools are loaded from an external source that mutates at runtime.

func (*Server) ReadResource added in v0.21.0

func (s *Server) ReadResource(ctx context.Context, uri string) (*ResourceResponse, error)

ReadResource resolves a URI to its content. Resolution order:

  1. Static resources by exact URI match.
  2. Static resource templates by pattern match (first match wins).
  3. [ResourceProvider]s on ctx, in attachment order (first hit wins).
  4. Remote servers registered via Server.ReplaceRemoteServers / Server.RegisterRemoteServer, tried in registration order (first hit wins). Unlike tools, remote resources aren't namespaced or cached in a lookup table — a federated server's resource URIs (e.g. a `ui://` MCP Apps view) are opaque and forwarded as-is, so this is a best-effort fan-out rather than an indexed lookup. That fan-out is bounded in two dimensions: per-attempt by [remoteResourceFanoutTimeout], and in depth by [maxResourceFanoutHops]' cycle guard, so mutually-federated servers can't loop or amplify an unresolved read.

Returns ErrUnknownResource if nothing handles the uri. When one or more remotes failed outright (rather than answering not-found), the returned error still wraps ErrUnknownResource — errors.Is holds — but names each failing remote, so a misconfigured or down federation is diagnosable instead of masquerading as a plain miss. See Server.ReadResourceFrom for a variant restricted to one specific source rather than fanning out to every registered remote.

func (*Server) ReadResourceFrom added in v0.27.0

func (s *Server) ReadResourceFrom(ctx context.Context, source, uri string) (*ResourceResponse, error)

ReadResourceFrom reads uri restricted to a single source, as identified by Server.ToolSource: "" for this server's own native resources only (static, templates, providers — no fan-out to any remote), or a remote server's Client.BaseURL to read from that one remote exclusively, never falling through to any other registered remote the way Server.ReadResource's fan-out does. Returns ErrUnknownResource if source doesn't match any registered remote, or if uri isn't found there.

Pairs with ToolSource for a host enforcing that an MCP Apps view may only read a resource belonging to the same server as the tool that mounted it: ReadResourceFrom(ctx, toolSource, uri) rather than the ambient ReadResource(ctx, uri), which would otherwise happily serve a same-named (or any) resource from a completely different federated server than the one the view is scoped to.

func (*Server) RefreshTools

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

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

func (*Server) RegisterPrompt added in v0.21.0

func (s *Server) RegisterPrompt(pb *PromptBuilder, handler PromptHandler)

RegisterPrompt registers a prompt. The prompt appears in prompts/list and is rendered by prompts/get. Registering a prompt with a name that already exists replaces the previous one.

Thread-safe. For per-request or per-user prompts, prefer WithPromptProviders over mutating the shared server.

func (*Server) RegisterRemoteServer

func (s *Server) RegisterRemoteServer(client *Client, opts ...RemoteServerOption) error

RegisterRemoteServer registers a remote MCP server with native visibility. Remote server tools appear in tools/list and are directly callable.

func (*Server) RegisterRemoteServerDiscoverable added in v0.10.0

func (s *Server) RegisterRemoteServerDiscoverable(client *Client, opts ...RemoteServerOption) error

RegisterRemoteServerDiscoverable registers a remote MCP server with discoverable visibility. Remote server tools do NOT appear in tools/list but are searchable via tool_search.

func (*Server) RegisterResource added in v0.21.0

func (s *Server) RegisterResource(rb *ResourceBuilder, handler ResourceHandler)

RegisterResource registers a static resource. The resource appears in resources/list and is served by resources/read. Registering a resource with a URI that already exists replaces the previous one.

Thread-safe. Configure before serving in simple setups; concurrent registration while requests are in flight is permitted (readers observe either the old or new set) but discouraged for per-request data — use WithResourceProviders instead.

func (*Server) RegisterResourceTemplate added in v0.21.0

func (s *Server) RegisterResourceTemplate(tb *ResourceTemplateBuilder, handler ResourceHandler)

RegisterResourceTemplate registers a parameterized resource template. The template appears in resources/templates/list; a client expands it into a concrete URI and reads it via resources/read. The handler receives the expanded URI and is responsible for parsing any variables out of it.

A template's URITemplate may contain one or more {var} placeholders. Each placeholder matches one or more characters in the requested URI. Templates are matched in registration order; the first match wins.

Thread-safe.

func (*Server) RegisterSkill added in v0.28.0

func (s *Server) RegisterSkill(skill *SkillBuilder) error

RegisterSkill adds a skill to the server: its files become readable resources and it appears in skills/list. Registering the first skill also declares the skills extension capability.

Returns an error — before any state changes — for a skill with no SKILL.md at its root, or whose frontmatter name does not equal the final path segment of its URI (skill://…/<name>/SKILL.md); both are required by the Agent Skills specification. Callers reading skills from files or databases should skip such entries with a warning rather than abort.

func (*Server) RegisterTool

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

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

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

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

func (*Server) RegisterTools added in v0.8.0

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

RegisterTools registers multiple tools with the server in a single batch, notifying subscribers once at the end. Each tool's visibility is determined by whether Discoverable() was called on its ToolBuilder.

func (*Server) ReplaceRemoteServers added in v0.12.11

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

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

func (*Server) ServeStdio added in v0.20.0

func (s *Server) ServeStdio(ctx context.Context, opts ...StdioOption) error

ServeStdio serves the MCP protocol over newline-delimited JSON-RPC 2.0 on os.Stdin/os.Stdout. It is the entry point for an MCP stdio server (the transport a host launches as a subprocess). It blocks until stdin reaches EOF.

Anything written to stdout must be protocol frames only, so send logs to stderr.

func (*Server) ServeStream added in v0.20.0

func (s *Server) ServeStream(ctx context.Context, in io.Reader, out io.Writer, opts ...StdioOption) error

ServeStream serves the MCP protocol over an arbitrary pair of newline-delimited JSON-RPC 2.0 streams. Use it for in-process pipes or any transport that is not the process's own stdio; ServeStdio wraps it for the common case.

The read loop runs here (in mcp) rather than in jsonrpc.Server.ServeStream so that outbound notifications can share the stream's write mutex, and so the caller's ctx (which carries the show-all flag) is threaded to handlers.

func (*Server) SetIcons added in v0.27.0

func (s *Server) SetIcons(icons ...Icon)

SetIcons attaches visual identifiers to this server's own identity, included as serverInfo.icons in initialize (Legacy) and as _meta["io.modelcontextprotocol/serverInfo"].icons on every Modern-era result and in server/discover. See Icon for the shape and the security precautions consumers must apply.

func (*Server) SetInstructions

func (s *Server) SetInstructions(instructions string)

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

func (*Server) SetOriginValidator added in v0.27.0

func (s *Server) SetOriginValidator(v OriginValidator)

SetOriginValidator overrides how Server.HandleRequest decides whether to accept a request's Origin header, replacing [defaultOriginValidator]'s policy entirely. Pass nil to restore the default. See Server.AllowOrigins for the simpler common case of widening the default rather than replacing it.

func (*Server) SetResponseStreaming added in v0.30.0

func (s *Server) SetResponseStreaming(delay, keepAlive time.Duration)

SetResponseStreaming configures streamed responses for long-running requests (see server_stream.go). delay is how long a request may run before the response switches to an SSE stream; 0 streams immediately and a negative value disables streaming (every response is application/json). keepAlive is the interval between keep-alive comments; <= 0 uses DefaultStreamingKeepAlive. Defaults apply when this is never called.

func (*Server) SetSessionManager added in v0.6.6

func (s *Server) SetSessionManager(manager SessionManager)

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

Example:

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

Use a custom SessionManager when you need:

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

func (*Server) Shutdown added in v0.27.0

func (s *Server) Shutdown()

Shutdown signals every open Modern-era subscriptions/listen stream to close gracefully: each one responds to its original request with a completion result (see the spec's "Graceful Closure") before ending, rather than the connection just going dead when the underlying HTTP server stops. Call it once, before (or while) shutting down the *http.Server this Server is mounted on — for example:

server.Shutdown()
httpServer.Shutdown(ctx)

It has no effect on Legacy clients (the GET SSE stream, handleSSEStream, simply ends when its connection does, matching pre-existing behavior) and is safe to call multiple times or on a server with no open subscriptions.

func (*Server) ToolSource added in v0.27.0

func (s *Server) ToolSource(name string) (source string, ok bool)

ToolSource reports which server a tool name actually resolves to, using the same resolution order as Server.CallTool (native tools first, then the fast toolToServer lookup, then the namespace-prefix fallback for a federated tool discovered via remote tool_search): "" for a tool registered directly on this server, or a federated tool's remote server's own Client.BaseURL — a stable identifier two tool names share if and only if they came from the same server, unlike Namespace, which callers may leave empty (or, in principle, reuse) with no uniqueness guarantee. ok is false if name doesn't resolve via any of these (an unknown name, or one that only a per-request ToolProvider would resolve, which has no persistent "source" the way a registered remote server does).

Intended for a host enforcing that an MCP Apps view may only reach a tool belonging to the same server as the tool that mounted it — see the extension's spec on visibility; the spec's "app" visibility says a view may call a tool, not that it may call one on a *different* server than its own, which visibility alone can't distinguish once two federated servers are aggregated under one endpoint with no namespace prefix.

func (*Server) UnregisterPrompt added in v0.21.0

func (s *Server) UnregisterPrompt(name string) bool

UnregisterPrompt removes a prompt by name. Returns true if a prompt was removed.

func (*Server) UnregisterRemoteServer added in v0.12.11

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

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

func (*Server) UnregisterResource added in v0.21.0

func (s *Server) UnregisterResource(uri string) bool

UnregisterResource removes a static resource by URI. Returns true if a resource was removed.

func (*Server) UnregisterResourceTemplate added in v0.21.0

func (s *Server) UnregisterResourceTemplate(uriTemplate string) bool

UnregisterResourceTemplate removes a resource template by its URI template string. Returns true if a template was removed.

func (*Server) UnregisterSkill added in v0.28.0

func (s *Server) UnregisterSkill(name string) bool

UnregisterSkill removes a skill by name, including its resources.

func (*Server) UnregisterTool added in v0.17.1

func (s *Server) UnregisterTool(name string) bool

UnregisterTool removes a tool by name from the server. Returns true if the tool was found and removed, false otherwise. This is safe to call concurrently.

type SessionManager added in v0.6.6

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

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

	// GetShowAll returns whether the session was created with show-all mode
	GetShowAll(ctx context.Context, sessionID string) (showAll bool, err error)

	// DeleteSession removes a session ahead of its natural expiry
	DeleteSession(ctx context.Context, sessionID string) error
}

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

type Skill added in v0.28.0

type Skill struct {
	// URI is the full resource URI of the skill's SKILL.md.
	URI string `json:"uri"`
	// Frontmatter is the SKILL.md frontmatter (at minimum name and
	// description per the Agent Skills specification).
	Frontmatter map[string]any `json:"frontmatter"`
	// Resources lists every file of the skill directory with its digest
	// (sha256 over the content bytes) and size.
	Resources []SkillResource `json:"resources"`
}

Skill is one skills/list or skills/get entry.

type SkillBuilder added in v0.28.0

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

SkillBuilder builds a skill registration from its files.

func NewSkill added in v0.28.0

func NewSkill(name string) *SkillBuilder

NewSkill creates a skill builder for a skill directory named name (the final skill-path segment; the SKILL.md frontmatter name must match it).

func (*SkillBuilder) Description added in v0.28.0

func (b *SkillBuilder) Description(description string) *SkillBuilder

Description sets the frontmatter description.

func (*SkillBuilder) EntryURI added in v0.28.0

func (b *SkillBuilder) EntryURI() string

EntryURI is the full URI of the skill's SKILL.md.

func (*SkillBuilder) File added in v0.28.0

func (b *SkillBuilder) File(relPath string, content []byte) *SkillBuilder

File adds one file to the skill directory by relative path. A skill MUST contain SKILL.md at its root; registration panics without it (a missing SKILL.md is a programmer error, like an invalid UI visibility).

func (*SkillBuilder) Metadata added in v0.28.0

func (b *SkillBuilder) Metadata(key string, value any) *SkillBuilder

Metadata sets a frontmatter metadata key (e.g. Metadata("version", "1.0.0") becomes frontmatter.metadata.version).

func (*SkillBuilder) Prefix added in v0.28.0

func (b *SkillBuilder) Prefix(segments ...string) *SkillBuilder

Prefix prepends organizational path segments to the skill's URI (e.g. Prefix("acme", "billing") yields skill://acme/billing/<name>/SKILL.md).

func (*SkillBuilder) RootURI added in v0.28.0

func (b *SkillBuilder) RootURI() string

RootURI is the skill's root directory URI (no trailing slash).

type SkillProvider added in v0.28.0

type SkillProvider interface {
	// ListSkills returns the skills this provider exposes for the request.
	// The context carries tenant/user/session information for filtering.
	// Return a nil or empty slice when the provider has nothing to expose.
	ListSkills(ctx context.Context) ([]Skill, error)
}

SkillProvider is the interface that providers implement to expose skills scoped to a request — for example a per-user catalog served from a database rather than the server's static registry.

It is the skills analogue of ToolProvider and ResourceProvider: attach instances to the request context with WithSkillProviders and the server merges them with any statically-registered skills (see Server.RegisterSkill) when serving skills/list and skills/get. A provider whose skills carry files should also implement ResourceProvider so those files answer resources/read.

func GetSkillProviders added in v0.28.0

func GetSkillProviders(ctx context.Context) []SkillProvider

GetSkillProviders returns the skill providers from the context, or nil if none are attached.

type SkillResource added in v0.28.0

type SkillResource struct {
	URI    string `json:"uri"`
	Digest string `json:"digest"`
	Size   int64  `json:"size"`
}

SkillResource is one skill file's listing entry.

type SkillsListingCache added in v0.28.0

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

SkillsListingCache caches per-source skills/list results and refreshes them in parallel, each fetch with its own budget. Built for chat-side prompt assembly (knot, llmrouter): a slow or dead remote is skipped without starving the others, and repeat prompts don't pay the round trips again within the TTL.

The zero value is ready to use, with a one-minute TTL and a one-second per-source budget; NewSkillsListingCache overrides either. Failed fetches are not cached — the next listing retries them.

func NewSkillsListingCache added in v0.28.0

func NewSkillsListingCache(ttl, fetchBudget time.Duration) *SkillsListingCache

NewSkillsListingCache sets the listing TTL and the per-source fetch budget. Zero for either keeps that default (one minute, one second).

func (*SkillsListingCache) Invalidate added in v0.28.0

func (c *SkillsListingCache) Invalidate()

Invalidate drops every cached listing (a source set that changed shape — servers added or removed — should not keep serving the old ones).

func (*SkillsListingCache) Listings added in v0.28.0

func (c *SkillsListingCache) Listings(ctx context.Context, sources []RemoteSkillsSource, onErr func(namespace string, err error)) []RemoteSkillsResult

Listings returns every source's skills, fetching uncached sources in parallel, each with its own budget. Sources whose fetch fails are skipped after onErr (which may be nil) — one dead remote never blanks the rest. Results keep source order and are not re-sorted: callers that need deterministic output sort by namespace themselves.

type StdioClientOption added in v0.20.0

type StdioClientOption func(*stdioClientConfig)

StdioClientOption configures a subprocess-backed stdio client.

func WithClientDir added in v0.20.0

func WithClientDir(dir string) StdioClientOption

WithClientDir sets the working directory for the child server process.

func WithClientEnv added in v0.20.0

func WithClientEnv(env []string) StdioClientOption

WithClientEnv sets the environment for the child server process. It replaces the entire environment: every variable the child sees must be listed, including PATH, HOME, etc. For the more common case of adding or overriding a few variables while keeping the parent environment, use WithClientExtraEnv instead.

func WithClientExtraEnv added in v0.23.0

func WithClientExtraEnv(kv ...string) StdioClientOption

WithClientExtraEnv adds or overrides the given KEY=VALUE environment variables in the child server process's environment, on top of the environment it would otherwise inherit (the parent's, or the full replacement set by WithClientEnv). Entries use os.Environ's "KEY=VALUE" form. Multiple options accumulate; for a repeated key the last value wins.

Unlike WithClientEnv (which replaces the whole environment), this keeps the parent environment intact so PATH, HOME, etc. remain available to the server.

func WithClientOnExit added in v0.20.0

func WithClientOnExit(fn func(error)) StdioClientOption

WithClientOnExit registers a callback invoked exactly once when the spawned server process exits — whether it crashes mid-session or is shut down by Client.Close. It is invoked asynchronously from a reaper goroutine, so it fires even if Close is never called; it must not block.

Without this, a caller has no way to learn that its child server has died other than subsequent calls failing. This is passed through to jsonrpc.WithOnExit.

func WithClientStderr added in v0.20.0

func WithClientStderr(w io.Writer) StdioClientOption

WithClientStderr routes the child server's standard error to w (default: inherited from the parent). Pass io.Discard to silence it.

type StdioOption added in v0.20.0

type StdioOption func(*stdioConfig)

StdioOption configures a stdio MCP server run.

func WithStdioShowAllTools added in v0.20.0

func WithStdioShowAllTools() StdioOption

WithStdioShowAllTools makes the stdio server expose every tool (including discoverable ones) on tools/list, bypassing the discovery meta-tools. It is the stdio equivalent of the HTTP show-all header/query flag.

type ToolBuilder

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

ToolBuilder provides fluent API for building tools

func NewTool

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

NewTool creates a new tool with the declarative API

func (*ToolBuilder) BuildOutputSchema

func (t *ToolBuilder) BuildOutputSchema() map[string]any

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

func (*ToolBuilder) BuildSchema

func (t *ToolBuilder) BuildSchema() map[string]any

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

func (*ToolBuilder) Description added in v0.6.0

func (t *ToolBuilder) Description() string

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

func (*ToolBuilder) Discoverable added in v0.10.0

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

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

func (*ToolBuilder) Icons added in v0.27.0

func (t *ToolBuilder) Icons(icons ...Icon) *ToolBuilder

Icons attaches visual identifiers to the tool's tools/list descriptor. See Icon for the shape and the security precautions consumers must apply.

func (*ToolBuilder) IsDiscoverable added in v0.10.0

func (t *ToolBuilder) IsDiscoverable() bool

IsDiscoverable returns true if the tool is marked as discoverable.

func (*ToolBuilder) Keywords added in v0.10.0

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

Keywords returns the keywords set for this tool.

func (*ToolBuilder) Meta added in v0.27.0

func (t *ToolBuilder) Meta(key string, value any) *ToolBuilder

Meta attaches an arbitrary field to the tool's _meta object, serialized on its tools/list descriptor. Used by MCP extensions; see ToolBuilder.UIResource for the MCP Apps case.

func (*ToolBuilder) Name added in v0.6.0

func (t *ToolBuilder) Name() string

Name returns the tool's name

func (*ToolBuilder) ToMCPTool added in v0.9.8

func (t *ToolBuilder) ToMCPTool() MCPTool

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

func (*ToolBuilder) UIResource added in v0.27.0

func (t *ToolBuilder) UIResource(resourceURI string, visibility ...string) *ToolBuilder

UIResource links this tool to a companion UI resource per the MCP Apps extension (SEP-1865): a compliant host fetches resourceURI (a ui:// resource registered with Server.RegisterResource) and renders it in a sandboxed iframe to display this tool's results. visibility restricts who may call the tool ("model", "app", or both); omit it to accept the spec default of both.

Hosts that don't support MCP Apps ignore this metadata and treat the tool as a normal text-only tool, so it's safe to attach unconditionally. To register different tool variants per host, check Server.ClientCapabilities with SupportsUIApps before calling this. UIResource and Visibility both target the same "ui" meta entry; each reads back whatever the other already set there so calling both (in either order) composes instead of one silently discarding the other's fields — see UIResource's own doc comment for why a caller might reasonably do that (its own visibility parameter covers the common case, but Visibility remains available to set/change it independently).

func (*ToolBuilder) Visibility added in v0.27.0

func (t *ToolBuilder) Visibility(visibility ...string) *ToolBuilder

Visibility restricts who may call this tool per the MCP Apps extension (SEP-1865), without linking it to a UI resource of its own: "model" (the agent), "app" (the UI itself, via the same server connection), or both. Use this for an app-only "action" tool whose calls always originate from a view that's already open — e.g. a form submission — which therefore has no rendering purpose of its own. Use ToolBuilder.UIResource instead when the tool SHOULD open or refresh a view when called.

type ToolCall added in v0.15.0

type ToolCall struct {
	Name      string
	Arguments map[string]any
}

ToolCall represents a single tool invocation for use with parallel calls.

type ToolCallParams

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

type ToolContent

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

type ToolError

type ToolError struct {
	Code    int
	Message string
	Data    any
}

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

Returning one in a tool handler or provider:

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

Detecting one as a caller (middleware, tests, custom transports) — use errors.As, which also unwraps wrapped errors, to recover the code/message/data:

resp, err := server.CallTool(ctx, name, args)
var toolErr *mcp.ToolError
if errors.As(err, &toolErr) {
    log.Printf("tool error %d: %s (data=%v)", toolErr.Code, toolErr.Message, toolErr.Data)
}

func (*ToolError) Error

func (e *ToolError) Error() string

type ToolFilterFunc added in v0.9.9

type ToolFilterFunc func(toolName string) bool

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

type ToolHandler

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

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

type ToolProvider added in v0.9.0

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

	// ExecuteTool executes a tool by name and returns its response.
	//
	// Miss contract: if this provider does not handle the named tool, return
	// (nil, nil). This is the canonical "not handled" signal and lets the
	// server (or a MultiProvider) try the next provider. Returning
	// (nil, ErrUnknownTool) is also accepted for the same purpose and behaves
	// identically. Any other non-nil error aborts dispatch and is returned to
	// the caller, so only use it for genuine failures, not for misses.
	//
	// Build the response with the NewToolResponse* constructors. If you have a
	// loose value (a string or any JSON-encodable type) rather than an
	// already-built response, wrap it with NewToolResponseAuto.
	ExecuteTool(ctx context.Context, name string, params map[string]any) (*ToolResponse, error)
}

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

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

func GetToolProviders added in v0.9.0

func GetToolProviders(ctx context.Context) []ToolProvider

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

type ToolRegistration added in v0.8.0

type ToolRegistration struct {
	Tool    *ToolBuilder
	Handler ToolHandler
}

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

func NewToolRegistration added in v0.8.0

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

NewToolRegistration creates a tool registration for use with RegisterTools.

type ToolRequest

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

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

func NewToolRequest added in v0.6.0

func NewToolRequest(args map[string]any) *ToolRequest

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

func (*ToolRequest) Args added in v0.6.3

func (r *ToolRequest) Args() map[string]any

Args returns all arguments as a map

func (*ToolRequest) Bool

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

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

func (*ToolRequest) BoolOr

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

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

func (*ToolRequest) BoolSlice added in v0.9.0

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

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

func (*ToolRequest) BoolSliceOr added in v0.9.0

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

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

func (*ToolRequest) Float

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

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

func (*ToolRequest) FloatOr

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

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

func (*ToolRequest) FloatSlice

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

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

func (*ToolRequest) FloatSliceOr

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

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

func (*ToolRequest) Int

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

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

func (*ToolRequest) IntOr

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

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

func (*ToolRequest) IntSlice

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

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

func (*ToolRequest) IntSliceOr

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

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

func (*ToolRequest) Object

func (r *ToolRequest) Object(name string) (map[string]any, error)

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

func (*ToolRequest) ObjectBool added in v0.19.0

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

ObjectBool extracts a bool property from an object parameter.

func (*ToolRequest) ObjectBoolOr added in v0.19.0

func (r *ToolRequest) ObjectBoolOr(objectName, propertyName string, defaultValue bool) bool

ObjectBoolOr extracts a bool property from an object parameter, returning defaultValue when the object or property is missing or not a boolean.

func (*ToolRequest) ObjectInt added in v0.19.0

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

ObjectInt extracts an int property from an object parameter.

func (*ToolRequest) ObjectIntOr added in v0.19.0

func (r *ToolRequest) ObjectIntOr(objectName, propertyName string, defaultValue int) int

ObjectIntOr extracts an int property from an object parameter, returning defaultValue when the object or property is missing or not a number.

func (*ToolRequest) ObjectOr

func (r *ToolRequest) ObjectOr(name string, defaultValue map[string]any) map[string]any

ObjectOr returns a parameter as an object or the default value

func (*ToolRequest) ObjectProperty added in v0.19.0

func (r *ToolRequest) ObjectProperty(objectName, propertyName string) (any, error)

GetObjectProperty extracts a property from an object parameter ObjectProperty extracts a property from an object parameter.

func (*ToolRequest) ObjectSlice

func (r *ToolRequest) ObjectSlice(name string) ([]map[string]any, error)

ObjectSlice returns a parameter as a slice of objects

func (*ToolRequest) ObjectSliceOr

func (r *ToolRequest) ObjectSliceOr(name string, defaultValue []map[string]any) []map[string]any

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

func (*ToolRequest) ObjectString added in v0.19.0

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

ObjectString extracts a string property from an object parameter.

func (*ToolRequest) ObjectStringOr added in v0.19.0

func (r *ToolRequest) ObjectStringOr(objectName, propertyName, defaultValue string) string

ObjectStringOr extracts a string property from an object parameter, returning defaultValue when the object or property is missing or not a string.

func (*ToolRequest) String

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

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

func (*ToolRequest) StringOr

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

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

func (*ToolRequest) StringSlice

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

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

func (*ToolRequest) StringSliceOr

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

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

type ToolResponse

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

ToolResponse represents the response from a tool

func NewToolResponseAudio

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

func NewToolResponseAuto added in v0.19.0

func NewToolResponseAuto(value any) *ToolResponse

NewToolResponseAuto builds a ToolResponse from a loose value, applying the same conversion the server uses internally:

  • a *ToolResponse is returned unchanged,
  • a string becomes a text response,
  • anything else is JSON-encoded.

Use it in ToolProvider.ExecuteTool when you have a dynamic value (e.g. the output of a script or a remote call) rather than an already-built response. Prefer the specific NewToolResponse* constructors when you know the type.

func NewToolResponseImage

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

func NewToolResponseJSON

func NewToolResponseJSON(data any) *ToolResponse

func NewToolResponseMulti

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

func NewToolResponseResource

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

func NewToolResponseStructured

func NewToolResponseStructured(data any) *ToolResponse

NewToolResponseStructured builds a structured tool result: data (which must marshal to a JSON object, per the MCP spec's structuredContent requirement — a non-object value produces an error-text result instead) is set as StructuredContent, and — per that spec's backwards compatibility guidance ("a tool that returns structured content SHOULD also return the serialized JSON in a TextContent block") — the same JSON is also included as a text content block, for clients that don't read structuredContent.

func NewToolResponseTOON added in v0.7.0

func NewToolResponseTOON(data any) *ToolResponse

func NewToolResponseText

func NewToolResponseText(text string) *ToolResponse

type ToolResult

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

type ToolVisibility added in v0.6.12

type ToolVisibility int

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

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

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

func (ToolVisibility) String added in v0.9.0

func (v ToolVisibility) String() string

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

type UICSP added in v0.27.0

type UICSP struct {
	// ConnectDomains are origins for fetch/XHR/WebSocket (CSP connect-src).
	ConnectDomains []string `json:"connectDomains,omitempty"`
	// ResourceDomains are origins for scripts, images, styles, fonts, media.
	ResourceDomains []string `json:"resourceDomains,omitempty"`
	// FrameDomains are origins allowed for nested iframes (CSP frame-src).
	FrameDomains []string `json:"frameDomains,omitempty"`
	// BaseURIDomains are origins allowed as the document's base URI.
	BaseURIDomains []string `json:"baseUriDomains,omitempty"`
}

UICSP declares the external origins a UI resource's HTML is allowed to reach. Hosts use it to construct the iframe's Content-Security-Policy; if omitted entirely, hosts apply a restrictive same-origin/inline-only default.

type UIPermissions added in v0.27.0

type UIPermissions struct {
	Camera         bool `json:"-"`
	Microphone     bool `json:"-"`
	Geolocation    bool `json:"-"`
	ClipboardWrite bool `json:"-"`
}

UIPermissions declares which sandboxed browser capabilities a UI resource requests. Hosts MAY honor these; the UI should still feature-detect rather than assume they were granted.

func (UIPermissions) MarshalJSON added in v0.27.0

func (p UIPermissions) MarshalJSON() ([]byte, error)

MarshalJSON encodes only the permissions that are requested, each as an empty object, matching the extension's `{camera?: {}, ...}` shape.

type UIResourceMeta added in v0.27.0

type UIResourceMeta struct {
	// CSP declares the external domains this UI's HTML needs to reach.
	CSP *UICSP `json:"csp,omitempty"`
	// Permissions declares browser capabilities this UI requests.
	Permissions *UIPermissions `json:"permissions,omitempty"`
	// Domain optionally requests a dedicated sandbox origin (host-dependent format).
	Domain string `json:"domain,omitempty"`
	// PrefersBorder requests (true) or declines (false) a visible host-drawn
	// border/background around the rendered view; omit to let the host decide.
	PrefersBorder *bool `json:"prefersBorder,omitempty"`
}

UIResourceMeta is the _meta.ui object on a UI resource's resources/read response (and optionally its resources/list descriptor), carrying security and rendering hints for the host. Attach it with NewUIResourceResponseText or ResourceBuilder.UIMeta / ResourceTemplateBuilder.UIMeta.

type UIToolMeta added in v0.27.0

type UIToolMeta struct {
	// ResourceURI is the ui:// resource the host renders when this tool is
	// called. Optional per spec: an "app"-only action tool — one only ever
	// called by a view that's already open, such as a form submission —
	// has no rendering purpose of its own and should omit it; see
	// [ToolBuilder.Visibility].
	ResourceURI string `json:"resourceUri,omitempty"`
	// Visibility controls who may call the tool: "model" (the agent) and/or
	// "app" (the UI itself, via the same server connection). Defaults to
	// ["model", "app"] per the spec when left empty.
	Visibility []string `json:"visibility,omitempty"`
}

UIToolMeta is the _meta.ui object on a tool descriptor (tools/list) that links the tool to a companion UI resource. Set it with ToolBuilder.UIResource or, for a tool with no resource of its own, ToolBuilder.Visibility.

Directories

Path Synopsis
ai
examples
client command
mcp-app-dashboard command
Command mcp-app-dashboard is a worked example of the MCP Apps extension (SEP-1865, https://github.com/modelcontextprotocol/ext-apps): a tool linked to an interactive HTML UI resource that a compliant host renders in a sandboxed iframe.
Command mcp-app-dashboard is a worked example of the MCP Apps extension (SEP-1865, https://github.com/modelcontextprotocol/ext-apps): a tool linked to an interactive HTML UI resource that a compliant host renders in a sandboxed iframe.
object-example command
openai command
per-user-tools command
Package main demonstrates per-user tool access using ToolProvider.
Package main demonstrates per-user tool access using ToolProvider.
remote-server command
server command
session-server command
stdio-client command
Command stdio-client launches an MCP stdio server as a subprocess and talks to it over the child's stdin/stdout.
Command stdio-client launches an MCP stdio server as a subprocess and talks to it over the child's stdin/stdout.
stdio-server command
Command stdio-server is an MCP server that speaks the protocol over stdin/stdout (newline-delimited JSON-RPC 2.0).
Command stdio-server is an MCP server that speaks the protocol over stdin/stdout (newline-delimited JSON-RPC 2.0).
tool-discovery command
unified-server command
internal
staticserver command
Command staticserver is a trivial static file server used only by .claude/launch.json for local browser-preview testing (e.g.
Command staticserver is a trivial static file server used only by .claude/launch.json for local browser-preview testing (e.g.
Package toon implements the TOON (Token-Oriented Object Notation) format.
Package toon implements the TOON (Token-Oriented Object Notation) format.

Jump to

Keyboard shortcuts

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