Overview
The Model Context Protocol (MCP) is a standardized protocol for exposing tools and resources to AI agents. Qwen-Agent supports MCP integration, allowing you to connect to any MCP-compatible server and use its tools seamlessly.
Quick Start
Here’s an example using an MCP SQLite server (examples/assistant_mcp_sqlite_bot.py:27):
from qwen_agent.agents import Assistant
llm_cfg = {'model': 'qwen-max'}
system = 'You are a database assistant with database query capabilities'
tools = [{
"mcpServers": {
"sqlite": {
"command": "uvx",
"args": [
"mcp-server-sqlite",
"--db-path",
"test.db"
]
}
}
}]
bot = Assistant(
llm=llm_cfg,
system_message=system,
function_list=tools
)
messages = [{'role': 'user', 'content': 'How many tables are in the database?'}]
for response in bot.run(messages):
print(response)
What is MCP?
MCP provides a standard way for servers to expose:
- Tools: Functions that agents can call
- Resources: Data sources and APIs
- Prompts: Pre-defined prompt templates
Benefits:
- ✅ Standardized protocol across different tools
- ✅ Easy integration with existing MCP servers
- ✅ Community-maintained server ecosystem
- ✅ Automatic tool discovery and registration
MCP servers are configured using a specific format in the function_list:
{
"mcpServers": {
"server_name": {
"command": "command_to_run",
"args": ["arg1", "arg2", ...],
"env": {"ENV_VAR": "value"} # Optional
}
}
}
Configuration Structure
| Field | Type | Description |
|---|
mcpServers | dict | Container for MCP server configurations |
server_name | str | Unique identifier for the server |
command | str | Command to launch the MCP server |
args | list | Command-line arguments |
env | dict | Optional environment variables |
Available MCP Servers
The MCP ecosystem includes many pre-built servers:
Database Servers
SQLite
tools = [{
"mcpServers": {
"sqlite": {
"command": "uvx",
"args": [
"mcp-server-sqlite",
"--db-path",
"database.db"
]
}
}
}]
PostgreSQL
tools = [{
"mcpServers": {
"postgres": {
"command": "uvx",
"args": ["mcp-server-postgres"],
"env": {
"POSTGRES_CONNECTION": "postgresql://user:pass@localhost/dbname"
}
}
}
}]
File System
tools = [{
"mcpServers": {
"filesystem": {
"command": "uvx",
"args": [
"mcp-server-filesystem",
"--allowed-directories",
"/path/to/safe/directory"
]
}
}
}]
Web Search
tools = [{
"mcpServers": {
"brave_search": {
"command": "uvx",
"args": ["mcp-server-brave-search"],
"env": {
"BRAVE_API_KEY": "your_api_key"
}
}
}
}]
Complete Example: Database Assistant
Here’s a complete application using MCP (examples/assistant_mcp_sqlite_bot.py):
from qwen_agent.agents import Assistant
from qwen_agent.gui import WebUI
def init_agent_service():
llm_cfg = {'model': 'qwen-max'}
system = 'You act as a database assistant with database query capabilities'
tools = [{
"mcpServers": {
"sqlite": {
"command": "uvx",
"args": [
"mcp-server-sqlite",
"--db-path",
"test.db"
]
}
}
}]
bot = Assistant(
llm=llm_cfg,
name='Database Assistant',
description='Database query assistant',
system_message=system,
function_list=tools
)
return bot
def app_gui():
bot = init_agent_service()
chatbot_config = {
'prompt.suggestions': [
'How many tables are in the database?',
'Create a student table with name and age',
'Add a student named Han Meimei, 6 years old',
]
}
WebUI(bot, chatbot_config=chatbot_config).run()
if __name__ == '__main__':
app_gui()
Multiple MCP Servers
You can configure multiple MCP servers simultaneously:
tools = [{
"mcpServers": {
# Database access
"sqlite": {
"command": "uvx",
"args": ["mcp-server-sqlite", "--db-path", "data.db"]
},
# File system access
"filesystem": {
"command": "uvx",
"args": [
"mcp-server-filesystem",
"--allowed-directories",
"/workspace"
]
},
# Web search
"search": {
"command": "uvx",
"args": ["mcp-server-brave-search"],
"env": {"BRAVE_API_KEY": "your_key"}
}
}
}]
bot = Assistant(
llm={'model': 'qwen-max'},
function_list=tools
)
MCP tools work alongside built-in tools:
from qwen_agent.agents import Assistant
tools = [
# Built-in tool
'code_interpreter',
# MCP server
{
"mcpServers": {
"sqlite": {
"command": "uvx",
"args": ["mcp-server-sqlite", "--db-path", "data.db"]
}
}
}
]
bot = Assistant(
llm={'model': 'qwen-max'},
function_list=tools
)
# Agent can now use both code_interpreter AND sqlite tools
messages = [{
'role': 'user',
'content': 'Query the database and visualize the results with matplotlib'
}]
for response in bot.run(messages):
print(response)
How MCP Integration Works
The MCP integration process (qwen_agent/tools/base.py:218):
1. Agent initialization
↓
2. MCPManager.initConfig()
↓
3. Launch MCP server process
↓
4. Discover available tools
↓
5. Register tools in function_map
↓
6. Tools available for agent use
When you add an MCP server to function_list:
# Agent.__init__ detects mcpServers key
if isinstance(tool, dict) and 'mcpServers' in tool:
# Initialize MCP connection
tools = MCPManager().initConfig(tool)
# Register each discovered tool
for tool in tools:
self.function_map[tool.name] = tool
Creating Custom MCP Servers
You can create your own MCP servers in any language:
Python Example
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool
# Create server
app = Server("my-custom-server")
# Define a tool
@app.tool()
async def calculate_sum(a: int, b: int) -> int:
"""Calculate the sum of two numbers."""
return a + b
# Run server
if __name__ == "__main__":
stdio_server(app)
Using Your Custom Server
tools = [{
"mcpServers": {
"my_server": {
"command": "python",
"args": ["my_custom_server.py"]
}
}
}]
bot = Assistant(
llm={'model': 'qwen-max'},
function_list=tools
)
Environment Configuration
Pass environment variables to MCP servers:
tools = [{
"mcpServers": {
"api_server": {
"command": "uvx",
"args": ["mcp-server-api"],
"env": {
"API_KEY": "your_secret_key",
"API_ENDPOINT": "https://api.example.com",
"DEBUG": "true"
}
}
}
}]
Environment variables are passed securely to the MCP server process and are not exposed in logs or responses.
Security Considerations
Security Best Practices
- Only use trusted MCP servers from verified sources
- Limit file system access with
--allowed-directories
- Store API keys in environment variables, not in code
- Review server source code before deployment
- Use minimal permissions for database connections
- Monitor server resource usage
Safe Configuration Example
import os
tools = [{
"mcpServers": {
"filesystem": {
"command": "uvx",
"args": [
"mcp-server-filesystem",
"--allowed-directories",
"/safe/workspace/only", # Restrict access
"--readonly" # Read-only mode
]
},
"database": {
"command": "uvx",
"args": ["mcp-server-postgres"],
"env": {
# Use environment variables
"POSTGRES_CONNECTION": os.getenv('DB_CONNECTION')
}
}
}
}]
Troubleshooting
Server Not Found
Error: Command 'uvx' not found
Solution: Install uvx (uv package runner):
Connection Failed
Error: Failed to connect to MCP server
Solution: Verify the server command works standalone:
uvx mcp-server-sqlite --db-path test.db
# Check if tools were registered
bot = Assistant(llm={'model': 'qwen-max'}, function_list=[mcp_config])
print(bot.function_map.keys()) # Should show MCP tools
Database Connection Issues
# Test database connection first
import sqlite3
conn = sqlite3.connect('test.db')
print("Database accessible")
conn.close()
Best Practices
MCP Integration Tips
- Test MCP servers independently before integration
- Use descriptive
server_name values for clarity
- Keep server configurations in separate config files
- Document required environment variables
- Implement error handling for server failures
- Monitor server logs during development
MCP Server Resources
Official Servers
- mcp-server-sqlite: SQLite database access
- mcp-server-postgres: PostgreSQL database access
- mcp-server-filesystem: File system operations
- mcp-server-brave-search: Web search via Brave API
- mcp-server-github: GitHub repository access
Installation
# Using uvx (recommended)
uvx mcp-server-sqlite --help
# Or install globally
pip install mcp-server-sqlite
Next Steps