diff --git a/docs/users/features/_meta.ts b/docs/users/features/_meta.ts index 5f82838e..5509cc74 100644 --- a/docs/users/features/_meta.ts +++ b/docs/users/features/_meta.ts @@ -6,6 +6,7 @@ export default { display: 'hidden', }, 'approval-mode': 'Approval Mode', + mcp: 'MCP', 'token-caching': 'Token Caching', sandbox: 'Sandboxing', }; diff --git a/docs/users/features/mcp.md b/docs/users/features/mcp.md new file mode 100644 index 00000000..77fcea45 --- /dev/null +++ b/docs/users/features/mcp.md @@ -0,0 +1,284 @@ +# Connect Qwen Code to tools via MCP + +Qwen Code can connect to external tools and data sources through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction). MCP servers give Qwen Code access to your tools, databases, and APIs. + +## What you can do with MCP + +With MCP servers connected, you can ask Qwen Code to: + +- Work with files and repos (read/search/write, depending on the tools you enable) +- Query databases (schema inspection, queries, reporting) +- Integrate internal services (wrap your APIs as MCP tools) +- Automate workflows (repeatable tasks exposed as tools/prompts) + +> [!tip] +> If you’re looking for the “one command to get started”, jump to [Quick start](#quick-start). + +## Quick start + +Qwen Code loads MCP servers from `mcpServers` in your `settings.json`. You can configure servers either: + +- By editing `settings.json` directly +- By using `qwen mcp` commands (see [CLI reference](#qwen-mcp-cli)) + +### Add your first server + +1. Add a server (example: remote HTTP MCP server): + +```bash +qwen mcp add --transport http my-server http://localhost:3000/mcp +``` + +2. Verify it shows up: + +```bash +qwen mcp list +``` + +3. Restart Qwen Code in the same project (or start it if it wasn’t running yet), then ask the model to use tools from that server. + +## Where configuration is stored (scopes) + +Most users only need these two scopes: + +- **Project scope (default)**: `.qwen/settings.json` in your project root +- **User scope**: `~/.qwen/settings.json` across all projects on your machine + +Write to user scope: + +```bash +qwen mcp add --scope user --transport http my-server http://localhost:3000/mcp +``` + +> [!tip] +> For advanced configuration layers (system defaults/system settings and precedence rules), see [Settings](/users/configuration/settings). + +## Configure servers + +### Choose a transport + +| Transport | When to use | JSON field(s) | +| --------- | ----------------------------------------------------------------- | ------------------------------------------- | +| `http` | Recommended for remote services; works well for cloud MCP servers | `httpUrl` (+ optional `headers`) | +| `sse` | Legacy/deprecated servers that only support Server-Sent Events | `url` (+ optional `headers`) | +| `stdio` | Local process (scripts, CLIs, Docker) on your machine | `command`, `args` (+ optional `cwd`, `env`) | + +> [!note] +> If a server supports both, prefer **HTTP** over **SSE**. + +### Configure via `settings.json` vs `qwen mcp add` + +Both approaches produce the same `mcpServers` entries in your `settings.json`—use whichever you prefer. + +#### Stdio server (local process) + +JSON (`.qwen/settings.json`): + +```json +{ + "mcpServers": { + "pythonTools": { + "command": "python", + "args": ["-m", "my_mcp_server", "--port", "8080"], + "cwd": "./mcp-servers/python", + "env": { + "DATABASE_URL": "$DB_CONNECTION_STRING", + "API_KEY": "${EXTERNAL_API_KEY}" + }, + "timeout": 15000 + } + } +} +``` + +CLI (writes to project scope by default): + +```bash +qwen mcp add pythonTools -e DATABASE_URL=$DB_CONNECTION_STRING -e API_KEY=$EXTERNAL_API_KEY \ + --timeout 15000 python -m my_mcp_server --port 8080 +``` + +#### HTTP server (remote streamable HTTP) + +JSON: + +```json +{ + "mcpServers": { + "httpServerWithAuth": { + "httpUrl": "http://localhost:3000/mcp", + "headers": { + "Authorization": "Bearer your-api-token" + }, + "timeout": 5000 + } + } +} +``` + +CLI: + +```bash +qwen mcp add --transport http httpServerWithAuth http://localhost:3000/mcp \ + --header "Authorization: Bearer your-api-token" --timeout 5000 +``` + +#### SSE server (remote Server-Sent Events) + +JSON: + +```json +{ + "mcpServers": { + "sseServer": { + "url": "http://localhost:8080/sse", + "timeout": 30000 + } + } +} +``` + +CLI: + +```bash +qwen mcp add --transport sse sseServer http://localhost:8080/sse --timeout 30000 +``` + +## Safety and control + +### Trust (skip confirmations) + +- **Server trust** (`trust: true`): bypasses confirmation prompts for that server (use sparingly). + +### Tool filtering (allow/deny tools per server) + +Use `includeTools` / `excludeTools` to restrict tools exposed by a server (from Qwen Code’s perspective). + +Example: include only a few tools: + +```json +{ + "mcpServers": { + "filteredServer": { + "command": "python", + "args": ["-m", "my_mcp_server"], + "includeTools": ["safe_tool", "file_reader", "data_processor"], + "timeout": 30000 + } + } +} +``` + +### Global allow/deny lists + +The `mcp` object in your `settings.json` defines global rules for all MCP servers: + +- `mcp.allowed`: allow-list of MCP server names (keys in `mcpServers`) +- `mcp.excluded`: deny-list of MCP server names + +Example: + +```json +{ + "mcp": { + "allowed": ["my-trusted-server"], + "excluded": ["experimental-server"] + } +} +``` + +## Troubleshooting + +- **Server shows “Disconnected” in `qwen mcp list`**: verify the URL/command is correct, then increase `timeout`. +- **Stdio server fails to start**: use an absolute `command` path, and double-check `cwd`/`env`. +- **Environment variables in JSON don’t resolve**: ensure they exist in the environment where Qwen Code runs (shell vs GUI app environments can differ). + +## Reference + +### `settings.json` structure + +#### Server-specific configuration (`mcpServers`) + +Add an `mcpServers` object to your `settings.json` file: + +```json +// ... file contains other config objects +{ + "mcpServers": { + "serverName": { + "command": "path/to/server", + "args": ["--arg1", "value1"], + "env": { + "API_KEY": "$MY_API_TOKEN" + }, + "cwd": "./server-directory", + "timeout": 30000, + "trust": false + } + } +} +``` + +Configuration properties: + +Required (one of the following): + +| Property | Description | +| --------- | ------------------------------------------------------ | +| `command` | Path to the executable for Stdio transport | +| `url` | SSE endpoint URL (e.g., `"http://localhost:8080/sse"`) | +| `httpUrl` | HTTP streaming endpoint URL | + +Optional: + +| Property | Type/Default | Description | +| ---------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `args` | array | Command-line arguments for Stdio transport | +| `headers` | object | Custom HTTP headers when using `url` or `httpUrl` | +| `env` | object | Environment variables for the server process. Values can reference environment variables using `$VAR_NAME` or `${VAR_NAME}` syntax | +| `cwd` | string | Working directory for Stdio transport | +| `timeout` | number
(default: 600,000) | Request timeout in milliseconds (default: 600,000ms = 10 minutes) | +| `trust` | boolean
(default: false) | When `true`, bypasses all tool call confirmations for this server (default: `false`) | +| `includeTools` | array | List of tool names to include from this MCP server. When specified, only the tools listed here will be available from this server (allowlist behavior). If not specified, all tools from the server are enabled by default. | +| `excludeTools` | array | List of tool names to exclude from this MCP server. Tools listed here will not be available to the model, even if they are exposed by the server.
Note: `excludeTools` takes precedence over `includeTools` - if a tool is in both lists, it will be excluded. | +| `targetAudience` | string | The OAuth Client ID allowlisted on the IAP-protected application you are trying to access. Used with `authProviderType: 'service_account_impersonation'`. | +| `targetServiceAccount` | string | The email address of the Google Cloud Service Account to impersonate. Used with `authProviderType: 'service_account_impersonation'`. | + + + +### Manage MCP servers with `qwen mcp` + +You can always configure MCP servers by manually editing `settings.json`, but the CLI is usually faster. + +#### Adding a server (`qwen mcp add`) + +```bash +qwen mcp add [options] [args...] +``` + +| Argument/Option | Description | Default | Example | +| ------------------- | ------------------------------------------------------------------- | ------------------ | ----------------------------------------- | +| `` | A unique name for the server. | — | `example-server` | +| `` | The command to execute (for `stdio`) or the URL (for `http`/`sse`). | — | `/usr/bin/python` or `http://localhost:8` | +| `[args...]` | Optional arguments for a `stdio` command. | — | `--port 5000` | +| `-s`, `--scope` | Configuration scope (user or project). | `project` | `-s user` | +| `-t`, `--transport` | Transport type (`stdio`, `sse`, `http`). | `stdio` | `-t sse` | +| `-e`, `--env` | Set environment variables. | — | `-e KEY=value` | +| `-H`, `--header` | Set HTTP headers for SSE and HTTP transports. | — | `-H "X-Api-Key: abc123"` | +| `--timeout` | Set connection timeout in milliseconds. | — | `--timeout 30000` | +| `--trust` | Trust the server (bypass all tool call confirmation prompts). | — (`false`) | `--trust` | +| `--description` | Set the description for the server. | — | `--description "Local tools"` | +| `--include-tools` | A comma-separated list of tools to include. | all tools included | `--include-tools mytool,othertool` | +| `--exclude-tools` | A comma-separated list of tools to exclude. | none | `--exclude-tools mytool` | + +#### Listing servers (`qwen mcp list`) + +```bash +qwen mcp list +``` + +#### Removing a server (`qwen mcp remove`) + +```bash +qwen mcp remove +``` diff --git a/docs/users/mcp/mcp-example-configs.md b/docs/users/mcp/mcp-example-configs.md deleted file mode 100644 index 1b8212c0..00000000 --- a/docs/users/mcp/mcp-example-configs.md +++ /dev/null @@ -1,533 +0,0 @@ -# MCP Example Configurations - -Ready-to-use MCP server configurations for common scenarios. - -## 📁 Local Development - -### Basic Setup - -```json -{ - "mcpServers": { - "workspace": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "trust": true, - "description": "Full workspace access" - } - } -} -``` - -### Multi-Directory Project - -```json -{ - "mcpServers": { - "frontend": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "./src", - "./public", - "./tests" - ], - "trust": true, - "description": "Frontend development files" - }, - "config": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "./config", - "./.env.example" - ], - "trust": true, - "includeTools": ["read_file", "list_directory"], - "description": "Configuration files (read-only)" - } - } -} -``` - -## 🧠 Memory & Context - -### Persistent Memory - -```json -{ - "mcpServers": { - "project-memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "trust": true, - "description": "Remember project context across sessions" - } - } -} -``` - -### Combined with Filesystem - -```json -{ - "mcpServers": { - "files": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "trust": true - }, - "memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "trust": true - } - } -} -``` - -## 🌐 Remote Servers (HTTP/SSE) - -### HTTP MCP Server - -```json -{ - "mcpServers": { - "remote-api": { - "httpUrl": "https://api.example.com/mcp", - "headers": { - "Authorization": "Bearer ${API_TOKEN}", - "Content-Type": "application/json" - }, - "timeout": 30000, - "description": "Remote MCP API" - } - } -} -``` - -### SSE Server with OAuth - -```json -{ - "mcpServers": { - "sse-service": { - "url": "https://mcp.example.com/sse", - "oauth": { - "enabled": true, - "scopes": ["read", "write"] - }, - "timeout": 60000, - "description": "SSE server with OAuth" - } - } -} -``` - -## 🐍 Python MCP Servers - -### Simple Python Server - -```json -{ - "mcpServers": { - "python-tools": { - "command": "python", - "args": ["-m", "my_mcp_server"], - "env": { - "PYTHONPATH": "${PWD}", - "DEBUG": "false" - }, - "description": "Custom Python MCP tools" - } - } -} -``` - -### Python with Virtual Environment - -```json -{ - "mcpServers": { - "python-venv": { - "command": "./venv/bin/python", - "args": ["-m", "mcp_server"], - "cwd": "./", - "env": { - "VIRTUAL_ENV": "${PWD}/venv" - }, - "description": "Python server in virtual environment" - } - } -} -``` - -## 🐳 Docker Containers - -### Basic Docker Server - -```json -{ - "mcpServers": { - "docker-mcp": { - "command": "docker", - "args": ["run", "-i", "--rm", "my-mcp-server:latest"], - "timeout": 45000, - "description": "MCP server in Docker" - } - } -} -``` - -### Docker with Volume Mounts - -```json -{ - "mcpServers": { - "docker-workspace": { - "command": "docker", - "args": [ - "run", - "-i", - "--rm", - "-v", - "${PWD}:/workspace", - "-w", - "/workspace", - "-e", - "API_KEY", - "mcp-tools:latest" - ], - "env": { - "API_KEY": "${MY_API_KEY}" - }, - "description": "Docker MCP with workspace access" - } - } -} -``` - -## 🛡️ Security-Focused Configs - -### Read-Only Filesystem - -```json -{ - "mcpServers": { - "readonly-docs": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "./docs", - "./README.md" - ], - "includeTools": ["read_file", "list_directory", "search_files"], - "excludeTools": [ - "write_file", - "create_directory", - "move_file", - "delete_file" - ], - "trust": true, - "description": "Read-only documentation access" - } - } -} -``` - -### Untrusted External Server - -```json -{ - "mcpServers": { - "external-api": { - "httpUrl": "https://external-mcp.example.com/api", - "trust": false, - "timeout": 15000, - "includeTools": ["search", "analyze"], - "description": "External API (requires confirmation)" - } - } -} -``` - -## 📊 Database Access - -### PostgreSQL MCP Server - -```json -{ - "mcpServers": { - "postgres": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-postgres", - "${DATABASE_URL}" - ], - "env": { - "DATABASE_URL": "$POSTGRES_CONNECTION_STRING" - }, - "timeout": 30000, - "trust": false, - "description": "PostgreSQL database access" - } - } -} -``` - -## 🧪 Testing & Development - -### Test Environment - -```json -{ - "mcpServers": { - "test-files": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "./tests", - "./fixtures" - ], - "trust": true, - "description": "Test files and fixtures" - }, - "test-memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "trust": true, - "description": "Test session memory" - } - } -} -``` - -### Debug Configuration - -```json -{ - "mcpServers": { - "debug-server": { - "command": "node", - "args": ["--inspect", "mcp-server.js"], - "env": { - "DEBUG": "*", - "LOG_LEVEL": "verbose" - }, - "timeout": 60000, - "description": "MCP server with debugging enabled" - } - } -} -``` - -## 🔄 CI/CD Integration - -### GitHub Actions Environment - -```json -{ - "mcpServers": { - "ci-workspace": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "${GITHUB_WORKSPACE}" - ], - "env": { - "GITHUB_TOKEN": "$GITHUB_TOKEN", - "CI": "true" - }, - "trust": true, - "description": "CI/CD workspace access" - } - } -} -``` - -## 🌟 Advanced Patterns - -### Multiple Servers Same Type - -```json -{ - "mcpServers": { - "project-a": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "../project-a"], - "description": "Project A files" - }, - "project-b": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "../project-b"], - "description": "Project B files" - }, - "shared-memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "description": "Shared knowledge across projects" - } - } -} -``` - -### Conditional Server Selection - -User-level config (`~/.qwen/settings.json`): - -```json -{ - "mcpServers": { - "global-memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "trust": true, - "description": "Global memory across all projects" - } - } -} -``` - -Project-level config (`.qwen/settings.json`): - -```json -{ - "mcpServers": { - "project-files": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "trust": true, - "description": "Project-specific files" - } - } -} -``` - -## 📝 Configuration Validation - -### Check Your Config - -```bash -# List configured servers -qwen mcp list - -# Show server details and schemas -qwen mcp list --schema - -# Test connection -qwen mcp list --descriptions -``` - -### Common Mistakes - -❌ **Wrong:** - -```json -{ - "mcpServers": { - "server": { - "command": "mcp-server", // Not in PATH - "args": ["./"] - } - } -} -``` - -✅ **Correct:** - -```json -{ - "mcpServers": { - "server": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "description": "Uses npx to ensure server is available" - } - } -} -``` - -## 🎯 Best Practices - -1. **Use descriptive names** - Make server purposes clear -2. **Set appropriate timeouts** - Match your server's response time -3. **Trust local servers** - Skip confirmation for your own tools -4. **Filter tools** - Use `includeTools`/`excludeTools` for security -5. **Document configs** - Add descriptions for team members -6. **Environment variables** - Keep secrets out of configs -7. **Test independently** - Verify servers work before configuring - -## 🔗 Quick Copy-Paste Configs - -### Starter Pack - -```json -{ - "mcpServers": { - "files": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "trust": true - }, - "memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "trust": true - } - } -} -``` - -### Documentation Project - -```json -{ - "mcpServers": { - "docs": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./docs"], - "includeTools": ["read_file", "list_directory"], - "trust": true - } - } -} -``` - -### Full-Stack Development - -```json -{ - "mcpServers": { - "frontend": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./frontend"], - "trust": true - }, - "backend": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./backend"], - "trust": true - }, - "shared": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./shared"], - "trust": true - }, - "memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "trust": true - } - } -} -``` - ---- - -**Need help?** Check `qwen mcp --help` or refer to the [complete MCP documentation](./tools/mcp-server.md). diff --git a/docs/users/mcp/mcp-quick-start.md b/docs/users/mcp/mcp-quick-start.md deleted file mode 100644 index 1bef3acc..00000000 --- a/docs/users/mcp/mcp-quick-start.md +++ /dev/null @@ -1,424 +0,0 @@ -# MCP Quick Start Guide - Practical Examples - -This guide provides real-world examples to get you started with Model Context Protocol (MCP) servers in Qwen Code. - -## 🚀 Getting Started in 5 Minutes - -### Step 1: Install MCP Servers - -Install official MCP servers from Anthropic: - -```bash -# Filesystem access -npm install -g @modelcontextprotocol/server-filesystem - -# Memory & Knowledge Graph -npm install -g @modelcontextprotocol/server-memory - -# Sequential thinking -npm install -g @modelcontextprotocol/server-sequential-thinking -``` - -### Step 2: Configure Your First MCP Server - -Create or edit `.qwen/settings.json` in your project: - -```json -{ - "mcpServers": { - "filesystem": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "description": "Access project files" - } - } -} -``` - -### Step 3: Verify Connection - -```bash -qwen mcp list -``` - -You should see: - -``` -✓ filesystem: npx -y @modelcontextprotocol/server-filesystem ./ (stdio) - Connected -``` - -## 📚 Practical Examples - -### Example 1: Local Development Assistant - -**Use Case:** Work on a Node.js project with file access and memory. - -**Configuration (`.qwen/settings.json`):** - -```json -{ - "mcpServers": { - "project-files": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "./src", - "./tests", - "./docs" - ], - "description": "Access source code, tests, and documentation", - "trust": true - }, - "project-memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "description": "Remember project decisions and context", - "trust": true - } - } -} -``` - -**Usage:** - -```bash -qwen - -> Remember: This project uses React 18 with TypeScript and follows Airbnb style guide -> List all files in the src directory -> Read src/App.tsx and suggest improvements -``` - -### Example 2: Multi-Repository Development - -**Use Case:** Working across multiple codebases simultaneously. - -**Configuration:** - -```json -{ - "mcpServers": { - "frontend": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "../frontend-app" - ], - "description": "Frontend repository access" - }, - "backend": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "../backend-api" - ], - "description": "Backend repository access" - }, - "shared-memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "description": "Shared knowledge across repositories" - } - } -} -``` - -### Example 3: Documentation-Only Access - -**Use Case:** Safe access to documentation without risking code changes. - -**Configuration:** - -```json -{ - "mcpServers": { - "docs": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "./docs", - "./README.md" - ], - "description": "Read-only documentation access", - "trust": true, - "includeTools": ["read_file", "list_directory"] - } - } -} -``` - -### Example 4: Custom Python MCP Server - -**Use Case:** Integrate custom Python tools via MCP. - -**Server File (`mcp_server.py`):** - -```python -#!/usr/bin/env python3 -import sys -from mcp.server.stdio import stdio_server -from mcp.server import Server -from mcp.types import Tool, TextContent - -server = Server("custom-tools") - -@server.list_tools() -async def list_tools() -> list[Tool]: - return [ - Tool( - name="analyze_python_code", - description="Static analysis of Python code", - inputSchema={ - "type": "object", - "properties": { - "file_path": {"type": "string"} - }, - "required": ["file_path"] - } - ) - ] - -@server.call_tool() -async def call_tool(name: str, arguments: dict) -> list[TextContent]: - if name == "analyze_python_code": - # Your custom logic here - return [TextContent(type="text", text=f"Analysis of {arguments['file_path']}")] - -async def main(): - async with stdio_server() as (read_stream, write_stream): - await server.run(read_stream, write_stream, server.create_initialization_options()) - -if __name__ == "__main__": - import asyncio - asyncio.run(main()) -``` - -**Configuration:** - -```json -{ - "mcpServers": { - "python-tools": { - "command": "python", - "args": ["mcp_server.py"], - "env": { - "PYTHONPATH": "${PWD}" - }, - "description": "Custom Python analysis tools" - } - } -} -``` - -### Example 5: Docker-Based MCP Server - -**Use Case:** Run MCP servers in isolated containers. - -**Configuration:** - -```json -{ - "mcpServers": { - "containerized-tools": { - "command": "docker", - "args": [ - "run", - "-i", - "--rm", - "-v", - "${PWD}:/workspace", - "-w", - "/workspace", - "my-mcp-server:latest" - ], - "description": "MCP tools running in Docker" - } - } -} -``` - -## 🔧 Configuration Tips - -### Environment Variables - -Use environment variables for sensitive data: - -```json -{ - "mcpServers": { - "api-server": { - "command": "node", - "args": ["api-server.js"], - "env": { - "API_KEY": "${MY_API_KEY}", - "DATABASE_URL": "$DB_CONNECTION" - } - } - } -} -``` - -### Trust Settings - -Trust servers you control to skip confirmation dialogs: - -```json -{ - "mcpServers": { - "trusted-server": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "trust": true - } - } -} -``` - -### Tool Filtering - -Limit which tools are available: - -```json -{ - "mcpServers": { - "filesystem": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "includeTools": ["read_file", "list_directory"], - "excludeTools": ["write_file", "move_file"] - } - } -} -``` - -## 🎯 Common Use Cases - -### Code Review Assistant - -```json -{ - "mcpServers": { - "codebase": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "description": "Full codebase access for reviews" - }, - "review-memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "description": "Remember review comments and patterns" - } - } -} -``` - -**Usage:** - -```bash -qwen - -> Review the changes in src/components/ -> Remember: We follow the single responsibility principle -> Check if all new components have tests -``` - -### Documentation Generator - -```json -{ - "mcpServers": { - "source": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./src"], - "includeTools": ["read_file", "list_directory"] - }, - "docs-writer": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./docs"], - "includeTools": ["write_file", "create_directory"] - } - } -} -``` - -### Learning Assistant - -```json -{ - "mcpServers": { - "tutorials": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "./tutorials", - "./examples" - ], - "trust": true - }, - "learning-progress": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "description": "Track learning progress and concepts" - } - } -} -``` - -## 🛠️ Troubleshooting - -### Server Won't Connect - -1. **Check the command is accessible:** - - ```bash - npx -y @modelcontextprotocol/server-filesystem ./ - ``` - -2. **Verify directory permissions:** - - ```bash - ls -la ./ - ``` - -3. **Check logs:** - ```bash - qwen --debug - ``` - -### No Tools Discovered - -Ensure the server actually provides tools: - -```bash -qwen mcp list --schema -``` - -### Tools Not Executing - -- Check parameter schemas match -- Verify timeout settings (increase if needed) -- Test the server independently first - -## 📖 Further Reading - -- [MCP Server Documentation](./tools/mcp-server.md) - Complete reference -- [Official MCP Specification](https://modelcontextprotocol.io/) - Protocol details -- [MCP Server Examples](https://github.com/modelcontextprotocol/servers) - Community servers - -## 🎓 Next Steps - -1. ✅ Configure your first MCP server -2. ✅ Verify connection with `qwen mcp list` -3. ✅ Try basic file operations -4. ✅ Add memory for persistent context -5. ✅ Explore community MCP servers -6. ✅ Build your own custom server - ---- - -**Pro Tip:** Start with trusted local servers (`trust: true`) for faster iteration, then add confirmation for production use. diff --git a/docs/users/mcp/mcp-testing-validation.md b/docs/users/mcp/mcp-testing-validation.md deleted file mode 100644 index 865c71d0..00000000 --- a/docs/users/mcp/mcp-testing-validation.md +++ /dev/null @@ -1,403 +0,0 @@ -# MCP Testing & Validation Guide - -This guide helps you test and validate your MCP server configurations. - -## ✅ Quick Validation Checklist - -### 1. Check MCP Servers Are Configured - -```bash -qwen mcp list -``` - -**Expected output:** - -``` -Configured MCP servers: - -✓ filesystem: npx -y @modelcontextprotocol/server-filesystem ./ (stdio) - Connected -✓ memory: npx -y @modelcontextprotocol/server-memory (stdio) - Connected -``` - -**Status indicators:** - -- ✓ (green) - Connected successfully -- ✗ (red) - Connection failed or not connected - -### 2. Verify Server Is Installed - -Test the server command directly: - -```bash -# Filesystem server -npx -y @modelcontextprotocol/server-filesystem --help - -# Memory server -npx -y @modelcontextprotocol/server-memory --help - -# Custom server -python mcp_server.py --help -``` - -### 3. Check Configuration File Syntax - -Validate your JSON configuration: - -```bash -# Linux/macOS -cat .qwen/settings.json | jq . - -# Windows PowerShell -Get-Content .qwen/settings.json | ConvertFrom-Json | ConvertTo-Json -``` - -### 4. Test Within Qwen Code Session - -Start an interactive session and check MCP status: - -```bash -qwen - -# Inside the session: -/mcp # Show all MCP servers and tools -/mcp desc # Show tool descriptions -/mcp schema # Show tool parameter schemas -``` - -## 🧪 Test Cases - -### Test Case 1: Filesystem Server - -**Configuration:** - -```json -{ - "mcpServers": { - "test-fs": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "trust": true - } - } -} -``` - -**Validation:** - -1. List files: Start `qwen` and ask "List all files in this directory" -2. Read file: "Read the README.md file" -3. Verify output contains actual file contents - -**Expected Tools:** - -- `read_file` - Read file contents -- `write_file` - Write to files -- `list_directory` - List directory contents -- `create_directory` - Create directories -- `move_file` - Move/rename files -- `search_files` - Search for files -- `get_file_info` - Get file metadata - -### Test Case 2: Memory Server - -**Configuration:** - -```json -{ - "mcpServers": { - "test-memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "trust": true - } - } -} -``` - -**Validation:** - -1. Store information: "Remember that this project uses React 18" -2. Query: "What JavaScript framework does this project use?" -3. Verify it recalls the information from step 1 - -**Expected Tools:** - -- `create_entities` - Create knowledge entities -- `create_relations` - Create relationships between entities -- `add_observations` - Add observations to entities -- `delete_entities` - Remove entities -- `delete_observations` - Remove observations -- `delete_relations` - Remove relationships -- `read_graph` - Read entire knowledge graph -- `search_nodes` - Search for specific nodes -- `open_nodes` - Open specific nodes by name - -### Test Case 3: Multiple Servers - -**Configuration:** - -```json -{ - "mcpServers": { - "files": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "trust": true - }, - "memory": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-memory"], - "trust": true - } - } -} -``` - -**Validation:** - -1. Check both servers are connected: `qwen mcp list` -2. Use filesystem tool: "List all JavaScript files" -3. Use memory tool: "Remember that we prefer TypeScript" -4. Verify both tools work simultaneously - -### Test Case 4: Tool Filtering - -**Configuration:** - -```json -{ - "mcpServers": { - "readonly-fs": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "includeTools": ["read_file", "list_directory"], - "trust": true - } - } -} -``` - -**Validation:** - -1. Start qwen session -2. Run `/mcp desc` to list available tools -3. Verify only `read_file` and `list_directory` are present -4. Verify `write_file`, `create_directory`, etc. are NOT available - -### Test Case 5: Untrusted Server Confirmation - -**Configuration:** - -```json -{ - "mcpServers": { - "untrusted": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "./"], - "trust": false - } - } -} -``` - -**Validation:** - -1. Ask qwen to read a file -2. Confirmation dialog should appear before execution -3. Options should include: - - Proceed once - - Always allow this tool - - Always allow this server - - Cancel - -## 🔍 Debugging Failed Connections - -### Issue: Server Shows "Disconnected" - -**Diagnostic steps:** - -1. **Test command manually:** - - ```bash - npx -y @modelcontextprotocol/server-filesystem ./ - ``` - -2. **Check for errors:** - - ```bash - qwen --debug - ``` - -3. **Verify paths are correct:** - - ```bash - # Check if directory exists - ls ./ - - # Check if command is in PATH - which npx # Linux/macOS - where npx # Windows - ``` - -4. **Check permissions:** - - ```bash - # Verify read/execute permissions - ls -la ./ - ``` - -5. **Review environment variables:** - ```bash - echo $PATH - echo $PYTHONPATH # For Python servers - ``` - -### Issue: No Tools Discovered - -**Diagnostic steps:** - -1. **Verify server implements MCP protocol:** - - ```bash - # For stdio servers, test input/output manually - echo '{"jsonrpc": "2.0", "method": "initialize", "id": 1}' | npx -y @modelcontextprotocol/server-filesystem ./ - ``` - -2. **Check server logs:** - - ```bash - # Some servers log to stderr - qwen --debug 2>&1 | grep MCP - ``` - -3. **Verify server version:** - ```bash - npm list -g @modelcontextprotocol/server-filesystem - ``` - -### Issue: Tools Fail to Execute - -**Diagnostic steps:** - -1. **Check parameter format:** - - Ensure parameters match the expected schema - - Verify JSON encoding is correct - -2. **Increase timeout:** - - ```json - { - "mcpServers": { - "slow-server": { - "command": "...", - "timeout": 60000 - } - } - } - ``` - -3. **Check server implementation:** - - Verify the server actually implements the tool - - Test the tool independently if possible - -## 📊 Validation Results - -### Expected Server Connection Times - -| Server Type | Typical Connection Time | Timeout Recommendation | -| ------------- | ----------------------- | ---------------------- | -| Filesystem | < 1 second | 10-30 seconds | -| Memory | < 1 second | 10-30 seconds | -| HTTP/SSE | 1-3 seconds | 30-60 seconds | -| Custom Python | 2-5 seconds | 30-60 seconds | -| Docker | 5-10 seconds | 60-120 seconds | - -### Tool Execution Times - -| Tool Type | Typical Duration | Timeout Recommendation | -| ----------------- | ---------------- | ---------------------- | -| Read file | < 100ms | 5-10 seconds | -| List directory | < 500ms | 10-15 seconds | -| Search files | 1-5 seconds | 30-60 seconds | -| Memory operations | < 1 second | 10-30 seconds | -| API calls | 1-10 seconds | 30-120 seconds | - -## 🎯 Success Criteria - -Your MCP configuration is working correctly if: - -✅ `qwen mcp list` shows all servers as "Connected" -✅ `/mcp` command in qwen session displays tools -✅ Tool executions complete without errors -✅ Confirmation dialogs appear for untrusted servers (if `trust: false`) -✅ Tool filtering works as expected (include/exclude) -✅ Environment variables are properly substituted -✅ Timeouts are appropriate for your server's response time - -## 🚀 Performance Tips - -1. **Use `trust: true` for local servers** to skip confirmation dialogs -2. **Set appropriate timeouts** - too low causes failures, too high slows down errors -3. **Filter tools** - Only enable tools you actually need -4. **Test servers independently** before configuring in qwen -5. **Use `--debug` flag** during initial setup -6. **Monitor resource usage** for long-running or resource-intensive servers - -## 📝 Validation Script Example - -Create a test script to automate validation: - -```bash -#!/bin/bash -# validate-mcp.sh - -echo "Testing MCP configuration..." - -# Test 1: Check config file exists -if [ ! -f .qwen/settings.json ]; then - echo "❌ Missing .qwen/settings.json" - exit 1 -fi -echo "✅ Config file exists" - -# Test 2: Validate JSON syntax -if ! cat .qwen/settings.json | jq . > /dev/null 2>&1; then - echo "❌ Invalid JSON in settings.json" - exit 1 -fi -echo "✅ Valid JSON syntax" - -# Test 3: Check servers are configured -SERVER_COUNT=$(cat .qwen/settings.json | jq '.mcpServers | length') -if [ "$SERVER_COUNT" -eq 0 ]; then - echo "❌ No MCP servers configured" - exit 1 -fi -echo "✅ $SERVER_COUNT MCP server(s) configured" - -# Test 4: Check connection status -qwen mcp list | grep -q "Connected" -if [ $? -eq 0 ]; then - echo "✅ At least one server is connected" -else - echo "❌ No servers connected" - exit 1 -fi - -echo "" -echo "✅ All validation checks passed!" -``` - -## 📚 Next Steps - -After validation: - -1. **Start using MCP tools** in your workflow -2. **Document your custom configurations** for team members -3. **Share your successful configs** with the community -4. **Monitor performance** and adjust timeouts as needed -5. **Explore more MCP servers** from the community - ---- - -**Having issues?** Check the [MCP troubleshooting guide](./tools/mcp-server.md#troubleshooting) or open an issue on GitHub. diff --git a/docs/users/mcp/mcp.md b/docs/users/mcp/mcp.md deleted file mode 100644 index d57b8bb7..00000000 --- a/docs/users/mcp/mcp.md +++ /dev/null @@ -1,850 +0,0 @@ -# MCP servers with Qwen Code - -This document provides a guide to configuring and using Model Context Protocol (MCP) servers with Qwen Code. - -## What is an MCP server? - -An MCP server is an application that exposes tools and resources to the CLI through the Model Context Protocol, allowing it to interact with external systems and data sources. MCP servers act as a bridge between the model and your local environment or other services like APIs. - -An MCP server enables the CLI to: - -- **Discover tools:** List available tools, their descriptions, and parameters through standardized schema definitions. -- **Execute tools:** Call specific tools with defined arguments and receive structured responses. -- **Access resources:** Read data from specific resources (though the CLI primarily focuses on tool execution). - -With an MCP server, you can extend the CLI’s capabilities to perform actions beyond its built-in features, such as interacting with databases, APIs, custom scripts, or specialized workflows. - -## Core Integration Architecture - -Qwen Code integrates with MCP servers through a sophisticated discovery and execution system built into the core package (`packages/core/src/tools/`): - -### Discovery Layer (`mcp-client.ts`) - -The discovery process is orchestrated by `discoverMcpTools()`, which: - -1. **Iterates through configured servers** from your `settings.json` `mcpServers` configuration -2. **Establishes connections** using appropriate transport mechanisms (Stdio, SSE, or Streamable HTTP) -3. **Fetches tool definitions** from each server using the MCP protocol -4. **Sanitizes and validates** tool schemas for compatibility with the Qwen API -5. **Registers tools** in the global tool registry with conflict resolution - -### Execution Layer (`mcp-tool.ts`) - -Each discovered MCP tool is wrapped in a `DiscoveredMCPTool` instance that: - -- **Handles confirmation logic** based on server trust settings and user preferences -- **Manages tool execution** by calling the MCP server with proper parameters -- **Processes responses** for both the LLM context and user display -- **Maintains connection state** and handles timeouts - -### Transport Mechanisms - -The CLI supports three MCP transport types: - -- **Stdio Transport:** Spawns a subprocess and communicates via stdin/stdout -- **SSE Transport:** Connects to Server-Sent Events endpoints -- **Streamable HTTP Transport:** Uses HTTP streaming for communication - -## How to set up your MCP server - -Qwen Code uses the `mcpServers` configuration in your `settings.json` file to locate and connect to MCP servers. This configuration supports multiple servers with different transport mechanisms. - -### Configure the MCP server in settings.json - -You can configure MCP servers in your `settings.json` file in two main ways: through the top-level `mcpServers`object for specific server definitions, and through the `mcp` object for global settings that control server discovery and execution. - -#### Global MCP Settings (`mcp`) - -The `mcp` object in your `settings.json` allows you to define global rules for all MCP servers. - -- **`mcp.serverCommand`** : A global command to start an MCP server. -- **`mcp.allowed`** (array of strings): A list of MCP server names to allow. If this is set, only servers from this list (matching the keys in the `mcpServers` object) will be connected to. -- **`mcp.excluded`** (array of strings): A list of MCP server names to exclude. Servers in this list will not be connected to. - -**Example:** - -``` -{ - "mcp": { - "allowed": ["my-trusted-server"], - "excluded": ["experimental-server"] - } -} -``` - -#### Server-Specific Configuration (`mcpServers`) - -The `mcpServers` object is where you define each individual MCP server you want the CLI to connect to. - -### Configuration Structure - -Add an `mcpServers` object to your `settings.json` file: - -``` -{ ...file contains other config objects - "mcpServers": { - "serverName": { - "command": "path/to/server", - "args": ["--arg1", "value1"], - "env": { - "API_KEY": "$MY_API_TOKEN" - }, - "cwd": "./server-directory", - "timeout": 30000, - "trust": false - } - } - } -``` - -### Configuration Properties - -Each server configuration supports the following properties: - -#### Required (one of the following) - -- **`command`** : Path to the executable for Stdio transport -- **`url`** : SSE endpoint URL (e.g., `"http://localhost:8080/sse"`) -- **`httpUrl`** : HTTP streaming endpoint URL - -#### Optional - -- **`args`** : Command-line arguments for Stdio transport -- **`headers`** (object): Custom HTTP headers when using `url` or `httpUrl` -- **`env`** (object): Environment variables for the server process. Values can reference environment variables using `$VAR_NAME` or `${VAR_NAME}` syntax -- **`cwd`** : Working directory for Stdio transport -- **`timeout`** (number): Request timeout in milliseconds (default: 600,000ms = 10 minutes) -- **`trust`** (boolean): When `true`, bypasses all tool call confirmations for this server (default: `false`) -- **`includeTools`** : List of tool names to include from this MCP server. When specified, only the tools listed here will be available from this server (allowlist behavior). If not specified, all tools from the server are enabled by default. -- **`excludeTools`** : List of tool names to exclude from this MCP server. Tools listed here will not be available to the model, even if they are exposed by the server.  - - **Note:** `excludeTools` takes precedence over `includeTools` - if a tool is in both lists, it will be excluded. -- **`targetAudience`** : The OAuth Client ID allowlisted on the IAP-protected application you are trying to access. Used with `authProviderType: 'service_account_impersonation'`. -- **`targetServiceAccount`** : The email address of the Google Cloud Service Account to impersonate. Used with `authProviderType: 'service_account_impersonation'`. - -### OAuth Support for Remote MCP Servers - -Qwen Code supports OAuth 2.0 authentication for remote MCP servers using SSE or HTTP transports. This enables secure access to MCP servers that require authentication. - -#### Automatic OAuth Discovery - -For servers that support OAuth discovery, you can omit the OAuth configuration and let the CLI discover it automatically: - -``` -{ - "mcpServers": { - "discoveredServer": { - "url": "https://api.example.com/sse" - } - } -} -``` - -The CLI will automatically: - -- Detect when a server requires OAuth authentication (401 responses) -- Discover OAuth endpoints from server metadata -- Perform dynamic client registration if supported -- Handle the OAuth flow and token management - -#### Authentication Flow - -When connecting to an OAuth-enabled server: - -1. **Initial connection attempt** fails with 401 Unauthorized -2. **OAuth discovery** finds authorization and token endpoints -3. **Browser opens** for user authentication (requires local browser access) -4. **Authorization code** is exchanged for access tokens -5. **Tokens are stored** securely for future use -6. **Connection retry** succeeds with valid tokens - -#### Browser Redirect Requirements - -**Important:** OAuth authentication requires that your local machine can: - -- Open a web browser for authentication -- Receive redirects on `http://localhost:7777/oauth/callback` - -This feature will not work in: - -- Headless environments without browser access -- Remote SSH sessions without X11 forwarding -- Containerized environments without browser support - -#### Managing OAuth Authentication - -Use the `/mcp auth` command to manage OAuth authentication: - -``` -# List servers requiring authentication -/mcp auth - -# Authenticate with a specific server -/mcp auth serverName - -# Re-authenticate if tokens expire -/mcp auth serverName -``` - -#### OAuth Configuration Properties - -- **`enabled`** (boolean): Enable OAuth for this server -- **`clientId`** : OAuth client identifier (optional with dynamic registration) -- **`clientSecret`** : OAuth client secret (optional for public clients) -- **`authorizationUrl`** : OAuth authorization endpoint (auto-discovered if omitted) -- **`tokenUrl`** : OAuth token endpoint (auto-discovered if omitted) -- **`scopes`** : Required OAuth scopes -- **`redirectUri`** : Custom redirect URI (defaults to `http://localhost:7777/oauth/callback`) -- **`tokenParamName`** : Query parameter name for tokens in SSE URLs -- **`audiences`** : Audiences the token is valid for - -#### Token Management - -OAuth tokens are automatically: - -- **Stored securely** in `~/.qwen/mcp-oauth-tokens.json` -- **Refreshed** when expired (if refresh tokens are available) -- **Validated** before each connection attempt -- **Cleaned up** when invalid or expired - -#### Authentication Provider Type - -You can specify the authentication provider type using the `authProviderType` property: - -- **`authProviderType`** : Specifies the authentication provider. Can be one of the following: - - **`dynamic_discovery`** (default): The CLI will automatically discover the OAuth configuration from the server. - - **`google_credentials`**: The CLI will use the Google Application Default Credentials (ADC) to authenticate with the server. When using this provider, you must specify the required scopes. - - **`service_account_impersonation`**: The CLI will impersonate a Google Cloud Service Account to authenticate with the server. This is useful for accessing IAP-protected services (this was specifically designed for Cloud Run services). - -#### Google Credentials - -``` -{ - "mcpServers": { - "googleCloudServer": { - "httpUrl": "https://my-gcp-service.run.app/mcp", - "authProviderType": "google_credentials", - "oauth": { - "scopes": ["https://www.googleapis.com/auth/userinfo.email"] - } - } - } -} -``` - -#### Service Account Impersonation - -To authenticate with a server using Service Account Impersonation, you must set the `authProviderType` to `service_account_impersonation` and provide the following properties: - -- **`targetAudience`** : The OAuth Client ID allowslisted on the IAP-protected application you are trying to access. -- **`targetServiceAccount`** : The email address of the Google Cloud Service Account to impersonate. - -The CLI will use your local Application Default Credentials (ADC) to generate an OIDC ID token for the specified service account and audience. This token will then be used to authenticate with the MCP server. - -#### Setup Instructions - -1. **[Create](https://cloud.google.com/iap/docs/oauth-client-creation)  or use an existing OAuth 2.0 client ID.** To use an existing OAuth 2.0 client ID, follow the steps in [How to share OAuth Clients](https://cloud.google.com/iap/docs/sharing-oauth-clients) . -2. **Add the OAuth ID to the allowlist for [programmatic access](https://cloud.google.com/iap/docs/sharing-oauth-clients#programmatic_access)  for the application.** Since Cloud Run is not yet a supported resource type in gcloud iap, you must allowlist the Client ID on the project. -3. **Create a service account.** [Documentation](https://cloud.google.com/iam/docs/service-accounts-create#creating) , [Cloud Console Link](https://console.cloud.google.com/iam-admin/serviceaccounts)  -4. **Add both the service account and users to the IAP Policy** in the “Security” tab of the Cloud Run service itself or via gcloud. -5. **Grant all users and groups** who will access the MCP Server the necessary permissions to [impersonate the service account](https://cloud.google.com/docs/authentication/use-service-account-impersonation)  (i.e., `roles/iam.serviceAccountTokenCreator`). -6. **[Enable](https://console.cloud.google.com/apis/library/iamcredentials.googleapis.com)  the IAM Credentials API** for your project. - -### Example Configurations - -#### Python MCP Server (Stdio) - -``` -{ - "mcpServers": { - "pythonTools": { - "command": "python", - "args": ["-m", "my_mcp_server", "--port", "8080"], - "cwd": "./mcp-servers/python", - "env": { - "DATABASE_URL": "$DB_CONNECTION_STRING", - "API_KEY": "${EXTERNAL_API_KEY}" - }, - "timeout": 15000 - } - } -} -``` - -#### Node.js MCP Server (Stdio) - -``` -{ - "mcpServers": { - "nodeServer": { - "command": "node", - "args": ["dist/server.js", "--verbose"], - "cwd": "./mcp-servers/node", - "trust": true - } - } -} -``` - -#### Docker-based MCP Server - -``` -{ - "mcpServers": { - "dockerizedServer": { - "command": "docker", - "args": [ "run", "-i", "--rm", "-e", "API_KEY", "-v", "${PWD}:/workspace", "my-mcp-server:latest" ], - "env": { - "API_KEY": "$EXTERNAL_SERVICE_TOKEN" - } - } - } -} -``` - -#### HTTP-based MCP Server - -``` -{ - "mcpServers": { - "httpServer": { - "httpUrl": "http://localhost:3000/mcp", - "timeout": 5000 - } - } -} -``` - -#### HTTP-based MCP Server with Custom Headers - -``` -{ - "mcpServers": { - "httpServerWithAuth": { - "httpUrl": "http://localhost:3000/mcp", - "headers": { - "Authorization": "Bearer your-api-token", - "X-Custom-Header": "custom-value", - "Content-Type": "application/json" - }, - "timeout": 5000 - } - } -} -``` - -#### MCP Server with Tool Filtering - -``` -{ - "mcpServers": { - "filteredServer": { - "command": "python", - "args": ["-m", "my_mcp_server"], - "includeTools": ["safe_tool", "file_reader", "data_processor"], - // "excludeTools": ["dangerous_tool", "file_deleter"], - "timeout": 30000 - } - } -} -``` - -### SSE MCP Server with SA Impersonation - -``` -{ - "mcpServers": { - "myIapProtectedServer": { - "url": "https://my-iap-service.run.app/sse", - "authProviderType": "service_account_impersonation", - "targetAudience": "YOUR_IAP_CLIENT_ID.apps.googleusercontent.com", - "targetServiceAccount": "your-sa@your-project.iam.gserviceaccount.com" - } - } -} -``` - -## Discovery Process Deep Dive - -When Qwen Code starts, it performs MCP server discovery through the following detailed process: - -### 1. Server Iteration and Connection - -For each configured server in `mcpServers`: - -1. **Status tracking begins:** Server status is set to `CONNECTING` -2. **Transport selection:** Based on configuration properties: - - `httpUrl` → `StreamableHTTPClientTransport` - - `url` → `SSEClientTransport` - - `command` → `StdioClientTransport` -3. **Connection establishment:** The MCP client attempts to connect with the configured timeout -4. **Error handling:** Connection failures are logged and the server status is set to `DISCONNECTED` - -### 2. Tool Discovery - -Upon successful connection: - -1. **Tool listing:** The client calls the MCP server’s tool listing endpoint -2. **Schema validation:** Each tool’s function declaration is validated -3. **Tool filtering:** Tools are filtered based on `includeTools` and `excludeTools` configuration -4. **Name sanitization:** Tool names are cleaned to meet Qwen API requirements: - - Invalid characters (non-alphanumeric, underscore, dot, hyphen) are replaced with underscores - - Names longer than 63 characters are truncated with middle replacement (`___`) - -### 3. Conflict Resolution - -When multiple servers expose tools with the same name: - -1. **First registration wins:** The first server to register a tool name gets the unprefixed name -2. **Automatic prefixing:** Subsequent servers get prefixed names: `serverName__toolName` -3. **Registry tracking:** The tool registry maintains mappings between server names and their tools - -### 4. Schema Processing - -Tool parameter schemas undergo sanitization for API compatibility: - -- **`$schema` properties** are removed -- **`additionalProperties`** are stripped -- **`anyOf` with `default`** have their default values removed (Vertex AI compatibility) -- **Recursive processing** applies to nested schemas - -### 5. Connection Management - -After discovery: - -- **Persistent connections:** Servers that successfully register tools maintain their connections -- **Cleanup:** Servers that provide no usable tools have their connections closed -- **Status updates:** Final server statuses are set to `CONNECTED` or `DISCONNECTED` - -## Tool Execution Flow - -When the model decides to use an MCP tool, the following execution flow occurs: - -### 1. Tool Invocation - -The model generates a `FunctionCall` with: - -- **Tool name:** The registered name (potentially prefixed) -- **Arguments:** JSON object matching the tool’s parameter schema - -### 2. Confirmation Process - -Each `DiscoveredMCPTool` implements sophisticated confirmation logic: - -#### Trust-based Bypass - -``` -if (this.trust) { - return false; // No confirmation needed -} -``` - -#### Dynamic Allow-listing - -The system maintains internal allow-lists for: - -- **Server-level:** `serverName` → All tools from this server are trusted -- **Tool-level:** `serverName.toolName` → This specific tool is trusted - -#### User Choice Handling - -When confirmation is required, users can choose: - -- **Proceed once:** Execute this time only -- **Always allow this tool:** Add to tool-level allow-list -- **Always allow this server:** Add to server-level allow-list -- **Cancel:** Abort execution - -### 3. Execution - -Upon confirmation (or trust bypass): - -1. **Parameter preparation:** Arguments are validated against the tool’s schema -2. **MCP call:** The underlying `CallableTool` invokes the server with: - -``` -const functionCalls = [{ - name: this.serverToolName, // Original server tool name - args: params, -},]; -``` - -3. **Response processing:** Results are formatted for both LLM context and user display - -### 4. Response Handling - -The execution result contains: - -- **`llmContent`:** Raw response parts for the language model’s context -- **`returnDisplay`:** Formatted output for user display (often JSON in markdown code blocks) - -## How to interact with your MCP server - -### Using the `/mcp` Command - -The `/mcp` command provides comprehensive information about your MCP server setup: - -`/mcp` - -This displays: - -- **Server list:** All configured MCP servers -- **Connection status:** `CONNECTED`, `CONNECTING`, or `DISCONNECTED` -- **Server details:** Configuration summary (excluding sensitive data) -- **Available tools:** List of tools from each server with descriptions -- **Discovery state:** Overall discovery process status - -### Example `/mcp` Output - -``` -MCP Servers Status: -📡 pythonTools (CONNECTED) - Command: python -m my_mcp_server --port 8080 - Working Directory: ./mcp-servers/python - Timeout: 15000ms - Tools: calculate_sum, file_analyzer, data_processor -🔌 nodeServer (DISCONNECTED) - Command: node dist/server.js --verbose - Error: Connection refused -🐳 dockerizedServer (CONNECTED) - Command: docker run -i --rm -e API_KEY my-mcp-server:latest - Tools: docker__deploy, docker__status -Discovery State: COMPLETED -``` - -### Tool Usage - -Once discovered, MCP tools are available to the Qwen model like built-in tools. The model will automatically: - -1. **Select appropriate tools** based on your requests -2. **Present confirmation dialogs** (unless the server is trusted) -3. **Execute tools** with proper parameters -4. **Display results** in a user-friendly format - -## Status Monitoring and Troubleshooting - -### Connection States - -The MCP integration tracks several states: - -#### Server Status (`MCPServerStatus`) - -- **`DISCONNECTED`:** Server is not connected or has errors -- **`CONNECTING`:** Connection attempt in progress -- **`CONNECTED`:** Server is connected and ready - -#### Discovery State (`MCPDiscoveryState`) - -- **`NOT_STARTED`:** Discovery hasn’t begun -- **`IN_PROGRESS`:** Currently discovering servers -- **`COMPLETED`:** Discovery finished (with or without errors) - -### Common Issues and Solutions - -#### Server Won’t Connect - -**Symptoms:** Server shows `DISCONNECTED` status - -**Troubleshooting:** - -1. **Check configuration:** Verify `command`, `args`, and `cwd` are correct -2. **Test manually:** Run the server command directly to ensure it works -3. **Check dependencies:** Ensure all required packages are installed -4. **Review logs:** Look for error messages in the CLI output -5. **Verify permissions:** Ensure the CLI can execute the server command - -#### No Tools Discovered - -**Symptoms:** Server connects but no tools are available - -**Troubleshooting:** - -1. **Verify tool registration:** Ensure your server actually registers tools -2. **Check MCP protocol:** Confirm your server implements the MCP tool listing correctly -3. **Review server logs:** Check stderr output for server-side errors -4. **Test tool listing:** Manually test your server’s tool discovery endpoint - -#### Tools Not Executing - -**Symptoms:** Tools are discovered but fail during execution - -**Troubleshooting:** - -1. **Parameter validation:** Ensure your tool accepts the expected parameters -2. **Schema compatibility:** Verify your input schemas are valid JSON Schema -3. **Error handling:** Check if your tool is throwing unhandled exceptions -4. **Timeout issues:** Consider increasing the `timeout` setting - -#### Sandbox Compatibility - -**Symptoms:** MCP servers fail when sandboxing is enabled - -**Solutions:** - -1. **Docker-based servers:** Use Docker containers that include all dependencies -2. **Path accessibility:** Ensure server executables are available in the sandbox -3. **Network access:** Configure sandbox to allow necessary network connections -4. **Environment variables:** Verify required environment variables are passed through - -### Debugging Tips - -1. **Enable debug mode:** Run the CLI with `--debug` for verbose output -2. **Check stderr:** MCP server stderr is captured and logged (INFO messages filtered) -3. **Test isolation:** Test your MCP server independently before integrating -4. **Incremental setup:** Start with simple tools before adding complex functionality -5. **Use `/mcp` frequently:** Monitor server status during development - -## Important Notes - -### Security Considerations - -- **Trust settings:** The `trust` option bypasses all confirmation dialogs. Use cautiously and only for servers you completely control -- **Access tokens:** Be security-aware when configuring environment variables containing API keys or tokens -- **Sandbox compatibility:** When using sandboxing, ensure MCP servers are available within the sandbox environment -- **Private data:** Using broadly scoped personal access tokens can lead to information leakage between repositories - -### Performance and Resource Management - -- **Connection persistence:** The CLI maintains persistent connections to servers that successfully register tools -- **Automatic cleanup:** Connections to servers providing no tools are automatically closed -- **Timeout management:** Configure appropriate timeouts based on your server’s response characteristics -- **Resource monitoring:** MCP servers run as separate processes and consume system resources - -### Schema Compatibility - -- **Property stripping:** The system automatically removes certain schema properties (`$schema`, `additionalProperties`) for Qwen API compatibility -- **Name sanitization:** Tool names are automatically sanitized to meet API requirements -- **Conflict resolution:** Tool name conflicts between servers are resolved through automatic prefixing - -This comprehensive integration makes MCP servers a powerful way to extend the CLI’s capabilities while maintaining security, reliability, and ease of use. - -## Returning Rich Content from Tools - -MCP tools are not limited to returning simple text. You can return rich, multi-part content, including text, images, audio, and other binary data in a single tool response. This allows you to build powerful tools that can provide diverse information to the model in a single turn. - -All data returned from the tool is processed and sent to the model as context for its next generation, enabling it to reason about or summarize the provided information. - -### How It Works - -To return rich content, your tool’s response must adhere to the MCP specification for a [`CallToolResult`](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool-result). The `content` field of the result should be an array of `ContentBlock` objects. The CLI will correctly process this array, separating text from binary data and packaging it for the model. - -You can mix and match different content block types in the `content` array. The supported block types include: - -- `text` -- `image` -- `audio` -- `resource` (embedded content) -- `resource_link` - -### Example: Returning Text and an Image - -Here is an example of a valid JSON response from an MCP tool that returns both a text description and an image: - -``` -{ - "content": [ - { - "type": "text", - "text": "Here is the logo you requested." - }, - { - "type": "image", - "data": "BASE64_ENCODED_IMAGE_DATA_HERE", - "mimeType": "image/png" - }, - { - "type": "text", - "text": "The logo was created in 2025." - } - ] -} -``` - -When Qwen Code receives this response, it will: - -1. Extract all the text and combine it into a single `functionResponse` part for the model. -2. Present the image data as a separate `inlineData` part. -3. Provide a clean, user-friendly summary in the CLI, indicating that both text and an image were received. - -This enables you to build sophisticated tools that can provide rich, multi-modal context to the Qwen model. - -## MCP Prompts as Slash Commands - -In addition to tools, MCP servers can expose predefined prompts that can be executed as slash commands within Qwen Code. This allows you to create shortcuts for common or complex queries that can be easily invoked by name. - -### Defining Prompts on the Server - -Here’s a small example of a stdio MCP server that defines prompts: - -``` -import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; -import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; -import { z } from 'zod'; - -const server = new McpServer({ - name: 'prompt-server', - version: '1.0.0', -}); - -server.registerPrompt( - 'poem-writer', - { - title: 'Poem Writer', - description: 'Write a nice haiku', - argsSchema: { title: z.string(), mood: z.string().optional() }, - }, - ({ title, mood }) => ({ - messages: [ - { - role: 'user', - content: { - type: 'text', - text: `Write a haiku${mood ? ` with the mood ${mood}` : ''} called ${title}. Note that a haiku is 5 syllables followed by 7 syllables followed by 5 syllables `, - }, - }, - ], - }), -); - -const transport = new StdioServerTransport(); -await server.connect(transport); -``` - -This can be included in `settings.json` under `mcpServers` with: - -``` -{ - "mcpServers": { - "nodeServer": { - "command": "node", - "args": ["filename.ts"] - } - } -} -``` - -### Invoking Prompts - -Once a prompt is discovered, you can invoke it using its name as a slash command. The CLI will automatically handle parsing arguments. - -``` -/poem-writer --title="Qwen Code" --mood="reverent" -``` - -or, using positional arguments: - -``` -/poem-writer "Qwen Code" reverent -``` - -When you run this command, the CLI executes the `prompts/get` method on the MCP server with the provided arguments. The server is responsible for substituting the arguments into the prompt template and returning the final prompt text. The CLI then sends this prompt to the model for execution. This provides a convenient way to automate and share common workflows. - -## Managing MCP Servers with `qwen mcp` - -While you can always configure MCP servers by manually editing your `settings.json` file, the CLI provides a convenient set of commands to manage your server configurations programmatically. These commands streamline the process of adding, listing, and removing MCP servers without needing to directly edit JSON files. - -### Adding a Server (`qwen mcp add`) - -The `add` command configures a new MCP server in your `settings.json`. Based on the scope (`-s, --scope`), it will be added to either the user config `~/.qwen/settings.json` or the project config `.qwen/settings.json`file. - -**Command:** - -``` -qwen mcp add [options] [args...] -``` - -- ``: A unique name for the server. -- ``: The command to execute (for `stdio`) or the URL (for `http`/`sse`). -- `[args...]`: Optional arguments for a `stdio` command. - -**Options (Flags):** - -- `-s, --scope`: Configuration scope (user or project). [default: “project”] -- `-t, --transport`: Transport type (stdio, sse, http). [default: “stdio”] -- `-e, --env`: Set environment variables (e.g. -e KEY=value). -- `-H, --header`: Set HTTP headers for SSE and HTTP transports (e.g. -H “X-Api-Key: abc123” -H “Authorization: Bearer abc123”). -- `--timeout`: Set connection timeout in milliseconds. -- `--trust`: Trust the server (bypass all tool call confirmation prompts). -- `--description`: Set the description for the server. -- `--include-tools`: A comma-separated list of tools to include. -- `--exclude-tools`: A comma-separated list of tools to exclude. - -#### Adding an stdio server - -This is the default transport for running local servers. - -``` -# Basic syntax -qwen mcp add [args...] - -# Example: Adding a local server -qwen mcp add my-stdio-server -e API_KEY=123 /path/to/server arg1 arg2 arg3 - -# Example: Adding a local python server -qwen mcp add python-server python server.py --port 8080 -``` - -#### Adding an HTTP server - -This transport is for servers that use the streamable HTTP transport. - -``` -# Basic syntax -qwen mcp add --transport http - -# Example: Adding an HTTP server -qwen mcp add --transport http http-server https://api.example.com/mcp/ - -# Example: Adding an HTTP server with an authentication header -qwen mcp add --transport http secure-http https://api.example.com/mcp/ --header "Authorization: Bearer abc123" -``` - -#### Adding an SSE server - -This transport is for servers that use Server-Sent Events (SSE). - -``` -# Basic syntax -qwen mcp add --transport sse - -# Example: Adding an SSE server -qwen mcp add --transport sse sse-server https://api.example.com/sse/ - -# Example: Adding an SSE server with an authentication header -qwen mcp add --transport sse secure-sse https://api.example.com/sse/ --header "Authorization: Bearer abc123" -``` - -### Listing Servers (`qwen mcp list`) - -To view all MCP servers currently configured, use the `list` command. It displays each server’s name, configuration details, and connection status. - -**Command:** - -``` -qwen mcp list -``` - -**Example Output:** - -``` -✓ stdio-server: command: python3 server.py (stdio) - Connected -✓ http-server: https://api.example.com/mcp (http) - Connected -✗ sse-server: https://api.example.com/sse (sse) - Disconnected -``` - -### Removing a Server (`qwen mcp remove`) - -To delete a server from your configuration, use the `remove` command with the server’s name. - -**Command:** - -``` -qwen mcp remove -``` - -**Example:** - -``` -qwen mcp remove my-server -``` - -This will find and delete the “my-server” entry from the `mcpServers` object in the appropriate `settings.json`file based on the scope (`-s, --scope`).