Skip to main content

stynx_code_tools/infrastructure/
read_mcp_resource_tool.rs

1use stynx_code_errors::AppResult;
2use stynx_code_types::{PermissionLevel, SearchReadInfo, Tool};
3use serde_json::{Value, json};
4
5pub struct ReadMcpResourceTool;
6
7impl ReadMcpResourceTool {
8    pub fn new() -> Self {
9        Self
10    }
11}
12
13#[async_trait::async_trait]
14impl Tool for ReadMcpResourceTool {
15    fn name(&self) -> &str {
16        "read_mcp_resource"
17    }
18
19    fn description(&self) -> &str {
20        "Read a specific MCP resource by its URI."
21    }
22
23    fn input_schema(&self) -> Value {
24        json!({
25            "type": "object",
26            "properties": {
27                "uri": {
28                    "type": "string",
29                    "description": "The URI of the MCP resource to read"
30                }
31            },
32            "required": ["uri"]
33        })
34    }
35
36    fn permission_level(&self) -> PermissionLevel {
37        PermissionLevel::ReadOnly
38    }
39
40    fn is_read_only(&self, _input: &Value) -> bool { true }
41    fn is_mcp(&self) -> bool { true }
42    fn is_concurrent_safe(&self, _input: &Value) -> bool { true }
43
44    fn is_search_or_read_command(&self, _input: &Value) -> SearchReadInfo {
45        SearchReadInfo { is_search: false, is_read: true, is_list: false }
46    }
47
48    async fn execute(&self, input: Value) -> AppResult<String> {
49        let uri = input
50            .get("uri")
51            .and_then(|v| v.as_str())
52            .ok_or_else(|| stynx_code_errors::AppError::Tool("missing 'uri' field".into()))?;
53
54        tracing::info!(uri, "reading MCP resource (stub)");
55
56        Ok(format!(
57            "MCP resource not available: '{uri}'.\n\
58             MCP integration will be implemented in Phase 4."
59        ))
60    }
61}