Implement SEP-1319: Decouple Request Payload from RPC Methods (#617)
* feat: implement SEP-1319 Decouple Request Payload from RPC Methods * test: update tests * fix: update handler trait methods to use new types * fix: update examples * fix: correct deprecation version * fix: update wrapper macros to use new *Params type names
This commit is contained in:
parent
48e989b711
commit
9e881a645b
13 changed files with 913 additions and 278 deletions
|
|
@ -6,7 +6,7 @@ use std::collections::HashMap;
|
|||
|
||||
use anyhow::Result;
|
||||
use rmcp::{
|
||||
model::CallToolRequestParam,
|
||||
model::CallToolRequestParams,
|
||||
service::ServiceExt,
|
||||
transport::{ConfigureCommandExt, TokioChildProcess},
|
||||
};
|
||||
|
|
@ -46,7 +46,8 @@ async fn main() -> Result<()> {
|
|||
|
||||
// Call tool 'git_status' with arguments = {"repo_path": "."}
|
||||
let _tool_result = client
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: "git_status".into(),
|
||||
arguments: serde_json::json!({ "repo_path": "." }).as_object().cloned(),
|
||||
task: None,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::Result;
|
||||
use rmcp::{
|
||||
ServiceExt,
|
||||
model::{CallToolRequestParam, GetPromptRequestParam, ReadResourceRequestParam},
|
||||
model::{CallToolRequestParams, GetPromptRequestParams, ReadResourceRequestParams},
|
||||
object,
|
||||
transport::{ConfigureCommandExt, TokioChildProcess},
|
||||
};
|
||||
|
|
@ -37,7 +37,8 @@ async fn main() -> Result<()> {
|
|||
|
||||
// Call tool echo
|
||||
let tool_result = client
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: "echo".into(),
|
||||
arguments: Some(object!({ "message": "hi from rmcp" })),
|
||||
task: None,
|
||||
|
|
@ -47,7 +48,8 @@ async fn main() -> Result<()> {
|
|||
|
||||
// Call tool longRunningOperation
|
||||
let tool_result = client
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: "longRunningOperation".into(),
|
||||
arguments: Some(object!({ "duration": 3, "steps": 1 })),
|
||||
task: None,
|
||||
|
|
@ -61,7 +63,8 @@ async fn main() -> Result<()> {
|
|||
|
||||
// Read resource
|
||||
let resource = client
|
||||
.read_resource(ReadResourceRequestParam {
|
||||
.read_resource(ReadResourceRequestParams {
|
||||
meta: None,
|
||||
uri: "test://static/resource/3".into(),
|
||||
})
|
||||
.await?;
|
||||
|
|
@ -73,7 +76,8 @@ async fn main() -> Result<()> {
|
|||
|
||||
// Get simple prompt
|
||||
let prompt = client
|
||||
.get_prompt(GetPromptRequestParam {
|
||||
.get_prompt(GetPromptRequestParams {
|
||||
meta: None,
|
||||
name: "simple_prompt".into(),
|
||||
arguments: None,
|
||||
})
|
||||
|
|
@ -82,7 +86,8 @@ async fn main() -> Result<()> {
|
|||
|
||||
// Get complex prompt (returns text & image)
|
||||
let prompt = client
|
||||
.get_prompt(GetPromptRequestParam {
|
||||
.get_prompt(GetPromptRequestParams {
|
||||
meta: None,
|
||||
name: "complex_prompt".into(),
|
||||
arguments: Some(object!({ "temperature": "0.5", "style": "formal" })),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use rmcp::{
|
||||
RmcpError,
|
||||
model::CallToolRequestParam,
|
||||
model::CallToolRequestParams,
|
||||
service::ServiceExt,
|
||||
transport::{ConfigureCommandExt, TokioChildProcess},
|
||||
};
|
||||
|
|
@ -39,7 +39,8 @@ async fn main() -> Result<(), RmcpError> {
|
|||
|
||||
// Call tool 'git_status' with arguments = {"repo_path": "."}
|
||||
let tool_result = client
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: "git_status".into(),
|
||||
arguments: serde_json::json!({ "repo_path": "." }).as_object().cloned(),
|
||||
task: None,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use clap::{Parser, ValueEnum};
|
|||
use rmcp::{
|
||||
ClientHandler, ServiceExt,
|
||||
model::{
|
||||
CallToolRequestParam, ClientCapabilities, ClientInfo, Implementation,
|
||||
CallToolRequestParams, ClientCapabilities, ClientInfo, Implementation,
|
||||
ProgressNotificationParam,
|
||||
},
|
||||
service::{NotificationContext, RoleClient},
|
||||
|
|
@ -123,6 +123,7 @@ impl ClientHandler for ProgressAwareClient {
|
|||
|
||||
fn get_info(&self) -> ClientInfo {
|
||||
ClientInfo {
|
||||
meta: None,
|
||||
protocol_version: Default::default(),
|
||||
capabilities: ClientCapabilities::default(),
|
||||
client_info: Implementation {
|
||||
|
|
@ -181,7 +182,8 @@ async fn test_stdio_transport(records: u32) -> Result<()> {
|
|||
// Call stream processor tool
|
||||
tracing::info!("Starting to process {} records...", records);
|
||||
let tool_result = service
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: "stream_processor".into(),
|
||||
arguments: None,
|
||||
task: None,
|
||||
|
|
@ -236,7 +238,8 @@ async fn test_http_transport(http_url: &str, records: u32) -> Result<()> {
|
|||
// Call stream processor tool
|
||||
tracing::info!("Starting to process {} records...", records);
|
||||
let tool_result = client
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: "stream_processor".into(),
|
||||
arguments: None,
|
||||
task: None,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ impl SamplingDemoClient {
|
|||
impl ClientHandler for SamplingDemoClient {
|
||||
async fn create_message(
|
||||
&self,
|
||||
params: CreateMessageRequestParam,
|
||||
params: CreateMessageRequestParams,
|
||||
_context: RequestContext<RoleClient>,
|
||||
) -> Result<CreateMessageResult, ErrorData> {
|
||||
tracing::info!("Received sampling request with {:?}", params);
|
||||
|
|
@ -101,7 +101,8 @@ async fn main() -> Result<()> {
|
|||
// Test the ask_llm tool
|
||||
tracing::info!("Testing ask_llm tool...");
|
||||
match client
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: "ask_llm".into(),
|
||||
arguments: Some(object!({
|
||||
"question": "Hello world"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::Result;
|
||||
use rmcp::{
|
||||
ServiceExt,
|
||||
model::{CallToolRequestParam, ClientCapabilities, ClientInfo, Implementation},
|
||||
model::{CallToolRequestParams, ClientCapabilities, ClientInfo, Implementation},
|
||||
transport::StreamableHttpClientTransport,
|
||||
};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
|
@ -18,6 +18,7 @@ async fn main() -> Result<()> {
|
|||
.init();
|
||||
let transport = StreamableHttpClientTransport::from_uri("http://localhost:8000/mcp");
|
||||
let client_info = ClientInfo {
|
||||
meta: None,
|
||||
protocol_version: Default::default(),
|
||||
capabilities: ClientCapabilities::default(),
|
||||
client_info: Implementation {
|
||||
|
|
@ -41,7 +42,8 @@ async fn main() -> Result<()> {
|
|||
tracing::info!("Available tools: {tools:#?}");
|
||||
|
||||
let tool_result = client
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: "increment".into(),
|
||||
arguments: serde_json::json!({}).as_object().cloned(),
|
||||
task: None,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
|||
use rig::tool::{ToolDyn as RigTool, ToolEmbeddingDyn, ToolSet};
|
||||
use rmcp::{
|
||||
RoleClient,
|
||||
model::{CallToolRequestParam, CallToolResult, Tool as McpTool},
|
||||
model::{CallToolRequestParams, CallToolResult, Tool as McpTool},
|
||||
service::{RunningService, ServerSink},
|
||||
};
|
||||
|
||||
|
|
@ -41,7 +41,8 @@ impl RigTool for McpToolAdaptor {
|
|||
let server = self.server.clone();
|
||||
Box::pin(async move {
|
||||
let call_mcp_tool_result = server
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: self.tool.name.clone(),
|
||||
arguments: serde_json::from_str(&args)
|
||||
.map_err(rig::tool::ToolError::JsonError)?,
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ impl ServerHandler for Counter {
|
|||
|
||||
async fn list_resources(
|
||||
&self,
|
||||
_request: Option<PaginatedRequestParam>,
|
||||
_request: Option<PaginatedRequestParams>,
|
||||
_: RequestContext<RoleServer>,
|
||||
) -> Result<ListResourcesResult, McpError> {
|
||||
Ok(ListResourcesResult {
|
||||
|
|
@ -229,7 +229,7 @@ impl ServerHandler for Counter {
|
|||
|
||||
async fn read_resource(
|
||||
&self,
|
||||
ReadResourceRequestParam { uri }: ReadResourceRequestParam,
|
||||
ReadResourceRequestParams { meta: _, uri }: ReadResourceRequestParams,
|
||||
_: RequestContext<RoleServer>,
|
||||
) -> Result<ReadResourceResult, McpError> {
|
||||
match uri.as_str() {
|
||||
|
|
@ -256,7 +256,7 @@ impl ServerHandler for Counter {
|
|||
|
||||
async fn list_resource_templates(
|
||||
&self,
|
||||
_request: Option<PaginatedRequestParam>,
|
||||
_request: Option<PaginatedRequestParams>,
|
||||
_: RequestContext<RoleServer>,
|
||||
) -> Result<ListResourceTemplatesResult, McpError> {
|
||||
Ok(ListResourceTemplatesResult {
|
||||
|
|
@ -268,7 +268,7 @@ impl ServerHandler for Counter {
|
|||
|
||||
async fn initialize(
|
||||
&self,
|
||||
_request: InitializeRequestParam,
|
||||
_request: InitializeRequestParams,
|
||||
context: RequestContext<RoleServer>,
|
||||
) -> Result<InitializeResult, McpError> {
|
||||
if let Some(http_request_part) = context.extensions.get::<axum::http::request::Parts>() {
|
||||
|
|
@ -347,7 +347,8 @@ mod tests {
|
|||
"source".into(),
|
||||
serde_json::Value::String("integration-test".into()),
|
||||
);
|
||||
let params = CallToolRequestParam {
|
||||
let params = CallToolRequestParams {
|
||||
meta: None,
|
||||
name: "long_task".into(),
|
||||
arguments: None,
|
||||
task: Some(task_meta),
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ impl ServerHandler for SqlQueryServer {
|
|||
|
||||
async fn complete(
|
||||
&self,
|
||||
request: CompleteRequestParam,
|
||||
request: CompleteRequestParams,
|
||||
_context: RequestContext<RoleServer>,
|
||||
) -> Result<CompleteResult, McpError> {
|
||||
let candidates = match &request.r#ref {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ impl ServerHandler for SamplingDemoServer {
|
|||
|
||||
async fn call_tool(
|
||||
&self,
|
||||
request: CallToolRequestParam,
|
||||
request: CallToolRequestParams,
|
||||
context: RequestContext<RoleServer>,
|
||||
) -> Result<CallToolResult, ErrorData> {
|
||||
match request.name.as_ref() {
|
||||
|
|
@ -48,7 +48,9 @@ impl ServerHandler for SamplingDemoServer {
|
|||
|
||||
let response = context
|
||||
.peer
|
||||
.create_message(CreateMessageRequestParam {
|
||||
.create_message(CreateMessageRequestParams {
|
||||
meta: None,
|
||||
task: None,
|
||||
messages: vec![SamplingMessage {
|
||||
role: Role::User,
|
||||
content: Content::text(question),
|
||||
|
|
@ -99,7 +101,7 @@ impl ServerHandler for SamplingDemoServer {
|
|||
|
||||
async fn list_tools(
|
||||
&self,
|
||||
_request: Option<PaginatedRequestParam>,
|
||||
_request: Option<PaginatedRequestParams>,
|
||||
_context: RequestContext<RoleServer>,
|
||||
) -> Result<ListToolsResult, ErrorData> {
|
||||
Ok(ListToolsResult {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
|||
use async_trait::async_trait;
|
||||
use rmcp::{
|
||||
RoleClient,
|
||||
model::{CallToolRequestParam, CallToolResult, Tool as McpTool},
|
||||
model::{CallToolRequestParams, CallToolResult, Tool as McpTool},
|
||||
service::{RunningService, ServerSink},
|
||||
};
|
||||
use serde_json::Value;
|
||||
|
|
@ -59,7 +59,8 @@ impl Tool for McpToolAdapter {
|
|||
println!("arguments: {:?}", arguments);
|
||||
let call_result = self
|
||||
.server
|
||||
.call_tool(CallToolRequestParam {
|
||||
.call_tool(CallToolRequestParams {
|
||||
meta: None,
|
||||
name: self.tool.name.clone(),
|
||||
arguments,
|
||||
task: None,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ async fn main() -> anyhow::Result<()> {
|
|||
println!("Calling sum tool: {}", sum_tool.name);
|
||||
let result = client
|
||||
.peer()
|
||||
.call_tool(rmcp::model::CallToolRequestParam {
|
||||
.call_tool(rmcp::model::CallToolRequestParams {
|
||||
meta: None,
|
||||
name: sum_tool.name.clone(),
|
||||
arguments: Some(rmcp::object!({
|
||||
"a": 10,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ async fn main() -> anyhow::Result<()> {
|
|||
println!("Calling sum tool: {}", sum_tool.name);
|
||||
let result = client
|
||||
.peer()
|
||||
.call_tool(rmcp::model::CallToolRequestParam {
|
||||
.call_tool(rmcp::model::CallToolRequestParams {
|
||||
meta: None,
|
||||
name: sum_tool.name.clone(),
|
||||
arguments: Some(rmcp::object!({
|
||||
"a": 10,
|
||||
|
|
|
|||
Loading…
Reference in a new issue