What is MCP?
The Model Context Protocol (MCP) is a standardized way to connect AI agents to external tools and data sources. MCP servers expose tools that DeerFlow can automatically discover and integrate.
MCP Capabilities
File Systems Access local or remote file systems
Databases Query PostgreSQL, SQLite, and other databases
External APIs Integrate GitHub, Brave Search, and more
Browser Automation Control browsers with Puppeteer
MCP Transport Types
DeerFlow supports three MCP transport mechanisms:
stdio
SSE (Server-Sent Events)
HTTP
Standard input/output communication with a subprocess. Best for : Local command-line tools, Node.js scripts{
"type" : "stdio" ,
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-github" ],
"env" : {
"GITHUB_TOKEN" : "$GITHUB_TOKEN"
}
}
HTTP-based streaming communication. Best for : Remote services, cloud-hosted tools{
"type" : "sse" ,
"url" : "https://api.example.com/mcp" ,
"headers" : {
"Authorization" : "Bearer $API_TOKEN"
}
}
Standard HTTP request/response. Best for : RESTful APIs, stateless services{
"type" : "http" ,
"url" : "https://api.example.com/mcp" ,
"headers" : {
"X-API-Key" : "$API_KEY"
}
}
Configuration
MCP servers are configured in extensions_config.json (separate from config.yaml).
Copy Example Configuration
cp extensions_config.example.json extensions_config.json
Configure MCP Servers
Edit extensions_config.json: {
"mcpServers" : {
"github" : {
"enabled" : true ,
"type" : "stdio" ,
"command" : "npx" ,
"args" : [
"-y" ,
"@modelcontextprotocol/server-github"
],
"env" : {
"GITHUB_TOKEN" : "$GITHUB_TOKEN"
}
},
"filesystem" : {
"enabled" : true ,
"type" : "stdio" ,
"command" : "npx" ,
"args" : [
"-y" ,
"@modelcontextprotocol/server-filesystem" ,
"/path/to/allowed/directory"
]
},
"postgres" : {
"enabled" : false ,
"type" : "stdio" ,
"command" : "npx" ,
"args" : [
"-y" ,
"@modelcontextprotocol/server-postgres" ,
"postgresql://user:pass@localhost/db"
]
}
}
}
Set Environment Variables
Set required API tokens in .env: GITHUB_TOKEN = your-github-token
Restart DeerFlow
MCP servers are loaded automatically on startup.
OAuth for HTTP/SSE Servers
For HTTP and SSE transport types, DeerFlow supports OAuth token acquisition and automatic refresh.
Supported Grant Types
client_credentials
refresh_token
OAuth 2.0 client credentials flow. {
"mcpServers" : {
"secure-api" : {
"enabled" : true ,
"type" : "http" ,
"url" : "https://api.example.com/mcp" ,
"oauth" : {
"enabled" : true ,
"token_url" : "https://auth.example.com/oauth/token" ,
"grant_type" : "client_credentials" ,
"client_id" : "$MCP_CLIENT_ID" ,
"client_secret" : "$MCP_CLIENT_SECRET" ,
"scope" : "mcp.read mcp.write"
}
}
}
}
OAuth 2.0 refresh token flow. {
"mcpServers" : {
"secure-api" : {
"enabled" : true ,
"type" : "sse" ,
"url" : "https://api.example.com/mcp" ,
"oauth" : {
"enabled" : true ,
"token_url" : "https://auth.example.com/oauth/token" ,
"grant_type" : "refresh_token" ,
"client_id" : "$MCP_CLIENT_ID" ,
"client_secret" : "$MCP_CLIENT_SECRET" ,
"refresh_token" : "$MCP_REFRESH_TOKEN" ,
"scope" : "mcp.read"
}
}
}
}
OAuth Configuration Options
{
"oauth" : {
"enabled" : true ,
"token_url" : "https://auth.example.com/oauth/token" ,
"grant_type" : "client_credentials" , // or "refresh_token"
"client_id" : "$MCP_OAUTH_CLIENT_ID" ,
"client_secret" : "$MCP_OAUTH_CLIENT_SECRET" ,
"scope" : "mcp.read mcp.write" ,
"refresh_skew_seconds" : 60 // Refresh tokens 60s before expiry
}
}
DeerFlow automatically refreshes tokens before they expire based on refresh_skew_seconds.
Popular MCP Servers
Official MCP Servers
Access GitHub repositories, issues, and pull requests. {
"github" : {
"enabled" : true ,
"type" : "stdio" ,
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-github" ],
"env" : {
"GITHUB_TOKEN" : "$GITHUB_TOKEN"
}
}
}
Get token : github.com/settings/tokens
Read and write files in allowed directories. {
"filesystem" : {
"enabled" : true ,
"type" : "stdio" ,
"command" : "npx" ,
"args" : [
"-y" ,
"@modelcontextprotocol/server-filesystem" ,
"/Users/username/Documents" ,
"/Users/username/Projects"
]
}
}
Only directories listed in args are accessible. Choose carefully for security.
Query PostgreSQL databases. {
"postgres" : {
"enabled" : true ,
"type" : "stdio" ,
"command" : "npx" ,
"args" : [
"-y" ,
"@modelcontextprotocol/server-postgres" ,
"postgresql://user:password@localhost:5432/database"
]
}
}
Web and local search using Brave. {
"brave-search" : {
"enabled" : true ,
"type" : "stdio" ,
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-brave-search" ],
"env" : {
"BRAVE_API_KEY" : "$BRAVE_API_KEY"
}
}
}
Get API key : brave.com/search/api
Browser automation and web scraping. {
"puppeteer" : {
"enabled" : true ,
"type" : "stdio" ,
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-puppeteer" ]
}
}
Find more servers in the MCP Servers Directory
Managing MCP Servers
Via API
Manage MCP configuration programmatically:
Get Configuration
Update Configuration
List Available Tools
curl http://localhost:2026/api/mcp/config
Dynamic Reloading
DeerFlow automatically detects changes to extensions_config.json:
Edit extensions_config.json
Save the file
MCP manager detects file change
New configuration loaded automatically
Next agent run uses updated tools
No restart required when modifying extensions_config.json.
Creating Custom MCP Servers
Create your own MCP server:
Choose Language/Framework
MCP servers can be written in any language. Official SDKs:
Python: mcp package
TypeScript: @modelcontextprotocol/sdk
Implement MCP Protocol
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" ,
},
{
capabilities: {
tools: {},
},
}
);
// Register tools
server . setRequestHandler ( "tools/list" , async () => {
return {
tools: [
{
name: "my_tool" ,
description: "Does something useful" ,
inputSchema: {
type: "object" ,
properties: {
param: { type: "string" }
}
}
}
]
};
});
// Handle tool calls
server . setRequestHandler ( "tools/call" , async ( request ) => {
// Implement tool logic
return { result: "success" };
});
// Start server
const transport = new StdioServerTransport ();
await server . connect ( transport );
Package and Publish
{
"name" : "mcp-server-custom" ,
"version" : "1.0.0" ,
"bin" : {
"mcp-server-custom" : "./dist/index.js"
}
}
Publish to npm or use locally.
Configure in DeerFlow
{
"mcpServers" : {
"my-custom-server" : {
"enabled" : true ,
"type" : "stdio" ,
"command" : "npx" ,
"args" : [ "-y" , "mcp-server-custom" ]
}
}
}
Security Considerations
MCP servers have access to sensitive resources. Configure carefully.
Best Practices
Use Environment Variables for Secrets
"env" : {
"API_KEY" : "$MY_API_KEY" // ✅ From .env
}
Never hardcode:
"env" : {
"API_KEY" : "sk-12345..." // ❌ Exposed in config
}
Limit Filesystem Access
[
"/Users/me/safe-directory" // ✅ Specific directory
]
Avoid:
[
"/" // ❌ Full system access
]
Disable Unused Servers
{
"enabled" : false // Disabled servers don't load
}
Review Server Code
Check source code of community servers
Verify npm package authenticity
Use official servers when available
Troubleshooting
Check logs for errors: Common issues:
Missing npm packages: npx will auto-install, but may fail
Invalid command path
Missing environment variables
Permission issues
OAuth authentication fails
Verify:
Token URL is correct
Client ID and secret are valid
Scope is appropriate
Environment variables are set
Check logs for OAuth errors: tail -f logs/gateway.log | grep oauth
Server crashes frequently
Add error logging to server code. Consider using http or sse transport instead of stdio for better error handling. Wrap server execution in a restart script: #!/bin/bash
while true ; do
npx -y @modelcontextprotocol/server-custom
echo "Server crashed, restarting..."
sleep 5
done
Next Steps
Custom Tools Learn about creating Python tools
Creating Skills Build skills that use MCP tools
MCP Specification Read the official MCP documentation
MCP Servers Browse community MCP servers