Skip to main content

CrewAI Research Agent

Multi-agent crew with MCP web research tools.

Difficulty: Intermediate

What You'll Learn

  • CrewAI @CrewBase pattern with @agent, @task, @crew decorators
  • Sequential multi-agent workflow (researcher → writer)
  • MCP tool integration with get_mcp_tools()
  • Proxy credential substitution for LLM API keys
  • Policy enforcement for MCP and HTTP access

Agents

AgentRoleTools
ResearcherSenior ResearcherMCP fetch tools (web fetch)
WriterTechnical WriterNone (synthesizes from research)

Setup

agentvisor template create crewai/research-agent
cd research-agent

export ANTHROPIC_API_KEY=sk-ant-...
temporal server start-dev &
agentvisor serve . --sandbox=none

Test It

THREAD=$(curl -sX POST http://localhost:8090/threads | jq -r '.thread_id')

# Research any topic
curl -sX POST "http://localhost:8090/threads/$THREAD/runs?wait=120s" \
-H "Content-Type: application/json" \
-d '{"input": {"topic": "the Rust programming language"}}' \
| jq '.output.output'

# Try another topic
curl -sX POST "http://localhost:8090/threads/$THREAD/runs?wait=120s" \
-H "Content-Type: application/json" \
-d '{"input": {"topic": "quantum computing recent developments 2024"}}' \
| jq '.output.output'

The crew accepts a topic input and returns a structured markdown report.

How It Works

  1. Discovery: AgentVisor detects crewai.yaml and selects the CrewAI framework provider
  2. Execution: python -m agentvisor.crewai.runner loads the research crew from crew.py
  3. Research phase: The Researcher agent calls MCP fetch tools → AgentVisor checks policy → host calls fetch server → web content returned
  4. Writing phase: The Writer agent synthesizes the research notes into a markdown report
  5. Output: The final report is returned as the crew output

Credential Flow

Guest Agent (ANTHROPIC_API_KEY=mav-tok-xxx)
└─► Guest Proxy (TLS termination)
└─► Host Proxy (token substitution: mav-tok-xxx → real key)
└─► api.anthropic.com (Authorization: Bearer real-key)

The real ANTHROPIC_API_KEY is never visible inside the guest sandbox.

Policy Model

ResourceMRN PatternPolicy
MCP fetch toolsmrn:agentvisor:mcp:fetch/.*Allow (authenticated)
Anthropic APImrn:agentvisor:http:api\.anthropic\.com.*Allow (authenticated)
All other HTTPmrn:agentvisor:http:.*Deny

Project Files

research-agent/
├── crew.py # ResearchCrew: researcher + writer agents
├── crewai.yaml # Crew discovery config (auto-detected by AgentVisor)
├── mav-agent-config.yaml # A2A metadata
├── requirements.txt # Python dependencies
├── agentvisor.yaml # Runtime config (proxy creds + MCP server)
└── policies/
└── domain.yml # Authorization policies

crewai.yaml

crews:
research: "./crew.py:ResearchCrew"
dependencies:
- "."

agentvisor.yaml (key sections)

proxy:
credentials:
- name: anthropic-key
guest_env_var: ANTHROPIC_API_KEY
destinations:
- "api\\.anthropic\\.com"
resolver:
type: bearer_token
source: env
env_var: ANTHROPIC_API_KEY

mcp:
servers:
- name: fetch
transport: stdio
command: ["uvx", "mcp-server-fetch"]

Customizing the Model

export ANTHROPIC_MODEL=claude-sonnet-4-5-20250514
agentvisor serve . --sandbox=none

Default: claude-haiku-4-5-20251001

Next Steps