Server data from the Official MCP Registry
Unified MCP gateway to Claude Code, Codex, and Gemini CLIs with sessions and async jobs.
Unified MCP gateway to Claude Code, Codex, and Gemini CLIs with sessions and async jobs.
Valid MCP server (2 strong, 3 medium validity signals). 2 known CVEs in dependencies (0 critical, 2 high severity) Package registry verified. Imported from the Official MCP Registry.
9 files analyzed · 3 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
This plugin requests these system permissions. Most are normal for its category.
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-verivus-oss-llm-cli-gateway": {
"args": [
"-y",
"llm-cli-gateway"
],
"command": "npx"
}
}
}From the project's GitHub README.
"Without consultation, plans are frustrated, but with many counselors they succeed." — Proverbs 15:22 (LSB)
A Model Context Protocol (MCP) server providing unified access to Claude Code, Codex, and Gemini CLIs with session management, retry logic, and async job orchestration.
~/.llm-cli-gateway/logs.db with correlation IDs, token usage, duration, retry counts, and circuit breaker state. Browse with Datasette: datasette ~/.llm-cli-gateway/logs.dbstructuredContent (model, cli, correlationId, sessionId, durationMs, token counts)*_request_async + polling toolsBefore using this gateway, you need to install the CLI tools you want to use:
# Installation instructions for Claude Code
# Visit: https://docs.anthropic.com/claude-code
npm install -g @anthropic-ai/claude-code
npm install -g @openai/codex
codex login
npm install -g @google/gemini-cli
# Or: https://github.com/google-gemini/gemini-cli
npm install -g llm-cli-gateway
Or use directly with npx:
{
"mcpServers": {
"llm-gateway": {
"command": "npx",
"args": ["-y", "llm-cli-gateway"]
}
}
}
git clone https://github.com/verivus-oss/llm-cli-gateway.git
cd llm-cli-gateway
npm install
npm run build
Add to your MCP client configuration (e.g., Claude Desktop):
{
"mcpServers": {
"llm-cli-gateway": {
"command": "node",
"args": ["/path/to/llm-cli-gateway/dist/index.js"]
}
}
}
claude_requestExecute a Claude Code request with optional session management.
Parameters:
prompt (string, required): The prompt to send (1-100,000 chars)model (string, optional): Model name or alias (use list_models for available values; supports latest)outputFormat (string, optional): Output format ("text" or "json"), default: "text"sessionId (string, optional): Specific session ID to usecontinueSession (boolean, optional): Continue the active sessioncreateNewSession (boolean, optional): Always create a new sessionallowedTools (string[], optional): Restrict Claude tools to this allow-listdisallowedTools (string[], optional): Explicitly deny listed Claude toolsdangerouslySkipPermissions (boolean, optional): Request CLI-side permission bypass (legacy mode only)approvalStrategy (string, optional): "legacy" (default) or "mcp_managed"approvalPolicy (string, optional): "strict", "balanced", or "permissive"mcpServers (string[], optional): Claude MCP servers to expose (default: ["sqry","exa","ref_tools"]; "trstr" available as opt-in)strictMcpConfig (boolean, optional): Require Claude to use only supplied MCP config, default: true (request fails if any requested server is unavailable)optimizePrompt (boolean, optional): Optimize prompt for token efficiency (44% reduction), default: falseoptimizeResponse (boolean, optional): Optimize response for token efficiency (37% reduction), default: falsecorrelationId (string, optional): Request trace ID (auto-generated if omitted)Response extras:
approval: Approval decision record when approvalStrategy="mcp_managed"mcpServers: Requested/enabled/missing MCP servers for this callExample:
{
"prompt": "Write a Python function to calculate fibonacci numbers",
"model": "sonnet",
"continueSession": true,
"optimizePrompt": true,
"optimizeResponse": true
}
codex_requestExecute a Codex request with optional session tracking.
Parameters:
prompt (string, required): The prompt to send (1-100,000 chars)model (string, optional): Model name or alias (use list_models for available values; supports latest, recommended: gpt-5.4)fullAuto (boolean, optional): Enable full-auto mode, default: falsedangerouslyBypassApprovalsAndSandbox (boolean, optional): Request Codex bypass flagsapprovalStrategy (string, optional): "legacy" (default) or "mcp_managed"approvalPolicy (string, optional): "strict", "balanced", or "permissive"mcpServers (string[], optional): MCP servers expected for Codex execution contextsessionId (string, optional): Session identifier for trackingcreateNewSession (boolean, optional): Always create a new sessionoptimizePrompt (boolean, optional): Optimize prompt for token efficiency, default: falseoptimizeResponse (boolean, optional): Optimize response for token efficiency, default: falsecorrelationId (string, optional): Request trace ID (auto-generated if omitted)idleTimeoutMs (number, optional): Kill a stuck Codex process after output inactivity; 30,000 to 3,600,000 msResponse extras:
approval: Approval decision record when approvalStrategy="mcp_managed"mcpServers: Requested MCP servers for this callExample:
{
"prompt": "Create a REST API endpoint",
"model": "gpt-5.4",
"fullAuto": true,
"optimizePrompt": true
}
gemini_requestExecute a Gemini CLI request with session support.
Parameters:
prompt (string, required): The prompt to send (1-100,000 chars)model (string, optional): Model name or alias (use list_models for available values; supports latest, pro, flash)sessionId (string, optional): Session ID to resumeresumeLatest (boolean, optional): Resume the latest session automaticallycreateNewSession (boolean, optional): Always create a new sessionapprovalMode (string, optional): Gemini approval mode (default|auto_edit|yolo) in legacy modeapprovalStrategy (string, optional): "legacy" (default) or "mcp_managed"approvalPolicy (string, optional): "strict", "balanced", or "permissive"mcpServers (string[], optional): Allowed Gemini MCP server namesallowedTools (string[], optional): Restrict Gemini tools to this allow-listincludeDirs (string[], optional): Additional workspace directories for GeminioptimizePrompt (boolean, optional): Optimize prompt for token efficiency, default: falseoptimizeResponse (boolean, optional): Optimize response for token efficiency, default: falsecorrelationId (string, optional): Request trace ID (auto-generated if omitted)Response extras:
approval: Approval decision record when approvalStrategy="mcp_managed"mcpServers: Requested MCP servers for this callExample:
{
"prompt": "Explain quantum computing",
"model": "latest",
"resumeLatest": true,
"optimizePrompt": true
}
claude_request_async / codex_request_asyncStart a long-running Claude or Codex request without waiting for completion in the same MCP call.
Use this flow when analysis/runtime can exceed client tool-call limits:
*_request_asyncllm_job_statusllm_job_resultllm_job_cancelAsync request tools accept the same approval strategy fields as their sync variants:
approvalStrategy: "legacy" (default) or "mcp_managed"approvalPolicy: "strict"|"balanced"|"permissive" overridemcpServers: Requested MCP servers (sqry, exa, ref_tools, trstr)claude_request_async also supports strictMcpConfig and fails fast when requested servers are unavailablellm_job_statusReturn lifecycle status (running, completed, failed, canceled) and metadata for an async job.
llm_job_resultReturn captured stdout/stderr for an async job (with configurable max chars per stream).
llm_job_cancelCancel a running async job.
approval_listList recent MCP-managed approval decisions recorded by the gateway.
Parameters:
limit (number, optional): Max records (1-500), default: 50cli (string, optional): Filter by "claude", "codex", or "gemini"Approval records are persisted to ~/.llm-cli-gateway/approvals.jsonl.
session_createCreate a new session for a specific CLI.
Parameters:
cli (string, required): CLI to create session for ("claude", "codex", "gemini")description (string, optional): Description for the sessionsetAsActive (boolean, optional): Set as active session, default: trueExample:
{
"cli": "claude",
"description": "Code review session",
"setAsActive": true
}
session_listList all sessions, optionally filtered by CLI.
Parameters:
cli (string, optional): Filter by CLI ("claude", "codex", "gemini")Response includes:
session_set_activeSet the active session for a specific CLI.
Parameters:
cli (string, required): CLI to set active session forsessionId (string, required): Session ID to activate (or null to clear)session_getRetrieve details for a specific session.
Parameters:
sessionId (string, required): Session ID to retrievesession_deleteDelete a specific session.
Parameters:
sessionId (string, required): Session ID to deletesession_clear_allClear all sessions, optionally for a specific CLI.
Parameters:
cli (string, optional): Clear sessions for specific CLI onlylist_modelsList available models for each CLI.
Parameters:
cli (string, optional): Specific CLI to list models for ("claude", "codex", "gemini")Response includes:
~/.llm-cli-gateway/sessions.json// 1. Create a new session
await callTool("session_create", {
cli: "claude",
description: "Debugging session",
setAsActive: true
});
// 2. Make requests (automatically uses active session)
await callTool("claude_request", {
prompt: "What's the bug in this code?",
// sessionId is automatically used
});
// 3. Continue the conversation
await callTool("claude_request", {
prompt: "Can you explain that fix in more detail?",
continueSession: true
});
// 4. List all sessions
await callTool("session_list", { cli: "claude" });
// 5. Switch to a different session
await callTool("session_set_active", {
cli: "claude",
sessionId: "some-other-session-id"
});
// 6. Delete when done
await callTool("session_delete", {
sessionId: "session-id-to-delete"
});
DEBUG: Enable debug logging (set to any value)
DEBUG=1 node dist/index.js
LLM_GATEWAY_APPROVAL_POLICY: Default approval policy when request does not pass approvalPolicy (strict, balanced, permissive)
LLM_GATEWAY_APPROVAL_POLICY=strict node dist/index.js
LLM_GATEWAY_LOGS_DB: Path to SQLite flight recorder database. Default: ~/.llm-cli-gateway/logs.db. Set to empty string or none to disable logging.
# Custom path
LLM_GATEWAY_LOGS_DB=/var/log/gateway/logs.db node dist/index.js
# Disable flight recorder
LLM_GATEWAY_LOGS_DB=none node dist/index.js
Each CLI can be configured through its own configuration files:
~/.claude/config.json~/.codex/config.toml~/.gemini/config.jsonSimon's llm tool made it trivially easy to talk to any LLM from the command line. But as AI-assisted development matures, the challenge shifts from "how do I call a model" to "how do I orchestrate multiple models reliably, and what did they actually do?"
Multiple models increase the confidence factor. When Claude writes code, Codex reviews it, and Gemini checks for bugs -- each bringing different training data and reasoning patterns -- the result is more robust than any single model alone. And often this isn't even enough. Having the models do iterative reviews is where you start getting real confidence.
Every interaction should be queryable data. Inspired by llm's SQLite logging philosophy, the gateway records every request and response to a local SQLite database. Not just prompts and responses -- retry counts, circuit breaker states, approval decisions, thinking blocks, cost estimates. Open it with Datasette and you have a complete operational picture of your AI usage:
datasette ~/.llm-cli-gateway/logs.db
The llm-gateway plugin bridges both worlds. Install it, and your existing llm workflows gain orchestration features without changing how you work:
llm install llm-gateway
llm -m gateway-claude "explain this function"
Your gateway interactions appear in both llm logs (for your personal history) and the gateway's flight recorder (for operational observability). Two audiences, one workflow.
Composability over monoliths. The gateway doesn't replace llm -- it complements it. Use llm directly when you want simplicity. Route through the gateway when you want resilience, multi-model coordination, or detailed operational telemetry. The plugin is the bridge, not the destination.
llm-cli-gateway/
├── src/
│ ├── index.ts # Main MCP server and tool definitions
│ ├── executor.ts # CLI execution with timeout support
│ ├── session-manager.ts # Session management logic
│ └── __tests__/
│ ├── executor.test.ts # Unit tests for executor
│ └── integration.test.ts # Integration tests
├── dist/ # Compiled JavaScript
├── package.json
├── tsconfig.json
└── vitest.config.ts
# Run all tests
npm test
# Run unit tests only
npm run test:unit
# Run integration tests only
npm run test:integration
# Watch mode
npm run test:watch
npm run build
npm start
The gateway provides detailed error messages for common issues:
Error executing claude CLI:
spawn claude ENOENT
The 'claude' command was not found. Please ensure claude CLI is installed and in your PATH.
Error executing codex CLI: Command timed out
Process timed out after 120000ms
Prompt cannot be empty
Prompt too long (max 100k chars)
Logs are written to stderr (stdout is reserved for MCP protocol):
[INFO] 2026-01-24T05:00:00.000Z - Starting llm-cli-gateway MCP server
[INFO] 2026-01-24T05:00:01.000Z - claude_request invoked with model=sonnet, prompt length=150
[INFO] 2026-01-24T05:00:05.000Z - claude_request completed successfully in 4523ms, response length=2048
[ERROR] 2026-01-24T05:00:10.000Z - codex CLI execution failed: spawn codex ENOENT
Enable debug logging:
DEBUG=1 node dist/index.js
Make sure the CLIs are installed and in your PATH:
which claude
which codex
which gemini
The gateway extends PATH to include common locations:
~/.local/bin/usr/local/bin/usr/bin~/.nvm/versions/node/*/bin directoriesIf you encounter permission errors, ensure the CLI tools have proper permissions:
chmod +x $(which claude)
chmod +x $(which codex)
chmod +x $(which gemini)
Sessions are stored in ~/.llm-cli-gateway/sessions.json. If you encounter issues:
ls -la ~/.llm-cli-gateway/
rm ~/.llm-cli-gateway/sessions.json
cat ~/.llm-cli-gateway/sessions.json
The gateway does not enforce a default execution timeout for LLM CLI requests.
If your MCP client/runtime enforces per-tool-call deadlines, use async tools (*_request_async + llm_job_status/llm_job_result) so long-running jobs can complete outside a single call window.
The gateway supports concurrent requests across different CLIs. Each request spawns a separate process.
spawn with separate arguments (not shell execution)npm testnpm run buildMIT. See LICENSE for details.
For issues and questions:
See CHANGELOG.md for detailed release history.
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
by mcp-marketplace · Developer Tools
Create, build, and publish Python MCP servers to PyPI — conversationally.
by Microsoft · Content & Media
Convert files (PDF, Word, Excel, images, audio) to Markdown for LLM consumption
by mcp-marketplace · Developer Tools
Scaffold, build, and publish TypeScript MCP servers to npm — conversationally
by mcp-marketplace · Finance
Free stock data and market news for any MCP-compatible AI assistant.