resources mcp

This commit is contained in:
Senstella
2025-10-07 23:05:36 +09:00
parent faf1f49d50
commit 8e5f3844cc

View File

@@ -1,5 +1,11 @@
use crate::fossil::{Fossil, FossilManager};
use crate::matcher::match_lines;
use rmcp::model::{
AnnotateAble, ListResourcesResult, PaginatedRequestParam, RawResource,
ReadResourceRequestParam, ReadResourceResult, ResourceContents,
};
use rmcp::service::RequestContext;
use rmcp::{ErrorData, RoleServer};
use rmcp::{
ServerHandler,
handler::server::{
@@ -9,6 +15,7 @@ use rmcp::{
model::{ServerCapabilities, ServerInfo},
schemars, tool, tool_handler, tool_router,
};
use serde_json::json;
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct CreateFossilRequest {
@@ -181,6 +188,67 @@ impl FossilEditor {
#[tool_handler]
impl ServerHandler for FossilEditor {
async fn list_resources(
&self,
_request: Option<PaginatedRequestParam>,
_: RequestContext<RoleServer>,
) -> Result<ListResourcesResult, ErrorData> {
let fossils = self.state.fossils.lock().unwrap();
let resources: Vec<_> = fossils
.keys()
.map(|id| {
let uri = format!("fossil://{}", id);
RawResource::new(uri, id).no_annotation()
})
.collect();
Ok(ListResourcesResult {
resources,
next_cursor: None,
})
}
async fn read_resource(
&self,
ReadResourceRequestParam { uri }: ReadResourceRequestParam,
_: RequestContext<RoleServer>,
) -> Result<ReadResourceResult, ErrorData> {
if let Some(fossil_id) = uri.strip_prefix("fossil://") {
let fossils = self.state.fossils.lock().unwrap();
if let Some(fossil) = fossils.get(fossil_id) {
if let Some(content) = fossil.latest() {
Ok(ReadResourceResult {
contents: vec![ResourceContents::text(content, uri)],
})
} else {
Err(ErrorData::resource_not_found(
"fossil_empty",
Some(json!({
"uri": uri,
"message": "Fossil exists but has no content"
})),
))
}
} else {
Err(ErrorData::resource_not_found(
"fossil_not_found",
Some(json!({
"uri": uri,
"message": format!("Fossil '{}' not found", fossil_id)
})),
))
}
} else {
Err(ErrorData::resource_not_found(
"invalid_uri",
Some(json!({
"uri": uri,
"message": "URI must start with 'fossil://'"
})),
))
}
}
fn get_info(&self) -> ServerInfo {
ServerInfo {
instructions: Some(
@@ -197,7 +265,7 @@ impl ServerHandler for FossilEditor {
- Use `revert` to undo recent edits on a fossil. Specify `steps` to undo multiple (defaults to 1). This rolls back to previous versions without losing history. Preview with `get_version` first if needed.
- Use `delete_fossil` to clean up and remove unused fossils by ID."#.into(),
),
capabilities: ServerCapabilities::builder().enable_tools().build(),
capabilities: ServerCapabilities::builder().enable_tools().enable_resources().build(),
..Default::default()
}
}