Skip to main content

ServerBuilderExt

Trait ServerBuilderExt 

Source
pub trait ServerBuilderExt: Sized {
    // Required methods
    fn tools_from_config(self, config: &ServerConfig) -> Self;
    fn try_tools_from_config(self, config: &ServerConfig) -> Result<Self>;
    fn tools_from_config_with_connector(
        self,
        config: &ServerConfig,
        connector: Arc<dyn SqlConnector>,
    ) -> Self;
    fn try_tools_from_config_with_connector(
        self,
        config: &ServerConfig,
        connector: Arc<dyn SqlConnector>,
    ) -> Result<Self>;
    fn code_mode_from_config(self, config: &ServerConfig) -> Self;
    fn try_code_mode_from_config(self, config: &ServerConfig) -> Result<Self>;
    fn try_code_mode_from_config_with_connector(
        self,
        config: &ServerConfig,
        connector: Arc<dyn SqlConnector>,
    ) -> Result<Self>;
    fn try_tools_from_config_with(
        self,
        config: &ServerConfig,
        hooks: &ToolkitHooks,
    ) -> Result<Self>;
    fn try_tools_from_config_with_connector_and_hooks(
        self,
        config: &ServerConfig,
        connector: Arc<dyn SqlConnector>,
        hooks: &ToolkitHooks,
    ) -> Result<Self>;
}
Expand description

Composable builder extensions for config-driven pmcp servers.

Implemented for pmcp::ServerBuilder (Phase 82’s public, Arc-aware builder) so config-driven wiring composes with the standard chained-method builder DSL.

Required Methods§

Source

fn tools_from_config(self, config: &ServerConfig) -> Self

Register every [[tools]] entry from config as a tool_arc handler (TKIT-07). Panicking convenience wrapping ServerBuilderExt::try_tools_from_config.

§Panics

Panics with "tools_from_config: ..." if crate::tools::synthesize_from_config returns Err. Prefer ServerBuilderExt::try_tools_from_config for production servers where misconfiguration must surface as a Result.

§Example
use pmcp::Server;
use pmcp_server_toolkit::{ServerBuilderExt, ServerConfig};

let cfg = ServerConfig::default();
let _builder = Server::builder()
    .name("demo")
    .version("0.1.0")
    .tools_from_config(&cfg);
Source

fn try_tools_from_config(self, config: &ServerConfig) -> Result<Self>

Fallible companion to ServerBuilderExt::tools_from_config (review R7).

§Errors

Returns crate::ToolkitError if synthesis fails — typically crate::ToolkitError::Synth or crate::ToolkitError::Validation.

§Example
use pmcp::Server;
use pmcp_server_toolkit::{ServerBuilderExt, ServerConfig};

let cfg = ServerConfig::default();
let _builder = Server::builder()
    .name("demo")
    .version("0.1.0")
    .try_tools_from_config(&cfg)?;
Source

fn tools_from_config_with_connector( self, config: &ServerConfig, connector: Arc<dyn SqlConnector>, ) -> Self

Register every [[tools]] entry from config as a tool_arc handler, threading connector into each handler so tools/call executes SQL and emits structuredContent (Phase 84 CONN-01 / D-06). Panicking convenience wrapping ServerBuilderExt::try_tools_from_config_with_connector.

This is the Shape A wiring point: production servers with a live connector use this entry point; the connector-less ServerBuilderExt::tools_from_config remains for callers that only need the synthesized tool schemas (handlers error at runtime if invoked).

§Panics

Panics with "tools_from_config_with_connector: ..." if crate::tools::synthesize_from_config_with_connector returns Err. Prefer ServerBuilderExt::try_tools_from_config_with_connector for production servers.

§Example
use std::sync::Arc;
use pmcp::Server;
use pmcp_server_toolkit::{ServerBuilderExt, ServerConfig};
use pmcp_server_toolkit::sql::SqlConnector;

fn build(connector: Arc<dyn SqlConnector>) {
    let cfg = ServerConfig::default();
    let _builder = Server::builder()
        .name("demo")
        .version("0.1.0")
        .tools_from_config_with_connector(&cfg, connector);
}
Source

fn try_tools_from_config_with_connector( self, config: &ServerConfig, connector: Arc<dyn SqlConnector>, ) -> Result<Self>

Fallible companion to ServerBuilderExt::tools_from_config_with_connector.

§Errors

Returns crate::ToolkitError if synthesis fails — typically crate::ToolkitError::Synth or crate::ToolkitError::Validation.

§Example
use std::sync::Arc;
use pmcp::Server;
use pmcp_server_toolkit::{ServerBuilderExt, ServerConfig};
use pmcp_server_toolkit::sql::SqlConnector;

let cfg = ServerConfig::default();
let _builder = Server::builder()
    .name("demo")
    .version("0.1.0")
    .try_tools_from_config_with_connector(&cfg, connector)?;
Source

fn code_mode_from_config(self, config: &ServerConfig) -> Self

Wire the [code_mode] block. Panicking convenience wrapping ServerBuilderExt::try_code_mode_from_config.

When the code-mode feature is disabled, this is a no-op that emits a tracing::warn! so operators auditing logs can spot the feature gap (threat T-83-08-02 mitigation).

§Panics

Panics if ServerBuilderExt::try_code_mode_from_config errors — commonly because token_secret’s referenced env var is unset, or an inline literal token_secret was supplied without the dev-only escape hatch (review R9). Prefer ServerBuilderExt::try_code_mode_from_config for production servers.

§Example
use pmcp::Server;
use pmcp_server_toolkit::{ServerBuilderExt, ServerConfig};

let cfg = ServerConfig::default();
let _builder = Server::builder()
    .name("demo")
    .version("0.1.0")
    .code_mode_from_config(&cfg);
Source

fn try_code_mode_from_config(self, config: &ServerConfig) -> Result<Self>

Fallible companion to ServerBuilderExt::code_mode_from_config (review R7) — the CONNECTORLESS, validation-only / no-tool path.

Tolerant of config.code_mode = None (returns the builder unchanged). When [code_mode] IS present this builds + validates the pipeline (so R9 / secret-resolution errors fire) but registers NO tools, because no executor is available to bind execute_code to. For the path that actually registers validate_code + execute_code, use the LOCKED connector-aware ServerBuilderExt::try_code_mode_from_config_with_connector.

§Errors

Returns crate::ToolkitError if code-mode wiring fails — commonly crate::ToolkitError::CodeMode (env var missing) or crate::ToolkitError::Validation (inline token_secret rejected per review R9).

§Example
use pmcp::Server;
use pmcp_server_toolkit::{ServerBuilderExt, ServerConfig};

let cfg = ServerConfig::default();
let _builder = Server::builder()
    .name("demo")
    .version("0.1.0")
    .try_code_mode_from_config(&cfg)?;
Source

fn try_code_mode_from_config_with_connector( self, config: &ServerConfig, connector: Arc<dyn SqlConnector>, ) -> Result<Self>

Wire the [code_mode] block, registering BOTH validate_code and execute_code over connector (the LOCKED connector-aware API — the pure-config binary’s path; SHAP-A-01 / SC-3).

When [code_mode] is present this constructs a crate::code_mode::SqlCodeExecutor from connector and delegates to crate::code_mode::code_mode_tools_from_executor, which registers the two tools with the static [code_mode] policy baked into the validation pipeline (allow_writes / allow_deletes / allow_ddl enforced; DELETE/DDL on a read-only config are rejected). When [code_mode] is absent this is a no-op (registers neither tool). Unlike the connectorless ServerBuilderExt::try_code_mode_from_config, this is the tool- registering path because it has an executor to bind execute_code to.

§Errors

Returns crate::ToolkitError if code-mode wiring fails — commonly crate::ToolkitError::CodeMode (env var missing / secret too short) or crate::ToolkitError::Validation (inline token_secret rejected per review R9).

§Example
use std::sync::Arc;
use pmcp::Server;
use pmcp_server_toolkit::{ServerBuilderExt, ServerConfig};
use pmcp_server_toolkit::sql::SqlConnector;

let cfg = ServerConfig::default();
let _builder = Server::builder()
    .name("demo")
    .version("0.1.0")
    .try_code_mode_from_config_with_connector(&cfg, connector)?;
Source

fn try_tools_from_config_with( self, config: &ServerConfig, hooks: &ToolkitHooks, ) -> Result<Self>

Self::try_tools_from_config with registered E1/E2 hooks, and the once-at-startup enforcement log (Phase 128).

§Why hooks are a PARAMETER rather than accumulated on the builder

This trait is implemented for CORE’s pmcp::ServerBuilder, whose fields are private. A Rust extension trait cannot add a field to a foreign type, so a with_request_policy(self) -> Self on this trait would have nowhere to store anything. ToolkitHooks carries the registrations instead and Self::try_tools_from_config became a thin wrapper passing a default — so no pre-existing signature changed and no existing caller broke.

§What E1 does NOT govern on this path

This entry point synthesizes SQL / connectorless tools and owns no HTTP egress surface, so a crate::RequestPolicy registered here has nothing to govern. That is reported as a startup WARNING rather than accepted in silence: a policy the operator registered and nothing consults is exactly the present-but-inert defect this phase exists to close. E1 reaches the two HTTP surfaces through pmcp-openapi-server’s build_server.

§Errors

As Self::try_tools_from_config.

Source

fn try_tools_from_config_with_connector_and_hooks( self, config: &ServerConfig, connector: Arc<dyn SqlConnector>, hooks: &ToolkitHooks, ) -> Result<Self>

Self::try_tools_from_config_with_connector with registered E1/E2 hooks (Phase 128). See Self::try_tools_from_config_with for the design and for what E1 does and does not govern on this path.

§Errors

As Self::try_tools_from_config_with_connector.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl ServerBuilderExt for ServerBuilder

Implementors§