List Models
list_modelsList available models from LLM providers like OpenAI, Google, Groq, and Ollama. Optionally fetch the latest models directly from the API.
Instructions
List available models for LLM providers
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| provider | No | Provider name (optional, lists all if not specified) | |
| fetch_latest | No | Fetch latest models from API vs using cached/configured |
Implementation Reference
- src/tools/list-models.ts:6-106 (handler)Main handler function that lists available models for LLM providers. Accepts optional 'provider' (to filter) and 'fetch_latest' args. Iterates providers and formats model info with nicknames, defaults, descriptions, and context window sizes. Falls back to cached/configured models.
export async function listModelsTool( providerManager: ProviderManager, args: Record<string, unknown> ) { const { provider, fetch_latest = false } = args as { provider?: string; fetch_latest?: boolean; }; try { let response = `${duckArt.panel}\nš **Available Models**\n\n`; if (provider) { // List models for a specific provider const providerInfo = providerManager.getAllProviders().find((p) => p.name === provider); if (!providerInfo) { throw new Error(`Provider "${provider}" not found`); } const models = await providerManager.getAvailableModels(provider); response += formatProviderModels( providerInfo.info.nickname, provider, models, providerInfo.info.model ); } else { // List models for all providers const allProviders = providerManager.getAllProviders(); for (const providerInfo of allProviders) { try { const models = await providerManager.getAvailableModels(providerInfo.name); response += formatProviderModels( providerInfo.info.nickname, providerInfo.name, models, providerInfo.info.model ); response += '\n'; } catch (error) { logger.warn(`Failed to get models for ${providerInfo.name}:`, error); response += `\nš¦ **${providerInfo.info.nickname}** (${providerInfo.name})\n`; response += ` ā ļø Failed to fetch models\n\n`; } } } response += `\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n`; response += fetch_latest ? 'š Fetched from API' : 'š Using cached/configured models'; logger.info(`Listed models for ${provider || 'all providers'}`); return { content: [ { type: 'text', text: response, }, ], }; } catch (error: unknown) { logger.error('Error listing models:', error); throw error; } } function formatProviderModels( nickname: string, providerName: string, models: ModelInfo[], defaultModel: string ): string { let output = `\nš¦ **${nickname}** (${providerName})\n`; if (models.length === 0) { output += ` š No models available\n`; return output; } for (const model of models) { const isDefault = model.id === defaultModel; const defaultMarker = isDefault ? ' **(default)**' : ''; output += ` ⢠${model.id}${defaultMarker}`; if (model.description) { output += ` - ${model.description}`; } else if (model.owned_by) { output += ` - by ${model.owned_by}`; } if (model.context_window) { output += ` [${model.context_window} tokens]`; } output += '\n'; } return output; } - src/tools/list-models.ts:73-106 (helper)formatProviderModels helper - formats a single provider's models into a readable string with nickname, model IDs, default markers, descriptions, and context window sizes.
function formatProviderModels( nickname: string, providerName: string, models: ModelInfo[], defaultModel: string ): string { let output = `\nš¦ **${nickname}** (${providerName})\n`; if (models.length === 0) { output += ` š No models available\n`; return output; } for (const model of models) { const isDefault = model.id === defaultModel; const defaultMarker = isDefault ? ' **(default)**' : ''; output += ` ⢠${model.id}${defaultMarker}`; if (model.description) { output += ` - ${model.description}`; } else if (model.owned_by) { output += ` - by ${model.owned_by}`; } if (model.context_window) { output += ` [${model.context_window} tokens]`; } output += '\n'; } return output; } - src/providers/types.ts:10-17 (schema)ModelInfo interface defining the shape of model data returned by listModels: id, created, owned_by, object, context_window, description.
export interface ModelInfo { id: string; created?: number; owned_by?: string; object?: string; context_window?: number; description?: string; } - src/server.ts:372-400 (registration)Registration of the 'list_models' tool on the MCP server with title, description, inputSchema (provider enum + fetch_latest boolean), annotations, and handler wiring to listModelsTool.
// list_models this.server.registerTool( 'list_models', { title: 'List Models', description: 'List available models for LLM providers', inputSchema: { provider: this.providerEnum() .optional() .describe('Provider name (optional, lists all if not specified)'), fetch_latest: z .boolean() .default(false) .describe('Fetch latest models from API vs using cached/configured'), }, annotations: { readOnlyHint: true, openWorldHint: true, }, }, async (args) => { try { return this.toolResult( await listModelsTool(this.providerManager, args as Record<string, unknown>) ); } catch (error) { return this.toolErrorResult(error); } } - src/providers/provider.ts:237-270 (helper)Base Provider class listModels implementation - fetches models from API via OpenAI client, falls back to configured availableModels list, then to default model.
async listModels(): Promise<ModelInfo[]> { try { // Try to fetch models from the API const response = await this.client.models.list(); const models: ModelInfo[] = []; for await (const model of response) { models.push({ id: model.id, created: model.created, owned_by: model.owned_by, object: model.object, }); } logger.debug(`Fetched ${models.length} models from ${this.name}`); return models; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); logger.warn(`Failed to fetch models from ${this.name}: ${errorMessage}`); // Fall back to configured models if (this.options.availableModels && this.options.availableModels.length > 0) { return this.options.availableModels.map((id) => ({ id, description: 'Configured model (not fetched from API)', })); } // Last fallback: return just the default model return [ { id: this.options.model, description: 'Default configured model', }, ];