Skip to content

Commit 020ff23

Browse files
authored
Fix: Allow --trust-tools to work on MCP servers (#206)
1 parent 75de393 commit 020ff23

File tree

2 files changed

+59
-16
lines changed

2 files changed

+59
-16
lines changed

crates/chat-cli/src/cli/chat/mod.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,15 @@ impl ChatArgs {
265265
tool_permissions.trust_tool(&tool.name);
266266
}
267267
} else if let Some(trusted) = self.trust_tools.map(|vec| vec.into_iter().collect::<HashSet<_>>()) {
268+
// --trust-all-tools takes precedence over --trust-tools=...
269+
for tool_name in &trusted {
270+
if !tool_name.is_empty() {
271+
// Store the original trust settings for later use with MCP tools
272+
tool_permissions.add_pending_trust_tool(tool_name.clone());
273+
}
274+
}
275+
276+
// Apply to currently known tools
268277
for tool in tool_config.values() {
269278
if trusted.contains(&tool.name) {
270279
tool_permissions.trust_tool(&tool.name);
@@ -1213,7 +1222,8 @@ impl ChatSession {
12131222
style::SetForegroundColor(Color::Reset),
12141223
style::SetAttribute(Attribute::Reset)
12151224
)?;
1216-
let user_input = match self.read_user_input(&self.generate_tool_trust_prompt(), false) {
1225+
let prompt = self.generate_tool_trust_prompt();
1226+
let user_input = match self.read_user_input(&prompt, false) {
12171227
Some(input) => input,
12181228
None => return Ok(ChatState::Exit),
12191229
};
@@ -1977,8 +1987,10 @@ impl ChatSession {
19771987
}
19781988

19791989
/// Helper function to generate a prompt based on the current context
1980-
fn generate_tool_trust_prompt(&self) -> String {
1981-
prompt::generate_prompt(self.conversation.current_profile(), self.all_tools_trusted())
1990+
fn generate_tool_trust_prompt(&mut self) -> String {
1991+
let profile = self.conversation.current_profile().map(|s| s.to_string());
1992+
let all_trusted = self.all_tools_trusted();
1993+
prompt::generate_prompt(profile.as_deref(), all_trusted)
19821994
}
19831995

19841996
async fn send_tool_use_telemetry(&mut self, telemetry: &TelemetryThread) {
@@ -1997,7 +2009,7 @@ impl ChatSession {
19972009
(self.terminal_width_provider)().unwrap_or(80)
19982010
}
19992011

2000-
fn all_tools_trusted(&self) -> bool {
2012+
fn all_tools_trusted(&mut self) -> bool {
20012013
self.conversation.tools.values().flatten().all(|t| match t {
20022014
FigTool::ToolSpecification(t) => self.tool_permissions.is_trusted(&t.name),
20032015
})

crates/chat-cli/src/cli/chat/tools/mod.rs

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ pub mod knowledge;
77
pub mod thinking;
88
pub mod use_aws;
99

10-
use std::collections::HashMap;
10+
use std::collections::{
11+
HashMap,
12+
HashSet,
13+
};
1114
use std::io::Write;
1215
use std::path::{
1316
Path,
@@ -136,30 +139,38 @@ pub struct ToolPermissions {
136139
// We need this field for any stragglers
137140
pub trust_all: bool,
138141
pub permissions: HashMap<String, ToolPermission>,
142+
// Store pending trust-tool patterns for MCP tools that may be loaded later
143+
pub pending_trusted_tools: HashSet<String>,
139144
}
140145

141146
impl ToolPermissions {
142147
pub fn new(capacity: usize) -> Self {
143148
Self {
144149
trust_all: false,
145150
permissions: HashMap::with_capacity(capacity),
151+
pending_trusted_tools: HashSet::new(),
146152
}
147153
}
148154

149-
pub fn is_trusted(&self, tool_name: &str) -> bool {
155+
pub fn is_trusted(&mut self, tool_name: &str) -> bool {
156+
// Check if we should trust from pending patterns first
157+
if self.should_trust_from_pending(tool_name) {
158+
self.trust_tool(tool_name);
159+
self.pending_trusted_tools.remove(tool_name);
160+
}
161+
150162
self.trust_all || self.permissions.get(tool_name).is_some_and(|perm| perm.trusted)
151163
}
152164

153165
/// Returns a label to describe the permission status for a given tool.
154-
pub fn display_label(&self, tool_name: &str) -> String {
155-
if self.has(tool_name) || self.trust_all {
156-
if self.is_trusted(tool_name) {
157-
format!(" {}", "trusted".dark_green().bold())
158-
} else {
159-
format!(" {}", "not trusted".dark_grey())
160-
}
161-
} else {
162-
self.default_permission_label(tool_name)
166+
pub fn display_label(&mut self, tool_name: &str) -> String {
167+
let is_trusted = self.is_trusted(tool_name);
168+
let has_setting = self.has(tool_name) || self.trust_all;
169+
170+
match (has_setting, is_trusted) {
171+
(true, true) => format!(" {}", "trusted".dark_green().bold()),
172+
(true, false) => format!(" {}", "not trusted".dark_grey()),
173+
_ => self.default_permission_label(tool_name),
163174
}
164175
}
165176

@@ -170,21 +181,41 @@ impl ToolPermissions {
170181

171182
pub fn untrust_tool(&mut self, tool_name: &str) {
172183
self.trust_all = false;
184+
self.pending_trusted_tools.remove(tool_name);
173185
self.permissions
174186
.insert(tool_name.to_string(), ToolPermission { trusted: false });
175187
}
176188

177189
pub fn reset(&mut self) {
178190
self.trust_all = false;
179191
self.permissions.clear();
192+
self.pending_trusted_tools.clear();
180193
}
181194

182195
pub fn reset_tool(&mut self, tool_name: &str) {
183196
self.trust_all = false;
184197
self.permissions.remove(tool_name);
198+
self.pending_trusted_tools.remove(tool_name);
185199
}
186200

187-
pub fn has(&self, tool_name: &str) -> bool {
201+
/// Add a pending trust pattern for tools that may be loaded later
202+
pub fn add_pending_trust_tool(&mut self, pattern: String) {
203+
self.pending_trusted_tools.insert(pattern);
204+
}
205+
206+
/// Check if a tool should be trusted based on preceding trust declarations
207+
pub fn should_trust_from_pending(&self, tool_name: &str) -> bool {
208+
// Check for exact match
209+
self.pending_trusted_tools.contains(tool_name)
210+
}
211+
212+
pub fn has(&mut self, tool_name: &str) -> bool {
213+
// Check if we should trust from pending tools first
214+
if self.should_trust_from_pending(tool_name) {
215+
self.trust_tool(tool_name);
216+
self.pending_trusted_tools.remove(tool_name);
217+
}
218+
188219
self.permissions.contains_key(tool_name)
189220
}
190221

0 commit comments

Comments
 (0)