diff --git a/Cargo.lock b/Cargo.lock index ee1812e08..852d6c254 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -588,7 +588,7 @@ dependencies = [ "brk_vec", "color-eyre", "derive_deref", - "schemars 1.0.0", + "schemars 1.0.1", "serde", "serde_json", "serde_with", @@ -633,9 +633,9 @@ dependencies = [ [[package]] name = "brk_rmcp" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecf167efab04b87a8850e12196228388733aa43adaeafd5b4d6f9e29d850263" +checksum = "26db177d2933b727fe5f53b52d5ebead13d57f94ed8637717117a8bb1a3f1bae" dependencies = [ "base64 0.22.1", "brk_rmcp-macros", @@ -648,7 +648,7 @@ dependencies = [ "paste", "pin-project-lite", "rand 0.9.1", - "schemars 1.0.0", + "schemars 1.0.1", "serde", "serde_json", "sse-stream", @@ -663,10 +663,11 @@ dependencies = [ [[package]] name = "brk_rmcp-macros" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e3a4b2b6bdb0508a756e9296321b6ce33234070060ad68f68c8372b7b53fc6" +checksum = "4557e65ffea1466260a6ab13e3ba54bcee69c39576e4bfb8b81e50b375924540" dependencies = [ + "darling", "proc-macro2", "quote", "serde_json", @@ -2849,9 +2850,9 @@ dependencies = [ [[package]] name = "oxc_resolver" -version = "11.2.0" +version = "11.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce097520c87cb9aae8b43b39b333a6709342db75b88e76b5c6bcadf0cccf16ea" +checksum = "3e9fbd425311540ada87997dbec6e9a2e0bab00b7e82db8e6ef79a0d0a9cfce1" dependencies = [ "cfg-if", "indexmap 2.9.0", @@ -3012,9 +3013,9 @@ dependencies = [ [[package]] name = "papaya" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6827e3fc394523c21d4464d02c0bb1c19966ea4a58a9844ad6d746214179d2bc" +checksum = "af228bb1296c9b044ee75e2a2325409c2d899bcfcc6150e5e41f148e0a87dd20" dependencies = [ "equivalent", "seize", @@ -3561,9 +3562,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "febc07c7e70b5db4f023485653c754d76e1bbe8d9dbfa20193ce13da9f9633f4" +checksum = "fe8c9d1c68d67dd9f97ecbc6f932b60eb289c5dbddd8aa1405484a8fd2fcd984" dependencies = [ "dyn-clone", "ref-cast", @@ -3574,9 +3575,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1eeedaab7b1e1d09b5b4661121f4d27f9e7487089b0117833ccd7a882ee1ecc" +checksum = "6ca9fcb757952f8e8629b9ab066fc62da523c46c2b247b1708a3be06dd82530b" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 1f1037de2..65e7632d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,8 @@ brk_interface = { version = "0.0.70", path = "crates/brk_interface" } brk_logger = { version = "0.0.70", path = "crates/brk_logger" } brk_mcp = { version = "0.0.70", path = "crates/brk_mcp" } brk_parser = { version = "0.0.70", path = "crates/brk_parser" } -brk_rmcp = { version = "0.1.7", features = ["transport-streamable-http-server", "transport-worker"]} +brk_rmcp = { version = "0.1.8", features = ["transport-streamable-http-server", "transport-worker"]} +# brk_rmcp = { path = "../rust-sdk/crates/rmcp", features = ["transport-streamable-http-server", "transport-worker"]} brk_server = { version = "0.0.70", path = "crates/brk_server" } brk_state = { version = "0.0.70", path = "crates/brk_state" } brk_store = { version = "0.0.70", path = "crates/brk_store" } @@ -48,7 +49,7 @@ jiff = "0.2.15" log = { version = "0.4.27" } minreq = { version = "2.13.4", features = ["https", "serde_json"] } rayon = "1.10.0" -schemars = "1.0.0" +schemars = "1.0.1" serde = { version = "1.0.219" } serde_bytes = "0.11.17" serde_derive = "1.0.219" diff --git a/crates/brk_interface/src/index.rs b/crates/brk_interface/src/index.rs index 252bd300e..a92b8fd90 100644 --- a/crates/brk_interface/src/index.rs +++ b/crates/brk_interface/src/index.rs @@ -12,29 +12,53 @@ use serde::{Deserialize, de::Error}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] pub enum Index { + #[schemars(description = "Date/day index")] DateIndex, + #[schemars(description = "Decade index")] DecadeIndex, + #[schemars(description = "Difficulty epoch index (equivalent to ~2 weeks)")] DifficultyEpoch, + #[schemars(description = "Empty output index")] EmptyOutputIndex, + #[schemars(description = "Halving epoch index (equivalent to ~4 years)")] HalvingEpoch, + #[schemars(description = "Height/block index")] Height, + #[schemars(description = "Transaction input index (based on total)")] InputIndex, + #[schemars(description = "Month index")] MonthIndex, + #[schemars(description = "Op return index")] OpReturnIndex, + #[schemars(description = "Transaction output index (based on total)")] OutputIndex, + #[schemars(description = "Index of P2A address")] P2AAddressIndex, + #[schemars(description = "Index of P2MS output")] P2MSOutputIndex, + #[schemars(description = "Index of P2PK (33 bytes) address")] P2PK33AddressIndex, + #[schemars(description = "Index of P2PK (65 bytes) address")] P2PK65AddressIndex, + #[schemars(description = "Index of P2PKH address")] P2PKHAddressIndex, + #[schemars(description = "Index of P2SH address")] P2SHAddressIndex, + #[schemars(description = "Index of P2TR address")] P2TRAddressIndex, + #[schemars(description = "Index of P2WPKH address")] P2WPKHAddressIndex, + #[schemars(description = "Index of P2WSH address")] P2WSHAddressIndex, + #[schemars(description = "Quarter index")] QuarterIndex, + #[schemars(description = "Transaction index")] TxIndex, + #[schemars(description = "Unknown output index")] UnknownOutputIndex, + #[schemars(description = "Week index")] WeekIndex, + #[schemars(description = "Year index")] YearIndex, } diff --git a/crates/brk_interface/src/params.rs b/crates/brk_interface/src/params.rs index 6fa25f39e..1f32751d3 100644 --- a/crates/brk_interface/src/params.rs +++ b/crates/brk_interface/src/params.rs @@ -12,11 +12,11 @@ use crate::{ #[derive(Debug, Deserialize, JsonSchema)] pub struct Params { #[serde(alias = "i")] - #[schemars(description = "Index of the values requested")] + #[schemars(description = "Index of requested vecs")] pub index: Index, #[serde(alias = "v")] - #[schemars(description = "Ids of the requested vecs")] + #[schemars(description = "Ids of requested vecs")] pub ids: MaybeIds, #[serde(flatten)] @@ -45,18 +45,24 @@ impl From<((Index, String), ParamsOpt)> for Params { pub struct ParamsOpt { #[serde(default, alias = "f", deserialize_with = "de_unquote_i64")] /// Inclusive starting index, if negative will be from the end + #[schemars(description = "Inclusive starting index, if negative will be from the end")] from: Option, #[serde(default, alias = "t", deserialize_with = "de_unquote_i64")] /// Exclusive ending index, if negative will be from the end, overrides 'count' + #[schemars( + description = "Exclusive ending index, if negative will be from the end, overrides 'count'" + )] to: Option, #[serde(default, alias = "c", deserialize_with = "de_unquote_usize")] - /// Number of values + /// Number of values requested + #[schemars(description = "Number of values requested")] count: Option, - /// Format of the output #[serde(default)] + /// Format of the output + #[schemars(description = "Format of the output")] format: Option, } diff --git a/crates/brk_mcp/src/lib.rs b/crates/brk_mcp/src/lib.rs index 6009511f8..eadd03a0d 100644 --- a/crates/brk_mcp/src/lib.rs +++ b/crates/brk_mcp/src/lib.rs @@ -6,12 +6,10 @@ use brk_interface::{IdParam, Interface, PaginatedIndexParam, PaginationParam, Params}; use brk_rmcp::{ Error as McpError, RoleServer, ServerHandler, - model::{ - CallToolResult, Content, Implementation, InitializeRequestParam, InitializeResult, - ProtocolVersion, ServerCapabilities, ServerInfo, - }, + handler::server::{router::tool::ToolRouter, tool::Parameters}, + model::*, service::RequestContext, - tool, + tool, tool_handler, tool_router, }; use log::info; @@ -20,14 +18,18 @@ pub mod route; #[derive(Clone)] pub struct MCP { interface: &'static Interface<'static>, + tool_router: ToolRouter, } const VERSION: &str = env!("CARGO_PKG_VERSION"); -#[tool(tool_box)] +#[tool_router] impl MCP { pub fn new(interface: &'static Interface<'static>) -> Self { - Self { interface } + Self { + interface, + tool_router: Self::tool_router(), + } } #[tool(description = " @@ -54,8 +56,8 @@ Get the count of all existing vec ids. Get the count of all existing vecs. Equals to the sum of supported Indexes of each vec id. ")] - async fn get_variant_count(&self) -> Result { - info!("mcp: get_variant_count"); + async fn get_vec_count(&self) -> Result { + info!("mcp: get_vec_count"); Ok(CallToolResult::success(vec![ Content::json(self.interface.get_vec_count()).unwrap(), ])) @@ -88,7 +90,7 @@ If the `page` param is omitted, it will default to the first page. ")] async fn get_vecids( &self, - #[tool(aggr)] pagination: PaginationParam, + Parameters(pagination): Parameters, ) -> Result { info!("mcp: get_vecids"); Ok(CallToolResult::success(vec![ @@ -103,7 +105,7 @@ If the `page` param is omitted, it will default to the first page. ")] async fn get_index_to_vecids( &self, - #[tool(aggr)] paginated_index: PaginatedIndexParam, + Parameters(paginated_index): Parameters, ) -> Result { info!("mcp: get_index_to_vecids"); Ok(CallToolResult::success(vec![ @@ -117,7 +119,7 @@ The list will be empty if the vec id isn't correct. ")] async fn get_vecid_to_indexes( &self, - #[tool(aggr)] param: IdParam, + Parameters(param): Parameters, ) -> Result { info!("mcp: get_vecid_to_indexes"); Ok(CallToolResult::success(vec![ @@ -127,14 +129,12 @@ The list will be empty if the vec id isn't correct. #[tool(description = " Get one or multiple vecs depending on given parameters. -If you'd like to request multiple vec ids, simply separate them with a ','. -To get the last value set `-1` to the `from` parameter. The response's format will depend on the given parameters, it will be: - A value: If requested only one vec and the given range returns one value (for example: `from=-1`) - A list: If requested only one vec and the given range returns multiple values (for example: `from=-1000&count=100` or `from=-444&to=-333`) - A matrix: When multiple vecs are requested, even if they each return one value. ")] - fn get_vecs(&self, #[tool(aggr)] params: Params) -> Result { + fn get_vecs(&self, Parameters(params): Parameters) -> Result { info!("mcp: get_vecs"); Ok(CallToolResult::success(vec![ Content::json(self.interface.search_and_format(params).unwrap()).unwrap(), @@ -152,7 +152,7 @@ Get the running version of the Bitcoin Research Kit. } } -#[tool(tool_box)] +#[tool_handler] impl ServerHandler for MCP { fn get_info(&self) -> ServerInfo { ServerInfo { @@ -181,13 +181,8 @@ An 'Index' (or indexes) is the timeframe of a dataset. async fn initialize( &self, _request: InitializeRequestParam, - context: RequestContext, + _context: RequestContext, ) -> Result { - if let Some(http_request_part) = context.extensions.get::() { - let initialize_headers = &http_request_part.headers; - let initialize_uri = &http_request_part.uri; - tracing::info!(?initialize_headers, %initialize_uri, "initialize from http server"); - } Ok(self.get_info()) } }