{
  "markdown": "# qodercli-mcp\n\n**English** | [简体中文](./README.zh-CN.md)\n\n[![npm version](https://img.shields.io/npm/v/qodercli-mcp)](https://www.npmjs.com/package/qodercli-mcp)\n[![npm weekly downloads](https://img.shields.io/npm/dw/qodercli-mcp?label=downloads%2Fweek)](https://www.npmjs.com/package/qodercli-mcp)\n[![npm total downloads](https://img.shields.io/npm/dt/qodercli-mcp?label=total%20downloads)](https://www.npmjs.com/package/qodercli-mcp)\n[![License: MIT](https://img.shields.io/github/license/cantbeblank96/qodercli-mcp)](./LICENSE)\n[![GitHub stars](https://img.shields.io/github/stars/cantbeblank96/qodercli-mcp?style=social)](https://github.com/cantbeblank96/qodercli-mcp)\n\n> **The missing MCP server mode for Qoder CLI** — delegate coding tasks to local Qoder agents from any MCP client (Qoder IDE, Claude Code, Cursor…).\n\nA minimal MCP server that wraps the local `qodercli` (Qoder CLI) as MCP tools, letting any MCP client (Qoder IDE, Claude Code, Cursor, …) call Qoder like a sub-agent.\n\n![demo](docs/demo.gif)\n\n*30s demo: MCP client ⇄ qodercli-mcp ⇄ qodercli — initialize → tools/list → list-models (real output, not sped up)*\n\n## Quick start\n\nZero-config via npx — add this to your MCP client config (`~/.qoder/mcp.json`, `claude_desktop_config.json`, …):\n\n```json\n{ \"mcpServers\": { \"qodercli-mcp\": { \"command\": \"npx\", \"args\": [\"-y\", \"qodercli-mcp\"] } } }\n```\n\nThree tools are exposed:\n\n| Tool | Purpose |\n|---|---|\n| `ask-qoder` | Delegate a task to qodercli |\n| `list-sessions` | Discover resumable sessions |\n| `list-models` | Runtime model discovery |\n\nHighlights: **verified permission semantics** (see below — e.g. `dont_ask` is read-only),\ncodex-style `sandbox`/`approval_policy`, structured output (`session_id`/`duration_ms`/`total_credits`).\n\nFull configuration options are in [Install](#install).\n\n## Why\n\nSome CLI agents ship an official MCP server mode (e.g. `codex mcp-server`), but `qodercli` currently only acts as an MCP **client**. This project fills that gap with a thin wrapper: it spawns `qodercli -p <prompt>` under the hood and streams the result back over MCP stdio.\n\n## Features\n\n- `ask-qoder` tool — delegate a prompt to qodercli\n- Structured output (`session_id`, `is_error`, `duration_ms`, `total_credits`, `num_turns`) via `-o json` parsing\n- `list-sessions` tool to discover resumable sessions\n- `list-models` tool for runtime model discovery (no stale model lists)\n- `reasoning_effort` parameter (`--reasoning-effort`)\n- Server `instructions` in the MCP initialize result guide clients on usage\n- Codex-style `sandbox` levels (`read-only` / `workspace-write` / `danger-full-access`)\n- System prompt injection (`system_prompt` / `append_system_prompt`)\n- Working directory, model, permission mode, output format control\n- Session resume (`resume_session_id`) for multi-turn delegation\n- Timeout protection with SIGKILL fallback\n- Proxy quota support (`HTTP_PROXY` / `HTTPS_PROXY` injection)\n- Zero build step — plain ESM JavaScript, Node.js >= 18\n\n## Prerequisites\n\n1. Node.js >= 18\n2. `qodercli` installed and signed in (`qodercli login`)\n\n## Install\n\n**Option A — npx (recommended)**: no clone needed, the MCP client downloads the package on first use.\n\n```json\n\"command\": \"npx\", \"args\": [\"-y\", \"qodercli-mcp\"]\n```\n\n**Option B — from source (for development)**:\n\n```bash\ngit clone https://github.com/cantbeblank96/qodercli-mcp.git\ncd qodercli-mcp\nnpm install\n```\n\n## MCP client configuration\n\n### Qoder IDE\n\nAdd to `~/.qoder/mcp.json`. Prefer the absolute path of `node` and set `QODERCLI_PATH` explicitly (nvm-managed binaries are often missing from the PATH seen by MCP child processes):\n\n> **Proxy Support**: To use your Qoder CLI proxy quota, add `HTTP_PROXY` and/or `HTTPS_PROXY` to the server's environment. When these are set at the MCP server level, they will be passed to all qodercli subprocesses.\n\n```json\n{\n  \"mcpServers\": {\n    \"qodercli-mcp\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"qodercli-mcp\"],\n      \"env\": {\n        \"QODERCLI_PATH\": \"/absolute/path/to/qodercli\",\n        \"PATH\": \"/usr/local/bin:/usr/bin:/bin\"\n      }\n    },\n    \"qodercli-mcp-with-proxy\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"qodercli-mcp\"],\n      \"env\": {\n        \"QODERCLI_PATH\": \"/absolute/path/to/qodercli\",\n        \"HTTP_PROXY\": \"http://127.0.0.1:39900\",\n        \"HTTPS_PROXY\": \"http://127.0.0.1:39900\",\n        \"PATH\": \"/usr/local/bin:/usr/bin:/bin\"\n      }\n    }\n  }\n}\n```\n\nDevelopers running a local checkout instead of the published package (Option B) should replace `command`/`args` with the absolute `node` path and `/path/to/qodercli-mcp/src/index.js` (nvm-managed `node` is often missing from the PATH seen by MCP child processes).\n\n### Claude Code / Claude Desktop\n\n```json\n{\n  \"mcpServers\": {\n    \"qodercli-mcp\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/qodercli-mcp/src/index.js\"],\n      \"env\": {\n        \"QODERCLI_PATH\": \"/absolute/path/to/qodercli\"\n      }\n    }\n  }\n}\n```\n\n## Tool: `ask-qoder`\n\n| Parameter | Type | Description |\n|---|---|---|\n| `prompt` | string (required) | The task or question for qodercli |\n| `cwd` | string | Working directory |\n| `model` | string | Model for this session; call `list-models` to discover available names |\n| `reasoning_effort` | string | Reasoning effort level (`--reasoning-effort`), e.g. `low`/`medium`/`high`; depends on the model |\n| `permission_mode` | enum | `dont_ask` (default, **read-only**) \\| `accept_edits` (auto-approve file edits) \\| `bypass_permissions` (full access incl. shell) \\| `auto` \\| `default`; mutually exclusive with `approval_policy`, prefer `sandbox` |\n| `approval_policy` | enum | codex-style: `untrusted`→read-only \\| `on-request`→auto \\| `never`→full access |\n| `sandbox` | enum | `read-only` \\| `workspace-write` \\| `danger-full-access` (codex-style; controls the effective permission mode) |\n| `system_prompt` | string | Replace the default system prompt |\n| `append_system_prompt` | string | Append instructions to the default system prompt |\n| `resume_session_id` | string | Resume a previous session |\n| `output_format` | string | Passed to `-o` (default `json`). Note: non-json formats degrade structured output (`session_id` etc. become unavailable) |\n| `extra_args` | string[] | Raw CLI args appended before the prompt; reserved flags (permission mode, system prompt, model, `-o`, `-r`, `-w`...) are rejected |\n| `timeout_ms` | number | Timeout in ms, default 600000 |\n\n### Structured output\n\n`ask-qoder` declares an MCP `outputSchema` and returns, in addition to the\nhuman-readable text, a `structuredContent` object:\n\n```json\n{\n  \"session_id\": \"77826b5c-...\",   // pass back as resume_session_id\n  \"content\": \"OK\",\n  \"is_error\": false,\n  \"exit_code\": 0,\n  \"duration_ms\": 1280,\n  \"total_credits\": 0.53,\n  \"num_turns\": 1,\n  \"timed_out\": false,\n  \"truncated\": false\n}\n```\n\n### Sandbox mapping\n\n| sandbox | Effective permission mode | Effect on qodercli |\n|---|---|---|\n| (omitted) | `dont_ask` | Read-only: permission-requiring tools are silently denied |\n| `read-only` | `dont_ask` | Plus `--disallowed-tools write_file,replace,run_shell_command` as defense in depth |\n| `workspace-write` | `accept_edits` | Agent can create/modify files in `cwd` |\n| `danger-full-access` | `bypass_permissions` | Full access including shell |\n\nExplicit `permission_mode` or `approval_policy` always wins over `sandbox`.\n\n### Permission modes (verified semantics)\n\n| Mode | Behavior |\n|---|---|\n| `dont_ask` | **Read-only**: silently denies every tool call that requires permission. Headless-safe default |\n| `accept_edits` | Auto-approves file edits; shell still governed by policy |\n| `bypass_permissions` | Auto-approves everything including shell |\n| `auto` | qodercli's own automatic policy |\n| `default` | Interactive confirmation — not headless-friendly, avoid in MCP calls |\n\n## Tool: `list-sessions`\n\nLists local qodercli sessions (index, summary, session id) so a client can\npick a `resume_session_id`. Takes no arguments.\n\n## Tool: `list-models`\n\nLists models currently supported by qodercli (via `--list-models`), so a\nclient can pick a valid `model` value at runtime instead of relying on\nstale knowledge. Returns both a text list and a structured `models` array.\nTakes no arguments.\n\n### Usage Examples\n\n#### Example 1: Simple code explanation\n```javascript\n{ \"name\": \"ask-qoder\", \"arguments\": { \n  \"prompt\": \"Explain what main.py does\",\n  \"cwd\": \"/path/to/project\",\n  \"timeout_ms\": 180000 \n}}\n```\n\n#### Example 2: Ask a second opinion\n```javascript\n{ \"name\": \"ask-qoder\", \"arguments\": { \n  \"prompt\": \"@src/service.py Review this file for security issues and suggest improvements\",\n  \"model\": \"qwen-plus\",\n  \"permission_mode\": \"dont_ask\",\n  \"timeout_ms\": 300000 \n}}\n```\n\n#### Example 3: Multi-turn conversation via resume\n```javascript\n// First call — session_id comes back in structuredContent\n{ \"name\": \"ask-qoder\", \"arguments\": {\n  \"prompt\": \"Help me refactor this module to improve readability\",\n  \"cwd\": \"/projects/backend\",\n  \"timeout_ms\": 300000 \n}}\n// Then reuse structuredContent.session_id:\n{ \"name\": \"ask-qoder\", \"arguments\": {\n  \"prompt\": \"Now add error handling for database timeouts\",\n  \"resume_session_id\": \"77826b5c-cd6b-4213-b423-d95b4e1deab0\"\n}}\n// Or discover ids with list-sessions\n{ \"name\": \"list-sessions\", \"arguments\": {} }\n```\n\n#### Example 4: Code review with specific focus\n```javascript\n{ \"name\": \"ask-qoder\", \"arguments\": {\n  \"prompt\": \"Analyze performance bottlenecks in utils.py\",\n  \"model\": \"qwen-max\",\n  \"permission_mode\": \"default\",\n  \"output_format\": \"text\",\n  \"timeout_ms\": 240000 \n}}\n```\n\n#### Example 5: Read-only analysis\n```javascript\n{ \"name\": \"ask-qoder\", \"arguments\": {\n  \"prompt\": \"Audit this codebase for security issues; do not modify anything\",\n  \"cwd\": \"/workspaces/repo\",\n  \"sandbox\": \"read-only\",\n  \"timeout_ms\": 300000 \n}}\n```\n`read-only` disables write/shell tools — good for audits and reviews.\n\n#### Example 6: Project-wide analysis\n```javascript\n{ \"name\": \"ask-qoder\", \"arguments\": {\n  \"prompt\": \"Summarize the architecture of this project and identify key modules\",\n  \"cwd\": \"/workspaces/repo\",\n  \"timeout_ms\": 420000,\n  \"model\": \"qwen-plus\"\n}}\n```\n\n### Best Practices\n\n1. **Specify working directory** — Always pass `cwd` when operating on a specific project\n2. **Use timeout protection** — For complex prompts, set explicit `timeout_ms` shorter than 60min\n3. **Resume for multi-turn** — Chain follow-ups via `resume_session_id` instead of repeating context\n4. **Model selection** — Call `list-models` first to discover currently supported models; larger models are better for deep analysis\n5. **Permission mode** — The server default is read-only (`dont_ask`); set `QODERCLI_DEFAULT_PERMISSION_MODE=bypass_permissions` to make full (YOLO) access the default for personal deployments. Per-call: tasks that must create/modify files need `sandbox: \"workspace-write\"`; shell access needs `danger-full-access`. Do not combine `sandbox` with an explicit `permission_mode` (the latter wins)\n\n## Environment variables\n\n| Variable | Default | Description |\n|---|---|---|\n| `QODERCLI_PATH` | `qodercli` | Path to the qodercli binary |\n| `QODERCLI_TIMEOUT_MS` | `600000` | Default timeout |\n| `QODERCLI_MAX_OUTPUT_MB` | `50` | Per-call stdout/stderr cap in MB (OOM protection) |\n| `QODERCLI_DEFAULT_PERMISSION_MODE` | `dont_ask` | Default permission mode when the caller omits permission_mode/approval_policy/sandbox; set `bypass_permissions` for full (YOLO) access |\n| `HTTP_PROXY` | - | HTTP proxy URL for qodercli |\n| `HTTPS_PROXY` | - | HTTPS proxy URL for qodercli |\n\n## Development\n\n```bash\nnpm test        # smoke test: protocol handshake + tool invocation\nnode src/index.js   # run the server manually (stdio)\n```\n\n## Disclaimer\n\nThis is an unofficial, third-party tool. It is not affiliated with, endorsed, or sponsored by Qoder. Use `permission_mode: bypass_permissions` with care — delegated prompts may modify files in the target working directory.\n\n## Product Hunt Gallery\n\nMain gallery image (**1270×760**, dark tech theme): [ph-gallery.png](docs/ph-gallery.png). Optional demo video can be converted from the GIF (`docs/demo.gif`).\n\n## License\n\nMIT\n",
  "bytes": 12168,
  "sha": "aecc1cb9dfd1aa973681f81f74087fe9e73be96baa9d4265460f362130da1636",
  "repo_slug": "cantbeblank96/qodercli-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_cantbeblank96_qodercli_mcp_e1f47425/readme"
}