embedded_debugger_mcp/tools/
debugger_tools.rs

1//! Complete RMCP 0.3.2 implementation for embedded debugger MCP tools
2//! 
3//! This implementation provides all 18 debugging tools (13 base + 5 RTT) using real probe-rs integration
4
5use rmcp::{
6    tool, tool_handler, tool_router, ServerHandler,
7    handler::server::{router::tool::ToolRouter, tool::Parameters},
8    model::*,
9    ErrorData as McpError,
10    service::RequestContext,
11    RoleServer,
12};
13use tracing::{debug, error, info, warn};
14use std::future::Future;
15use std::collections::HashMap;
16use std::sync::Arc;
17use tokio::sync::RwLock;
18
19use super::types::*;
20// Flash types will be used through crate::flash:: prefix
21use crate::rtt::RttManager;
22
23// Probe-rs imports
24use probe_rs::probe::list::Lister;
25use probe_rs::{Session, Permissions, CoreStatus, MemoryInterface, RegisterValue};
26
27/// Debug session information
28#[derive(Debug)]
29pub struct DebugSession {
30    pub session_id: String,
31    pub probe_identifier: String,
32    pub target_chip: String,
33    pub created_at: chrono::DateTime<chrono::Utc>,
34    pub session: Arc<tokio::sync::Mutex<Session>>,
35    pub rtt_manager: Arc<tokio::sync::Mutex<RttManager>>,
36}
37
38/// Complete embedded debugger tool handler with all 18 tools
39#[derive(Clone)]
40pub struct EmbeddedDebuggerToolHandler {
41    #[allow(dead_code)]
42    tool_router: ToolRouter<EmbeddedDebuggerToolHandler>,
43    sessions: Arc<RwLock<HashMap<String, Arc<DebugSession>>>>,
44    max_sessions: usize,
45}
46
47impl EmbeddedDebuggerToolHandler {
48    pub fn new(max_sessions: usize) -> Self {
49        Self {
50            tool_router: Self::tool_router(),
51            sessions: Arc::new(RwLock::new(HashMap::new())),
52            max_sessions,
53        }
54    }
55}
56
57impl Default for EmbeddedDebuggerToolHandler {
58    fn default() -> Self {
59        Self::new(5)
60    }
61}
62
63#[tool_router]
64impl EmbeddedDebuggerToolHandler {
65    // =============================================================================
66    // Debugger Management Tools (4 tools)
67    // =============================================================================
68
69    #[tool(description = "List all available debug probes (J-Link, ST-Link, DAPLink, etc.)")]
70    async fn list_probes(&self, Parameters(_args): Parameters<ListProbesArgs>) -> Result<CallToolResult, McpError> {
71        debug!("Listing available debug probes");
72        
73        // Real probe-rs integration
74        let probes = Lister::new().list_all();
75        let message = if probes.is_empty() {
76            "No debug probes found.\n\nPlease ensure your probe is connected and drivers are installed.\nSupported probes: J-Link, ST-Link, DAPLink, Black Magic Probe".to_string()
77        } else {
78            let mut result = format!("Found {} debug probe(s):\n\n", probes.len());
79            
80            for (i, probe) in probes.iter().enumerate() {
81                result.push_str(&format!("{}. {}\n", i + 1, probe.identifier));
82                result.push_str(&format!("   VID:PID = {:04X}:{:04X}\n", probe.vendor_id, probe.product_id));
83                
84                if let Some(serial) = &probe.serial_number {
85                    result.push_str(&format!("   Serial: {}\n", serial));
86                }
87                
88                result.push_str(&format!("   Probe Type: {:?}\n", probe.probe_type()));
89                result.push('\n');
90            }
91            
92            result
93        };
94        
95        info!("Listed {} debug probes", probes.len());
96        Ok(CallToolResult::success(vec![Content::text(message)]))
97    }
98
99    #[tool(description = "Connect to a debug probe and target chip")]
100    async fn connect(&self, Parameters(args): Parameters<ConnectArgs>) -> Result<CallToolResult, McpError> {
101        debug!("Connecting to probe '{}' and target '{}'", args.probe_selector, args.target_chip);
102        
103        // Check session limit
104        {
105            let sessions = self.sessions.read().await;
106            if sessions.len() >= self.max_sessions {
107                let error_msg = format!("Session limit exceeded. Maximum {} sessions allowed.", self.max_sessions);
108                return Err(McpError::internal_error(error_msg, None));
109            }
110        }
111        
112        // Real probe-rs implementation
113        let probes = Lister::new().list_all();
114        
115        if probes.is_empty() {
116            return Err(McpError::internal_error(
117                "❌ No debug probes found\n\nPlease connect a supported probe (J-Link, ST-Link, DAPLink, etc.)".to_string(),
118                None
119            ));
120        }
121        
122        let selected_probe = if args.probe_selector.to_lowercase() == "auto" {
123            probes.first()
124        } else {
125            probes.iter().find(|p| p.identifier.contains(&args.probe_selector))
126        };
127
128        match selected_probe {
129            Some(probe_info) => {
130                info!("Opening probe: {}", probe_info.identifier);
131                match probe_info.open() {
132                    Ok(probe) => {
133                        info!("Attaching to target: {}", args.target_chip);
134                        match probe.attach(&args.target_chip, Permissions::default()) {
135                            Ok(session) => {
136                                let session_id = format!("session_{}", chrono::Utc::now().timestamp_millis());
137                                
138                                let debug_session = DebugSession {
139                                    session_id: session_id.clone(),
140                                    probe_identifier: probe_info.identifier.clone(),
141                                    target_chip: args.target_chip.clone(),
142                                    created_at: chrono::Utc::now(),
143                                    session: Arc::new(tokio::sync::Mutex::new(session)),
144                                    rtt_manager: Arc::new(tokio::sync::Mutex::new(RttManager::new())),
145                                };
146                                
147                                // Store session
148                                {
149                                    let mut sessions = self.sessions.write().await;
150                                    sessions.insert(session_id.clone(), Arc::new(debug_session));
151                                }
152                                
153                                let message = format!(
154                                    "✅ Debug session established!\n\n\
155                                    Session ID: {}\n\
156                                    Probe: {} (VID:PID = {:04X}:{:04X})\n\
157                                    Target: {}\n\
158                                    Connected at: {}\n\n\
159                                    Target connection established and ready for debugging.\n\
160                                    Use this session ID for all debug operations.",
161                                    session_id,
162                                    probe_info.identifier,
163                                    probe_info.vendor_id, probe_info.product_id,
164                                    args.target_chip,
165                                    chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC")
166                                );
167                                
168                                info!("Created debug session: {}", session_id);
169                                Ok(CallToolResult::success(vec![Content::text(message)]))
170                            }
171                            Err(e) => {
172                                error!("Failed to attach to target '{}': {}", args.target_chip, e);
173                                let error_msg = format!(
174                                    "❌ Failed to attach to target '{}'\n\n\
175                                    Error: {}\n\n\
176                                    Suggestions:\n\
177                                    - Check target chip name (try: STM32F407VGTx, nRF52840_xxAA)\n\
178                                    - Ensure target is powered and connected\n\
179                                    - Verify SWD/JTAG connections",
180                                    args.target_chip, e
181                                );
182                                Err(McpError::internal_error(error_msg, None))
183                            }
184                        }
185                    }
186                    Err(e) => {
187                        error!("Failed to open probe '{}': {}", probe_info.identifier, e);
188                        let error_msg = format!(
189                            "❌ Failed to open probe '{}'\n\nError: {}\n\n\
190                            Suggestions:\n\
191                            - Check probe drivers installation\n\
192                            - Verify USB connection\n\
193                            - Try disconnecting and reconnecting probe",
194                            probe_info.identifier, e
195                        );
196                        Err(McpError::internal_error(error_msg, None))
197                    }
198                }
199            }
200            None => {
201                let available_probes: Vec<String> = probes
202                    .iter()
203                    .map(|p| format!("- {}", p.identifier))
204                    .collect();
205                
206                let error_msg = format!(
207                    "❌ Probe '{}' not found\n\n\
208                    Available probes:\n{}\n\n\
209                    Use 'auto' to connect to first available probe.",
210                    args.probe_selector,
211                    available_probes.join("\n")
212                );
213                Err(McpError::internal_error(error_msg, None))
214            }
215        }
216    }
217
218    #[tool(description = "Disconnect from a debug session")]
219    async fn disconnect(&self, Parameters(args): Parameters<DisconnectArgs>) -> Result<CallToolResult, McpError> {
220        debug!("Disconnecting session: {}", args.session_id);
221        
222        // Remove session from storage
223        let removed_session = {
224            let mut sessions = self.sessions.write().await;
225            sessions.remove(&args.session_id)
226        };
227        
228        match removed_session {
229            Some(session) => {
230                let message = format!(
231                    "✅ Debug session disconnected successfully\n\n\
232                    Session ID: {}\n\
233                    Probe: {}\n\
234                    Target: {}\n\
235                    Duration: {:.1} minutes\n\n\
236                    probe-rs Session resources have been cleaned up.",
237                    args.session_id,
238                    session.probe_identifier,
239                    session.target_chip,
240                    (chrono::Utc::now() - session.created_at).num_seconds() as f64 / 60.0
241                );
242                
243                info!("Disconnected debug session: {}", args.session_id);
244                Ok(CallToolResult::success(vec![Content::text(message)]))
245            }
246            None => {
247                let error_msg = format!("❌ Session '{}' not found\n\nUse 'list_sessions' to see active sessions", args.session_id);
248                Err(McpError::internal_error(error_msg, None))
249            }
250        }
251    }
252
253    #[tool(description = "Get basic information about a debug session")]
254    async fn probe_info(&self, Parameters(args): Parameters<ProbeInfoArgs>) -> Result<CallToolResult, McpError> {
255        debug!("Getting probe info for session: {}", args.session_id);
256        
257        // Get session from storage
258        let session_arc = {
259            let sessions = self.sessions.read().await;
260            match sessions.get(&args.session_id) {
261                Some(session) => session.clone(),
262                None => {
263                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
264                    return Err(McpError::internal_error(error_msg, None));
265                }
266            }
267        };
268        
269        // Calculate session duration
270        let duration_minutes = (chrono::Utc::now() - session_arc.created_at).num_seconds() as f64 / 60.0;
271        
272        let message = format!(
273            "📊 Debug Session Information\n\n\
274            Probe Information:\n\
275            - Identifier: {}\n\
276            - Connected: true\n\n\
277            Target Information:\n\
278            - Chip: {}\n\n\
279            Session Status:\n\
280            - Session ID: {}\n\
281            - Created: {}\n\
282            - Duration: {:.1} minutes\n\n\
283            Session is active and ready for operations.",
284            session_arc.probe_identifier,
285            session_arc.target_chip,
286            args.session_id,
287            session_arc.created_at.format("%Y-%m-%d %H:%M:%S UTC"),
288            duration_minutes
289        );
290        
291        info!("Retrieved probe info for session: {}", args.session_id);
292        Ok(CallToolResult::success(vec![Content::text(message)]))
293    }
294
295    // =============================================================================
296    // Target Control Tools (5 tools)
297    // =============================================================================
298
299    #[tool(description = "Halt the target CPU execution")]
300    async fn halt(&self, Parameters(args): Parameters<HaltArgs>) -> Result<CallToolResult, McpError> {
301        debug!("Halting target for session: {}", args.session_id);
302        
303        let session_arc = {
304            let sessions = self.sessions.read().await;
305            match sessions.get(&args.session_id) {
306                Some(session) => session.clone(),
307                None => {
308                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
309                    return Err(McpError::internal_error(error_msg, None));
310                }
311            }
312        };
313        
314        // Halt the target
315        {
316            let mut session = session_arc.session.lock().await;
317            let mut core = match session.core(0) {
318                Ok(core) => core,
319                Err(e) => {
320                    error!("Failed to get core for session {}: {}", args.session_id, e);
321                    return Err(McpError::internal_error(format!("Failed to get core: {}", e), None));
322                }
323            };
324            
325            match core.halt(std::time::Duration::from_millis(1000)) {
326                Ok(_) => {
327                    // Get status after halt
328                    match core.status() {
329                        Ok(_status) => {
330                            let pc = core.read_core_reg(core.program_counter()).map(|v: RegisterValue| v.try_into().unwrap_or(0u32)).unwrap_or(0);
331                            let sp = core.read_core_reg(core.stack_pointer()).map(|v: RegisterValue| v.try_into().unwrap_or(0u32)).unwrap_or(0);
332                            
333                            let message = format!(
334                                "✅ Target halted successfully!\n\n\
335                                Session ID: {}\n\
336                                PC: 0x{:08X}\n\
337                                SP: 0x{:08X}\n\
338                                State: Halted\n",
339                                args.session_id, pc, sp
340                            );
341                            
342                            info!("Halt completed for session: {}", args.session_id);
343                            Ok(CallToolResult::success(vec![Content::text(message)]))
344                        }
345                        Err(e) => {
346                            warn!("Failed to get status after halt: {}", e);
347                            let message = format!(
348                                "✅ Target halted successfully!\n\n\
349                                Session ID: {}\n\
350                                State: Halted\n",
351                                args.session_id
352                            );
353                            Ok(CallToolResult::success(vec![Content::text(message)]))
354                        }
355                    }
356                }
357                Err(e) => {
358                    error!("Failed to halt target for session {}: {}", args.session_id, e);
359                    Err(McpError::internal_error(format!("Failed to halt target: {}", e), None))
360                }
361            }
362        }
363    }
364
365    #[tool(description = "Resume target CPU execution")]
366    async fn run(&self, Parameters(args): Parameters<RunArgs>) -> Result<CallToolResult, McpError> {
367        debug!("Running target for session: {}", args.session_id);
368        
369        let session_arc = {
370            let sessions = self.sessions.read().await;
371            match sessions.get(&args.session_id) {
372                Some(session) => session.clone(),
373                None => {
374                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
375                    return Err(McpError::internal_error(error_msg, None));
376                }
377            }
378        };
379        
380        // Resume the target
381        {
382            let mut session = session_arc.session.lock().await;
383            let mut core = match session.core(0) {
384                Ok(core) => core,
385                Err(e) => {
386                    error!("Failed to get core for session {}: {}", args.session_id, e);
387                    return Err(McpError::internal_error(format!("Failed to get core: {}", e), None));
388                }
389            };
390            
391            match core.run() {
392                Ok(_) => {
393                    let message = format!(
394                        "✅ Target resumed execution successfully!\n\n\
395                        Session ID: {}\n\
396                        Status: Running\n\n\
397                        The target is now executing code. Use 'halt' to stop execution.",
398                        args.session_id
399                    );
400                    
401                    info!("Run completed for session: {}", args.session_id);
402                    Ok(CallToolResult::success(vec![Content::text(message)]))
403                }
404                Err(e) => {
405                    error!("Failed to run target for session {}: {}", args.session_id, e);
406                    Err(McpError::internal_error(format!("Failed to run target: {}", e), None))
407                }
408            }
409        }
410    }
411
412    #[tool(description = "Reset the target CPU")]
413    async fn reset(&self, Parameters(args): Parameters<ResetArgs>) -> Result<CallToolResult, McpError> {
414        debug!("Resetting target for session: {}", args.session_id);
415        
416        let session_arc = {
417            let sessions = self.sessions.read().await;
418            match sessions.get(&args.session_id) {
419                Some(session) => session.clone(),
420                None => {
421                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
422                    return Err(McpError::internal_error(error_msg, None));
423                }
424            }
425        };
426        
427        // Reset the target
428        {
429            let mut session = session_arc.session.lock().await;
430            let mut core = match session.core(0) {
431                Ok(core) => core,
432                Err(e) => {
433                    error!("Failed to get core for session {}: {}", args.session_id, e);
434                    return Err(McpError::internal_error(format!("Failed to get core: {}", e), None));
435                }
436            };
437            
438            match core.reset() {
439                Ok(_) => {
440                    if args.halt_after_reset {
441                        match core.halt(std::time::Duration::from_millis(1000)) {
442                            Ok(_) => {},
443                            Err(e) => warn!("Failed to halt after reset: {}", e),
444                        }
445                    }
446                    
447                    let pc = core.read_core_reg(core.program_counter()).map(|v: RegisterValue| v.try_into().unwrap_or(0u32)).unwrap_or(0);
448                    let sp = core.read_core_reg(core.stack_pointer()).map(|v: RegisterValue| v.try_into().unwrap_or(0u32)).unwrap_or(0);
449                    
450                    let message = format!(
451                        "✅ Target reset completed successfully!\n\n\
452                        Session ID: {}\n\
453                        Reset type: {}\n\
454                        Halted after reset: {}\n\
455                        PC: 0x{:08X}\n\
456                        SP: 0x{:08X}\n\
457                        State: {}\n",
458                        args.session_id,
459                        args.reset_type,
460                        args.halt_after_reset,
461                        pc, sp,
462                        if args.halt_after_reset { "Halted" } else { "Running" }
463                    );
464                    
465                    info!("Reset completed for session: {}", args.session_id);
466                    Ok(CallToolResult::success(vec![Content::text(message)]))
467                }
468                Err(e) => {
469                    error!("Failed to reset target for session {}: {}", args.session_id, e);
470                    Err(McpError::internal_error(format!("Failed to reset target: {}", e), None))
471                }
472            }
473        }
474    }
475
476    #[tool(description = "Execute a single instruction step")]
477    async fn step(&self, Parameters(args): Parameters<StepArgs>) -> Result<CallToolResult, McpError> {
478        debug!("Single stepping target for session: {}", args.session_id);
479        
480        let session_arc = {
481            let sessions = self.sessions.read().await;
482            match sessions.get(&args.session_id) {
483                Some(session) => session.clone(),
484                None => {
485                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
486                    return Err(McpError::internal_error(error_msg, None));
487                }
488            }
489        };
490        
491        // Single step the target
492        {
493            let mut session = session_arc.session.lock().await;
494            let mut core = match session.core(0) {
495                Ok(core) => core,
496                Err(e) => {
497                    error!("Failed to get core for session {}: {}", args.session_id, e);
498                    return Err(McpError::internal_error(format!("Failed to get core: {}", e), None));
499                }
500            };
501            
502            match core.step() {
503                Ok(_) => {
504                    let pc = core.read_core_reg(core.program_counter()).map(|v: RegisterValue| v.try_into().unwrap_or(0u32)).unwrap_or(0);
505                    let sp = core.read_core_reg(core.stack_pointer()).map(|v: RegisterValue| v.try_into().unwrap_or(0u32)).unwrap_or(0);
506                    
507                    let message = format!(
508                        "✅ Single step completed successfully!\n\n\
509                        Session ID: {}\n\
510                        PC: 0x{:08X}\n\
511                        SP: 0x{:08X}\n\
512                        State: Halted\n",
513                        args.session_id, pc, sp
514                    );
515                    
516                    info!("Step completed for session: {}", args.session_id);
517                    Ok(CallToolResult::success(vec![Content::text(message)]))
518                }
519                Err(e) => {
520                    error!("Failed to step target for session {}: {}", args.session_id, e);
521                    Err(McpError::internal_error(format!("Failed to step target: {}", e), None))
522                }
523            }
524        }
525    }
526
527    #[tool(description = "Get current status of the target CPU and debug session")]
528    async fn get_status(&self, Parameters(args): Parameters<GetStatusArgs>) -> Result<CallToolResult, McpError> {
529        debug!("Getting status for session: {}", args.session_id);
530        
531        let session_arc = {
532            let sessions = self.sessions.read().await;
533            match sessions.get(&args.session_id) {
534                Some(session) => session.clone(),
535                None => {
536                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
537                    return Err(McpError::internal_error(error_msg, None));
538                }
539            }
540        };
541        
542        // Get target status
543        {
544            let mut session = session_arc.session.lock().await;
545            let mut core = match session.core(0) {
546                Ok(core) => core,
547                Err(e) => {
548                    error!("Failed to get core for session {}: {}", args.session_id, e);
549                    return Err(McpError::internal_error(format!("Failed to get core: {}", e), None));
550                }
551            };
552            
553            match core.status() {
554                Ok(status) => {
555                    let pc = core.read_core_reg(core.program_counter()).map(|v: RegisterValue| v.try_into().unwrap_or(0u32)).unwrap_or(0);
556                    let sp = core.read_core_reg(core.stack_pointer()).map(|v: RegisterValue| v.try_into().unwrap_or(0u32)).unwrap_or(0);
557                    
558                    let is_halted = matches!(status, CoreStatus::Halted(_));
559                    let halt_reason = match status {
560                        CoreStatus::Halted(reason) => format!("{:?}", reason),
561                        CoreStatus::Running => "N/A".to_string(),
562                        _ => "Unknown".to_string(),
563                    };
564                    
565                    let message = format!(
566                        "📊 Debug Session Status\n\n\
567                        Core Information:\n\
568                        - PC: 0x{:08X}\n\
569                        - SP: 0x{:08X}\n\
570                        - State: {}\n\
571                        - Halt reason: {}\n\n\
572                        Session Information:\n\
573                        - ID: {}\n\
574                        - Connected: true\n\
575                        - Target: {}\n\
576                        - Probe: {}\n\
577                        - Duration: {:.1} minutes\n",
578                        pc, sp,
579                        if is_halted { "Halted" } else { "Running" },
580                        halt_reason,
581                        args.session_id,
582                        session_arc.target_chip,
583                        session_arc.probe_identifier,
584                        (chrono::Utc::now() - session_arc.created_at).num_seconds() as f64 / 60.0
585                    );
586                    
587                    Ok(CallToolResult::success(vec![Content::text(message)]))
588                }
589                Err(e) => {
590                    error!("Failed to get core status for session {}: {}", args.session_id, e);
591                    Err(McpError::internal_error(format!("Failed to get core status: {}", e), None))
592                }
593            }
594        }
595    }
596
597    // =============================================================================
598    // Memory Operation Tools (2 tools)
599    // =============================================================================
600
601    #[tool(description = "Read memory from the target")]
602    async fn read_memory(&self, Parameters(args): Parameters<ReadMemoryArgs>) -> Result<CallToolResult, McpError> {
603        debug!("Reading memory for session: {} at address {}", args.session_id, args.address);
604        
605        // Parse address
606        let address = match parse_address(&args.address) {
607            Ok(addr) => addr,
608            Err(e) => {
609                error!("Invalid address '{}': {}", args.address, e);
610                return Err(McpError::internal_error(format!("Invalid address '{}': {}", args.address, e), None));
611            }
612        };
613
614        let session_arc = {
615            let sessions = self.sessions.read().await;
616            match sessions.get(&args.session_id) {
617                Some(session) => session.clone(),
618                None => {
619                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
620                    return Err(McpError::internal_error(error_msg, None));
621                }
622            }
623        };
624
625        // Read memory
626        {
627            let mut session = session_arc.session.lock().await;
628            let mut core = match session.core(0) {
629                Ok(core) => core,
630                Err(e) => {
631                    error!("Failed to get core for session {}: {}", args.session_id, e);
632                    return Err(McpError::internal_error(format!("Failed to get core: {}", e), None));
633                }
634            };
635            
636            let mut data = vec![0u8; args.size as usize];
637            match core.read(address, &mut data) {
638                Ok(_) => {
639                    debug!("Read {} bytes from address 0x{:08X}", data.len(), address);
640                    
641                    let formatted_data = format_memory_data(&data, &args.format, address);
642                    let message = format!(
643                        "📖 Memory read completed successfully!\n\n\
644                        Session ID: {}\n\
645                        Address: 0x{:08X}\n\
646                        Size: {} bytes\n\
647                        Format: {}\n\n\
648                        Data:\n{}",
649                        args.session_id, address, args.size, args.format, formatted_data
650                    );
651                    
652                    info!("Memory read completed for session: {}", args.session_id);
653                    Ok(CallToolResult::success(vec![Content::text(message)]))
654                }
655                Err(e) => {
656                    error!("Failed to read memory for session {}: {}", args.session_id, e);
657                    Err(McpError::internal_error(format!("Failed to read memory: {}", e), None))
658                }
659            }
660        }
661    }
662
663    #[tool(description = "Write memory to the target")]
664    async fn write_memory(&self, Parameters(args): Parameters<WriteMemoryArgs>) -> Result<CallToolResult, McpError> {
665        debug!("Writing memory for session: {} at address {}", args.session_id, args.address);
666        
667        // Parse address
668        let address = match parse_address(&args.address) {
669            Ok(addr) => addr,
670            Err(e) => {
671                error!("Invalid address '{}': {}", args.address, e);
672                return Err(McpError::internal_error(format!("Invalid address '{}': {}", args.address, e), None));
673            }
674        };
675
676        // Parse data based on format
677        let data = match parse_data(&args.data, &args.format) {
678            Ok(data) => data,
679            Err(e) => {
680                error!("Invalid data '{}': {}", args.data, e);
681                return Err(McpError::internal_error(format!("Invalid data '{}': {}", args.data, e), None));
682            }
683        };
684
685        let session_arc = {
686            let sessions = self.sessions.read().await;
687            match sessions.get(&args.session_id) {
688                Some(session) => session.clone(),
689                None => {
690                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
691                    return Err(McpError::internal_error(error_msg, None));
692                }
693            }
694        };
695
696        // Write memory
697        {
698            let mut session = session_arc.session.lock().await;
699            let mut core = match session.core(0) {
700                Ok(core) => core,
701                Err(e) => {
702                    error!("Failed to get core for session {}: {}", args.session_id, e);
703                    return Err(McpError::internal_error(format!("Failed to get core: {}", e), None));
704                }
705            };
706            
707            match core.write(address, &data) {
708                Ok(_) => {
709                    let message = format!(
710                        "✏️ Memory write completed successfully!\n\n\
711                        Session ID: {}\n\
712                        Address: 0x{:08X}\n\
713                        Data: {}\n\
714                        Format: {}\n\
715                        Bytes written: {}",
716                        args.session_id, address, args.data, args.format, data.len()
717                    );
718                    
719                    info!("Memory write completed for session: {}", args.session_id);
720                    Ok(CallToolResult::success(vec![Content::text(message)]))
721                }
722                Err(e) => {
723                    error!("Failed to write memory for session {}: {}", args.session_id, e);
724                    Err(McpError::internal_error(format!("Failed to write memory: {}", e), None))
725                }
726            }
727        }
728    }
729
730    // =============================================================================
731    // Breakpoint Tools (2 tools)
732    // =============================================================================
733
734    #[tool(description = "Set a breakpoint at the specified address")]
735    async fn set_breakpoint(&self, Parameters(args): Parameters<SetBreakpointArgs>) -> Result<CallToolResult, McpError> {
736        debug!("Setting breakpoint for session: {} at address {}", args.session_id, args.address);
737        
738        // Parse address
739        let address = match parse_address(&args.address) {
740            Ok(addr) => addr,
741            Err(e) => {
742                error!("Invalid address '{}': {}", args.address, e);
743                return Err(McpError::internal_error(format!("Invalid address '{}': {}", args.address, e), None));
744            }
745        };
746
747        let session_arc = {
748            let sessions = self.sessions.read().await;
749            match sessions.get(&args.session_id) {
750                Some(session) => session.clone(),
751                None => {
752                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
753                    return Err(McpError::internal_error(error_msg, None));
754                }
755            }
756        };
757
758        // Set breakpoint
759        {
760            let mut session = session_arc.session.lock().await;
761            let mut core = match session.core(0) {
762                Ok(core) => core,
763                Err(e) => {
764                    error!("Failed to get core for session {}: {}", args.session_id, e);
765                    return Err(McpError::internal_error(format!("Failed to get core: {}", e), None));
766                }
767            };
768            
769            match core.set_hw_breakpoint(address) {
770                Ok(_) => {
771                    let message = format!(
772                        "🎯 Breakpoint set successfully!\n\n\
773                        Session ID: {}\n\
774                        Address: 0x{:08X}\n\
775                        Type: Hardware breakpoint\n\n\
776                        The target will halt when execution reaches this address.",
777                        args.session_id, address
778                    );
779                    
780                    info!("Breakpoint set for session: {} at 0x{:08X}", args.session_id, address);
781                    Ok(CallToolResult::success(vec![Content::text(message)]))
782                }
783                Err(e) => {
784                    error!("Failed to set breakpoint for session {}: {}", args.session_id, e);
785                    Err(McpError::internal_error(format!("Failed to set breakpoint: {}", e), None))
786                }
787            }
788        }
789    }
790
791    #[tool(description = "Clear a breakpoint at the specified address")]
792    async fn clear_breakpoint(&self, Parameters(args): Parameters<ClearBreakpointArgs>) -> Result<CallToolResult, McpError> {
793        debug!("Clearing breakpoint for session: {} at address {}", args.session_id, args.address);
794        
795        // Parse address
796        let address = match parse_address(&args.address) {
797            Ok(addr) => addr,
798            Err(e) => {
799                error!("Invalid address '{}': {}", args.address, e);
800                return Err(McpError::internal_error(format!("Invalid address '{}': {}", args.address, e), None));
801            }
802        };
803
804        let session_arc = {
805            let sessions = self.sessions.read().await;
806            match sessions.get(&args.session_id) {
807                Some(session) => session.clone(),
808                None => {
809                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
810                    return Err(McpError::internal_error(error_msg, None));
811                }
812            }
813        };
814
815        // Clear breakpoint
816        {
817            let mut session = session_arc.session.lock().await;
818            let mut core = match session.core(0) {
819                Ok(core) => core,
820                Err(e) => {
821                    error!("Failed to get core for session {}: {}", args.session_id, e);
822                    return Err(McpError::internal_error(format!("Failed to get core: {}", e), None));
823                }
824            };
825            
826            match core.clear_hw_breakpoint(address) {
827                Ok(_) => {
828                    let message = format!(
829                        "🎯 Breakpoint cleared successfully!\n\n\
830                        Session ID: {}\n\
831                        Address: 0x{:08X}\n\n\
832                        The breakpoint has been removed.",
833                        args.session_id, address
834                    );
835                    
836                    info!("Breakpoint cleared for session: {} at 0x{:08X}", args.session_id, address);
837                    Ok(CallToolResult::success(vec![Content::text(message)]))
838                }
839                Err(e) => {
840                    error!("Failed to clear breakpoint for session {}: {}", args.session_id, e);
841                    Err(McpError::internal_error(format!("Failed to clear breakpoint: {}", e), None))
842                }
843            }
844        }
845    }
846
847    // =============================================================================
848    // RTT Communication Tools (5 tools)
849    // =============================================================================
850
851    #[tool(description = "Attach to RTT (Real-Time Transfer) for communication with target")]
852    async fn rtt_attach(&self, Parameters(args): Parameters<RttAttachArgs>) -> Result<CallToolResult, McpError> {
853        debug!("Attaching RTT for session: {}", args.session_id);
854        
855        // Get session from storage
856        let session_arc = {
857            let sessions = self.sessions.read().await;
858            match sessions.get(&args.session_id) {
859                Some(session) => session.clone(),
860                None => {
861                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
862                    return Err(McpError::internal_error(error_msg, None));
863                }
864            }
865        };
866
867        // Parse control block address if provided
868        let control_block_address = if let Some(addr_str) = args.control_block_address {
869            match parse_address(&addr_str) {
870                Ok(addr) => Some(addr),
871                Err(e) => {
872                    let error_msg = format!("❌ Invalid control block address '{}': {}", addr_str, e);
873                    return Err(McpError::internal_error(error_msg, None));
874                }
875            }
876        } else {
877            None
878        };
879
880        // Parse memory ranges if provided
881        let memory_ranges = if let Some(ranges) = args.memory_ranges {
882            let mut parsed_ranges = Vec::new();
883            for range in ranges {
884                let start = parse_address(&range.start).map_err(|e| {
885                    McpError::internal_error(format!("Invalid start address '{}': {}", range.start, e), None)
886                })?;
887                let end = parse_address(&range.end).map_err(|e| {
888                    McpError::internal_error(format!("Invalid end address '{}': {}", range.end, e), None)
889                })?;
890                parsed_ranges.push((start, end));
891            }
892            Some(parsed_ranges)
893        } else {
894            None
895        };
896
897        // Attach RTT
898        {
899            let mut rtt_manager = session_arc.rtt_manager.lock().await;
900            match rtt_manager.attach(session_arc.session.clone(), control_block_address, memory_ranges).await {
901                Ok(_) => {
902                    let up_channels = rtt_manager.up_channel_count();
903                    let down_channels = rtt_manager.down_channel_count();
904                    
905                    let message = format!(
906                        "✅ RTT attached successfully!\n\n\
907                        Session ID: {}\n\
908                        Up Channels (Target→Host): {}\n\
909                        Down Channels (Host→Target): {}\n\n\
910                        RTT is now ready for real-time communication with the target.\n\
911                        Use 'rtt_read' to read from target and 'rtt_write' to send data to target.",
912                        args.session_id, up_channels, down_channels
913                    );
914                    
915                    info!("RTT attached successfully for session: {}", args.session_id);
916                    Ok(CallToolResult::success(vec![Content::text(message)]))
917                }
918                Err(e) => {
919                    error!("Failed to attach RTT for session {}: {}", args.session_id, e);
920                    let error_msg = format!(
921                        "❌ Failed to attach RTT\n\n\
922                        Session ID: {}\n\
923                        Error: {}\n\n\
924                        Suggestions:\n\
925                        - Ensure the target firmware has RTT enabled and initialized\n\
926                        - Check that the target is halted\n\
927                        - Verify memory ranges if specified\n\
928                        - Try different control block address if known",
929                        args.session_id, e
930                    );
931                    Err(McpError::internal_error(error_msg, None))
932                }
933            }
934        }
935    }
936
937    #[tool(description = "Detach from RTT communication")]
938    async fn rtt_detach(&self, Parameters(args): Parameters<RttDetachArgs>) -> Result<CallToolResult, McpError> {
939        debug!("Detaching RTT for session: {}", args.session_id);
940        
941        // Get session from storage
942        let session_arc = {
943            let sessions = self.sessions.read().await;
944            match sessions.get(&args.session_id) {
945                Some(session) => session.clone(),
946                None => {
947                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
948                    return Err(McpError::internal_error(error_msg, None));
949                }
950            }
951        };
952
953        // Detach RTT
954        {
955            let mut rtt_manager = session_arc.rtt_manager.lock().await;
956            match rtt_manager.detach().await {
957                Ok(_) => {
958                    let message = format!(
959                        "✅ RTT detached successfully\n\n\
960                        Session ID: {}\n\n\
961                        RTT communication has been closed.",
962                        args.session_id
963                    );
964                    
965                    info!("RTT detached successfully for session: {}", args.session_id);
966                    Ok(CallToolResult::success(vec![Content::text(message)]))
967                }
968                Err(e) => {
969                    error!("Failed to detach RTT for session {}: {}", args.session_id, e);
970                    let error_msg = format!("❌ Failed to detach RTT: {}", e);
971                    Err(McpError::internal_error(error_msg, None))
972                }
973            }
974        }
975    }
976
977    #[tool(description = "Read data from RTT up channel (target to host)")]
978    async fn rtt_read(&self, Parameters(args): Parameters<RttReadArgs>) -> Result<CallToolResult, McpError> {
979        debug!("Reading from RTT channel {} for session: {}", args.channel, args.session_id);
980        
981        // Get session from storage
982        let session_arc = {
983            let sessions = self.sessions.read().await;
984            match sessions.get(&args.session_id) {
985                Some(session) => session.clone(),
986                None => {
987                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
988                    return Err(McpError::internal_error(error_msg, None));
989                }
990            }
991        };
992
993        // Read from RTT
994        {
995            let mut rtt_manager = session_arc.rtt_manager.lock().await;
996            if !rtt_manager.is_attached() {
997                let error_msg = format!("❌ RTT not attached for session '{}'\n\nUse 'rtt_attach' first", args.session_id);
998                return Err(McpError::internal_error(error_msg, None));
999            }
1000
1001            match rtt_manager.read_channel(args.channel).await {
1002                Ok(data) => {
1003                    let data_len = data.len();
1004                    let data_str = if data.is_empty() {
1005                        "No data available".to_string()
1006                    } else {
1007                        // Try to decode as UTF-8, fall back to hex if not valid
1008                        match String::from_utf8(data.clone()) {
1009                            Ok(text) => {
1010                                if text.chars().all(|c| c.is_ascii_graphic() || c.is_ascii_whitespace()) {
1011                                    format!("Text: {}", text)
1012                                } else {
1013                                    format!("Mixed: {} (hex: {})", text, hex::encode(&data))
1014                                }
1015                            }
1016                            Err(_) => format!("Binary data (hex): {}", hex::encode(&data))
1017                        }
1018                    };
1019
1020                    let message = format!(
1021                        "📥 RTT Read from Channel {}\n\n\
1022                        Session ID: {}\n\
1023                        Bytes Read: {}\n\n\
1024                        Data:\n{}",
1025                        args.channel, args.session_id, data_len, data_str
1026                    );
1027                    
1028                    debug!("Read {} bytes from RTT channel {} for session: {}", data_len, args.channel, args.session_id);
1029                    Ok(CallToolResult::success(vec![Content::text(message)]))
1030                }
1031                Err(e) => {
1032                    error!("Failed to read from RTT channel {} for session {}: {}", args.channel, args.session_id, e);
1033                    let error_msg = format!(
1034                        "❌ Failed to read from RTT channel {}\n\n\
1035                        Session ID: {}\n\
1036                        Error: {}",
1037                        args.channel, args.session_id, e
1038                    );
1039                    Err(McpError::internal_error(error_msg, None))
1040                }
1041            }
1042        }
1043    }
1044
1045    #[tool(description = "Write data to RTT down channel (host to target)")]
1046    async fn rtt_write(&self, Parameters(args): Parameters<RttWriteArgs>) -> Result<CallToolResult, McpError> {
1047        debug!("Writing to RTT channel {} for session: {}", args.channel, args.session_id);
1048        
1049        // Get session from storage
1050        let session_arc = {
1051            let sessions = self.sessions.read().await;
1052            match sessions.get(&args.session_id) {
1053                Some(session) => session.clone(),
1054                None => {
1055                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
1056                    return Err(McpError::internal_error(error_msg, None));
1057                }
1058            }
1059        };
1060
1061        // Parse data based on encoding
1062        let data_bytes = match args.encoding.as_str() {
1063            "utf8" => args.data.as_bytes().to_vec(),
1064            "hex" => {
1065                match hex::decode(&args.data) {
1066                    Ok(bytes) => bytes,
1067                    Err(e) => {
1068                        let error_msg = format!("❌ Invalid hex data '{}': {}", args.data, e);
1069                        return Err(McpError::internal_error(error_msg, None));
1070                    }
1071                }
1072            }
1073            "binary" => {
1074                // Parse binary string like "10110011 11001100"
1075                let binary_str = args.data.replace(' ', "");
1076                if binary_str.len() % 8 != 0 {
1077                    let error_msg = format!("❌ Binary data must be multiple of 8 bits: '{}'", args.data);
1078                    return Err(McpError::internal_error(error_msg, None));
1079                }
1080                
1081                let mut bytes = Vec::new();
1082                for chunk in binary_str.chars().collect::<Vec<_>>().chunks(8) {
1083                    let byte_str: String = chunk.iter().collect();
1084                    match u8::from_str_radix(&byte_str, 2) {
1085                        Ok(byte) => bytes.push(byte),
1086                        Err(e) => {
1087                            let error_msg = format!("❌ Invalid binary byte '{}': {}", byte_str, e);
1088                            return Err(McpError::internal_error(error_msg, None));
1089                        }
1090                    }
1091                }
1092                bytes
1093            }
1094            _ => {
1095                let error_msg = format!("❌ Unsupported encoding '{}'. Use 'utf8', 'hex', or 'binary'", args.encoding);
1096                return Err(McpError::internal_error(error_msg, None));
1097            }
1098        };
1099
1100        // Write to RTT
1101        {
1102            let mut rtt_manager = session_arc.rtt_manager.lock().await;
1103            if !rtt_manager.is_attached() {
1104                let error_msg = format!("❌ RTT not attached for session '{}'\n\nUse 'rtt_attach' first", args.session_id);
1105                return Err(McpError::internal_error(error_msg, None));
1106            }
1107
1108            match rtt_manager.write_channel(args.channel, &data_bytes).await {
1109                Ok(bytes_written) => {
1110                    let message = format!(
1111                        "📤 RTT Write to Channel {}\n\n\
1112                        Session ID: {}\n\
1113                        Data: {}\n\
1114                        Encoding: {}\n\
1115                        Bytes Written: {}\n\n\
1116                        Data sent successfully to target.",
1117                        args.channel, args.session_id, args.data, args.encoding, bytes_written
1118                    );
1119                    
1120                    info!("Wrote {} bytes to RTT channel {} for session: {}", bytes_written, args.channel, args.session_id);
1121                    Ok(CallToolResult::success(vec![Content::text(message)]))
1122                }
1123                Err(e) => {
1124                    error!("Failed to write to RTT channel {} for session {}: {}", args.channel, args.session_id, e);
1125                    let error_msg = format!(
1126                        "❌ Failed to write to RTT channel {}\n\n\
1127                        Session ID: {}\n\
1128                        Error: {}",
1129                        args.channel, args.session_id, e
1130                    );
1131                    Err(McpError::internal_error(error_msg, None))
1132                }
1133            }
1134        }
1135    }
1136
1137    #[tool(description = "List available RTT channels")]
1138    async fn rtt_channels(&self, Parameters(args): Parameters<RttChannelsArgs>) -> Result<CallToolResult, McpError> {
1139        debug!("Listing RTT channels for session: {}", args.session_id);
1140        
1141        // Get session from storage
1142        let session_arc = {
1143            let sessions = self.sessions.read().await;
1144            match sessions.get(&args.session_id) {
1145                Some(session) => session.clone(),
1146                None => {
1147                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
1148                    return Err(McpError::internal_error(error_msg, None));
1149                }
1150            }
1151        };
1152
1153        // List RTT channels
1154        {
1155            let rtt_manager = session_arc.rtt_manager.lock().await;
1156            if !rtt_manager.is_attached() {
1157                let error_msg = format!("❌ RTT not attached for session '{}'\n\nUse 'rtt_attach' first", args.session_id);
1158                return Err(McpError::internal_error(error_msg, None));
1159            }
1160
1161            let channels = rtt_manager.get_channels();
1162            let channel_count = channels.len();
1163            
1164            if channels.is_empty() {
1165                let message = format!(
1166                    "📋 RTT Channels\n\n\
1167                    Session ID: {}\n\n\
1168                    No RTT channels available.",
1169                    args.session_id
1170                );
1171                return Ok(CallToolResult::success(vec![Content::text(message)]));
1172            }
1173
1174            let mut message = format!("📋 RTT Channels\n\nSession ID: {}\n\n", args.session_id);
1175            
1176            // Group channels by direction
1177            let mut up_channels = Vec::new();
1178            let mut down_channels = Vec::new();
1179            
1180            for channel in &channels {
1181                match channel.direction {
1182                    crate::rtt::ChannelDirection::Up => up_channels.push(channel),
1183                    crate::rtt::ChannelDirection::Down => down_channels.push(channel),
1184                }
1185            }
1186
1187            if !up_channels.is_empty() {
1188                message.push_str("📥 Up Channels (Target → Host):\n");
1189                for channel in up_channels {
1190                    message.push_str(&format!(
1191                        "  {}. {} (Size: {} bytes, Mode: {})\n",
1192                        channel.id, channel.name, channel.buffer_size, channel.mode
1193                    ));
1194                }
1195                message.push('\n');
1196            }
1197
1198            if !down_channels.is_empty() {
1199                message.push_str("📤 Down Channels (Host → Target):\n");
1200                for channel in down_channels {
1201                    message.push_str(&format!(
1202                        "  {}. {} (Size: {} bytes, Mode: {})\n",
1203                        channel.id, channel.name, channel.buffer_size, channel.mode
1204                    ));
1205                }
1206            }
1207
1208            info!("Listed {} RTT channels for session: {}", channel_count, args.session_id);
1209            Ok(CallToolResult::success(vec![Content::text(message)]))
1210        }
1211    }
1212
1213    // =============================================================================
1214    // Flash Programming Tools (4 tools)
1215    // =============================================================================
1216
1217    #[tool(description = "Erase flash memory sectors or entire chip")]
1218    async fn flash_erase(&self, Parameters(args): Parameters<FlashEraseArgs>) -> Result<CallToolResult, McpError> {
1219        debug!("Flash erase for session: {}, type: {}", args.session_id, args.erase_type);
1220        
1221        let session_arc = {
1222            let sessions = self.sessions.read().await;
1223            match sessions.get(&args.session_id) {
1224                Some(session) => session.clone(),
1225                None => {
1226                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
1227                    return Err(McpError::internal_error(error_msg, None));
1228                }
1229            }
1230        };
1231
1232        // Parse erase type and parameters
1233        let erase_type = match args.erase_type.as_str() {
1234            "all" => crate::flash::EraseType::All,
1235            "sectors" => {
1236                let address = match args.address {
1237                    Some(addr_str) => parse_address(&addr_str).map_err(|e| McpError::internal_error(e, None))?,
1238                    None => return Err(McpError::internal_error("Address required for sector erase".to_string(), None)),
1239                };
1240                let size = match args.size {
1241                    Some(sz) => sz as usize,
1242                    None => return Err(McpError::internal_error("Size required for sector erase".to_string(), None)),
1243                };
1244                crate::flash::EraseType::Sectors { address, size }
1245            }
1246            _ => return Err(McpError::internal_error(format!("Invalid erase type: {}", args.erase_type), None)),
1247        };
1248
1249        // Perform erase operation
1250        {
1251            let mut session = session_arc.session.lock().await;
1252            match crate::flash::FlashManager::erase_flash(&mut session, erase_type).await {
1253                Ok(result) => {
1254                    let message = format!(
1255                        "✅ Flash erase completed successfully!\n\n\
1256                        Session ID: {}\n\
1257                        Erase Type: {}\n\
1258                        Duration: {}ms\n\
1259                        {}\n\n\
1260                        Flash memory has been erased and is ready for programming.",
1261                        args.session_id,
1262                        args.erase_type,
1263                        result.erase_time_ms,
1264                        match result.sectors_erased {
1265                            Some(count) => format!("Sectors Erased: {}", count),
1266                            None => "Full chip erased".to_string(),
1267                        }
1268                    );
1269                    
1270                    info!("Flash erase completed for session: {}", args.session_id);
1271                    Ok(CallToolResult::success(vec![Content::text(message)]))
1272                }
1273                Err(e) => {
1274                    error!("Flash erase failed for session {}: {}", args.session_id, e);
1275                    let error_msg = format!(
1276                        "❌ Flash erase failed\n\n\
1277                        Session ID: {}\n\
1278                        Error: {}\n\n\
1279                        Suggestions:\n\
1280                        - Check if flash is write-protected\n\
1281                        - Ensure target is halted\n\
1282                        - Verify flash address range",
1283                        args.session_id, e
1284                    );
1285                    Err(McpError::internal_error(error_msg, None))
1286                }
1287            }
1288        }
1289    }
1290
1291    #[tool(description = "Program file to flash memory (supports ELF, HEX, BIN)")]
1292    async fn flash_program(&self, Parameters(args): Parameters<FlashProgramArgs>) -> Result<CallToolResult, McpError> {
1293        debug!("Flash program for session: {}, file: {}", args.session_id, args.file_path);
1294        
1295        let session_arc = {
1296            let sessions = self.sessions.read().await;
1297            match sessions.get(&args.session_id) {
1298                Some(session) => session.clone(),
1299                None => {
1300                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
1301                    return Err(McpError::internal_error(error_msg, None));
1302                }
1303            }
1304        };
1305
1306        // Parse file path and format
1307        let file_path = std::path::Path::new(&args.file_path);
1308        let format = match args.format.as_str() {
1309            "auto" => crate::flash::FileFormat::Auto,
1310            "elf" => crate::flash::FileFormat::Elf,
1311            "hex" => crate::flash::FileFormat::Hex,
1312            "bin" => crate::flash::FileFormat::Bin,
1313            _ => return Err(McpError::internal_error(format!("Unsupported format: {}", args.format), None)),
1314        };
1315
1316        // Parse base address if provided
1317        let base_address = if let Some(addr_str) = args.base_address {
1318            Some(parse_address(&addr_str).map_err(|e| McpError::internal_error(e, None))?)
1319        } else {
1320            None
1321        };
1322
1323        // Perform programming operation
1324        {
1325            let mut session = session_arc.session.lock().await;
1326            match crate::flash::FlashManager::program_file(&mut session, file_path, format, base_address).await {
1327                Ok(result) => {
1328                    let message = format!(
1329                        "✅ Flash programming completed successfully!\n\n\
1330                        Session ID: {}\n\
1331                        File: {}\n\
1332                        Format: {}\n\
1333                        Bytes Programmed: {}\n\
1334                        Duration: {}ms\n\
1335                        Verification: {}\n\n\
1336                        Firmware has been programmed to flash memory.",
1337                        args.session_id,
1338                        args.file_path,
1339                        args.format,
1340                        result.bytes_programmed,
1341                        result.programming_time_ms,
1342                        match result.verification_result {
1343                            Some(true) => "✅ Passed",
1344                            Some(false) => "❌ Failed",
1345                            None => "Not performed",
1346                        }
1347                    );
1348                    
1349                    info!("Flash programming completed for session: {}", args.session_id);
1350                    Ok(CallToolResult::success(vec![Content::text(message)]))
1351                }
1352                Err(e) => {
1353                    error!("Flash programming failed for session {}: {}", args.session_id, e);
1354                    let error_msg = format!(
1355                        "❌ Flash programming failed\n\n\
1356                        Session ID: {}\n\
1357                        File: {}\n\
1358                        Error: {}\n\n\
1359                        Suggestions:\n\
1360                        - Check file exists and is readable\n\
1361                        - Verify file format is correct\n\
1362                        - Ensure flash is erased first\n\
1363                        - Check target memory map",
1364                        args.session_id, args.file_path, e
1365                    );
1366                    Err(McpError::internal_error(error_msg, None))
1367                }
1368            }
1369        }
1370    }
1371
1372    #[tool(description = "Verify flash memory contents")]
1373    async fn flash_verify(&self, Parameters(args): Parameters<FlashVerifyArgs>) -> Result<CallToolResult, McpError> {
1374        debug!("Flash verify for session: {}", args.session_id);
1375        
1376        let session_arc = {
1377            let sessions = self.sessions.read().await;
1378            match sessions.get(&args.session_id) {
1379                Some(session) => session.clone(),
1380                None => {
1381                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
1382                    return Err(McpError::internal_error(error_msg, None));
1383                }
1384            }
1385        };
1386
1387        // Parse address
1388        let address = parse_address(&args.address).map_err(|e| McpError::internal_error(e, None))?;
1389
1390        // Get expected data
1391        let expected_data = if let Some(file_path) = &args.file_path {
1392            // Read from file
1393            std::fs::read(file_path)
1394                .map_err(|e| McpError::internal_error(format!("Failed to read file {}: {}", file_path, e), None))?
1395        } else if let Some(hex_data) = &args.data {
1396            // Parse hex data
1397            match parse_data(hex_data, "hex") {
1398                Ok(data) => data,
1399                Err(e) => return Err(McpError::internal_error(format!("Invalid hex data: {}", e), None)),
1400            }
1401        } else {
1402            return Err(McpError::internal_error("Either file_path or data must be provided".to_string(), None));
1403        };
1404
1405        // Limit to specified size
1406        let expected_data = if expected_data.len() > args.size as usize {
1407            &expected_data[..args.size as usize]
1408        } else {
1409            &expected_data
1410        };
1411
1412        // Perform verification
1413        {
1414            let mut session = session_arc.session.lock().await;
1415            match crate::flash::FlashManager::verify_flash(&mut session, expected_data, address).await {
1416                Ok(result) => {
1417                    let message = if result.success {
1418                        format!(
1419                            "✅ Flash verification successful!\n\n\
1420                            Session ID: {}\n\
1421                            Address: 0x{:08X}\n\
1422                            Bytes Verified: {}\n\n\
1423                            All flash contents match expected data.",
1424                            args.session_id, address, result.bytes_verified
1425                        )
1426                    } else {
1427                        let mut message = format!(
1428                            "❌ Flash verification failed!\n\n\
1429                            Session ID: {}\n\
1430                            Address: 0x{:08X}\n\
1431                            Bytes Verified: {}\n\
1432                            Mismatches: {}\n\n\
1433                            First {} mismatches:\n",
1434                            args.session_id, address, result.bytes_verified, result.mismatches.len(),
1435                            std::cmp::min(10, result.mismatches.len())
1436                        );
1437                        
1438                        for (i, mismatch) in result.mismatches.iter().take(10).enumerate() {
1439                            message.push_str(&format!(
1440                                "  {}. 0x{:08X}: expected 0x{:02X}, got 0x{:02X}\n",
1441                                i + 1, mismatch.address, mismatch.expected, mismatch.actual
1442                            ));
1443                        }
1444                        
1445                        if result.mismatches.len() > 10 {
1446                            message.push_str(&format!("  ... and {} more mismatches\n", result.mismatches.len() - 10));
1447                        }
1448                        
1449                        message
1450                    };
1451                    
1452                    info!("Flash verification completed for session: {}", args.session_id);
1453                    Ok(CallToolResult::success(vec![Content::text(message)]))
1454                }
1455                Err(e) => {
1456                    error!("Flash verification failed for session {}: {}", args.session_id, e);
1457                    let error_msg = format!(
1458                        "❌ Flash verification error\n\n\
1459                        Session ID: {}\n\
1460                        Error: {}",
1461                        args.session_id, e
1462                    );
1463                    Err(McpError::internal_error(error_msg, None))
1464                }
1465            }
1466        }
1467    }
1468
1469    #[tool(description = "Complete firmware deployment: erase, program, verify, run and attach RTT")]
1470    async fn run_firmware(&self, Parameters(args): Parameters<RunFirmwareArgs>) -> Result<CallToolResult, McpError> {
1471        debug!("Run firmware for session: {}, file: {}", args.session_id, args.file_path);
1472        
1473        let session_arc = {
1474            let sessions = self.sessions.read().await;
1475            match sessions.get(&args.session_id) {
1476                Some(session) => session.clone(),
1477                None => {
1478                    let error_msg = format!("❌ Session '{}' not found\n\nUse 'connect' to establish a debug session first", args.session_id);
1479                    return Err(McpError::internal_error(error_msg, None));
1480                }
1481            }
1482        };
1483
1484        let mut status_messages = Vec::new();
1485        let start_time = std::time::Instant::now();
1486
1487        // Step 1: Erase flash
1488        status_messages.push("🔄 Step 1/5: Erasing flash memory...".to_string());
1489        {
1490            let mut session = session_arc.session.lock().await;
1491            match crate::flash::FlashManager::erase_flash(&mut session, crate::flash::EraseType::All).await {
1492                Ok(_) => status_messages.push("✅ Flash erased successfully".to_string()),
1493                Err(e) => {
1494                    let error_msg = format!("❌ Flash erase failed: {}", e);
1495                    status_messages.push(error_msg.clone());
1496                    return Err(McpError::internal_error(format!("{}\n\n{}", status_messages.join("\n"), error_msg), None));
1497                }
1498            }
1499        }
1500
1501        // Step 2: Program firmware
1502        status_messages.push("🔄 Step 2/5: Programming firmware...".to_string());
1503        let format = match args.format.as_str() {
1504            "auto" => crate::flash::FileFormat::Auto,
1505            "elf" => crate::flash::FileFormat::Elf,
1506            "hex" => crate::flash::FileFormat::Hex,
1507            "bin" => crate::flash::FileFormat::Bin,
1508            _ => return Err(McpError::internal_error(format!("Unsupported format: {}", args.format), None)),
1509        };
1510
1511        {
1512            let mut session = session_arc.session.lock().await;
1513            match crate::flash::FlashManager::program_file(&mut session, std::path::Path::new(&args.file_path), format, None).await {
1514                Ok(result) => status_messages.push(format!("✅ Programmed {} bytes", result.bytes_programmed)),
1515                Err(e) => {
1516                    let error_msg = format!("❌ Programming failed: {}", e);
1517                    status_messages.push(error_msg.clone());
1518                    return Err(McpError::internal_error(format!("{}\n\n{}", status_messages.join("\n"), error_msg), None));
1519                }
1520            }
1521        }
1522
1523        // Step 3: Reset and run
1524        if args.reset_after_flash {
1525            status_messages.push("🔄 Step 3/5: Resetting target...".to_string());
1526            {
1527                let mut session = session_arc.session.lock().await;
1528                let mut core = match session.core(0) {
1529                    Ok(core) => core,
1530                    Err(e) => return Err(McpError::internal_error(format!("Failed to get core: {}", e), None)),
1531                };
1532                
1533                match core.reset() {
1534                    Ok(_) => {
1535                        status_messages.push("✅ Target reset successfully".to_string());
1536                        // Run the target
1537                        match core.run() {
1538                            Ok(_) => status_messages.push("✅ Target running".to_string()),
1539                            Err(e) => warn!("Failed to run after reset: {}", e),
1540                        }
1541                    }
1542                    Err(e) => {
1543                        let error_msg = format!("❌ Reset failed: {}", e);
1544                        status_messages.push(error_msg.clone());
1545                        return Err(McpError::internal_error(format!("{}\n\n{}", status_messages.join("\n"), error_msg), None));
1546                    }
1547                }
1548            }
1549        }
1550
1551        // Step 4: Attach RTT (if requested) - Mimic probe-rs run behavior
1552        if args.attach_rtt {
1553            status_messages.push("🔄 Step 4/5: Attaching RTT (probe-rs style)...".to_string());
1554            
1555            // Key improvement: Give target more time to boot, mimic probe-rs run timing
1556            info!("Allowing target firmware to fully initialize RTT control block...");
1557            tokio::time::sleep(tokio::time::Duration::from_millis(2000)).await; // Initial 2s delay
1558            
1559            // Give target additional time to fully initialize RTT (key improvement)
1560            info!("Giving target additional time to initialize RTT control block...");
1561            tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;
1562            
1563            // Enhanced RTT retry mechanism with probe-rs style timing
1564            let mut rtt_attached = false;
1565            let max_attempts = 8; // Increase retry attempts
1566            let mut attempt = 1;
1567            
1568            while attempt <= max_attempts && !rtt_attached {
1569                // probe-rs style delay strategy: 1s, 1.5s, 2s, 2.5s, 3s, 3.5s, 4s, 4.5s
1570                let delay_ms = 1000 + (attempt - 1) * 500;
1571                info!("RTT attach attempt {}/{}, waiting {}ms for RTT control block...", attempt, max_attempts, delay_ms);
1572                tokio::time::sleep(tokio::time::Duration::from_millis(delay_ms as u64)).await;
1573                
1574                // Small delay between RTT attempts (let target stabilize)
1575                tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
1576                
1577                // Try RTT attachment with different strategies (probe-rs style optimization)
1578                let mut rtt_manager = session_arc.rtt_manager.lock().await;
1579                let rtt_result = match attempt {
1580                    1..=2 => {
1581                        // First 2 attempts: ELF symbol detection (probe-rs priority method)
1582                        debug!("RTT attempt {}: Using ELF symbol detection (probe-rs style)", attempt);
1583                        rtt_manager.attach_with_elf(session_arc.session.clone(), std::path::Path::new(&args.file_path)).await
1584                    }
1585                    3..=5 => {
1586                        // Attempts 3-5: standard attach, let probe-rs auto-scan memory
1587                        debug!("RTT attempt {}: Using standard memory map scan", attempt);
1588                        rtt_manager.attach(session_arc.session.clone(), None, None).await
1589                    }
1590                    6..=7 => {
1591                        // Attempts 6-7: try STM32G4 specific memory ranges
1592                        debug!("RTT attempt {}: Using STM32G4 specific memory ranges", attempt);
1593                        let stm32g4_ranges = vec![
1594                            (0x20000000, 0x20004000), // SRAM1 first half: 16KB - most likely RTT location
1595                            (0x20004000, 0x20008000), // SRAM1 second half: 16KB
1596                            (0x20008000, 0x2000A000), // SRAM2: 8KB
1597                        ];
1598                        rtt_manager.attach(session_arc.session.clone(), None, Some(stm32g4_ranges)).await
1599                    }
1600                    _ => {
1601                        // Last attempt: try common RTT control block addresses
1602                        let cb_addr = 0x20000000;
1603                        debug!("RTT attempt {}: Using specific control block address 0x{:08X}", attempt, cb_addr);
1604                        rtt_manager.attach(session_arc.session.clone(), Some(cb_addr), None).await
1605                    }
1606                };
1607                
1608                match rtt_result {
1609                    Ok(_) => {
1610                        let up_channels = rtt_manager.up_channel_count();
1611                        let down_channels = rtt_manager.down_channel_count();
1612                        status_messages.push(format!("✅ RTT attached on attempt {} ({} up, {} down channels)", attempt, up_channels, down_channels));
1613                        info!("RTT successfully attached after {} attempts!", attempt);
1614                        rtt_attached = true;
1615                    }
1616                    Err(e) => {
1617                        if attempt == max_attempts {
1618                            // Final attempt failed
1619                            status_messages.push(format!("⚠️ RTT attach failed after {} attempts: {}", max_attempts, e));
1620                            warn!("RTT attachment failed completely after {} attempts", max_attempts);
1621                        } else {
1622                            debug!("RTT attach attempt {}/{} failed: {}, retrying with different strategy...", attempt, max_attempts, e);
1623                        }
1624                    }
1625                }
1626                attempt += 1;
1627            }
1628            
1629            // If RTT successfully connected, give extra initialization time
1630            if rtt_attached {
1631                info!("RTT connected successfully, allowing channel stabilization...");
1632                tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
1633            }
1634        }
1635
1636        status_messages.push("🔄 Step 5/5: Finalizing...".to_string());
1637        let elapsed = start_time.elapsed();
1638
1639        let message = format!(
1640            "🚀 Firmware deployment completed!\n\n\
1641            Session ID: {}\n\
1642            File: {}\n\
1643            Format: {}\n\
1644            Total Time: {:.1}s\n\n\
1645            Status:\n{}\n\n\
1646            ✅ Firmware is now running on target.\n\
1647            {}",
1648            args.session_id,
1649            args.file_path,
1650            args.format,
1651            elapsed.as_secs_f64(),
1652            status_messages.join("\n"),
1653            if args.attach_rtt { "Use 'rtt_read' to monitor target output." } else { "Use 'rtt_attach' to enable real-time communication." }
1654        );
1655
1656        info!("Firmware deployment completed for session: {} in {:.1}s", args.session_id, elapsed.as_secs_f64());
1657        Ok(CallToolResult::success(vec![Content::text(message)]))
1658    }
1659}
1660
1661// =============================================================================
1662// Utility Functions
1663// =============================================================================
1664
1665/// Parse address string (hex or decimal) to u64
1666fn parse_address(addr_str: &str) -> Result<u64, String> {
1667    let addr_str = addr_str.trim();
1668    
1669    if addr_str.starts_with("0x") || addr_str.starts_with("0X") {
1670        u64::from_str_radix(&addr_str[2..], 16)
1671            .map_err(|e| format!("Invalid hex address: {}", e))
1672    } else {
1673        addr_str.parse::<u64>()
1674            .map_err(|e| format!("Invalid decimal address: {}", e))
1675    }
1676}
1677
1678/// Parse data string based on format
1679fn parse_data(data_str: &str, format: &str) -> Result<Vec<u8>, String> {
1680    match format {
1681        "hex" => {
1682            // Remove spaces and 0x prefixes
1683            let clean_str = data_str.replace(" ", "").replace("0x", "").replace("0X", "");
1684            if clean_str.len() % 2 != 0 {
1685                return Err("Hex data must have even number of characters".to_string());
1686            }
1687            
1688            (0..clean_str.len())
1689                .step_by(2)
1690                .map(|i| u8::from_str_radix(&clean_str[i..i+2], 16))
1691                .collect::<Result<Vec<_>, _>>()
1692                .map_err(|e| format!("Invalid hex data: {}", e))
1693        }
1694        "ascii" => Ok(data_str.as_bytes().to_vec()),
1695        "words32" => {
1696            let words: Result<Vec<u32>, _> = data_str
1697                .split_whitespace()
1698                .map(|s| {
1699                    if s.starts_with("0x") || s.starts_with("0X") {
1700                        u32::from_str_radix(&s[2..], 16)
1701                    } else {
1702                        s.parse::<u32>()
1703                    }
1704                })
1705                .collect();
1706            
1707            match words {
1708                Ok(words) => {
1709                    let mut data = Vec::new();
1710                    for word in words {
1711                        data.extend_from_slice(&word.to_le_bytes());
1712                    }
1713                    Ok(data)
1714                }
1715                Err(e) => Err(format!("Invalid word32 data: {}", e)),
1716            }
1717        }
1718        "words16" => {
1719            let words: Result<Vec<u16>, _> = data_str
1720                .split_whitespace()
1721                .map(|s| {
1722                    if s.starts_with("0x") || s.starts_with("0X") {
1723                        u16::from_str_radix(&s[2..], 16)
1724                    } else {
1725                        s.parse::<u16>()
1726                    }
1727                })
1728                .collect();
1729            
1730            match words {
1731                Ok(words) => {
1732                    let mut data = Vec::new();
1733                    for word in words {
1734                        data.extend_from_slice(&word.to_le_bytes());
1735                    }
1736                    Ok(data)
1737                }
1738                Err(e) => Err(format!("Invalid word16 data: {}", e)),
1739            }
1740        }
1741        _ => Err(format!("Unsupported data format: {}", format)),
1742    }
1743}
1744
1745/// Format memory data for display
1746fn format_memory_data(data: &[u8], format: &str, base_address: u64) -> String {
1747    match format {
1748        "hex" => {
1749            let mut result = String::new();
1750            for (i, chunk) in data.chunks(16).enumerate() {
1751                let addr = base_address + (i * 16) as u64;
1752                result.push_str(&format!("0x{:08X}: ", addr));
1753                
1754                // Hex bytes
1755                for (j, byte) in chunk.iter().enumerate() {
1756                    if j == 8 { result.push(' '); }
1757                    result.push_str(&format!("{:02X} ", byte));
1758                }
1759                
1760                // Pad if needed
1761                if chunk.len() < 16 {
1762                    let padding = (16 - chunk.len()) * 3 + (if chunk.len() <= 8 { 1 } else { 0 });
1763                    result.push_str(&" ".repeat(padding));
1764                }
1765                
1766                // ASCII representation
1767                result.push_str("| ");
1768                for byte in chunk {
1769                    if byte.is_ascii_graphic() || *byte == b' ' {
1770                        result.push(*byte as char);
1771                    } else {
1772                        result.push('.');
1773                    }
1774                }
1775                result.push('\n');
1776            }
1777            result
1778        }
1779        "binary" => {
1780            data.iter()
1781                .map(|b| format!("{:08b}", b))
1782                .collect::<Vec<_>>()
1783                .join(" ")
1784        }
1785        "words32" => {
1786            let mut result = String::new();
1787            for (i, chunk) in data.chunks(4).enumerate() {
1788                if chunk.len() == 4 {
1789                    let addr = base_address + (i * 4) as u64;
1790                    let word = u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]);
1791                    result.push_str(&format!("0x{:08X}: 0x{:08X}\n", addr, word));
1792                }
1793            }
1794            result
1795        }
1796        "words16" => {
1797            let mut result = String::new();
1798            for (i, chunk) in data.chunks(2).enumerate() {
1799                if chunk.len() == 2 {
1800                    let addr = base_address + (i * 2) as u64;
1801                    let word = u16::from_le_bytes([chunk[0], chunk[1]]);
1802                    result.push_str(&format!("0x{:08X}: 0x{:04X}\n", addr, word));
1803                }
1804            }
1805            result
1806        }
1807        "ascii" => {
1808            String::from_utf8_lossy(data).to_string()
1809        }
1810        _ => {
1811            // Default to hex if unknown format
1812            format_memory_data(data, "hex", base_address)
1813        }
1814    }
1815}
1816
1817#[tool_handler]
1818impl ServerHandler for EmbeddedDebuggerToolHandler {
1819    fn get_info(&self) -> ServerInfo {
1820        ServerInfo {
1821            protocol_version: ProtocolVersion::V_2024_11_05,
1822            capabilities: ServerCapabilities::builder().enable_tools().build(),
1823            server_info: Implementation::from_build_env(),
1824            instructions: Some("Complete embedded debugging and flash programming MCP server supporting ARM Cortex-M, RISC-V, and other architectures via probe-rs. Provides comprehensive debugging and flash programming capabilities including probe detection, target connection, memory operations, breakpoints, RTT communication, and flash programming with real hardware integration. All 22 tools available: list_probes, connect, disconnect, probe_info, halt, run, reset, step, get_status, read_memory, write_memory, set_breakpoint, clear_breakpoint, rtt_attach, rtt_detach, rtt_read, rtt_write, rtt_channels, flash_erase, flash_program, flash_verify, run_firmware.".to_string()),
1825        }
1826    }
1827
1828    async fn initialize(
1829        &self,
1830        _request: InitializeRequestParam,
1831        _context: RequestContext<RoleServer>,
1832    ) -> Result<InitializeResult, McpError> {
1833        info!("Complete Embedded Debugger MCP server initialized with all 22 tools (18 debug + 4 flash)");
1834        Ok(self.get_info())
1835    }
1836}