Skip to content

Commit 18676e3

Browse files
authored
Merge pull request #121 from guyernest/feat/cargo-pmcp-oauth
fix: resolve test compilation errors across workspace
2 parents d59b830 + 65f9fc4 commit 18676e3

File tree

10 files changed

+89
-217
lines changed

10 files changed

+89
-217
lines changed

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,9 @@ required-features = ["schema-generation"]
378378
name = "comprehensive_benchmarks"
379379
harness = false
380380
[workspace]
381-
members = ["pmcp-macros", "crates/mcp-tester", "examples/wasm-client", "examples/25-oauth-basic", "examples/test-basic", "cargo-pmcp"]
382-
exclude = ["fuzz", "examples/cloudflare-worker-mcp", "examples/26-server-tester"]
381+
members = ["pmcp-macros", "crates/mcp-tester", "examples/25-oauth-basic", "examples/test-basic", "cargo-pmcp"]
382+
# WASM examples require wasm32-unknown-unknown target and are excluded from regular workspace tests
383+
exclude = ["fuzz", "examples/cloudflare-worker-mcp", "examples/26-server-tester", "examples/wasm-client"]
383384

384385
[package.metadata.docs.rs]
385386
all-features = true

cargo-pmcp/src/deployment/registry.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,10 @@ mod tests {
187187

188188
#[test]
189189
fn test_registry_register_and_get() {
190-
let mut registry = TargetRegistry::new();
190+
// Use empty registry for isolated test (not new() which pre-populates)
191+
let mut registry = TargetRegistry {
192+
targets: std::collections::HashMap::new(),
193+
};
191194
let target = Arc::new(MockTarget {
192195
id: "test".to_string(),
193196
name: "Test Target".to_string(),

examples/25-oauth-basic/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ async fn main() -> Result<()> {
101101
// Create a scope-based authorizer that defines access rules
102102
let authorizer = ScopeBasedAuthorizer::new()
103103
// Public tool - no scopes required (anyone can access)
104-
.require_scopes("public_info", vec![])
104+
.require_scopes("public_info", Vec::<String>::new())
105105
// Protected tool - requires basic read scope
106106
.require_scopes("protected_data", vec!["read".to_string()])
107107
// Admin tool - requires admin scope

examples/25-oauth-basic/stdio-minimal.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ impl ToolHandler for AdminTool {
6767
async fn main() -> Result<(), Box<dyn std::error::Error>> {
6868
// Create scope-based authorizer
6969
let authorizer = ScopeBasedAuthorizer::new()
70-
.require_scopes("public_info", vec![]) // No scopes required
71-
.require_scopes("protected_data", vec!["read".to_string()]) // Read scope required
70+
.require_scopes("public_info", Vec::<String>::new()) // No scopes required
71+
.require_scopes("protected_data", vec!["read".to_string()]) // Read scope required
7272
.require_scopes("admin_action", vec!["admin".to_string()]) // Admin scope required
7373
.default_scopes(vec!["mcp:tools:use".to_string()]); // Default for other tools
7474

examples/25-oauth-basic/test-client.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
2828
session_id: None,
2929
enable_json_response: true,
3030
on_resumption_token: None,
31+
http_middleware_chain: None,
3132
};
3233

3334
// Create the transport

pmcp-macros/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ tokio = { version = "1.46", features = ["full"] }
3232
trybuild = "1.0"
3333
pretty_assertions = "1.4"
3434
insta = { version = "1.43", features = ["json"] }
35+
async-trait = "0.1"
36+
proptest = "1.6"
3537

3638
[features]
3739
default = []
3840
debug = [] # Enable debug output in macros
41+
tool_router_dev = [] # Enable WIP tool_router tests

pmcp-macros/src/tool.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ pub fn expand_tool(args: TokenStream, input: ItemFn) -> syn::Result<TokenStream>
109109

110110
impl #wrapper_name {
111111
/// Get tool definition
112-
pub fn definition() -> pmcp::types::Tool {
113-
pmcp::types::Tool {
114-
name: #tool_name.to_string(),
115-
description: Some(#description.to_string()),
116-
input_schema: Some(Self::input_schema()),
117-
}
112+
pub fn definition() -> pmcp::types::ToolInfo {
113+
pmcp::types::ToolInfo::new(
114+
#tool_name,
115+
Some(#description.to_string()),
116+
Self::input_schema(),
117+
)
118118
}
119119

120120
/// Generate input schema
@@ -192,7 +192,7 @@ fn generate_param_extraction(params: &[ParamInfo]) -> syn::Result<TokenStream> {
192192
extractions.push(quote! {
193193
let #name: #ty = args.get(#name_str)
194194
.and_then(|v| serde_json::from_value(v.clone()).ok())
195-
.ok_or_else(|| pmcp::Error::InvalidParams(
195+
.ok_or_else(|| pmcp::Error::invalid_params(
196196
format!("Missing required parameter: {}", #name_str)
197197
))?;
198198
});
@@ -212,16 +212,16 @@ fn generate_result_conversion(return_type: &Type) -> syn::Result<TokenStream> {
212212
match result {
213213
Ok(value) => {
214214
let json_value = serde_json::to_value(value)
215-
.map_err(|e| pmcp::Error::InternalError(e.to_string()))?;
215+
.map_err(|e| pmcp::Error::internal(e.to_string()))?;
216216
Ok(json_value)
217217
}
218-
Err(e) => Err(pmcp::Error::ToolError(e.to_string()))
218+
Err(e) => Err(pmcp::Error::internal(format!("Tool error: {}", e)))
219219
}
220220
})
221221
} else {
222222
Ok(quote! {
223223
let json_value = serde_json::to_value(result)
224-
.map_err(|e| pmcp::Error::InternalError(e.to_string()))?;
224+
.map_err(|e| pmcp::Error::internal(e.to_string()))?;
225225
Ok(json_value)
226226
})
227227
}

pmcp-macros/src/tool_router.rs

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -72,26 +72,16 @@ pub fn expand_tool_router(args: TokenStream, mut input: ItemImpl) -> syn::Result
7272
// Generate handle_tool method
7373
let handle_tool_method = generate_handle_tool_method(&tool_methods, &vis);
7474

75-
// Generate router initialization method
76-
let router_init = generate_router_init(&router_field, &vis);
77-
7875
// Add generated methods to the impl block
76+
// Note: init_tool_router is not generated as the router field management is left to the user
7977
input.items.push(ImplItem::Fn(tools_method));
8078
input.items.push(ImplItem::Fn(handle_tool_method));
81-
input.items.push(ImplItem::Fn(router_init));
8279

8380
// Add router field to the struct (this would need to be done separately)
8481
// For now, we'll document that the user needs to add it manually
8582

86-
let expanded = quote! {
87-
#input
88-
89-
impl ToolRouterInfo for Self {
90-
const ROUTER_FIELD: &'static str = stringify!(#router_field);
91-
}
92-
};
93-
94-
Ok(expanded)
83+
// Just output the modified impl block with the generated methods
84+
Ok(quote! { #input })
9585
}
9686

9787
/// Collect all methods marked with #[tool] from the impl block
@@ -173,21 +163,21 @@ fn generate_tools_method(methods: &[ToolMethod], vis: &Visibility) -> ImplItemFn
173163
let name = &method.tool_name;
174164
let description = &method.description;
175165
quote! {
176-
pmcp::types::Tool {
177-
name: #name.to_string(),
178-
description: Some(#description.to_string()),
179-
input_schema: Some(serde_json::json!({
166+
pmcp::types::ToolInfo::new(
167+
#name,
168+
Some(#description.to_string()),
169+
serde_json::json!({
180170
"type": "object",
181171
"properties": {},
182172
"required": []
183-
})),
184-
}
173+
}),
174+
)
185175
}
186176
})
187177
.collect();
188178

189179
parse_quote! {
190-
#vis fn tools(&self) -> Vec<pmcp::types::Tool> {
180+
#vis fn tools(&self) -> Vec<pmcp::types::ToolInfo> {
191181
vec![
192182
#(#tool_definitions),*
193183
]
@@ -213,7 +203,7 @@ fn generate_handle_tool_method(methods: &[ToolMethod], vis: &Visibility) -> Impl
213203
let result = self.#method_name(args.clone())#await_token;
214204
match result {
215205
Ok(value) => Ok(serde_json::to_value(value)?),
216-
Err(e) => Err(pmcp::Error::ToolError(e.to_string())),
206+
Err(e) => Err(pmcp::Error::internal(format!("Tool error: {}", e))),
217207
}
218208
}
219209
}
@@ -225,27 +215,16 @@ fn generate_handle_tool_method(methods: &[ToolMethod], vis: &Visibility) -> Impl
225215
&self,
226216
name: &str,
227217
args: serde_json::Value,
228-
extra: pmcp::RequestHandlerExtra,
218+
_extra: pmcp::RequestHandlerExtra,
229219
) -> pmcp::Result<serde_json::Value> {
230220
match name {
231221
#(#match_arms)*
232-
_ => Err(pmcp::Error::MethodNotFound(format!("Unknown tool: {}", name))),
222+
_ => Err(pmcp::Error::method_not_found(format!("Unknown tool: {}", name))),
233223
}
234224
}
235225
}
236226
}
237227

238-
/// Generate router initialization method
239-
fn generate_router_init(router_field: &Ident, vis: &Visibility) -> ImplItemFn {
240-
parse_quote! {
241-
#vis fn init_tool_router(&mut self) {
242-
// Initialize the tool router
243-
// This is a placeholder - actual implementation would depend on the router type
244-
self.#router_field = Default::default();
245-
}
246-
}
247-
}
248-
249228
/// Parse visibility string into syn::Visibility
250229
fn parse_visibility(vis_str: &Option<String>) -> syn::Result<Visibility> {
251230
match vis_str {
@@ -261,11 +240,6 @@ fn parse_visibility(vis_str: &Option<String>) -> syn::Result<Visibility> {
261240
}
262241
}
263242

264-
/// Trait to mark types that have a tool router
265-
trait ToolRouterInfo {
266-
const ROUTER_FIELD: &'static str;
267-
}
268-
269243
#[cfg(test)]
270244
mod tests {
271245
use super::*;

pmcp-macros/src/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ pub fn generate_error_conversion(error_type: &Type) -> TokenStream {
175175
if is_pmcp_error(error_type) {
176176
quote! { e }
177177
} else {
178-
quote! { pmcp::Error::ToolError(e.to_string()) }
178+
quote! { pmcp::Error::internal(format!("Tool error: {}", e)) }
179179
}
180180
}
181181

0 commit comments

Comments
 (0)