From 454efc391ba5815f84ea0c438d1c37b8513a1fc8 Mon Sep 17 00:00:00 2001 From: Alfonso de la Guarda Reyes Date: Tue, 9 Dec 2025 01:57:24 -0500 Subject: [PATCH] feat(server): expose Qwen agent in MCP server - Add QwenCLI import and integration - Create check_qwen_availability() tool - Create qwen_subagent() tool with streaming support - Update valid_subagents to include 'qwen' - Update default configuration to include Qwen - Update CLI help and examples - Update README.md with Qwen documentation Closes #1 --- AGENTS.md | 417 ++++++++++++++++++++++++++++++++ README.md | 6 +- roundtable_mcp_server/server.py | 208 +++++++++++++++- 3 files changed, 620 insertions(+), 11 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..b656d7f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,417 @@ +# AI Agents Guide + +This document provides core principles for AI coding assistants. + +## Core Principles + +### Universal Standards +- **Language**: + - Code, comments, and documentation: **English only** + - Agent communication with user: **Spanish only** + - GitLab/Linear issues: **Spanish only** + - Multilingual projects: **Must use i18n** (according to specs) +- **Commits**: Clear, descriptive commit messages using conventional commits +- **Naming**: Descriptive, self-documenting names +- **Comments**: Explain "why" not "what" - code should be self-explanatory +- **Modification First**: Always modify existing files before creating new ones +- **Documentation**: Only generate for major features, not every small change +- **MCP Tools**: Use available MCP tools for every task +- **Verification**: Always verify changes before declaring completion +- **Memory**: Save all important information to Mem0 +- **Context7**: Always use Context7 for library documentation +- **Task Tracking**: Track all tasks in GitLab +- **Autonomy**: Complete tasks without asking for confirmation at each step + +### Development Principles + +**Package Management:** +- Always use **stable and latest versions** of packages +- Avoid beta, alpha, or experimental versions unless explicitly requested +- Check for security updates and compatibility + +**Infrastructure & Monitoring:** +- Monitoring tools (Prometheus, Grafana, etc.) are **OPTIONAL** - only add if explicitly requested +- Docker/Docker Compose are **OPTIONAL** - only use if explicitly requested, prefer local services +- Keep infrastructure simple and minimal by default +- Mark infrastructure additions as **optional** in GitLab issues + +**Version Control & CI/CD:** +- **Default platform**: GitLab (repository, issues, CI/CD pipelines) +- Use GitLab CI/CD tools by default (.gitlab-ci.yml) +- GitHub is **OPTIONAL** - only use if explicitly requested +- Never recommend GitHub unless specifically asked + +**Architecture Improvements:** +- Architecture improvements are **OPTIONAL** - never mandatory +- Must be marked as **optional** in GitLab issues +- Only implement if explicitly requested or approved +- Document why improvements are optional in issue description + +### Agent Autonomy - CRITICAL + +**CRITICAL: Complete tasks autonomously without stopping for confirmation** + +**You MUST:** +- ✅ Complete the entire task from start to finish +- ✅ Make all necessary decisions autonomously +- ✅ Create, modify, and commit files as needed +- ✅ Run tests and fix issues without asking +- ✅ Update documentation when required +- ✅ Deploy changes if part of the task +- ✅ Work through errors and find solutions +- ✅ Continue until task is fully complete + +**You MUST NOT:** +- ❌ Stop to ask for confirmation at each step +- ❌ Ask permission to create/modify files in project directory +- ❌ Ask permission to run tests or commands +- ❌ Ask permission to commit changes +- ❌ Ask permission to update documentation +- ❌ Stop when encountering errors (fix them) +- ❌ Ask "should I continue?" or "shall I proceed?" + +**ONLY ask for confirmation when:** +- ⚠️ Deleting files outside the project directory +- ⚠️ Making changes to production systems +- ⚠️ Modifying critical infrastructure +- ⚠️ Changing security configurations +- ⚠️ Deleting databases or data + +**Example - Bad (asking unnecessarily):** +``` +❌ "I've created the login component. Should I continue with the tests?" +❌ "I found an error. Should I fix it?" +❌ "The tests are failing. Should I investigate?" +❌ "Should I commit these changes?" +❌ "Should I update the documentation?" +``` + +**Example - Good (autonomous completion):** +``` +✅ "Task completed: + - Created login component + - Added unit tests (all passing) + - Fixed linting errors + - Updated documentation + - Committed changes + - Updated GitLab issue #123" +``` + +**Workflow:** +1. Understand the complete task +2. Plan all necessary steps +3. Execute all steps autonomously +4. Fix any issues encountered +5. Verify everything works +6. Complete all documentation +7. Report completion with summary + +**Within project directory, you can:** +- Create any files +- Modify any files +- Delete files (part of refactoring) +- Run any commands +- Install dependencies +- Run tests +- Commit changes +- Push changes +- Create branches +- Create merge requests + +**Only stop and ask when:** +- Deleting files outside project (e.g., ~/.config/, /etc/) +- Modifying system files +- Changing production databases +- Deleting production data +- Changing security policies + +### Critical MCP Tools - MANDATORY + +**Must use every time:** +- **Context7**: For ANY documentation query (never use training data) +- **Mem0**: Save ALL important information (not available in Copilot CLI - use other agents) +- **GitLab MCP**: Track ALL tasks (if not available, use `glab` CLI) +- **Sentry**: Integrate in ALL applications + +**Must use for UI:** +- **Playwright**: Testing and automation +- **Chrome DevTools**: Debugging and inspection + +**Must use for complex problems:** +- **Sequential Thinking**: Step-by-step reasoning + +**Note**: GitHub Copilot CLI has a known bug with MCP environment variables. GitLab MCP and Mem0 don't work in Copilot CLI. Use `glab` CLI as fallback for GitLab operations in Copilot CLI. This issue does NOT affect other agents. + +**See ~/Documentos/prompts/MCP_TOOLS.md for complete guide** + +### Commit Message Format + +```bash +(): + + + +Closes # +``` + +**Types**: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` + +**Example:** +```bash +feat(auth): implement OAuth2 login + +Adds JWT token generation and validation. + +Closes #456 +``` + +## Working Philosophy + +### Modify Before Create +- Always check if file exists before creating new one +- Extend existing functions/classes rather than duplicating +- Refactor existing code to accommodate new features +- Only create new files when absolutely necessary + +### Documentation Strategy +- Commit messages are primary documentation +- Code comments for complex logic only +- Generate documentation only for: + - Major features or milestones + - New public APIs + - Significant refactoring + - When explicitly requested +- Update existing docs when modifying behavior + +## Task Management - MANDATORY + +**CRITICAL: Create and track ALL tasks in GitLab** + +**Default Platform: GitLab** +- All issues, merge requests, and CI/CD in GitLab +- **Prefer GitLab MCP** for operations (if available) +- **Fallback to `glab` CLI** if GitLab MCP not available +- GitHub is only used if explicitly requested + +### Quick Workflow + +1. **Create GitLab issue** (technical tracking) + - Get GitLab ID (e.g., #456) + +2. **Work and commit** + ```bash + git commit -m "feat: implement feature + + Closes #456" + ``` + +3. **Close issue** + - GitLab closes via commit + +**See ~/Documentos/prompts/TASK_MANAGEMENT.md for complete workflow** + +## UI Development - MANDATORY + +**CRITICAL: Always use Playwright and Chrome DevTools for UI work** + +### Quick Workflow + +1. **Playwright**: Automate and test + - Write tests for user flows + - Verify UI behavior + - Test responsive design + - Capture screenshots + +2. **Chrome DevTools**: Inspect and debug + - Check console errors + - Monitor network requests + - Inspect element styles + - Profile performance + +3. **Verify before completing** + - All tests pass + - No console errors + - Responsive works + - Accessibility passes + +**See ~/Documentos/prompts/UI_TESTING.md for complete guide** + +## CI/CD Monitoring - MANDATORY + +**CRITICAL: Monitor pipeline status for all changes** + +**Default: GitLab CI/CD** +- Use GitLab CI/CD pipelines (.gitlab-ci.yml) +- Monitor GitLab pipeline status +- GitHub Actions only if explicitly requested + +### Quick Workflow + +1. **After push**: Check pipeline triggered +2. **During pipeline**: Monitor job status +3. **If failure**: Fix immediately +4. **After success**: Update issues with pipeline link +5. **After deployment**: Document in issues + +**See ~/Documentos/prompts/CICD.md for complete guide** + +## Verification Requirements + +Before declaring task complete: + +**Code Changes:** +- [ ] Tests pass (unit + integration) +- [ ] Linting passes +- [ ] Code formatted correctly +- [ ] No console errors/warnings + +**Documentation:** +- [ ] Context7 used for all library docs +- [ ] Important info saved to Mem0 +- [ ] Commit messages descriptive + +**Task Tracking:** +- [ ] GitLab issue created and updated +- [ ] Status synchronized + +**UI Work (if applicable):** +- [ ] Playwright tests pass +- [ ] Chrome DevTools checks pass +- [ ] Responsive design verified +- [ ] Accessibility verified + +**CI/CD:** +- [ ] Pipeline passes +- [ ] All jobs successful +- [ ] Deployment successful (if applicable) +- [ ] Pipeline linked in issues + +## Quick Reference + +### Before Starting +1. Query Mem0 for project context +2. Check Context7 for library docs +3. Review GitLab issues +4. Verify current patterns + +### During Work +1. Use Context7 for API references +2. Use Sequential Thinking for complex logic +3. Use Playwright/Chrome DevTools for UI +4. Save decisions to Mem0 + +### After Completing +1. Update GitLab issues +2. Save patterns to Mem0 +3. Verify pipeline passes +4. Document deployment + +### When Stuck +1. Query Mem0 for similar problems +2. Use Roundtable for other perspectives +3. Use Perplexity for research +4. Use Context7 for documentation + +## Specialized Guides + +For detailed information on specific topics: + +### MCP Tools +- **~/Documentos/prompts/MCP_TOOLS.md** - Complete guide to all 14 MCP tools + - Context7, Mem0, Playwright, Chrome DevTools + - GitLab, Sentry, SSH, Perplexity + - Tool combinations and patterns + - Copilot CLI limitations and workarounds + +### Task Management +- **~/Documentos/prompts/TASK_MANAGEMENT.md** - GitLab workflow + - Dual tracking process + - Issue creation and linking + - Status synchronization + - Commit message format + +### UI Testing +- **~/Documentos/prompts/UI_TESTING.md** - Playwright + Chrome DevTools + - UI testing patterns + - Debugging techniques + - Verification checklist + - Common scenarios + +### CI/CD +- **~/Documentos/prompts/CICD.md** - Pipeline monitoring + - Pipeline tracking + - Failure handling + - Deployment procedures + - Rollback process + +### Error Tracking +- **~/Documentos/prompts/SENTRY.MD** - Sentry integration (MANDATORY) + - SDK installation + - Configuration + - Error capture + - Performance monitoring + +### Programming Languages +- **~/Documentos/prompts/TYPESCRIPT.MD** - TypeScript/Node.js/Bun +- **~/Documentos/prompts/PYTHON.MD** - Python development +- **~/Documentos/prompts/GO.MD** - Go development +- **~/Documentos/prompts/RUST.MD** - Rust development + +### Frameworks & UI +- **~/Documentos/prompts/REACT.MD** - React development +- **~/Documentos/prompts/REACT_NATIVE.MD** - React Native +- **~/Documentos/prompts/ANGULAR.MD** - Angular development + +### Architecture & Patterns +- **~/Documentos/prompts/EDA.MD** - Event-Driven Architecture +- **~/Documentos/prompts/BDS.MD** - Backend Design Systems +- **~/Documentos/prompts/LLM.MD** - LLM integration + +### Testing & Quality +- **~/Documentos/prompts/TESTING_ADV.MD** - Advanced testing +- **~/Documentos/prompts/TROUBLESHOOTING.MD** - Debugging strategies + +### Project Management +- **~/Documentos/prompts/NEW_TASK.MD** - Starting new tasks +- **~/Documentos/prompts/TECHNICAL_DEBT.MD** - Managing technical debt +- **~/Documentos/prompts/GENERAL.MD** - General guidelines + +### Configuration +- **~/Documentos/prompts/AGENTS_CONFIG.md** - Complete agent configuration reference + - All 21 agents with MCP config paths + - Configuration formats by agent + - Quick update commands + +## Usage Guidelines + +- **Always consult specialized guide** when working in specific domain +- **Follow domain-specific patterns** from specialized guides +- **Use AGENTS.md** as starting point and quick reference +- **Refer to detailed guides** for complete workflows + +## GitHub Copilot CLI Specific Notes + +**File Location:** +- Copilot CLI reads `AGENTS.md` from **current directory** +- For IDEs (VS Code, etc.), use `.github/copilot-instructions.md` + +**Known Limitations:** +- MCP servers requiring environment variables don't work (bug in v1.2.0) +- Affected: mem0, gitlab MCP +- Working: All other 11 MCP servers + +**Workarounds:** +- **GitLab**: Prefer GitLab MCP (works in other agents), fallback to `glab` CLI in Copilot CLI + ```bash + glab issue list + glab issue create + glab mr list + ``` +- **Mem0**: Use other agents (Kiro, Claude Desktop, VS Code) + +--- + +**Last Updated**: 2025-12-07 +**Maintained By**: Alfonso De Gennaro +**Total Agents**: 21 (17 local + 4 remote) +**MCP Servers**: 14 functional diff --git a/README.md b/README.md index d34516b..80ca880 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Stop copy-pasting between AI models. Roundtable AI is a local MCP server that le **Key Features:** - **Context Continuity**: Shared project context across all sub-agents - **Parallel Execution**: All agents work simultaneously -- **Model Specialization**: Right AI for each task (Gemini's 1M context, Claude's reasoning, Codex's implementation) +- **Model Specialization**: Right AI for each task (Gemini's 1M context, Claude's reasoning, Codex's implementation, Qwen's code generation) - **Zero Markup**: Uses your existing CLI tools and API subscriptions - **26+ IDE Support**: Works with Claude Code, Cursor, VS Code, JetBrains, and more @@ -41,12 +41,12 @@ roundtable-ai --check roundtable-ai # Use specific assistants only -roundtable-ai --agents codex,claude +roundtable-ai --agents codex,claude,qwen ``` **One-liner for Claude Code:** ```bash -claude mcp add roundtable-ai -- roundtable-ai --agents gemini,claude,codex,cursor +claude mcp add roundtable-ai -- roundtable-ai --agents gemini,claude,codex,cursor,qwen ``` **Try this multi-agent prompt in your IDE:** diff --git a/roundtable_mcp_server/server.py b/roundtable_mcp_server/server.py index ff0d02e..442e169 100644 --- a/roundtable_mcp_server/server.py +++ b/roundtable_mcp_server/server.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Roundtable AI MCP Server. -This MCP server exposes CLI subagents (Codex, Claude, Cursor, Gemini) via the MCP protocol. +This MCP server exposes CLI subagents (Codex, Claude, Cursor, Gemini, Qwen) via the MCP protocol. It supports stdio transport for integration with any MCP-compatible client. Developed by Roundtable AI for seamless AI assistant integration. @@ -69,6 +69,7 @@ def _import_module_item(module_name: str, item_name: str): from claudable_helper.cli.adapters.claude_code import ClaudeCodeCLI from claudable_helper.cli.adapters.cursor_agent import CursorAgentCLI from claudable_helper.cli.adapters.gemini_cli import GeminiCLI + from claudable_helper.cli.adapters.qwen_cli import QwenCLI CLI_ADAPTERS_AVAILABLE = True except ImportError as e: logger.warning(f"CLI adapters not available for direct import: {e}") @@ -87,7 +88,7 @@ class SubagentConfig(BaseModel): class ServerConfig(BaseModel): """Configuration for the MCP server.""" subagents: List[str] = Field( - default_factory=lambda: ["codex", "claude", "cursor", "gemini"], + default_factory=lambda: ["codex", "claude", "cursor", "gemini", "qwen"], description="List of subagents to enable" ) working_dir: Optional[str] = Field( @@ -126,7 +127,7 @@ def parse_config_from_env() -> ServerConfig: if subagents_env: # Environment variable override - use specified subagents subagents = [s.strip().lower() for s in subagents_env.split(",") if s.strip()] - valid_subagents = {"codex", "claude", "cursor", "gemini"} + valid_subagents = {"codex", "claude", "cursor", "gemini", "qwen"} config.subagents = [s for s in subagents if s in valid_subagents] config.verbose = os.getenv("CLI_MCP_VERBOSE", "false").lower() in ("true", "1", "yes", "on") logger.info(f"Verbose: {config.verbose}") @@ -137,7 +138,7 @@ def parse_config_from_env() -> ServerConfig: logger.info(f"Using subagents from environment variable: {config.subagents}") elif ignore_availability: # Ignore availability cache and enable all subagents - config.subagents = ["codex", "claude", "cursor", "gemini"] + config.subagents = ["codex", "claude", "cursor", "gemini", "qwen"] logger.info("Ignoring availability cache - enabling all subagents") else: # Use availability cache to determine enabled subagents @@ -151,7 +152,7 @@ def parse_config_from_env() -> ServerConfig: # Fallback to default if no availability data logger.warning("No availability data found, falling back to default subagents") logger.warning("Run 'python -m roundtable_mcp_server.availability_checker --check' to check CLI availability") - config.subagents = ["codex", "claude", "cursor", "gemini"] + config.subagents = ["codex", "claude", "cursor", "gemini", "qwen"] # Parse working directory working_dir = os.getenv("CLI_MCP_WORKING_DIR") @@ -288,6 +289,30 @@ async def check_gemini_availability(ctx: Context = None) -> str: return f"❌ {error_msg}" +@server.tool() +async def check_qwen_availability(ctx: Context = None) -> str: + """ + Check if Qwen CLI is available and configured properly. + + Returns: + Status message about Qwen availability + """ + if "qwen" not in enabled_subagents: + return "❌ Qwen subagent is not enabled in this server instance" + + logger.info("Checking Qwen availability") + + try: + check_qwen = _import_module_item("cli_subagent", "check_qwen_availability") + result = await check_qwen() + logger.debug(f"Qwen availability result: {result}") + return result + except Exception as e: + error_msg = f"Error checking Qwen availability: {str(e)}" + logger.error(error_msg, exc_info=True) + return f"❌ {error_msg}" + + @server.tool() async def codex_subagent( instruction: str, @@ -970,6 +995,173 @@ async def gemini_subagent( return f"❌ {error_msg}" +@server.tool() +async def qwen_subagent( + instruction: str, + project_path: Optional[str] = None, + session_id: Optional[str] = None, + model: Optional[str] = None, + is_initial_prompt: bool = False, + ctx: Context = None +) -> str: + """ + Execute a coding task using Qwen CLI agent. + + Qwen has access to file operations, shell commands, web search, + and can make code changes directly. It's ideal for implementing features, + fixing bugs, refactoring code, and other development tasks. + + IMPORTANT: Always provide an absolute path for project_path to ensure proper execution. + If you don't provide project_path, the current working directory will be used. + + Args: + instruction: The coding task or instruction to execute + project_path: ABSOLUTE path to the project directory (e.g., '/home/user/myproject'). If not provided, uses current working directory. + session_id: Optional session ID for conversation continuity + model: Optional model to use ('qwen-coder' is the default model) + is_initial_prompt: Whether this is the first prompt in a new session + + Returns: + Summary of what the Qwen agent accomplished + """ + if "qwen" not in enabled_subagents: + return "❌ Qwen subagent is not enabled in this server instance" + + if not CLI_ADAPTERS_AVAILABLE: + # Fallback to old method if CLI adapters not available + try: + qwen_exec = _import_module_item("cli_subagent", "qwen_subagent") + result = await qwen_exec( + instruction=instruction, + project_path=project_path, + session_id=session_id, + model=model, + images=None, + is_initial_prompt=is_initial_prompt + ) + return result + except Exception as e: + error_msg = f"Error executing Qwen subagent: {str(e)}" + logger.error(error_msg, exc_info=True) + return f"❌ {error_msg}" + + # Robust path validation and fallback + if not project_path or project_path.strip() == "": + project_path = str(working_dir.absolute()) if working_dir else str(Path.cwd().absolute()) + logger.debug(f"Using fallback directory: {project_path}") + else: + # Ensure we have an absolute path + project_path = str(Path(project_path).absolute()) + logger.debug(f"Using provided project path: {project_path}") + + # Validate the directory exists + if not Path(project_path).exists(): + error_msg = f"Project directory does not exist: {project_path}" + logger.error(error_msg) + return f"❌ {error_msg}" + + logger.info(f"Qwen: {model} [INSTRUCTION]: {instruction}") + logger.debug(f"[MCP-TOOL] qwen_subagent started - project_path: {project_path}, model: {model}, session_id: {session_id}") + + try: + # Initialize QwenCLI directly + qwen_cli = QwenCLI() + + # Check if Qwen is available + availability = await qwen_cli.check_availability() + if not availability.get("available", False): + error_msg = availability.get("error", "Qwen CLI not available") + logger.error(f"Qwen unavailable: {error_msg}") + return f"❌ Qwen CLI not available: {error_msg}" + + # Collect all messages from streaming execution with progress reporting + messages = [] + agent_responses = [] + tool_uses = [] + message_count = 0 + logger.info(f"Qwen subagent execution started :verbose={config.verbose}") + logger.debug(f"[MCP-TOOL] Qwen CLI streaming started - will process messages and report progress") + + async for message in qwen_cli.execute_with_streaming( + instruction=instruction, + project_path=project_path, + session_id=session_id, + model=model, + images=None, + is_initial_prompt=is_initial_prompt + ): + message_count += 1 + messages.append(message) + + # Get message type as string + msg_type = getattr(message, "message_type", None) + msg_type_str = getattr(msg_type, "value", str(msg_type)) + + # Get content with fallback + content = getattr(message, "content", "") + content_preview = str(content)[:100] if content else "" + + # Progress reporting with debug logging + progress_message = f"Qwen #{message_count}: {msg_type_str} => {content}" + logger.debug(f"[PROGRESS] {progress_message}") + await ctx.report_progress( + progress=message_count, + total=None, + message=progress_message + ) + + # Categorize messages for summary + if hasattr(message, 'role') and message.role == "assistant": + if message.content and message.content.strip(): + agent_responses.append(message.content.strip()) + elif msg_type_str == "tool_use": + tool_uses.append(message.content) + elif msg_type_str == "tool_result": + tool_uses.append(f"Tool result: {message.content}") + elif msg_type_str == "error": + logger.error(f"Qwen error: {message.content}") + return f"❌ Qwen execution failed: {message.content}" + elif msg_type_str == "result": + logger.debug(f"Qwen result: {message.content}, not adding to agent_responses") + else: + # Capture any other message types that might contain useful content + if message.content and str(message.content).strip(): + agent_responses.append(str(message.content).strip()) + + # Create comprehensive summary + summary_parts = [] + + if agent_responses: + if len(agent_responses) == 1: + summary_parts.append(f"**Qwen Response:**\n{agent_responses[0]}") + else: + combined_response = "\n\n".join(agent_responses) + summary_parts.append(f"**Qwen Response:**\n{combined_response}") + + if tool_uses: + summary_parts.append(f"🔧 **Tools Used ({len(tool_uses)}):**") + for tool_use in tool_uses: + summary_parts.append(f"• {tool_use}") + + if not summary_parts: + summary_parts.append("✅ Qwen task completed successfully (no detailed output captured)") + + summary = "\n\n".join(summary_parts) + + logger.info("Qwen subagent execution completed") + logger.debug(f"[MCP-TOOL] Qwen execution completed - total messages: {message_count}, agent_responses: {len(agent_responses)}, tool_uses: {len(tool_uses)}") + logger.debug(f"Result summary: {summary}") + + final_response = summary if config.verbose else (agent_responses[-1] if agent_responses else "✅ Qwen task completed successfully") + logger.info(f"[TOOL-RESPONSE] Qwen final response: {final_response}") + return final_response + + except Exception as e: + error_msg = f"Error executing Qwen subagent: {str(e)}" + await ctx.error(error_msg) + return f"❌ {error_msg}" + + @server.tool() async def test_tool(context: Context,signal: bool = True) -> Any: """ @@ -1035,10 +1227,10 @@ def main(): Examples: python -m roundtable_mcp_server # Start MCP server with auto-detected agents python -m roundtable_mcp_server --check # Check CLI availability - python -m roundtable_mcp_server --agents codex,gemini # Start with specific agents + python -m roundtable_mcp_server --agents codex,gemini,qwen # Start with specific agents Environment Variables: - CLI_MCP_SUBAGENTS Comma-separated list of subagents (codex,claude,cursor,gemini) + CLI_MCP_SUBAGENTS Comma-separated list of subagents (codex,claude,cursor,gemini,qwen) CLI_MCP_WORKING_DIR Default working directory CLI_MCP_DEBUG Enable debug logging (true/false) CLI_MCP_IGNORE_AVAILABILITY Ignore availability cache (true/false) @@ -1058,7 +1250,7 @@ def main(): parser.add_argument( "--agents", type=str, - help="Comma-separated list of agents to enable (codex,claude,cursor,gemini)" + help="Comma-separated list of agents to enable (codex,claude,cursor,gemini,qwen)" ) args = parser.parse_args()