You have access to a CLI with its own authentication (e.g., Kiro with AWS credentials)
The CLI provides models not available via standard API (e.g., proprietary models)
You want to use the CLI's built-in tools and context
How it works
Mithril spawns the CLI process with the prompt as argument
Uses --no-interactive + structured output format
Parses the JSON/text response from stdout
Returns it through the standard ChatProvider interface
Example: Kiro CLI
Under the hood
# What Mithril does internally:
kiro-cli chat "Your prompt here" \
--model claude-opus-4.6 \
--no-interactive \
--output-format stream-json \
--agent-engine v2
# Output: JSON Lines with runStarted, agent_message_chunk, runFinished
Adding your own CLI provider
Any CLI that accepts a prompt and outputs text can be wrapped as a provider.
You just need to adjust the command arguments and output parsing in a new src/providers/your_cli.rs file.
Template
pub struct YourProvider {
model: String,
}
#[async_trait]
impl ChatProvider for YourProvider {
fn name(&self) -> &str { "your_provider" }
fn model(&self) -> &str { &self.model }
async fn chat(&self, messages: &[ChatMessage]) -> Result<String> {
// For Cloud: HTTP POST to API
// For CLI: spawn subprocess, parse output
todo!()
}
async fn chat_stream(&self, messages: &[ChatMessage], on_chunk: ...) -> Result<String> {
// Stream tokens one by one
todo!()
}
async fn chat_with_tools(&self, messages: &[ChatMessage], tools: &[ToolDefinition]) -> Result<ToolCallResult> {
// Function calling or fallback to plain chat
let text = self.chat(messages).await?;
Ok(ToolCallResult::Text(text))
}
}
// Register in src/providers/mod.rs create_provider_with_model():
"your_provider" => Ok(Box::new(YourProvider::new(model)))