pub struct Surface { /* private fields */ }Expand description
The registry seen as resources and tools.
The context is taken from Live per call rather than held, because an MCP session
outlives many commits: a surface that captured one context would answer a client
attached this morning with the repository as it was this morning, for the whole day.
The listings are memoised per generation of the repository, so a client that lists its
tools a thousand times builds them once, and a client that lists them after a commit
that added a capability sees it.
Implementations§
Source§impl Surface
impl Surface
Sourcepub fn for_peer(&self, peer: PeerId) -> Self
pub fn for_peer(&self, peer: PeerId) -> Self
The same surface, seen from one peer: every call it makes carries that identity,
which is how peers.announce knows who is speaking. The listings are shared.
Sourcepub fn tools_json(&self) -> Arc<Vec<Value>> ⓘ
pub fn tools_json(&self) -> Arc<Vec<Value>> ⓘ
The tool listing as tools/list answers it, prepared once per generation.
Sourcepub fn resources_json(&self) -> Arc<Vec<Value>> ⓘ
pub fn resources_json(&self) -> Arc<Vec<Value>> ⓘ
The resource listing as resources/list answers it, prepared once per generation.
Sourcepub fn tools_result(&self) -> Arc<Box<RawValue>> ⓘ
pub fn tools_result(&self) -> Arc<Box<RawValue>> ⓘ
The whole tools/list result, {"tools": [...]}, serialised once: a frame that
carries it copies bytes and builds nothing.
Sourcepub fn resources_result(&self) -> Arc<Box<RawValue>> ⓘ
pub fn resources_result(&self) -> Arc<Box<RawValue>> ⓘ
The whole resources/list result, {"resources": [...]}, serialised once.
Sourcepub fn context(&self) -> Arc<Context> ⓘ
pub fn context(&self) -> Arc<Context> ⓘ
The context behind the surface, as the repository is now.
Owned rather than borrowed: the context this answers with is replaced when the
repository moves, so a reference into the surface would be a promise it cannot
keep. Callers hold the Arc for as long as they read it, which is what keeps one
answer built from one generation.
let surface = Surface::new(ctx);
// the peer board is this process's own life and is the same across every reading
assert!(Arc::ptr_eq(&surface.context().peers, &surface.context().peers));Sourcepub fn peer(&self) -> Option<&PeerId>
pub fn peer(&self) -> Option<&PeerId>
The peer this surface speaks for, when it speaks for one.
Sourcepub fn index(&self) -> Arc<Index> ⓘ
pub fn index(&self) -> Arc<Index> ⓘ
The index behind the surface, as the repository is now.
let surface = Surface::new(ctx);
assert_eq!(surface.index().objects.len(), surface.context().index.objects.len());Sourcepub fn registry(&self) -> Arc<CapabilityRegistry> ⓘ
pub fn registry(&self) -> Arc<CapabilityRegistry> ⓘ
The registry behind the surface, as the repository is now.
let surface = Surface::new(ctx);
assert_eq!(surface.registry().len(), surface.context().registry.len());Sourcepub fn resources(&self) -> Arc<Vec<Resource>> ⓘ
pub fn resources(&self) -> Arc<Vec<Resource>> ⓘ
Every resource: executable ones (a query read as a document) first, then the declarative ones, each group by canonical id. Computed once and shared.
Sourcepub fn read(&self, uri: &str) -> Result<ResourceContent, SurfaceError>
pub fn read(&self, uri: &str) -> Result<ResourceContent, SurfaceError>
Read one resource: an object’s content, or a query with a resource exposure answered
as JSON. The resolution is objects.get’s (builtin::resolve), so the tool, the
HTTP route and this read answer one URI alike.
Sourcepub fn call(
&self,
name: &str,
args: &Value,
) -> Result<ToolOutcome, SurfaceError>
pub fn call( &self, name: &str, args: &Value, ) -> Result<ToolOutcome, SurfaceError>
Call a tool by name, for a caller on this machine.
Sourcepub fn repository_info(&self) -> Result<Value, SurfaceError>
pub fn repository_info(&self) -> Result<Value, SurfaceError>
The repository report, as the repository.info capability answers it.