mcpkit

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: MIT Imports: 8 Imported by: 0

README

mcpkit

mcpkit is a small, opinionated helper package for Go applications that expose Model Context Protocol servers with the official Go SDK.

It standardizes the pieces that should be consistent across applications:

  • server identity, instructions, and logging;
  • explicit read-only, mutating, and destructive tool annotations;
  • clean stdio shutdown;
  • bounded stateless Streamable HTTP with cross-origin protection;
  • initialized in-memory client sessions for black-box tests.

Applications still own tool schemas, authentication, authorization, audit identity, confirmation and idempotency policy, and domain behavior.

Server and tools

server := mcpkit.MustServer(mcpkit.ServerConfig{
    Name:         "inventory",
    Version:      version,
    Instructions: "Use inventory tools for live infrastructure facts.",
    Logger:       logger,
})

mcp.AddTool(server, &mcp.Tool{
    Name:        "inventory_list_hosts",
    Description: "List current managed hosts.",
    Annotations: mcpkit.ReadOnly(false),
}, listHosts)

if err := mcpkit.RunStdio(ctx, server); err != nil {
    return err
}

openWorld is explicit on every annotation helper. Use false for a closed application or configured data set and true when a tool may interact with arbitrary external entities. These annotations are advisory client hints, not authorization or confirmation enforcement; handlers must enforce their own safety policy.

Stateless HTTP

Authentication wraps the MCP handler and supplies identity through the request context. The application can then create a server whose tools close over that identity.

handler, err := mcpkit.StatelessHTTP(
    func(r *http.Request) *mcp.Server {
        return newServer(currentUser(r))
    },
    mcpkit.HTTPOptions{Logger: logger, MaxRequestBodyBytes: 2 << 20},
)
if err != nil {
    return err
}
mux.Handle("/mcp", requireBearer(handler))

The helper defaults to JSON responses, stateless sessions, a 1 MiB body limit, SDK localhost protection, and Go browser cross-origin protection. An MCP handler without an authentication wrapper is publicly callable: origin and localhost checks are not access control, and non-browser clients commonly send neither browser header. Authentication, authorization, Host allowlisting, timeouts, rate limiting, and concurrency limits remain application and deployment responsibilities.

Reverse proxies that connect over loopback while preserving an external Host must set DisableLocalhostProtection only when the loopback listener cannot be reached by untrusted clients. Prefer TrustedOrigins for legitimate browser origins; DisableBrowserOriginProtection is reserved for an outer layer that already enforces Origin and Sec-Fetch-Site.

The SDK logger can include tool arguments at debug level. Do not enable debug logging in production when tool inputs may contain sensitive information.

Tests

session := mcpkittest.Connect(t, server)
result, err := session.CallTool(t.Context(), &mcp.CallToolParams{
    Name: "inventory_list_hosts",
})

Compatibility

mcpkit currently targets Go 1.26 and github.com/modelcontextprotocol/go-sdk v1.7.0.

License

MIT

Documentation

Overview

Package mcpkit provides small, opinionated helpers shared by Go MCP servers.

It standardizes server metadata, tool safety annotations, local stdio lifecycle, and bounded stateless HTTP transport. Applications retain their tool schemas, authentication, authorization, auditing, and domain behavior.

Index

Constants

View Source
const DefaultMaxRequestBodyBytes int64 = 1 << 20

Variables

This section is empty.

Functions

func Destructive

func Destructive(idempotent, openWorld bool) *mcp.ToolAnnotations

Destructive marks a write that may overwrite, revoke, or delete state.

func MustServer

func MustServer(cfg ServerConfig) *mcp.Server

MustServer is NewServer for application initialization where invalid static configuration is a programming error.

func Mutating

func Mutating(idempotent, openWorld bool) *mcp.ToolAnnotations

Mutating marks an additive or non-destructive write. Idempotent describes whether repeating the same call has no additional effect.

func NewServer

func NewServer(cfg ServerConfig) (*mcp.Server, error)

NewServer constructs an official-SDK server with consistent metadata.

func NormalClose

func NormalClose(err error) bool

NormalClose reports errors produced by an expected client disconnect or caller cancellation. Wrapped errors must preserve their cause for errors.Is; message text is deliberately not used to classify process exit status.

func ReadOnly

func ReadOnly(openWorld bool) *mcp.ToolAnnotations

ReadOnly marks a tool as side-effect free and idempotent. Set openWorld when it may read from arbitrary external entities rather than a closed service or configured data set. MCP annotations are advisory client hints; applications must still enforce authorization and safety policy in their handlers.

func RunStdio

func RunStdio(ctx context.Context, server *mcp.Server) error

RunStdio serves until the client disconnects or ctx is cancelled. Normal transport closure is reported as success so command entry points do not need to duplicate SDK-specific EOF handling.

func StatelessHTTP

func StatelessHTTP(factory func(*http.Request) *mcp.Server, opts HTTPOptions) (http.Handler, error)

StatelessHTTP returns a JSON-response Streamable HTTP handler with a request body limit and browser cross-origin protection.

The returned handler is publicly callable unless the application wraps it in authentication and authorization middleware. Cross-origin and localhost protections defend browser and DNS-rebinding boundaries; they are not access control and non-browser clients may send neither relevant header. Public deployments must also provide appropriate rate, concurrency, and request timeout limits. Authentication should wrap this handler so the factory can derive identity from r.Context; returning nil for a missing identity makes the SDK reject the request.

SDK logging can include tool arguments at debug level. Do not attach a debug logger in production when tool inputs may contain sensitive information.

Types

type HTTPOptions

type HTTPOptions struct {
	// MaxRequestBodyBytes defaults to 1 MiB. Negative values are invalid; zero
	// selects the default rather than disabling the limit.
	MaxRequestBodyBytes int64
	Logger              *slog.Logger
	// TrustedOrigins permits exact browser Origin values such as
	// "https://console.example.com" while retaining protection against all
	// other cross-origin browser requests.
	TrustedOrigins []string
	// DisableBrowserOriginProtection disables only Go's outer Origin and
	// Sec-Fetch-Site checks. It does not disable the SDK's independent localhost
	// DNS-rebinding protection and it is not an authentication mechanism. Use it
	// only when a trusted outer HTTP layer already enforces browser origins.
	DisableBrowserOriginProtection bool
	// DisableLocalhostProtection permits reverse proxies that connect to a
	// loopback listener while preserving the external Host header. Use it only
	// when a trusted proxy or network boundary prevents direct untrusted access
	// to that listener. Browser origin protection remains independent.
	DisableLocalhostProtection bool
}

HTTPOptions controls the bounded stateless Streamable HTTP helper.

type ServerConfig

type ServerConfig struct {
	Name         string
	Version      string
	Instructions string
	Logger       *slog.Logger
	PageSize     int
}

ServerConfig is the metadata and behavior shared by one application's MCP server. Name is required. Version should normally be the application build version rather than a separate MCP API version.

Directories

Path Synopsis
Package mcpkittest provides black-box MCP test connections.
Package mcpkittest provides black-box MCP test connections.

Jump to

Keyboard shortcuts

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