pub struct McpPool { /* private fields */ }Expand description
A shared MCP connection pool over one executor, caching each connected server’s advertised tool defs by config signature.
Implementations§
Source§impl McpPool
impl McpPool
Sourcepub fn new(shared: Arc<Mutex<ToolExecutor>>, reserved: HashSet<String>) -> Self
pub fn new(shared: Arc<Mutex<ToolExecutor>>, reserved: HashSet<String>) -> Self
Build a pool over shared, reserving reserved names from advertisement.
Sourcepub fn with_env_allowlist(self, allow: Vec<String>) -> Self
pub fn with_env_allowlist(self, allow: Vec<String>) -> Self
Allow these credential-shaped variables in MCP ${VAR} headers.
Sourcepub fn with_credential_store(self, kind: CredentialStoreKind) -> Self
pub fn with_credential_store(self, kind: CredentialStoreKind) -> Self
Read and write MCP grants through kind’s backend.
Sourcepub fn for_daemon(
shared_mcp: Arc<Mutex<ToolExecutor>>,
config_servers: &[MCPServerConfig],
) -> Arc<Self> ⓘ
pub fn for_daemon( shared_mcp: Arc<Mutex<ToolExecutor>>, config_servers: &[MCPServerConfig], ) -> Arc<Self> ⓘ
Build the daemon’s shared pool over shared_mcp: reserve built-in and
sub-agent tool names (so a server tool can’t shadow a core one) and seed
the already-connected global config_servers with empty defs, so a
blueprint that re-declares one doesn’t open a duplicate connection.
Sourcepub fn for_daemon_with(
shared_mcp: Arc<Mutex<ToolExecutor>>,
config_servers: &[MCPServerConfig],
credential_store: CredentialStoreKind,
allow_env_vars: Vec<String>,
) -> Arc<Self> ⓘ
pub fn for_daemon_with( shared_mcp: Arc<Mutex<ToolExecutor>>, config_servers: &[MCPServerConfig], credential_store: CredentialStoreKind, allow_env_vars: Vec<String>, ) -> Arc<Self> ⓘ
for_daemon reading and writing MCP OAuth grants
through credential_store’s backend.
The pool refreshes lapsed tokens and writes them back, so it has to write them where the user asked for them to be kept - otherwise the first refresh after a keychain migration would put a fresh refresh token back on disk.
Sourcepub fn seed(&self, config: &MCPServerConfig, defs: Vec<Tool>)
pub fn seed(&self, config: &MCPServerConfig, defs: Vec<Tool>)
Seed the cache with an already-connected server’s defs (used at startup for
the global config servers, connected once by ToolRegistry::build).
Sourcepub async fn ensure(&self, config: &MCPServerConfig) -> Vec<Tool>
pub async fn ensure(&self, config: &MCPServerConfig) -> Vec<Tool>
Ensure config is connected (idempotent by signature) and return its
advertised tool defs. A connection failure logs and returns no defs (the
agent simply doesn’t get that server’s tools); it is not cached, so a later
spawn retries.
Sourcepub async fn ensure_all(self: Arc<Self>, servers: Vec<MCPServerConfig>)
pub async fn ensure_all(self: Arc<Self>, servers: Vec<MCPServerConfig>)
Connect every server in servers (idempotent). Takes Arc<Self> + owned
servers so it can be tokio::spawned directly as a detached warm task
(e.g. by the fan-out spawner) without a wrapping closure.
Sourcepub async fn warm_recovered(&self, runs_dir: &Path)
pub async fn warm_recovered(&self, runs_dir: &Path)
Warm the per-agent [[mcp_servers]] of every non-terminal persisted run in
runs_dir, so a run reloaded on daemon restart can still execute its
blueprint MCP tools (their advertisement is restored from the snapshot;
only the shared connection is lost across a restart). Blueprint paths are
collected synchronously, then connected - no fs iterator is held across an
.await.
Sourcepub fn cached_defs_for(&self, configs: &[MCPServerConfig]) -> Vec<Tool>
pub fn cached_defs_for(&self, configs: &[MCPServerConfig]) -> Vec<Tool>
The cached defs for every config in configs (pool must already be warm
for them - call Self::ensure first). Unknown/unconnected configs
contribute nothing. This is the sync read the spawner uses.
Auto Trait Implementations§
impl !Freeze for McpPool
impl !RefUnwindSafe for McpPool
impl !UnwindSafe for McpPool
impl Send for McpPool
impl Sync for McpPool
impl Unpin for McpPool
impl UnsafeUnpin for McpPool
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> ConditionalSend for Twhere
T: Send,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more