pub struct ServerBuilder { /* private fields */ }Expand description
The builder behind Server::builder.
Implementations§
Source§impl ServerBuilder
impl ServerBuilder
Sourcepub const fn request_state_key(self, key: StateKey) -> Self
pub const fn request_state_key(self, key: StateKey) -> Self
Sets the key SEP-2322 requestState is sealed under.
Optional: a transport fills one from the OS random source when it is absent. Set it explicitly when several replicas serve one endpoint — they must share it, or a retry that lands on a different replica finds its state refused.
Sourcepub fn version(self, version: impl Into<String>) -> Self
pub fn version(self, version: impl Into<String>) -> Self
Sets the version this server reports in serverInfo.
Defaults to the version of the crate that built it, which is right for
a server that is this crate — the examples, the conformance runner —
and wrong for one that merely links it. A library user shipping their
own server should say so here rather than let the dependency’s version
stand in for theirs, which would have every downstream server claiming
to be whatever protocol-droid happened to be pinned at.
Sourcepub fn idempotency(
self,
store: Arc<dyn IdempotencyStore<Result = JsonObject>>,
) -> Self
pub fn idempotency( self, store: Arc<dyn IdempotencyStore<Result = JsonObject>>, ) -> Self
Replaces the store tools/call is deduplicated through.
For a store that outlives the process — a shared cache, a table — or
for a test that wants to assert on what was recorded. A server that
keeps its own IdSource across restarts has a gap the in-memory
default cannot close: a call recorded before a restart is unknown
after it, and the retry runs the tool again.
Sourcepub fn with_state<T: Send + Sync + 'static>(self, value: T) -> Self
pub fn with_state<T: Send + Sync + 'static>(self, value: T) -> Self
Registers a value handlers can read through
RequestContext::state.
T is keyed by TypeId, so two with_state calls with the same
T keep the later value (the registry is a HashMap, and the
later write is the one the lookup will see). The Send + Sync
bounds are the same every other port in this crate asks for; a
pool of non-Send handles cannot live in this map.
The point of this method is the #[tool] problem: a macro that
generates module-scope items cannot see self, so the handler
it generates has no captured environment. Storing the state
here and reading it through the request context is the
standard answer, and the only one that keeps the macro
out of the receiver business.
Sourcepub fn tool(self, tool: Tool, handler: ToolHandler) -> Self
pub fn tool(self, tool: Tool, handler: ToolHandler) -> Self
Adds a tool, and publishes it to the registry in the same step.
Takes a whole Tool rather than a name and a schema string, because
a schema string can only ever express the plainest tool there is. An
output schema, annotations and icons all change what the tool
requires of a session, and a builder that cannot name them would
register a tool whose requirement nothing had computed.
Registering and publishing together is the point: a tool in the list but not in the registry is a tool a client can see and not call, and one in neither is a handler that never runs. There is no state in between for a caller to be wrong in.
Sourcepub fn restricted_tool(
self,
registered: Registered,
handler: ToolHandler,
) -> Self
pub fn restricted_tool( self, registered: Registered, handler: ToolHandler, ) -> Self
Adds a tool that carries its own requirements.
tool takes a Tool, and a Tool cannot say
“callers need the files:read scope” — that lives on Registered,
which wraps a primitive with the policy it must satisfy. So without this
method the scope half of is_visible is reachable from no builder
call, auth.rs is dead code, and a server can be built that has no way
to express an authorisation rule at all. That is the same dead-gate
shape T11 found, one layer up.
A Registered carrying something other than a tool is registered
under its own id and left out of the call table: it stays visible to
tools/list and the listing is the truth, so nothing is silently
dropped, but there is no handler to name for a tools/call of it.
Sourcepub fn simple_tool(
self,
name: impl Into<PrimitiveId>,
input_schema: &str,
handler: ToolHandler,
) -> Result<Self, JsonObjectError>
pub fn simple_tool( self, name: impl Into<PrimitiveId>, input_schema: &str, handler: ToolHandler, ) -> Result<Self, JsonObjectError>
Adds a plain tool: a name, an input schema, and a handler.
The common case, and the one a tool without an output schema or
annotations fits. It exists so the common case is one line rather than
a Tool::new(...)? at every call site, and it returns a Result
because the schema is the one fallible step.
§Errors
The JsonObject from parsing
input_schema. The schema is validated here, once, so a malformed one
fails at build time rather than on the first call.
Sourcepub fn resource_with(self, resource: Resource, reader: ResourceHandler) -> Self
pub fn resource_with(self, resource: Resource, reader: ResourceHandler) -> Self
Adds a resource.
Adds a resource together with the reader that answers resources/read
for it.
Both at once, and there is deliberately no resource(resource) beside
it. A resource that is listed by resources/list and then refused by
resources/read is a server telling a peer something false, and the
dispatcher has to answer InvalidParams for the read because it has no
other way to distinguish that from a URI the server never had. Making
the reader a separate opt-in would put that state one method call away,
and the failure would surface to a client rather than at the call site
that built it.
Sourcepub fn resource_template(self, template: ResourceTemplate) -> Self
pub fn resource_template(self, template: ResourceTemplate) -> Self
Adds a resource template.
Templates are listed by their own method, and they are a distinct
PrimitiveKind in the registry, so a template needs its own entry
point rather than sharing resource’s.
Sourcepub fn prompt_with(self, prompt: Prompt, getter: PromptHandler) -> Self
pub fn prompt_with(self, prompt: Prompt, getter: PromptHandler) -> Self
Adds a prompt together with the getter that answers prompts/get for it.
Required together for the reason resource_with
takes both.
Trait Implementations§
Source§impl Debug for ServerBuilder
impl Debug for ServerBuilder
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Prints the same three facts as Server, plus whether a store was
supplied.
The last is the one worth having here, and it is the question to ask first when a recorded result has gone missing across a restart: a server still on the default has an in-process bound, and no way to see that from the built server it became.