pub struct ServerBuilder { /* private fields */ }Expand description
Builder for configuring an MCP server.
Implementations§
Source§impl ServerBuilder
impl ServerBuilder
Sourcepub fn new(name: impl Into<String>, version: impl Into<String>) -> Self
pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self
Creates a new server builder.
Statistics collection is enabled by default. Use without_stats
to disable it for performance-critical scenarios.
Console configuration defaults to environment-based settings. Use
with_console_config for programmatic control.
Sourcepub fn try_new(
name: impl Into<String>,
version: impl Into<String>,
) -> Result<Self, ServerLaunchPolicyError>
pub fn try_new( name: impl Into<String>, version: impl Into<String>, ) -> Result<Self, ServerLaunchPolicyError>
Creates a new server builder after validating the reserved launch policy.
This is the typed construction boundary for applications that need to report a malformed or unavailable launch policy instead of panicking.
Sourcepub fn try_new_with_fixed_protocol_policy(
name: impl Into<String>,
version: impl Into<String>,
policy: ProtocolPolicy,
) -> Result<Self, ServerLaunchPolicyError>
pub fn try_new_with_fixed_protocol_policy( name: impl Into<String>, version: impl Into<String>, policy: ProtocolPolicy, ) -> Result<Self, ServerLaunchPolicyError>
Creates a builder whose protocol policy is fixed by the embedding component rather than the process launch environment.
The selected policy is validated against the compiled feature set, but
this constructor deliberately does not read FASTMCP_PROTOCOL_POLICY.
It also reserves the selected policy, so a later
protocol_policy call validates its argument
without changing the fixed selection. This is intended for sealed
component facades that expose only one protocol era.
Sourcepub fn on_duplicate(self, behavior: DuplicateBehavior) -> Self
pub fn on_duplicate(self, behavior: DuplicateBehavior) -> Self
Sets the behavior when registering duplicate component names.
Controls what happens when a tool, resource, resource template, prompt, or mounted component is registered with an identifier that already exists:
DuplicateBehavior::Error: Reject the conflicting registration, log the error, and continue constructing the builderDuplicateBehavior::Warn: Log warning, keep original (default)DuplicateBehavior::Replace: Replace with new componentDuplicateBehavior::Ignore: Silently keep original
§Example
Server::new("demo", "1.0")
.on_duplicate(DuplicateBehavior::Error) // Strict mode
.tool(handler1)
.tool(handler2) // Rejected and logged if the name conflicts
.build();Sourcepub fn auth_provider<P: AuthProvider + 'static>(self, provider: P) -> Self
pub fn auth_provider<P: AuthProvider + 'static>(self, provider: P) -> Self
Sets an authentication provider.
Sourcepub fn without_stats(self) -> Self
pub fn without_stats(self) -> Self
Disables statistics collection.
Use this for performance-critical scenarios where the overhead of atomic operations for stats tracking is undesirable. The overhead is minimal (typically nanoseconds per request), so this is rarely needed.
Sourcepub fn request_timeout(self, secs: u64) -> Self
pub fn request_timeout(self, secs: u64) -> Self
Sets the request timeout in seconds.
Set to 0 to omit the server-owned ceiling. Ambient/request and handler deadlines are still composed into admission checks, cooperative checkpoints, and late-result rejection; this setting cannot relax them. A deadline does not preempt blocking synchronous code or imply that descendant work has been cancelled and drained. Default is 30 seconds.
Sourcepub fn max_bidirectional_requests_per_connection(
self,
max: usize,
) -> McpResult<Self>
pub fn max_bidirectional_requests_per_connection( self, max: usize, ) -> McpResult<Self>
Sets the maximum number of in-flight server-to-client requests for one transport connection.
§Errors
Returns InvalidParams when max is zero or exceeds the hard safety
limit enforced by the bidirectional request tracker.
Sourcepub fn list_page_size(self, page_size: usize) -> Self
pub fn list_page_size(self, page_size: usize) -> Self
Sets the pagination page size for list methods.
When set, list methods will return up to page_size items and provide an
opaque nextCursor for retrieving the next page. When not set (default),
list methods return all items in a single response.
Sourcepub fn mask_error_details(self, enabled: bool) -> Self
pub fn mask_error_details(self, enabled: bool) -> Self
Enables or disables error detail masking.
When enabled, internal error details are hidden from client responses:
- Stack traces removed
- File paths sanitized
- Internal state not exposed
- Generic “Internal server error” message returned
Client errors (invalid request, method not found, etc.) are preserved since they don’t contain sensitive internal details.
Default is false (disabled) for development convenience.
§Example
let server = Server::new("api", "1.0")
.mask_error_details(true) // Always mask in production
.build();Sourcepub fn auto_mask_errors(self) -> Self
pub fn auto_mask_errors(self) -> Self
Automatically masks error details based on environment.
Masking is enabled when:
FASTMCP_ENVis set to “production”FASTMCP_MASK_ERRORSis set to “true” or “1”- The build is a release build (
cfg!(not(debug_assertions)))
Masking is explicitly disabled when:
FASTMCP_MASK_ERRORSis set to “false” or “0”
§Example
let server = Server::new("api", "1.0")
.auto_mask_errors()
.build();Sourcepub fn is_error_masking_enabled(&self) -> bool
pub fn is_error_masking_enabled(&self) -> bool
Returns whether error masking is enabled.
Sourcepub fn strict_input_validation(self, enabled: bool) -> Self
pub fn strict_input_validation(self, enabled: bool) -> Self
Enables or disables strict input validation.
When enabled, tool input validation will reject any properties not
explicitly defined in the tool’s input schema (enforces additionalProperties: false).
When disabled (default), extra properties are allowed unless the schema
explicitly sets additionalProperties: false.
§Example
let server = Server::new("api", "1.0")
.strict_input_validation(true) // Reject unknown properties
.build();Sourcepub fn is_strict_input_validation_enabled(&self) -> bool
pub fn is_strict_input_validation_enabled(&self) -> bool
Returns whether strict input validation is enabled.
Sourcepub fn protocol_policy(
self,
policy: ProtocolPolicy,
) -> Result<Self, ServerLaunchPolicyError>
pub fn protocol_policy( self, policy: ProtocolPolicy, ) -> Result<Self, ServerLaunchPolicyError>
Selects the immutable MCP protocol-era policy for live stdio and runtime connections.
With the exact legacy adapter enabled, the default ProtocolPolicy::Auto classifies the
first accepted opening frame and then pins that connection to its selected era. Without
that adapter, construction defaults to ProtocolPolicy::ModernOnly. ModernOnly and
LegacyOnly reject an opening frame from the other exact supported era before it can enter
request dispatch. In a no-legacy production build, Auto and LegacyOnly return
ServerLaunchPolicyError::FeatureUnavailable before either can be stored.
Sourcepub fn try_set_protocol_policy(
&mut self,
policy: ProtocolPolicy,
) -> Result<(), ServerLaunchPolicyError>
pub fn try_set_protocol_policy( &mut self, policy: ProtocolPolicy, ) -> Result<(), ServerLaunchPolicyError>
Attempts to select the immutable MCP protocol-era policy without consuming the builder.
A policy unavailable in the compiled feature set is rejected before this builder is changed. A reserved launch or component policy still takes precedence over an explicit builder selection.
Sourcepub fn extension_registry<R>(
self,
handlers: ExtensionHandlerRegistry,
server_discovery: ServerExtensionDiscovery,
resolver: R,
) -> Result<Self, ServerExtensionConfigurationError>where
R: ExtensionSettingsCompatibilityResolver + Send + 'static,
pub fn extension_registry<R>(
self,
handlers: ExtensionHandlerRegistry,
server_discovery: ServerExtensionDiscovery,
resolver: R,
) -> Result<Self, ServerExtensionConfigurationError>where
R: ExtensionSettingsCompatibilityResolver + Send + 'static,
Installs the server’s modern-only extension handlers and discovery settings.
Descriptor registration remains mutable only until Self::build. The
builder validates the advertised identifiers immediately, then freezes
the handler and descriptor registries together while building the
immutable Server. Exact MCP 2024-11-05 remains outside this path.
Sourcepub fn http_config(self, config: HttpServerConfig) -> Self
pub fn http_config(self, config: HttpServerConfig) -> Self
Sourcepub fn oauth_http_routes(self, routes: OAuthHttpRoutes) -> Self
pub fn oauth_http_routes(self, routes: OAuthHttpRoutes) -> Self
Installs immutable OAuth authorization, token, and revocation routes into the native HTTP listener.
The routes retain an explicit public HTTPS endpoint base and are admitted before MCP request conversion. OIDC/JWKS/ID-token routes are deliberately not installed here.
Sourcepub fn build_http_endpoint(
self,
legacy_origin: impl Into<String>,
) -> Result<ServerHttpEndpoint, ServerHttpEndpointError>
pub fn build_http_endpoint( self, legacy_origin: impl Into<String>, ) -> Result<ServerHttpEndpoint, ServerHttpEndpointError>
Builds a live dual-era HTTP endpoint with an exact legacy SSE origin.
The modern route remains at HttpServerConfig::mcp_path, while the
exact MCP 2024-11-05 SSE route advertises legacy_origin plus the
configured legacy message path.
Sourcepub fn middleware<M: Middleware + 'static>(self, middleware: M) -> Self
pub fn middleware<M: Middleware + 'static>(self, middleware: M) -> Self
Registers a middleware.
Sourcepub fn tool<H: ToolHandler + 'static>(self, handler: H) -> Self
pub fn tool<H: ToolHandler + 'static>(self, handler: H) -> Self
Registers a tool handler.
Duplicate handling is controlled by on_duplicate.
If DuplicateBehavior::Error is set and a duplicate is found,
an error will be logged and the tool will not be registered.
Sourcepub fn legacy_tool<H: ToolHandler + 'static>(self, handler: H) -> Self
pub fn legacy_tool<H: ToolHandler + 'static>(self, handler: H) -> Self
Registers an intentionally exact MCP 2024-11-05-only tool handler.
This does not depend on builder call order or the connection protocol
policy. The tool is available through exact legacy list/call routes and
omitted from all MCP 2026-07-28 catalogs and dispatch. Use Self::tool
for ordinary dual-era registration; it never falls back to this path
when final schema admission fails.
Sourcepub fn resource<H: ResourceHandler + 'static>(self, handler: H) -> Self
pub fn resource<H: ResourceHandler + 'static>(self, handler: H) -> Self
Registers a resource handler.
Duplicate handling is controlled by on_duplicate.
If DuplicateBehavior::Error is set and a duplicate is found,
an error will be logged and the resource will not be registered.
Sourcepub fn resource_subscriptions(self) -> Self
pub fn resource_subscriptions(self) -> Self
Advertises the resources.subscribe capability so clients may
subscribe to registered resource URIs.
Registering a resource or template already advertises subscribe because
session and exact-2024 dispatch serve resources/subscribe for those
URIs. This remains for servers that want the capability visible before
any catalog entry is installed.
Sourcepub fn legacy_resource<H: ResourceHandler + 'static>(self, handler: H) -> Self
pub fn legacy_resource<H: ResourceHandler + 'static>(self, handler: H) -> Self
Registers an intentionally exact MCP 2024-11-05-only resource.
Sourcepub fn resource_template(self, template: ResourceTemplate) -> Self
pub fn resource_template(self, template: ResourceTemplate) -> Self
Registers a resource template.
Duplicate handling is controlled by on_duplicate.
With DuplicateBehavior::Error, a conflicting template is rejected
and logged while builder construction continues.
Sourcepub fn legacy_resource_template(self, template: ResourceTemplate) -> Self
pub fn legacy_resource_template(self, template: ResourceTemplate) -> Self
Registers an intentionally exact MCP 2024-11-05-only resource template.
Sourcepub fn prompt<H: PromptHandler + 'static>(self, handler: H) -> Self
pub fn prompt<H: PromptHandler + 'static>(self, handler: H) -> Self
Registers a prompt handler.
Duplicate handling is controlled by on_duplicate.
If DuplicateBehavior::Error is set and a duplicate is found,
an error will be logged and the prompt will not be registered.
Sourcepub fn legacy_prompt<H: PromptHandler + 'static>(self, handler: H) -> Self
pub fn legacy_prompt<H: PromptHandler + 'static>(self, handler: H) -> Self
Registers an intentionally exact MCP 2024-11-05-only prompt.
Sourcepub fn completion_handler<H: CompletionHandler + 'static>(
self,
handler: H,
) -> Self
pub fn completion_handler<H: CompletionHandler + 'static>( self, handler: H, ) -> Self
Registers the server-wide completion/complete handler.
The handler receives disjoint exact-legacy and final request parameter
types. Building with a handler installs the real router dispatch target,
which is the sole condition that enables final discovery’s
capabilities.completions claim.
Sourcepub fn legacy_completion_handler<H: CompletionHandler + 'static>(
self,
handler: H,
) -> Self
pub fn legacy_completion_handler<H: CompletionHandler + 'static>( self, handler: H, ) -> Self
Registers a completion handler for exact MCP 2024-11-05 dispatch only.
Initialize advertises capabilities.completions so a 2024-11-05 client
can discover completion/complete. Final server/discover still omits
completions unless a modern handler is also installed.
Sourcepub fn prompt_completion_handler<H: CompletionHandler + 'static>(
self,
prompt_name: impl Into<String>,
handler: H,
) -> Self
pub fn prompt_completion_handler<H: CompletionHandler + 'static>( self, prompt_name: impl Into<String>, handler: H, ) -> Self
Registers a final completion provider for one exact prompt name.
Final completion/complete dispatch validates the referenced prompt
and argument before selecting this provider. Exact MCP 2024-11-05
completion remains on Self::completion_handler or
Self::legacy_completion_handler.
Sourcepub fn resource_template_completion_handler<H: CompletionHandler + 'static>(
self,
uri_template: impl Into<String>,
handler: H,
) -> Self
pub fn resource_template_completion_handler<H: CompletionHandler + 'static>( self, uri_template: impl Into<String>, handler: H, ) -> Self
Registers a final completion provider for one exact resource-template URI.
Final dispatch admits the registered resource template and requested template variable before selecting this provider.
Sourcepub fn legacy_resource_template_completion_handler<H: CompletionHandler + 'static>(
self,
uri_template: impl Into<String>,
handler: H,
) -> Self
pub fn legacy_resource_template_completion_handler<H: CompletionHandler + 'static>( self, uri_template: impl Into<String>, handler: H, ) -> Self
Registers an exact MCP 2024-11-05 completion provider for one resource template URI.
Exact-2024 dispatch selects this provider before the server-wide
Self::legacy_completion_handler fallback. Initialize advertises
capabilities.completions so a 2024-11-05 client can discover
completion/complete.
Sourcepub fn mount(self, server: Server, prefix: Option<&str>) -> Self
pub fn mount(self, server: Server, prefix: Option<&str>) -> Self
Mounts another server’s components into this server with an optional prefix.
This consumes the source server and moves all its tools, resources, and prompts
into this server. Names/URIs are prefixed with prefix/ if a prefix is provided.
§Example
let db_server = Server::new("db", "1.0")
.tool(query_tool)
.tool(insert_tool)
.build();
let api_server = Server::new("api", "1.0")
.tool(endpoint_tool)
.build();
let main = Server::new("main", "1.0")
.mount(db_server, Some("db")) // db/query, db/insert
.mount(api_server, Some("api")) // api/endpoint
.build();§Prefix Rules
- Prefixes must be alphanumeric plus underscores and hyphens
- Prefixes cannot contain slashes
- With prefix
"db", tool"query"becomes"db/query" - Without prefix, names are preserved (may cause conflicts)
Duplicate handling follows on_duplicate. With
DuplicateBehavior::Error, any conflict rejects the complete mount;
the failure is logged and fluent builder construction continues.
Sourcepub fn mount_preserving_resource_uris(
self,
server: Server,
prefix: Option<&str>,
) -> Self
pub fn mount_preserving_resource_uris( self, server: Server, prefix: Option<&str>, ) -> Self
Mounts tools and prompts with an optional name prefix, and keeps resource and template URIs exact.
Use this when the destination must remain a modern catalog: a nonempty
{prefix}/{uri} key is not an absolute final URI.
Sourcepub fn mount_tools(self, server: Server, prefix: Option<&str>) -> Self
pub fn mount_tools(self, server: Server, prefix: Option<&str>) -> Self
Mounts only tools from another server with an optional prefix.
Similar to mount, but only transfers tools, ignoring
resources and prompts.
§Example
let utils_server = Server::new("utils", "1.0")
.tool(format_tool)
.tool(parse_tool)
.resource(config_resource) // Will NOT be mounted
.build();
let main = Server::new("main", "1.0")
.mount_tools(utils_server, Some("utils")) // Only tools
.build();Duplicate handling follows on_duplicate.
Sourcepub fn mount_resources(self, server: Server, prefix: Option<&str>) -> Self
pub fn mount_resources(self, server: Server, prefix: Option<&str>) -> Self
Mounts only resources from another server with an optional prefix.
Similar to mount, but only transfers resources,
ignoring tools and prompts.
§Example
let data_server = Server::new("data", "1.0")
.resource(config_resource)
.resource(schema_resource)
.tool(query_tool) // Will NOT be mounted
.build();
let main = Server::new("main", "1.0")
.mount_resources(data_server, Some("data")) // Only resources
.build();Duplicate handling follows on_duplicate for
both static resources and resource templates.
Sourcepub fn mount_prompts(self, server: Server, prefix: Option<&str>) -> Self
pub fn mount_prompts(self, server: Server, prefix: Option<&str>) -> Self
Mounts only prompts from another server with an optional prefix.
Similar to mount, but only transfers prompts,
ignoring tools and resources.
§Example
let templates_server = Server::new("templates", "1.0")
.prompt(greeting_prompt)
.prompt(error_prompt)
.tool(format_tool) // Will NOT be mounted
.build();
let main = Server::new("main", "1.0")
.mount_prompts(templates_server, Some("tmpl")) // Only prompts
.build();Duplicate handling follows on_duplicate.
Sourcepub fn instructions(self, instructions: impl Into<String>) -> Self
pub fn instructions(self, instructions: impl Into<String>) -> Self
Sets custom server instructions.
Sourcepub fn title(self, title: impl Into<String>) -> Self
pub fn title(self, title: impl Into<String>) -> Self
Sets the modern discovery title. Exact-2024 initialize stays name/version.
Sourcepub fn description(self, description: impl Into<String>) -> Self
pub fn description(self, description: impl Into<String>) -> Self
Sets the modern discovery description.
Sourcepub fn website_url(self, website_url: impl Into<String>) -> Self
pub fn website_url(self, website_url: impl Into<String>) -> Self
Sets the modern discovery website URL.
Sourcepub fn log_level(self, level: Level) -> Self
pub fn log_level(self, level: Level) -> Self
Sets the log level.
Default is read from FASTMCP_LOG environment variable, or INFO if not set.
Sourcepub fn log_level_filter(self, filter: LevelFilter) -> Self
pub fn log_level_filter(self, filter: LevelFilter) -> Self
Sets the log level from a filter, including LevelFilter::Off.
Sourcepub fn log_timestamps(self, show: bool) -> Self
pub fn log_timestamps(self, show: bool) -> Self
Sets whether to show timestamps in logs.
Default is true.
Sourcepub fn log_targets(self, show: bool) -> Self
pub fn log_targets(self, show: bool) -> Self
Sets whether to show target/module paths in logs.
Default is true.
Sourcepub fn log_file_line(self, show: bool) -> Self
pub fn log_file_line(self, show: bool) -> Self
Sets whether to show source file and line in logs.
Sourcepub fn logging(self, config: LoggingConfig) -> Self
pub fn logging(self, config: LoggingConfig) -> Self
Sets the full logging configuration.
Sourcepub fn with_console_config(self, config: ConsoleConfig) -> Self
pub fn with_console_config(self, config: ConsoleConfig) -> Self
Sets the complete console configuration.
This controls server-owned console output, including the banner, traffic logging, logger formatting, and rich/plain display mode.
§Example
use fastmcp_console::config::{ConsoleConfig, BannerStyle};
Server::new("demo", "1.0.0")
.with_console_config(
ConsoleConfig::new()
.with_banner(BannerStyle::Compact)
.plain_mode()
)
.build();Sets the banner style.
Controls how the startup banner is displayed.
Default is BannerStyle::Full.
Disables the startup banner.
Sourcepub fn with_traffic_logging(self, verbosity: TrafficVerbosity) -> Self
pub fn with_traffic_logging(self, verbosity: TrafficVerbosity) -> Self
Enables request/response traffic logging.
Controls the verbosity of traffic logging:
None: No traffic logging (default)Summary: Method name and timing onlyFull: Full request/response bodies
Sourcepub fn plain_mode(self) -> Self
pub fn plain_mode(self) -> Self
Forces plain text output (no colors/styling).
Useful for CI environments, logging to files, or when running as an MCP server where rich output might interfere with the JSON-RPC protocol.
Sourcepub fn force_color(self) -> Self
pub fn force_color(self) -> Self
Forces color output even in non-TTY environments.
Sourcepub fn console_config(&self) -> &ConsoleConfig
pub fn console_config(&self) -> &ConsoleConfig
Returns a reference to the current console configuration.
Sourcepub fn on_startup<F, E>(self, hook: F) -> Self
pub fn on_startup<F, E>(self, hook: F) -> Self
Registers a startup hook that runs before the server starts accepting connections.
The hook can perform initialization tasks like:
- Opening database connections
- Loading configuration files
- Initializing caches
If the hook returns an error, the server will not start.
§Example
Server::new("demo", "1.0.0")
.on_startup(|| {
println!("Server starting up...");
Ok(())
})
.run_stdio();Sourcepub fn on_shutdown<F>(self, hook: F) -> Self
pub fn on_shutdown<F>(self, hook: F) -> Self
Registers a shutdown hook that runs when the server is shutting down.
The hook can perform cleanup tasks like:
- Closing database connections
- Flushing caches
- Saving state
Shutdown hooks are run on a best-effort basis. If the process is forcefully terminated, hooks may not run.
§Example
Server::new("demo", "1.0.0")
.on_shutdown(|| {
println!("Server shutting down...");
})
.run_stdio();Sourcepub fn build(self) -> Server
pub fn build(self) -> Server
Builds the server after a valid builder-level configuration.
Both Self::try_new and Self::protocol_policy reject invalid or
unavailable policy selections before a builder exists.
When the tasks feature is enabled and the builder has not already
installed a local or proxy Tasks owner, this installs a process-local
in-memory official Tasks runtime so tasks/get, tasks/update, and
tasks/cancel are served. Call [Self::final_tasks] to replace that
default with an application-owned store. The historical
[Self::with_task_manager] path stays quarantined and does not receive
the official methods.
Sourcepub fn try_build(self) -> Result<Server, ServerLaunchPolicyError>
pub fn try_build(self) -> Result<Server, ServerLaunchPolicyError>
Builds a server through the historical fallible spelling.
Invalid launch configuration is rejected by Self::try_new before
the builder exists, so this always returns the result of Self::build.