Skip to main content

embacle_server/mcp/tools/
list_models.rs

1// ABOUTME: MCP tool that lists available providers and their models
2// ABOUTME: Mirrors the /v1/models endpoint functionality via MCP protocol
3//
4// SPDX-License-Identifier: Apache-2.0
5// Copyright (c) 2026 dravr.ai
6
7use async_trait::async_trait;
8use embacle::ALL_PROVIDERS;
9use serde_json::{json, Value};
10
11use crate::mcp::protocol::{CallToolResult, ToolDefinition};
12use crate::mcp::tools::McpTool;
13use crate::state::SharedState;
14
15/// Lists available LLM providers and the server's default
16pub struct ListModels;
17
18#[async_trait]
19impl McpTool for ListModels {
20    fn definition(&self) -> ToolDefinition {
21        ToolDefinition {
22            name: "list_models".to_owned(),
23            description: "List available LLM providers and the server's default provider"
24                .to_owned(),
25            input_schema: json!({
26                "type": "object",
27                "properties": {},
28                "additionalProperties": false
29            }),
30        }
31    }
32
33    async fn execute(&self, state: &SharedState, _arguments: Value) -> CallToolResult {
34        let default = state.default_provider();
35        let providers: Vec<String> = ALL_PROVIDERS.iter().map(ToString::to_string).collect();
36
37        let result = json!({
38            "default_provider": default.to_string(),
39            "available_providers": providers,
40            "hint": "Use 'provider:model' in the prompt tool's model field to route to a specific provider"
41        });
42
43        match serde_json::to_string_pretty(&result) {
44            Ok(json) => CallToolResult::text(json),
45            Err(e) => CallToolResult::error(format!("Serialization failed: {e}")),
46        }
47    }
48}