ScoutAI — Agentic Web Research System
A modular research system that determines when external research is needed, plans focused research tasks, executes web searches through MCP, synthesizes the collected findings, and streams execution progress to the frontend in real time.
Orchestration
LangGraph
Tool Layer
MCP + Tavily
Backend
FastAPI
Streaming
SSE
Problem & Approach.
The problem
A basic research assistant can be implemented as a simple sequence: send a question to an LLM, call a search tool, and generate an answer.
That approach becomes harder to maintain as the system grows. Not every message requires research, complex questions need decomposition, tool execution should be separated from synthesis, and long-running workflows need a way to communicate progress to the user.
The approach
ScoutAI treats research as an explicit workflow rather than a single LLM operation. A Router first determines the required execution path. Research requests then move through planning, research execution, and synthesis.
External capabilities are isolated through MCP, while FastAPI exposes the workflow as an SSE stream that the Next.js client consumes incrementally.
System Architecture.
The core workflow is implemented as a conditional LangGraph pipeline. The Router provides the decision layer, while the research path is divided into planning, execution, and synthesis.
[ User Query ]
│
▼
┌─────────────┐
│ Router │
└──────┬──────┘
│
┌──────────────┴──────────────┐
│ │
needs_research = false needs_research = true
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Casual │ │ Planner │
└──────┬──────┘ └──────┬──────┘
│ │
│ ▼
│ ┌─────────────┐
│ │ Researcher │
│ └──────┬──────┘
│ │
│ ▼
│ ┌─────────────┐
│ │ MCP Client │
│ └──────┬──────┘
│ │
│ ▼
│ ┌─────────────┐
│ │ MCP Server │
│ └──────┬──────┘
│ │
│ ▼
│ ┌─────────────┐
│ │ Tavily Search│
│ └──────┬──────┘
│ │
│ ▼
│ ┌─────────────┐
│ │ Synthesizer │
│ └──────┬──────┘
│ │
└────────────┬───────────────┘
▼
[ Final Answer ]
│
▼
[ SSE Stream ]
│
▼
[ Next.js UI ]Agentic Workflow.
Each stage has a defined responsibility and communicates through shared LangGraph state. This keeps the workflow composable and makes individual stages easier to modify independently.
Router
Classifies the incoming request and determines whether external research is necessary. Casual requests bypass the research pipeline entirely.
Planner
Decomposes a research question into focused tasks using structured output backed by a Pydantic schema.
Researcher
Executes each planned task and retrieves external information through the MCP tool layer while emitting execution progress.
MCP
Provides a protocol boundary between the agent and external capabilities. The current implementation exposes a Tavily-powered web search tool.
Synthesizer
Receives the collected research and produces the final response using the gathered evidence as its primary context.
Intent-Aware Routing.
The Router introduces an explicit decision layer before research execution. It uses the LLM to determine whether the request needs external information rather than relying on a hardcoded list of phrases.
Casual request
User → Router → Casual → Final AnswerSimple conversation bypasses the research pipeline and is handled directly by the configured LLM.
Research request
User → Router → Planner → Researcher → SynthesizerRequests requiring external or current information enter the full research workflow.
LangGraph State
class ResearchState(TypedDict):
query: str
needs_research: bool
plan: list[str]
research: list[str]
answer: strStructured Planning.
Broad questions are converted into focused research tasks before any web search is performed. The Planner uses structured output backed by Pydantic so the Researcher receives a predictable data structure.
Example
Compare Python and TypeScript for building AI-powered web applications.
ResearchPlan ├── AI/ML libraries ├── Ecosystem maturity ├── Performance ├── Web development └── Developer experience
Contract
class ResearchPlan(BaseModel):
tasks: list[str]The structured result is stored in graph state and becomes the input contract for the Researcher.
MCP Tool Architecture.
Web search is deliberately separated from the core agent through the Model Context Protocol. The Researcher interacts with an MCP client rather than directly depending on the search provider.
Researcher
│
▼
MCP Client
│
▼
MCP Server
│
▼
search()
│
▼
Tavily
│
▼
Research ResultThis creates a clean capability boundary. Additional tools can be exposed through MCP without embedding their implementation directly into the LangGraph research workflow.
Evidence & Synthesis.
Research execution and final answer generation are intentionally separate. The Researcher collects information while the Synthesizer receives the accumulated findings and produces the final response.
Research Tasks → Evidence Collection → Synthesis → Final Answer
Keeping these responsibilities separate makes the system easier to reason about and gives the final generation stage a clear body of research context instead of mixing search execution with response generation.
Real-Time Agent Streaming.
Research can involve multiple model calls and external searches. Instead of keeping the interface in a generic loading state, ScoutAI streams execution events from LangGraph through FastAPI using Server-Sent Events.
LangGraph
│
├── router
├── planner
├── researcher
│ ├── task_started
│ └── task_completed
│
└── synthesizer
│
└── final_answer
│
▼
FastAPI SSE
│
▼
EventSourceResponse
│
▼
Browser ReadableStream
│
▼
Next.js UIplanning / plan
Communicates the beginning and result of the research planning stage.
task_started / task_completed
Exposes research execution progress as individual tasks run.
final_answer
Delivers the completed response through the same interface for both execution paths.
Streaming Contract.
Internal LangGraph execution events are translated into a smaller, frontend-oriented SSE event model. This keeps the UI independent from the internal graph implementation.
planningplantask_startedtask_completedsynthesis_startedfinal_answerInternal Agent Execution
↓
Event Translation
↓
FastAPI SSE Endpoint
↓
Browser ReadableStream
↓
React State
Architecture Evolution.
ScoutAI started as a simpler linear research workflow. As the system evolved, explicit routing, stronger boundaries between responsibilities, and real-time execution visibility were introduced.
Before
Every message entered the research workflow.
Now
A Router now decides whether research is necessary before the research pipeline begins.
Before
The workflow was primarily linear.
Now
LangGraph conditionally branches between casual conversation and research execution.
Before
Planning, execution, and synthesis were more tightly coupled.
Now
Each responsibility is isolated into a dedicated graph node with shared typed state.
Before
The user had little visibility during long-running research.
Now
Custom LangGraph events are translated into SSE events and streamed to the frontend in real time.
Key Engineering Decisions.
Conditional Agent Execution
The system does not send every message through the research pipeline. A dedicated LLM-based Router determines whether external research is actually required.
Separation of Responsibilities
Routing, planning, research execution, and synthesis are implemented as separate LangGraph nodes instead of being combined into a single monolithic agent call.
Structured Research Plans
The Planner produces a typed research plan using Pydantic structured output. This gives the Researcher a predictable interface rather than relying on arbitrary model-generated text.
MCP as a Tool Boundary
Web search is isolated behind an MCP client and server. The core research workflow therefore does not depend directly on the implementation details of the search provider.
Dedicated Synthesis
Research collection and answer generation are separate stages. The Researcher gathers evidence while the Synthesizer is responsible for turning that evidence into the final response.
Unified Streaming Contract
Both casual and research paths ultimately emit the same final_answer SSE event, allowing the frontend to maintain a single response pipeline.
Technology.
My Role.
I designed and implemented the system architecture, agent workflow, backend API, MCP integration, and frontend streaming experience. The project was built as an exploration of how these components work together as a complete AI system.
Current Limitations.
This is a v1 architecture and is intentionally focused on the core agent workflow rather than production-scale research infrastructure.
Future Direction.
The current architecture provides a foundation for expanding the system without replacing its core workflow model.
Engineering takeaway
The interesting part is the system around the model.
Building ScoutAI reinforced that an AI application is not just about prompting an LLM. Once the workflow involves planning, external tools, shared state, multiple execution stages, and long-running operations, architecture becomes part of the AI engineering problem.
ScoutAI is an ongoing exploration of how modular agent systems can be designed so that individual capabilities can evolve without requiring the entire application to be rewritten.