Skip to main content

sentry_mcp/tools/
mod.rs

1pub mod get_issue_details;
2pub mod get_trace_details;
3pub mod search_issue_events;
4
5use crate::api_client::SentryApiClient;
6use get_issue_details::{GetIssueDetailsInput, execute as execute_get_issue_details};
7use get_trace_details::{GetTraceDetailsInput, execute as execute_get_trace_details};
8use rmcp::{
9    ErrorData as McpError,
10    ServerHandler,
11    handler::server::{router::tool::ToolRouter, wrapper::Parameters},
12    model::*,
13    tool_handler, tool_router,
14};
15use search_issue_events::{SearchIssueEventsInput, execute as execute_search_events};
16use std::sync::Arc;
17use tracing::info;
18
19#[derive(Clone)]
20pub struct SentryTools {
21    client: Arc<SentryApiClient>,
22    tool_router: ToolRouter<SentryTools>,
23}
24
25impl Default for SentryTools {
26    fn default() -> Self {
27        Self::new()
28    }
29}
30
31#[tool_router]
32impl SentryTools {
33    pub fn new() -> Self {
34        Self {
35            client: Arc::new(SentryApiClient::new()),
36            tool_router: Self::tool_router(),
37        }
38    }
39    #[rmcp::tool(description = "Retrieve detailed information about a specific Sentry issue including metadata, tags, and optionally an event. Accepts either an issueUrl OR (organizationSlug + issueId).")]
40    async fn get_issue_details(
41        &self,
42        Parameters(input): Parameters<GetIssueDetailsInput>,
43    ) -> Result<CallToolResult, McpError> {
44        info!("get_issue_details: {:?}", input);
45        execute_get_issue_details(&*self.client, input).await
46    }
47    #[rmcp::tool(description = "Retrieve trace details including span tree and timing information. Useful for analyzing distributed system performance.")]
48    async fn get_trace_details(
49        &self,
50        Parameters(input): Parameters<GetTraceDetailsInput>,
51    ) -> Result<CallToolResult, McpError> {
52        info!("get_trace_details: {:?}", input);
53        execute_get_trace_details(&*self.client, input).await
54    }
55    #[rmcp::tool(description = "Search events for a specific issue using a query string. Returns matching events with their details.")]
56    async fn search_issue_events(
57        &self,
58        Parameters(input): Parameters<SearchIssueEventsInput>,
59    ) -> Result<CallToolResult, McpError> {
60        info!("search_issue_events: {:?}", input);
61        execute_search_events(&*self.client, input).await
62    }
63}
64
65#[tool_handler]
66impl ServerHandler for SentryTools {
67    fn get_info(&self) -> ServerInfo {
68        ServerInfo {
69            protocol_version: ProtocolVersion::V_2024_11_05,
70            capabilities: ServerCapabilities {
71                tools: Some(ToolsCapability {
72                    list_changed: Some(true),
73                }),
74                ..Default::default()
75            },
76            server_info: Implementation {
77                name: "sentry-mcp".to_string(),
78                version: env!("CARGO_PKG_VERSION").to_string(),
79                title: None,
80                icons: None,
81                website_url: None,
82            },
83            ..Default::default()
84        }
85    }
86}