Server
Creating and configuring the MCP server
The Server is the central object in finemcp. It holds all registered tools, resources, prompts, roots, and middleware — and handles the MCP JSON-RPC protocol.
Creating a Server
s := finemcp.NewServer("my-server", "1.0.0")
The constructor takes a server name and version, plus optional functional options:
s := finemcp.NewServer("my-server", "1.0.0",
finemcp.WithResourceSubscriptions(),
finemcp.WithStreamBufferSize(64),
finemcp.WithMaxSessions(5000),
)
Server Options
| Option | Default | Description |
|---|---|---|
WithInstructions(text) | "" | Human-readable instructions sent to the client on initialize |
WithServerTitle(title) | "" | Human-readable display title for the server |
WithServerDescription(desc) | "" | Human-readable description included in the initialize response |
WithWebsiteURL(url) | "" | Website URL included in the initialize response |
WithIcons(icons...) | nil | Icons (logo/thumbnail/favicon) for the server |
WithLifespan(fn) | nil | Hook called once the server is initialized; use for startup/shutdown logic |
WithResourceSubscriptions() | disabled | Enable resources/subscribe and change notifications |
WithTaskStore(ts) | nil | Attach a TaskStore for spec-compliant async task management |
WithSupportedVersions(v...) | 2025-11-25, 2025-03-26, 2024-11-05 | Override supported protocol versions |
WithMaxSessionTools(n) | 100 | Max session-scoped tools per session |
WithMaxSessions(n) | 10000 | Max concurrent sessions |
WithStreamBufferSize(n) | 16 | Channel buffer size for streaming chunks |
WithMaxNotificationMethods(n) | 1000 | Max distinct notification methods that can be registered |
WithMaxHandlersPerNotification(n) | 100 | Max handlers per notification method |
WithNotificationPanicHandler(h) | nil | Custom handler for panics inside notification handlers |
Registering Components
Tools
tool, _ := finemcp.NewTool("ping", handler, finemcp.WithDescription("Health check"))
s.RegisterTool(tool)
// Register multiple at once
s.RegisterTools(tool1, tool2, tool3)
// Remove a tool
s.RemoveTool("ping")
// List all tools
tools := s.ListTools()
Resources
res, _ := finemcp.NewResource("config://app", "Config", handler)
s.RegisterResource(res)
tmpl, _ := finemcp.NewResourceTemplate("user://{id}", "User", handler)
s.RegisterResourceTemplate(tmpl)
Prompts
prompt, _ := finemcp.NewPrompt("greet", handler)
s.RegisterPrompt(prompt)
Roots
root, _ := finemcp.NewRoot("file:///workspace", finemcp.WithRootName("Workspace"))
s.RegisterRoot(root)
Middleware
Apply middleware that wraps all tool invocations:
s.Use(middleware.Recovery())
s.Use(middleware.Logging(logger))
s.Use(middleware.RateLimit(10))
Middleware executes in registration order (first registered = outermost wrapper). See Middleware for details.
Authentication
Set a protocol-level auth checker that runs before any tool call:
s.SetAuthChecker(middleware.RequireAuth())
For HTTP-level authentication (bearer tokens, API keys), wrap the transport handler:
handler := middleware.HTTPAuth(verifier, transport.Handler(s))
See Auth Middleware for full details.
Multi-Tenancy
Set a tenant resolver for per-tenant tool/resource filtering:
s.SetTenantResolver(middleware.NewTenantResolver(extractor, store))
See Multi-Tenant Middleware for details.
Notifications
Notify connected clients when server state changes:
s.NotifyToolsListChanged()
s.NotifyResourcesListChanged()
s.NotifyPromptsListChanged()
s.NotifyRootsListChanged()
s.NotifyResourceUpdated("config://app/settings")
Session Lifecycle
MCP follows a strict session lifecycle:
- Client sends
initialize— withprotocolVersion,clientInfo, andcapabilities - Server responds — with negotiated version and server capabilities
- Client sends
initializednotification — session is now active - Normal operations —
tools/call,resources/read,prompts/get, etc. - Shutdown —
s.Shutdown(ctx)sends close notifications
Each session allows exactly one initialize call. Subsequent initialize calls return an error.
Accessors
s.Name() // "my-server"
s.Version() // "1.0.0"
s.NegotiatedVersion() // "2025-11-25" (after initialization)
Shutdown
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
s.Shutdown(ctx)