> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/QwenLM/qwen-code/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Context Protocol (MCP)

> Extend Qwen Code with MCP servers for additional tools and context

## Overview

The Model Context Protocol (MCP) is an open standard that allows AI assistants to connect to external data sources and tools. Qwen Code supports MCP, enabling you to:

* **Add custom tools** from MCP servers
* **Access external data** (databases, APIs, filesystems)
* **Integrate services** (GitHub, Slack, Jira, etc.)
* **Build extensions** without modifying Qwen Code
* **Share tools** across different AI assistants

<Info>
  MCP is an open standard by Anthropic. Learn more at [modelcontextprotocol.io](https://modelcontextprotocol.io)
</Info>

## Quick Start

### Add an MCP Server

```bash theme={null}
# Add filesystem server (stdio transport)
qwen mcp add filesystem npx -y @modelcontextprotocol/server-filesystem /path/to/directory

# Add GitHub server (stdio transport)
qwen mcp add github npx -y @modelcontextprotocol/server-github

# Add HTTP server
qwen mcp add my-api https://api.example.com/mcp --transport http

# Add SSE server
qwen mcp add events https://events.example.com/mcp --transport sse
```

### List MCP Servers

```bash theme={null}
# Command line
qwen mcp list

# Interactive mode
/mcp
```

### Remove an MCP Server

```bash theme={null}
qwen mcp remove github
```

## MCP Transports

Qwen Code supports three MCP transport types:

<Tabs>
  <Tab title="STDIO (Standard I/O)">
    **Use for:** Local processes, command-line tools

    ```bash theme={null}
    qwen mcp add myserver node /path/to/server.js
    ```

    The server:

    * Runs as a subprocess
    * Communicates via stdin/stdout
    * Started on-demand
    * Stopped when Qwen Code exits

    **Example servers:**

    * `@modelcontextprotocol/server-filesystem`
    * `@modelcontextprotocol/server-github`
    * `@modelcontextprotocol/server-postgres`
    * Custom Node.js/Python servers
  </Tab>

  <Tab title="HTTP">
    **Use for:** Remote services, long-running servers

    ```bash theme={null}
    qwen mcp add api https://api.example.com/mcp --transport http
    ```

    The server:

    * Runs independently (not managed by Qwen Code)
    * Uses HTTP request/response
    * Can handle multiple clients
    * Stateless or stateful

    **When to use:**

    * Shared team services
    * Production APIs
    * Services with authentication
    * Multi-tenant servers
  </Tab>

  <Tab title="SSE (Server-Sent Events)">
    **Use for:** Streaming data, real-time updates

    ```bash theme={null}
    qwen mcp add events https://events.example.com/mcp --transport sse
    ```

    The server:

    * Pushes updates to the client
    * Long-lived connection
    * Streaming responses
    * Real-time notifications

    **When to use:**

    * Real-time data feeds
    * Progress updates for long operations
    * Event streams
    * Live monitoring
  </Tab>
</Tabs>

## Configuration

### Settings File

MCP servers are configured in your settings:

```json theme={null}
// ~/.qwen/settings.json or .qwen/settings.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"],
      "env": {
        "NODE_ENV": "production"
      }
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      },
      "trust": true
    },
    "company-api": {
      "httpUrl": "https://api.company.com/mcp",
      "headers": {
        "Authorization": "Bearer ${API_TOKEN}",
        "X-Client-Id": "qwen-code"
      },
      "timeout": 30000
    },
    "events": {
      "url": "https://events.company.com/mcp",
      "headers": {
        "Authorization": "Bearer ${EVENTS_TOKEN}"
      }
    }
  }
}
```

### Command Line Options

```bash theme={null}
# Add with environment variables
qwen mcp add postgres \
  npx -y @modelcontextprotocol/server-postgres \
  -e DATABASE_URL="postgresql://localhost/mydb"

# Add with custom timeout
qwen mcp add slow-api \
  https://api.example.com/mcp \
  --transport http \
  --timeout 60000

# Add with headers
qwen mcp add auth-api \
  https://api.example.com/mcp \
  --transport http \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Client-Id: qwen"

# Add with description
qwen mcp add github \
  npx -y @modelcontextprotocol/server-github \
  --description "GitHub API integration for issues and PRs"

# Trust server (bypass approval prompts)
qwen mcp add trusted \
  npx -y @company/trusted-server \
  --trust

# Selectively enable tools
qwen mcp add github \
  npx -y @modelcontextprotocol/server-github \
  --include-tools "create_issue,list_issues"

# Exclude specific tools
qwen mcp add github \
  npx -y @modelcontextprotocol/server-github \
  --exclude-tools "delete_repository"
```

## Using MCP Tools

Once configured, MCP tools are available to the AI:

```
> List all issues in the main repository

I'll use the GitHub MCP server to list issues...

✓ Executed: mcp_tool("github", "list_issues", {"repo": "owner/repo"})

Found 42 open issues:
1. Fix authentication bug (#123)
2. Add dark mode (#124)
...
```

### Tool Discovery

The AI automatically discovers available tools:

```bash theme={null}
# In interactive mode
/mcp
```

Shows:

* Connected servers
* Available tools from each server
* Tool descriptions and parameters
* Connection status

### Manual Tool Invocation

You can request specific MCP tools:

```
> Use the GitHub server to create an issue titled "Add tests" with body "We need more test coverage"

✓ Executed: mcp_tool("github", "create_issue", {
  "title": "Add tests",
  "body": "We need more test coverage",
  "repo": "owner/repo"
})

Created issue #125
```

## Approval and Security

### First-Use Approval

By default, MCP tools require approval on first use:

```
? Allow MCP tool call?
  Server: github
  Tool: create_issue
  Args: { title: "Bug fix", ... }
  
  [Allow] [Reject] [Always Allow Server] [Always Allow Tool]
```

Choices:

* **Allow**: Execute once
* **Reject**: Skip this call
* **Always Allow Server**: Trust all tools from this server
* **Always Allow Tool**: Trust this specific tool

### Trusted Servers

Mark servers as trusted to skip approval:

```json theme={null}
{
  "mcpServers": {
    "trusted-server": {
      "command": "...",
      "trust": true  // Skip approval for all tools
    }
  }
}
```

```bash theme={null}
# Or via command line
qwen mcp add trusted npx -y @company/trusted-server --trust
```

<Warning>
  Only trust MCP servers you control or from reputable sources. MCP tools can read/write files, make network requests, and execute code.
</Warning>

### Tool Filtering

Limit which tools are available:

```json theme={null}
{
  "mcpServers": {
    "github": {
      "command": "...",
      "includeTools": ["list_issues", "create_issue", "comment_issue"],
      "excludeTools": ["delete_repository", "force_push"]
    }
  }
}
```

## Popular MCP Servers

<AccordionGroup>
  <Accordion title="@modelcontextprotocol/server-filesystem">
    **Purpose:** Access files outside the workspace

    ```bash theme={null}
    qwen mcp add filesystem \
      npx -y @modelcontextprotocol/server-filesystem \
      /home/user/documents
    ```

    **Tools:**

    * `read_file` - Read files
    * `write_file` - Write files
    * `list_directory` - List files
    * `search_files` - Search content

    **Use cases:**

    * Access data directories
    * Read configuration files
    * Process documents
    * Manage assets
  </Accordion>

  <Accordion title="@modelcontextprotocol/server-github">
    **Purpose:** GitHub API integration

    ```bash theme={null}
    export GITHUB_TOKEN="ghp_..."
    qwen mcp add github \
      npx -y @modelcontextprotocol/server-github
    ```

    **Tools:**

    * `list_issues` - List issues
    * `create_issue` - Create issues
    * `comment_issue` - Comment on issues
    * `list_pull_requests` - List PRs
    * `create_pull_request` - Create PRs
    * And many more...

    **Use cases:**

    * Automate issue management
    * Create PRs from changes
    * Code review automation
    * Project management
  </Accordion>

  <Accordion title="@modelcontextprotocol/server-postgres">
    **Purpose:** PostgreSQL database access

    ```bash theme={null}
    export DATABASE_URL="postgresql://localhost/mydb"
    qwen mcp add postgres \
      npx -y @modelcontextprotocol/server-postgres
    ```

    **Tools:**

    * `query` - Execute SQL queries
    * `list_tables` - List tables
    * `describe_table` - Get table schema

    **Use cases:**

    * Data analysis
    * Schema exploration
    * Query generation
    * Data migration
  </Accordion>

  <Accordion title="@modelcontextprotocol/server-slack">
    **Purpose:** Slack integration

    ```bash theme={null}
    export SLACK_TOKEN="xoxb-..."
    qwen mcp add slack \
      npx -y @modelcontextprotocol/server-slack
    ```

    **Tools:**

    * `send_message` - Send messages
    * `list_channels` - List channels
    * `search_messages` - Search history

    **Use cases:**

    * Send notifications
    * Automate workflows
    * Analyze conversations
    * Team communication
  </Accordion>
</AccordionGroup>

## Building Custom MCP Servers

### Node.js Example

```typescript theme={null}
// server.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new Server({
  name: 'my-custom-server',
  version: '1.0.0',
});

// Register a tool
server.tool(
  'greet',
  'Greets a user by name',
  {
    name: {
      type: 'string',
      description: 'The name to greet',
    },
  },
  async ({ name }) => ({
    content: [
      {
        type: 'text',
        text: `Hello, ${name}! Welcome to my custom MCP server.`,
      },
    ],
  })
);

// Start the server
const transport = new StdioServerTransport();
await server.connect(transport);
```

Build and use:

```bash theme={null}
# Build
npx tsc server.ts

# Add to Qwen Code
qwen mcp add custom node /path/to/server.js

# Use it
> Greet Alice using the custom server

✓ Executed: mcp_tool("custom", "greet", {"name": "Alice"})

Hello, Alice! Welcome to my custom MCP server.
```

### Python Example

```python theme={null}
# server.py
from mcp.server import Server
from mcp.server.stdio import stdio_server

app = Server("my-python-server")

@app.tool(
    name="calculate",
    description="Performs a calculation"
)
async def calculate(expression: str) -> str:
    try:
        result = eval(expression)  # Be careful with eval!
        return f"Result: {result}"
    except Exception as e:
        return f"Error: {str(e)}"

if __name__ == "__main__":
    stdio_server(app)
```

Use:

```bash theme={null}
qwen mcp add calc python /path/to/server.py
```

## Advanced Features

### Context Providers

MCP servers can provide context (not just tools):

```typescript theme={null}
// Server provides repository context
server.resource(
  'repo-info',
  'Information about the current repository',
  async () => ({
    content: [
      {
        type: 'text',
        text: 'Repository: owner/repo\nBranch: main\nLast commit: abc123',
      },
    ],
  })
);
```

Qwen Code automatically includes this context when relevant.

### Prompts

MCP servers can provide reusable prompts:

```typescript theme={null}
server.prompt(
  'code-review',
  'Comprehensive code review template',
  async () => ({
    messages: [
      {
        role: 'user',
        content: [
          {
            type: 'text',
            text: 'Review this code for security, performance, and best practices.',
          },
        ],
      },
    ],
  })
);
```

Invoke MCP prompts:

```bash theme={null}
# List prompts
/mcp

# Use a prompt (shown in UI as available commands)
```

### Sampling

MCP servers can request AI completions:

```typescript theme={null}
// Inside a tool implementation
const response = await server.sample({
  messages: [
    {
      role: 'user',
      content: 'Explain this code briefly',
    },
  ],
  maxTokens: 100,
});
```

This allows MCP servers to use AI for their own logic.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Server won't start">
    **Problem:** MCP server fails to connect.

    **Solutions:**

    * Check command is correct: `qwen mcp list` shows command
    * Verify dependencies installed: `npm list -g @modelcontextprotocol/server-*`
    * Check environment variables are set
    * Look at debug logs: `DEBUG=qwen:mcp qwen`
    * Test server manually: `npx @modelcontextprotocol/server-github --help`
  </Accordion>

  <Accordion title="Tools not available">
    **Problem:** MCP tools don't appear or can't be used.

    **Solutions:**

    * Verify server is connected: `/mcp`
    * Check tool filtering: `includeTools`/`excludeTools` in config
    * Ensure server implements the tool correctly
    * Try removing and re-adding the server
  </Accordion>

  <Accordion title="Authentication errors">
    **Problem:** MCP server can't authenticate to external service.

    **Solutions:**

    * Check environment variables: `echo $GITHUB_TOKEN`
    * Verify token has correct permissions
    * Use `${VAR}` syntax in settings for env var expansion
    * Check headers are correctly configured
  </Accordion>

  <Accordion title="Slow or hanging">
    **Problem:** MCP tool calls are very slow.

    **Solutions:**

    * Increase timeout: `"timeout": 60000`
    * Check server performance
    * Use HTTP transport for remote servers (not stdio)
    * Enable streaming responses if supported
  </Accordion>

  <Accordion title="Permission denied">
    **Problem:** MCP tool requires approval even when trusted.

    **Solutions:**

    * Set `"trust": true` in server config
    * Or use YOLO approval mode: `--approval-mode yolo`
    * Check persistent approvals: `/permissions`
  </Accordion>
</AccordionGroup>

## Best Practices

1. **Start with stdio**: Use stdio transport for local servers, HTTP for remote
2. **Set timeouts**: Prevent hanging with reasonable timeout values
3. **Use environment variables**: Don't hardcode secrets in settings
4. **Filter tools**: Only enable tools you need for security
5. **Trust carefully**: Only set `trust: true` for servers you control
6. **Test separately**: Verify MCP servers work outside Qwen Code first
7. **Version control**: Commit project-level MCP configs (without secrets)
8. **Document setup**: Create README for team members setting up MCP servers
9. **Monitor usage**: Check logs if servers behave unexpectedly
10. **Update regularly**: Keep MCP SDK and servers up to date

## Examples

### Database Analysis

```bash theme={null}
# Setup
export DATABASE_URL="postgresql://localhost/myapp"
qwen mcp add db npx -y @modelcontextprotocol/server-postgres

# Use
qwen --prompt "Analyze the users table and suggest indexes"
```

### GitHub Automation

```bash theme={null}
# Setup  
export GITHUB_TOKEN="ghp_..."
qwen mcp add github npx -y @modelcontextprotocol/server-github

# Use
qwen --approval-mode yolo \
  --prompt "Create an issue for each TODO comment in the code"
```

### Custom Integration

```typescript theme={null}
// company-server.ts - Custom MCP server for your company
import { Server } from '@modelcontextprotocol/sdk/server/index.js';

const server = new Server({ name: 'company-tools', version: '1.0.0' });

// Jira integration
server.tool('create_jira_ticket', 'Create a Jira ticket', {
  summary: { type: 'string' },
  description: { type: 'string' },
  priority: { type: 'string', enum: ['Low', 'Medium', 'High'] },
}, async (args) => {
  // Call Jira API
  const ticket = await jira.createIssue(args);
  return { content: [{ type: 'text', text: `Created ${ticket.key}` }] };
});

// Slack integration
server.tool('notify_team', 'Send Slack notification', {
  channel: { type: 'string' },
  message: { type: 'string' },
}, async (args) => {
  await slack.postMessage(args.channel, args.message);
  return { content: [{ type: 'text', text: 'Notification sent' }] };
});

// Deploy tool
server.tool('deploy', 'Deploy to environment', {
  environment: { type: 'string', enum: ['staging', 'production'] },
}, async (args) => {
  await deploy(args.environment);
  return { content: [{ type: 'text', text: `Deployed to ${args.environment}` }] };
});

// Start server
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
await server.connect(new StdioServerTransport());
```

```bash theme={null}
# Add to Qwen Code
qwen mcp add company node /path/to/company-server.js

# Use
qwen --approval-mode yolo \
  --prompt "Fix the auth bug, create a Jira ticket for tracking, and notify the team"
```

## Next Steps

<CardGroup cols={2}>
  <Card title="MCP SDK Documentation" icon="book" href="https://modelcontextprotocol.io">
    Learn to build custom MCP servers
  </Card>

  <Card title="Approval Modes" icon="shield" href="/features/approval-modes">
    Control MCP tool permissions
  </Card>

  <Card title="Configuration" icon="gear" href="/configuration/settings">
    Advanced MCP configuration
  </Card>

  <Card title="Examples" icon="code" href="/examples/mcp-servers">
    Browse MCP server examples
  </Card>
</CardGroup>
