Skip to main content

ares/mcp/
tools.rs

1// ares/src/mcp/tools.rs
2// Input and output types for all ARES MCP tools.
3// Each struct maps to one MCP tool's parameters or return value.
4
5use serde::{Deserialize, Serialize};
6
7// =============================================================================
8// ares_list_agents
9// =============================================================================
10
11/// Input for ares_list_agents tool.
12/// No parameters required — lists all agents for the authenticated tenant.
13#[derive(Debug, Deserialize, Serialize, Default)]
14pub struct ListAgentsInput {}
15
16/// One agent in the list response.
17#[derive(Debug, Serialize, Deserialize, Clone)]
18pub struct AgentSummary {
19    /// Agent name (unique within tenant)
20    pub name: String,
21    /// Human-readable description
22    pub description: String,
23    /// Agent type: "chat", "workflow", "autonomous"
24    pub agent_type: String,
25    /// Whether the agent is currently active
26    pub active: bool,
27    /// When the agent was last deployed
28    pub deployed_at: String,
29}
30
31/// Output for ares_list_agents tool.
32#[derive(Debug, Serialize)]
33pub struct ListAgentsOutput {
34    pub agents: Vec<AgentSummary>,
35    pub total: usize,
36}
37
38// =============================================================================
39// ares_run_agent
40// =============================================================================
41
42/// Input for ares_run_agent tool.
43#[derive(Debug, Deserialize, Serialize)]
44pub struct RunAgentInput {
45    /// Name of the agent to run (must exist in tenant's agent list)
46    pub agent_name: String,
47    /// The message to send to the agent
48    pub message: String,
49    /// Optional context ID for continuing a conversation
50    #[serde(default)]
51    pub context_id: Option<String>,
52}
53
54/// Output for ares_run_agent tool.
55#[derive(Debug, Serialize)]
56pub struct RunAgentOutput {
57    /// The agent's response text
58    pub response: String,
59    /// Which agent handled the request
60    pub agent: String,
61    /// Context ID for continuing this conversation
62    pub context_id: String,
63    /// Sources cited by the agent (if any)
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub sources: Option<Vec<SourceRef>>,
66}
67
68/// A source reference from an agent response.
69#[derive(Debug, Serialize, Deserialize, Clone)]
70pub struct SourceRef {
71    pub title: String,
72    pub url: Option<String>,
73    pub snippet: Option<String>,
74}
75
76// =============================================================================
77// ares_get_status
78// =============================================================================
79
80/// Input for ares_get_status tool.
81#[derive(Debug, Deserialize, Serialize)]
82pub struct GetStatusInput {
83    /// Context ID from a previous ares_run_agent call
84    pub context_id: String,
85}
86
87/// Output for ares_get_status tool.
88#[derive(Debug, Serialize)]
89pub struct GetStatusOutput {
90    pub context_id: String,
91    /// "running", "completed", "failed", "not_found"
92    pub status: String,
93    /// Partial response text if still running
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub partial_response: Option<String>,
96    /// Error message if status is "failed"
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub error: Option<String>,
99}
100
101// =============================================================================
102// ares_deploy_agent
103// =============================================================================
104
105/// Input for ares_deploy_agent tool.
106#[derive(Debug, Deserialize, Serialize)]
107pub struct DeployAgentInput {
108    /// The .toon config file contents as a string (TOML format)
109    pub toon_config: String,
110    /// Optional: override the agent name from the config
111    #[serde(default)]
112    pub name_override: Option<String>,
113}
114
115/// Output for ares_deploy_agent tool.
116#[derive(Debug, Serialize)]
117pub struct DeployAgentOutput {
118    /// Name of the deployed agent
119    pub agent_name: String,
120    /// "created" or "updated"
121    pub action: String,
122    /// Whether the agent is now active
123    pub active: bool,
124    /// Deployment timestamp
125    pub deployed_at: String,
126}
127
128// =============================================================================
129// ares_get_usage
130// =============================================================================
131
132/// Input for ares_get_usage tool.
133#[derive(Debug, Deserialize, Serialize, Default)]
134pub struct GetUsageInput {
135    /// Optional: filter by date range (ISO 8601, e.g. "2026-03-01")
136    #[serde(default)]
137    pub from_date: Option<String>,
138    #[serde(default)]
139    pub to_date: Option<String>,
140}
141
142/// Output for ares_get_usage tool.
143#[derive(Debug, Serialize)]
144pub struct GetUsageOutput {
145    pub tenant_id: String,
146    pub tier: String,
147    pub period: UsagePeriod,
148    pub current_usage: UsageStats,
149    pub quota: UsageQuota,
150}
151
152/// Usage period range.
153#[derive(Debug, Serialize)]
154pub struct UsagePeriod {
155    pub from: String,
156    pub to: String,
157}
158
159/// Current usage statistics.
160#[derive(Debug, Serialize)]
161pub struct UsageStats {
162    pub total_requests: u64,
163    pub chat_requests: u64,
164    pub mcp_requests: u64,
165    pub tokens_used: u64,
166    pub agents_deployed: u32,
167}
168
169/// Quota limits for the tenant's tier.
170#[derive(Debug, Serialize)]
171pub struct UsageQuota {
172    pub max_requests_per_month: u64,
173    pub max_agents: u32,
174    pub max_tokens_per_month: u64,
175    /// Percentage of quota used (0.0 to 1.0)
176    pub utilization: f64,
177}
178
179// =============================================================================
180// eruka_read (proxy)
181// =============================================================================
182
183/// Input for eruka_read proxy tool.
184#[derive(Debug, Deserialize, Serialize)]
185pub struct ErukaReadInput {
186    /// Eruka workspace ID (defaults to tenant's workspace if omitted)
187    #[serde(default)]
188    pub workspace_id: Option<String>,
189    /// Category to read from (e.g. "identity", "market", "content")
190    pub category: String,
191    /// Specific field to read (e.g. "company_name")
192    pub field: String,
193}
194
195/// Output for eruka_read proxy tool.
196#[derive(Debug, Serialize)]
197pub struct ErukaReadOutput {
198    pub field: String,
199    pub value: serde_json::Value,
200    /// "CONFIRMED", "UNCERTAIN", "UNKNOWN"
201    pub state: String,
202    pub confidence: f64,
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub last_updated: Option<String>,
205}
206
207// =============================================================================
208// eruka_write (proxy)
209// =============================================================================
210
211/// Input for eruka_write proxy tool.
212#[derive(Debug, Deserialize, Serialize)]
213pub struct ErukaWriteInput {
214    /// Eruka workspace ID (defaults to tenant's workspace if omitted)
215    #[serde(default)]
216    pub workspace_id: Option<String>,
217    /// Category to write to
218    pub category: String,
219    /// Field name
220    pub field: String,
221    /// Value to write (any JSON value)
222    pub value: serde_json::Value,
223    /// Confidence score (0.0 to 1.0, use 1.0 for user-confirmed facts)
224    pub confidence: f64,
225    /// Source of the information (e.g. "user_interview", "web_research")
226    pub source: String,
227}
228
229/// Output for eruka_write proxy tool.
230#[derive(Debug, Serialize)]
231pub struct ErukaWriteOutput {
232    pub field: String,
233    /// "CONFIRMED" if confidence >= 1.0, "UNCERTAIN" otherwise
234    pub state: String,
235    pub written_at: String,
236}
237
238// =============================================================================
239// eruka_search (proxy)
240// =============================================================================
241
242/// Input for eruka_search proxy tool.
243#[derive(Debug, Deserialize, Serialize)]
244pub struct ErukaSearchInput {
245    /// Eruka workspace ID (defaults to tenant's workspace if omitted)
246    #[serde(default)]
247    pub workspace_id: Option<String>,
248    /// Natural language search query
249    pub query: String,
250    /// Maximum number of results (default 5)
251    #[serde(default = "default_search_limit")]
252    pub limit: u32,
253}
254
255fn default_search_limit() -> u32 {
256    5
257}
258
259/// One result from eruka_search.
260#[derive(Debug, Serialize)]
261pub struct ErukaSearchResult {
262    pub category: String,
263    pub field: String,
264    pub value: serde_json::Value,
265    pub state: String,
266    pub relevance: f64,
267}
268
269/// Output for eruka_search proxy tool.
270#[derive(Debug, Serialize)]
271pub struct ErukaSearchOutput {
272    pub results: Vec<ErukaSearchResult>,
273    pub total_results: usize,
274}