Remove mcp_macros and unused types (#3581)

This commit is contained in:
Jack Amadeo
2025-07-22 16:32:24 -04:00
committed by GitHub
parent ccf188bcc8
commit eab80366e5
9 changed files with 0 additions and 336 deletions

17
Cargo.lock generated
View File

@@ -5428,22 +5428,6 @@ dependencies = [
"utoipa",
]
[[package]]
name = "mcp-macros"
version = "0.1.0"
dependencies = [
"async-trait",
"convert_case",
"mcp-core",
"proc-macro2",
"quote",
"schemars",
"serde",
"serde_json",
"syn 2.0.99",
"tokio",
]
[[package]]
name = "mcp-server"
version = "0.1.0"
@@ -5452,7 +5436,6 @@ dependencies = [
"async-trait",
"futures",
"mcp-core",
"mcp-macros",
"pin-project",
"rmcp",
"schemars",

View File

@@ -11,7 +11,6 @@ use goose::permission::permission_confirmation::PrincipalType;
use goose::providers::base::{ConfigKey, ModelInfo, ProviderMetadata};
use goose::session::info::SessionInfo;
use goose::session::SessionMetadata;
use mcp_core::handler::ToolResultSchema;
use mcp_core::tool::{Tool, ToolAnnotations};
use rmcp::model::ResourceContents;
use rmcp::model::{Annotations, Content, EmbeddedResource, ImageContent, Role, TextContent};
@@ -348,7 +347,6 @@ derive_utoipa!(ResourceContents as ResourceContentsSchema);
TextContentSchema,
ToolResponse,
ToolRequest,
ToolResultSchema,
ToolConfirmationRequest,
ThinkingContent,
RedactedThinkingContent,

View File

@@ -1,11 +1,7 @@
use async_trait::async_trait;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[allow(unused_imports)] // this is used in schema below
use serde_json::json;
use serde_json::Value;
use thiserror::Error;
use utoipa::ToSchema;
#[non_exhaustive]
#[derive(Error, Debug, Clone, Deserialize, Serialize, PartialEq)]
@@ -22,18 +18,6 @@ pub enum ToolError {
pub type ToolResult<T> = std::result::Result<T, ToolError>;
// Define schema manually without generics issues
#[derive(ToSchema)]
#[schema(example = json!({"success": true, "data": {}}))]
pub struct ToolResultSchema {
#[schema(example = "Operation completed successfully")]
pub message: Option<String>,
#[schema(example = true)]
pub success: bool,
#[schema(value_type = Object)]
pub data: Option<serde_json::Value>,
}
#[derive(Error, Debug)]
pub enum ResourceError {
#[error("Execution failed: {0}")]
@@ -51,38 +35,3 @@ pub enum PromptError {
#[error("Prompt not found: {0}")]
NotFound(String),
}
/// Trait for implementing MCP tools
#[async_trait]
pub trait ToolHandler: Send + Sync + 'static {
/// The name of the tool
fn name(&self) -> &'static str;
/// A description of what the tool does
fn description(&self) -> &'static str;
/// JSON schema describing the tool's parameters
fn schema(&self) -> Value;
/// Execute the tool with the given parameters
async fn call(&self, params: Value) -> ToolResult<Value>;
}
/// Trait for implementing MCP resources
#[async_trait]
pub trait ResourceTemplateHandler: Send + Sync + 'static {
/// The URL template for this resource
fn template() -> &'static str;
/// JSON schema describing the resource parameters
fn schema() -> Value;
/// Get the resource value
async fn get(&self, params: Value) -> ToolResult<String>;
}
/// Helper function to generate JSON schema for a type
pub fn generate_schema<T: JsonSchema>() -> ToolResult<Value> {
let schema = schemars::schema_for!(T);
serde_json::to_value(schema).map_err(|e| ToolError::SchemaError(e.to_string()))
}

View File

@@ -1,27 +0,0 @@
[package]
name = "mcp-macros"
version = "0.1.0"
edition = "2021"
[lints]
workspace = true
[lib]
proc-macro = true
[dependencies]
syn = { version = "2.0", features = ["full", "extra-traits"] }
quote = "1.0"
proc-macro2 = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
mcp-core = { path = "../mcp-core" }
async-trait = "0.1"
schemars = "0.8"
convert_case = "0.6.0"
[dev-dependencies]
tokio = { version = "1.43", features = ["full"] }
async-trait = "0.1"
serde_json = "1.0"
schemars = "0.8"

View File

@@ -1,53 +0,0 @@
use mcp_core::handler::{ToolError, ToolHandler};
use mcp_macros::tool;
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
// Create an instance of our tool
let calculator = Calculator;
// Print tool information
println!("Tool name: {}", calculator.name());
println!("Tool description: {}", calculator.description());
println!("Tool schema: {}", calculator.schema());
// Test the tool with some sample input
let input = serde_json::json!({
"x": 5,
"y": 3,
"operation": "multiply"
});
let result = calculator.call(input).await?;
println!("Result: {}", result);
Ok(())
}
#[tool(
name = "calculator",
description = "Perform basic arithmetic operations",
params(
x = "First number in the calculation",
y = "Second number in the calculation",
operation = "The operation to perform (add, subtract, multiply, divide)"
)
)]
async fn calculator(x: i32, y: i32, operation: String) -> Result<i32, ToolError> {
match operation.as_str() {
"add" => Ok(x + y),
"subtract" => Ok(x - y),
"multiply" => Ok(x * y),
"divide" => {
if y == 0 {
Err(ToolError::ExecutionError("Division by zero".into()))
} else {
Ok(x / y)
}
}
_ => Err(ToolError::InvalidParameters(format!(
"Unknown operation: {}",
operation
))),
}
}

View File

@@ -1,152 +0,0 @@
use convert_case::{Case, Casing};
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use std::collections::HashMap;
use syn::{
parse::Parse, parse::ParseStream, parse_macro_input, punctuated::Punctuated, Expr, ExprLit,
FnArg, ItemFn, Lit, Meta, Pat, PatType, Token,
};
struct MacroArgs {
name: Option<String>,
description: Option<String>,
param_descriptions: HashMap<String, String>,
}
impl Parse for MacroArgs {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut name = None;
let mut description = None;
let mut param_descriptions = HashMap::new();
let meta_list: Punctuated<Meta, Token![,]> = Punctuated::parse_terminated(input)?;
for meta in meta_list {
match meta {
Meta::NameValue(nv) => {
let ident = nv.path.get_ident().unwrap().to_string();
if let Expr::Lit(ExprLit {
lit: Lit::Str(lit_str),
..
}) = nv.value
{
match ident.as_str() {
"name" => name = Some(lit_str.value()),
"description" => description = Some(lit_str.value()),
_ => {}
}
}
}
Meta::List(list) if list.path.is_ident("params") => {
let nested: Punctuated<Meta, Token![,]> =
list.parse_args_with(Punctuated::parse_terminated)?;
for meta in nested {
if let Meta::NameValue(nv) = meta {
if let Expr::Lit(ExprLit {
lit: Lit::Str(lit_str),
..
}) = nv.value
{
let param_name = nv.path.get_ident().unwrap().to_string();
param_descriptions.insert(param_name, lit_str.value());
}
}
}
}
_ => {}
}
}
Ok(MacroArgs {
name,
description,
param_descriptions,
})
}
}
#[proc_macro_attribute]
pub fn tool(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as MacroArgs);
let input_fn = parse_macro_input!(input as ItemFn);
// Extract function details
let fn_name = &input_fn.sig.ident;
let fn_name_str = fn_name.to_string();
// Generate PascalCase struct name from the function name
let struct_name = format_ident!("{}", { fn_name_str.to_case(Case::Pascal) });
// Use provided name or function name as default
let tool_name = args.name.unwrap_or(fn_name_str);
let tool_description = args.description.unwrap_or_default();
// Extract parameter names, types, and descriptions
let mut param_defs = Vec::new();
let mut param_names = Vec::new();
for arg in input_fn.sig.inputs.iter() {
if let FnArg::Typed(PatType { pat, ty, .. }) = arg {
if let Pat::Ident(param_ident) = &**pat {
let param_name = &param_ident.ident;
let param_name_str = param_name.to_string();
let description = args
.param_descriptions
.get(&param_name_str)
.map(|s| s.as_str())
.unwrap_or("");
param_names.push(param_name);
param_defs.push(quote! {
#[schemars(description = #description)]
#param_name: #ty
});
}
}
}
// Generate the implementation
let params_struct_name = format_ident!("{}Parameters", struct_name);
let expanded = quote! {
#[derive(serde::Deserialize, schemars::JsonSchema)]
struct #params_struct_name {
#(#param_defs,)*
}
#input_fn
#[derive(Default)]
struct #struct_name;
#[async_trait::async_trait]
impl mcp_core::handler::ToolHandler for #struct_name {
fn name(&self) -> &'static str {
#tool_name
}
fn description(&self) -> &'static str {
#tool_description
}
fn schema(&self) -> serde_json::Value {
mcp_core::handler::generate_schema::<#params_struct_name>()
.expect("Failed to generate schema")
}
async fn call(&self, params: serde_json::Value) -> Result<serde_json::Value, mcp_core::handler::ToolError> {
let params: #params_struct_name = serde_json::from_value(params)
.map_err(|e| mcp_core::handler::ToolError::InvalidParameters(e.to_string()))?;
// Extract parameters and call the function
let result = #fn_name(#(params.#param_names,)*).await
.map_err(|e| mcp_core::handler::ToolError::ExecutionError(e.to_string()))?;
Ok(serde_json::to_value(result).expect("should serialize"))
}
}
};
TokenStream::from(expanded)
}

View File

@@ -10,7 +10,6 @@ workspace = true
anyhow = "1.0.94"
thiserror = "1.0"
mcp-core = { path = "../mcp-core" }
mcp-macros = { path = "../mcp-macros" }
rmcp = { workspace = true }
serde = { version = "1.0.216", features = ["derive"] }
serde_json = "1.0.133"

View File

@@ -2975,31 +2975,6 @@
}
}
},
"ToolResultSchema": {
"type": "object",
"required": [
"success",
"data"
],
"properties": {
"data": {
"type": "object"
},
"message": {
"type": "string",
"example": "Operation completed successfully",
"nullable": true
},
"success": {
"type": "boolean",
"example": true
}
},
"example": {
"data": {},
"success": true
}
},
"UpdateScheduleRequest": {
"type": "object",
"required": [

View File

@@ -763,14 +763,6 @@ export type ToolResponse = {
};
};
export type ToolResultSchema = {
data: {
[key: string]: unknown;
};
message?: string | null;
success: boolean;
};
export type UpdateScheduleRequest = {
cron: string;
};