///| Resource Registry - Internal resource management
///|
priv struct ResourceEntry {
name : String
description : String
uri : String
mime_type : String
handler : async (Json) -> Result[
@resource.ResourceReadOutcome,
@types.MCPError,
]
}
///|
priv struct ResourceTemplateEntry {
uri_template : String
name : String
description : String?
mime_type : String?
}
///|
struct ResourceRegistry {
resources : Map[String, ResourceEntry]
templates : Map[String, ResourceTemplateEntry]
}
///|
fn ResourceRegistry::ResourceRegistry() -> ResourceRegistry {
{ resources: Default::default(), templates: Default::default() }
}
///|
fn ResourceRegistry::register(
self : ResourceRegistry,
uri : String,
name : String,
description : String,
mime_type : String,
handler : async (Json) -> Result[
@resource.ResourceReadOutcome,
@types.MCPError,
],
) -> Unit {
self.resources.set(uri, { name, description, uri, mime_type, handler })
}
///|
fn ResourceRegistry::register_simple(
self : ResourceRegistry,
uri : String,
name : String,
description : String,
mime_type : String,
handler : async () -> Result[@resource.ResourceReadResult, @types.MCPError],
) -> Unit {
let wrapped = async fn(
_params : Json,
) -> Result[@resource.ResourceReadOutcome, @types.MCPError] {
match handler() {
Ok(result) => Ok(@resource.ResourceReadOutcome::Complete(result))
Err(e) => Err(e)
}
}
self.register(uri, name, description, mime_type, wrapped)
}
///|
fn[T : @resource.Resource] ResourceRegistry::register_trait_resource(
self : ResourceRegistry,
resource : T,
) -> Unit {
let name = resource.name()
let description = resource.description()
let uri = resource.uri()
let mime_type = resource.mime_type()
let handler = async fn(
_params : Json,
) -> Result[@resource.ResourceReadOutcome, @types.MCPError] {
match resource.read() {
Ok(result) => Ok(@resource.ResourceReadOutcome::Complete(result))
Err(e) => Err(e)
}
}
self.register(uri, name, description, mime_type, handler)
}
///|
fn[T : @resource.ResourceMRTR] ResourceRegistry::register_trait_resource_mrtr(
self : ResourceRegistry,
resource : T,
) -> Unit {
let name = resource.name()
let description = resource.description()
let uri = resource.uri()
let mime_type = resource.mime_type()
let handler = async fn(
params : Json,
) -> Result[@resource.ResourceReadOutcome, @types.MCPError] {
resource.read(params)
}
self.register(uri, name, description, mime_type, handler)
}
///|
fn ResourceRegistry::register_template(
self : ResourceRegistry,
uri_template : String,
name : String,
description : String?,
mime_type : String?,
) -> Unit {
self.templates.set(uri_template, {
uri_template,
name,
description,
mime_type,
})
}
///|
fn ResourceRegistry::list_resources(
self : ResourceRegistry,
) -> Array[@resource.ResourceDefinition] {
let entries : Array[ResourceEntry] = Array::from_iter(self.resources.values())
entries.sort_by(fn(a, b) { a.uri.compare(b.uri) })
entries.map(fn(entry) {
{
uri: entry.uri,
name: entry.name,
description: Some(entry.description),
mime_type: Some(entry.mime_type),
}
})
}
///|
fn ResourceRegistry::list_templates(
self : ResourceRegistry,
) -> Array[@resource.ResourceTemplateDefinition] {
let entries : Array[ResourceTemplateEntry] = Array::from_iter(
self.templates.values(),
)
entries.sort_by(fn(a, b) { a.uri_template.compare(b.uri_template) })
entries.map(fn(entry) {
{
uri_template: entry.uri_template,
name: entry.name,
description: entry.description,
mime_type: entry.mime_type,
}
})
}
///|
async fn ResourceRegistry::read_resource(
self : ResourceRegistry,
uri : String,
params : Json,
) -> Result[@resource.ResourceReadOutcome, @types.MCPError] {
match self.resources.get(uri) {
Some(entry) => {
let handler = entry.handler
handler(params)
}
// Per 2026-07-28 spec, resource-not-found is InvalidParams (-32602),
// not the old -32002 or MethodNotFound.
None => Err(@types.InvalidParams("Resource not found: " + uri))
}
}