Skip to content

Commit cfe15d4

Browse files
committed
Working MCP tools
1 parent 8a0a9de commit cfe15d4

File tree

14 files changed

+1006
-1349
lines changed

14 files changed

+1006
-1349
lines changed

crates/agent/src/agent/agent_config/definitions.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use crate::agent::consts::BUILTIN_VIBER_AGENT_NAME;
1313
use crate::agent::tools::BuiltInToolName;
1414

1515
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
16-
#[serde(tag = "specVersion")]
16+
// #[serde(tag = "specVersion")]
17+
#[serde(untagged)]
1718
pub enum Config {
1819
#[serde(rename = "2025_08_22")]
1920
V2025_08_22(AgentConfigV2025_08_22),
@@ -50,9 +51,9 @@ impl Config {
5051
}
5152
}
5253

53-
pub fn tool_settings(&self) -> &ToolSettings {
54+
pub fn tool_settings(&self) -> Option<&ToolSettings> {
5455
match self {
55-
Config::V2025_08_22(a) => &a.tool_settings,
56+
Config::V2025_08_22(a) => a.tool_settings.as_ref(),
5657
}
5758
}
5859

@@ -74,9 +75,9 @@ impl Config {
7475
}
7576
}
7677

77-
pub fn mcp_servers(&self) -> Option<&McpServers> {
78+
pub fn mcp_servers(&self) -> &HashMap<String, McpServerConfig> {
7879
match self {
79-
Config::V2025_08_22(a) => a.mcp_servers.as_ref(),
80+
Config::V2025_08_22(a) => &a.mcp_servers,
8081
}
8182
}
8283

@@ -120,9 +121,10 @@ pub struct AgentConfigV2025_08_22 {
120121
pub tool_aliases: HashMap<String, String>,
121122
/// Settings for specific tools
122123
#[serde(default)]
123-
pub tool_settings: ToolSettings,
124+
pub tool_settings: Option<ToolSettings>,
124125
/// A JSON schema specification describing the arguments for when this agent is invoked as a
125126
/// tool.
127+
#[serde(default)]
126128
pub tool_schema: Option<InputSchema>,
127129

128130
/// Hooks to add additional context
@@ -132,12 +134,13 @@ pub struct AgentConfigV2025_08_22 {
132134
///
133135
/// TODO: unimplemented
134136
#[serde(skip)]
137+
#[allow(dead_code)]
135138
pub model_preferences: Option<ModelPreferences>,
136139

137140
// mcp
138141
/// Configuration for Model Context Protocol (MCP) servers
139142
#[serde(default)]
140-
pub mcp_servers: Option<McpServers>,
143+
pub mcp_servers: HashMap<String, McpServerConfig>,
141144
/// Whether or not to include the legacy ~/.aws/amazonq/mcp.json in the agent
142145
///
143146
/// You can reference tools brought in by these servers as just as you would with the servers
@@ -198,6 +201,7 @@ pub struct FileWriteSettings {
198201

199202
/// This mirrors claude's config set up.
200203
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
204+
#[serde(rename_all = "camelCase")]
201205
pub struct McpServers {
202206
pub mcp_servers: HashMap<String, McpServerConfig>,
203207
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//! Unused code
2+
3+
#[derive(Debug, Clone)]
4+
pub struct ConfigHandle {
5+
/// Sender for sending requests to the tool manager task
6+
sender: RequestSender<AgentConfigRequest, AgentConfigResponse, AgentConfigError>,
7+
}
8+
9+
impl ConfigHandle {
10+
pub async fn get_config(&self, agent_name: &str) -> Result<AgentConfig, AgentConfigError> {
11+
match self
12+
.sender
13+
.send_recv(AgentConfigRequest::GetConfig {
14+
agent_name: agent_name.to_string(),
15+
})
16+
.await
17+
.unwrap_or(Err(AgentConfigError::Channel))?
18+
{
19+
AgentConfigResponse::Config(agent_config) => Ok(agent_config),
20+
other => {
21+
error!(?other, "received unexpected response");
22+
Err(AgentConfigError::Custom("received unexpected response".to_string()))
23+
},
24+
}
25+
}
26+
}
27+
28+
#[derive(Debug)]
29+
pub struct AgentConfigManager {
30+
configs: Vec<AgentConfig>,
31+
32+
request_tx: RequestSender<AgentConfigRequest, AgentConfigResponse, AgentConfigError>,
33+
request_rx: RequestReceiver<AgentConfigRequest, AgentConfigResponse, AgentConfigError>,
34+
}
35+
36+
impl AgentConfigManager {
37+
pub fn new() -> Self {
38+
let (request_tx, request_rx) = new_request_channel();
39+
Self {
40+
configs: Vec::new(),
41+
request_tx,
42+
request_rx,
43+
}
44+
}
45+
46+
pub async fn spawn(mut self) -> Result<(ConfigHandle, Vec<AgentConfigError>)> {
47+
let request_tx_clone = self.request_tx.clone();
48+
49+
// TODO - return errors back.
50+
let (configs, errors) = load_agents().await?;
51+
self.configs = configs;
52+
53+
tokio::spawn(async move {
54+
self.run().await;
55+
});
56+
57+
Ok((
58+
ConfigHandle {
59+
sender: request_tx_clone,
60+
},
61+
errors,
62+
))
63+
}
64+
65+
async fn run(mut self) {
66+
loop {
67+
tokio::select! {
68+
req = self.request_rx.recv() => {
69+
let Some(req) = req else {
70+
warn!("Agent config request channel has closed, exiting");
71+
break;
72+
};
73+
let res = self.handle_agent_config_request(req.payload).await;
74+
respond!(req, res);
75+
}
76+
}
77+
}
78+
}
79+
80+
async fn handle_agent_config_request(
81+
&mut self,
82+
req: AgentConfigRequest,
83+
) -> Result<AgentConfigResponse, AgentConfigError> {
84+
match req {
85+
AgentConfigRequest::GetConfig { agent_name } => {
86+
let agent_config = self
87+
.configs
88+
.iter()
89+
.find_map(|a| {
90+
if a.config.name() == agent_name {
91+
Some(a.clone())
92+
} else {
93+
None
94+
}
95+
})
96+
.ok_or(AgentConfigError::AgentNotFound { name: agent_name })?;
97+
Ok(AgentConfigResponse::Config(agent_config))
98+
},
99+
AgentConfigRequest::GetAllConfigs => {
100+
todo!()
101+
},
102+
}
103+
}
104+
}
105+
106+
#[derive(Debug, Clone)]
107+
pub enum AgentConfigRequest {
108+
GetConfig { agent_name: String },
109+
GetAllConfigs,
110+
}
111+
112+
#[derive(Debug, Clone)]
113+
pub enum AgentConfigResponse {
114+
Config(AgentConfig),
115+
AllConfigs {
116+
configs: Vec<AgentConfig>,
117+
invalid_configs: Vec<()>,
118+
},
119+
}

0 commit comments

Comments
 (0)