@ask-llm/mcp
v0.6.1
Published
Unified MCP server for multi-LLM consultation — registers tools from all available providers (Gemini, Codex, Claude, Ollama, Antigravity) behind runtime availability checks
Maintainers
Readme
Ask LLM MCP (Unified)
All LLM providers in one MCP server — auto-detects what's installed
A unified MCP server that auto-detects installed LLM providers (Gemini, Codex, Claude, Ollama, Antigravity) and registers only the available tools. One install, all providers. Works with Claude Code, Codex CLI, Cursor, Warp, Copilot, and 40+ other MCP clients.
Part of the Ask LLM monorepo.
Quick Start
Claude Code
claude mcp add ask-llm -- npx -y @ask-llm/mcpClaude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"ask-llm": {
"command": "npx",
"args": ["-y", "@ask-llm/mcp"]
}
}
}Prerequisites
- Node.js v20.0.0 or higher
- At least one provider installed:
- Gemini CLI for
ask-geminitools - Codex CLI for
ask-codextools - Claude Code CLI for Codex and other non-Claude hosts to consult Claude
- Ollama running locally for
ask-ollamatools
- Gemini CLI for
How It Works
On startup, the unified server:
- Checks CLI availability (Gemini, Codex, Claude, Antigravity)
- Checks HTTP availability via health endpoints (Ollama)
- Dynamically imports and registers tools from available providers
- Exposes only the tools for providers that are actually installed
Tools
The orchestrator exposes a single ask-llm tool (not one tool per provider — ADR-029, for token efficiency); you pick the provider per call. When any provider is installed it registers:
| Tool | Purpose |
|------|---------|
| ask-llm | Route a prompt to a provider via the provider param (gemini, codex, claude, ollama, antigravity); optional sessionId for multi-turn |
| multi-llm | Dispatch one prompt to multiple providers in parallel; structured per-provider report |
| get-usage-stats | Per-session token totals + per-provider/model breakdowns (in-memory) |
| diagnose | Environment diagnostics — provider CLI presence + versions |
| ping | Connection test |
Claude is intentionally suppressed when the MCP host is already Claude Code because Claude Code rejects nested Claude sessions. It is auto-detected normally from Codex and other clients.
Machine Protocol
machine exposes a stdin-only JSON interface for factory controllers. It accepts one request of at most 2 MiB, with the prompt bounded to 150,000 characters by the schema, validates it before loading a provider, and writes exactly one typed result document to stdout. Prompts and issue content are never accepted through argv, and diagnostics go only to stderr.
Create a request file without putting its content in the command line:
{
"schemaVersion": 1,
"requestId": "factory-review-0001",
"role": "review",
"provider": "codex",
"prompt": "<redacted review input>",
"readOnly": true,
"writerProvider": "claude",
"includeDirs": ["packages/example"]
}Then dispatch it through stdin:
npx -y ask-llm-mcp machine < request.jsonA valid dispatch returns a typed success or provider-failure envelope:
{
"schemaVersion": 1,
"requestId": "factory-review-0001",
"status": "success",
"role": "review",
"provider": "codex",
"actualModel": "<redacted model>",
"rawResponseSha256": "<redacted sha256>",
"durationMs": 1200,
"usage": { "inputTokens": 100, "outputTokens": 20, "totalTokens": 120 },
"fallback": {
"occurred": false,
"requestedModel": "<redacted model>",
"actualModel": "<redacted model>"
},
"session": { "sessionId": "<redacted session>", "transcriptPath": null },
"payload": { "summary": "<redacted>", "findings": [] },
"quotaSignal": { "kind": "runtime_proxy_required" },
"failure": null
}The complete envelope also records model, fallback, duration, token, response-hash, and session provenance. Provider-level failures use the same strict result contract and still exit successfully so controllers can parse and classify them.
All machine dispatches force readOnly: true and pass read-only sandbox options to the provider adapter. The interface supports Codex, Claude, and Antigravity; it does not provide a write path. Subscription usage percentages remain unknown unless the provider exposes them, and the dispatcher never infers a percentage from token counts.
| Exit code | Meaning | Stdout |
|-----------|---------|--------|
| 0 | Valid result envelope, including provider-level failure | One JSON document |
| 2 | Missing, oversized, malformed, or schema-invalid stdin request | Empty |
| 3 | Dispatcher infrastructure failure | Empty |
Use machine-schema to retrieve the stable canonical request/result schema bundle and its digest:
npx -y ask-llm-mcp machine-schema > machine-schema.json{
"digest": "<redacted sha256>",
"failure": { "<redacted>": true },
"request": { "<redacted>": true },
"refinements": { "version": 1, "rules": [] },
"result": { "<redacted>": true },
"rolePayloads": { "brainstorm": {}, "review": {}, "verify": {} }
}The whole bundle is authoritative. Validate a document against its Draft 2020-12 request, result, or failure schema first, then run validateMachineSchemaRefinements(target, document, bundle.refinements). The portable refinement descriptors cover sibling-field equality rules that standard JSON Schema cannot express, including self-review and fallback provenance checks. The digest covers every base schema, role payload schema, and refinement descriptor.
machine-schema is provider-independent: it neither detects nor loads a provider and does not require a provider CLI to be installed. The refinement interpreter and its MachineSchemaRefinement, MachineSchemaRefinementSet, MachineSchemaRefinementViolation, and MachineSchemaTarget types are exported from ask-llm-mcp/machine and the package root.
Documentation
Full docs at lykhoyda.github.io/ask-llm
License
MIT
