Multi-agent vehicle-damage assessment. A LangGraph supervisor reasons over MCP-wrapped models and coordinates specialist agents through a full detect → describe → severity → price → fraud chain — with typed hand-offs and replayable trajectory observability.
This repository showcases the core agentic workflow: the supervisor, the MCP tool boundary, the vision-reasoning and specialist agents, and the chat app. It is a portfolio build replicating a multi-agent architecture from my industry PhD research.
flowchart TB
user([User query + vehicle image]) --> sup
subgraph client["Supervisor process — Claude/Bedrock brain + MCP client"]
sup["Supervisor<br/>ReAct: routing, orchestration, synthesis"]
mem["Memory<br/>thread checkpointer + DynamoDB"]
sup <--> mem
end
sup <-->|MCP tool calls| mcp
subgraph server["AssessAuto MCP server — the model-serving boundary"]
mcp["MCP server (5 tools)"]
mcp -->|SageMaker| det["detect_damage · GDINO+SAM detector"]
mcp -->|Bedrock| vis["describe_damage · Claude"]
mcp -->|Bedrock| sev["score_severity · Claude"]
mcp -->|Bedrock| price["estimate_price · Claude"]
mcp -->|Bedrock| fraud["flag_fraud · Claude"]
end
sup --> ans([Unified answer + trajectory])
sup -.trace.-> log["OTel spans / replayable trajectory"]
The supervisor is a pure MCP client — it never calls the models directly. Every model
capability is an MCP tool. The damage detector runs as a separate Amazon SageMaker endpoint
(invoked by detect_damage); the reasoning agents run on Claude via Amazon Bedrock.
Each hand-off is a validated, typed structure (never free text), and every run emits a
replayable trajectory.
detect_damage— finds damage regions (boxes + labels) via the SageMaker detector.describe_damage— annotates the regions and asks Claude for a typed per-region assessment (type, location, severity, description).score_severity— normalises the assessment into consistent 0–100 scores.estimate_price— an AUD repair-cost range with a repair-vs-replace call.flag_fraud— cross-checks detector regions against the description for inconsistencies.
The supervisor runs a ReAct loop and uses only the tools a given question needs — a
narrow "what damage is visible?" stops after describe_damage; a full assessment runs the
whole chain — then reconciles everything into one answer.
A real run on a collision photo: the detector boxes the shattered windshield, and the agents produce a full assessment — overall severity, an AUD repair estimate with a repair-vs-replace call, and a consistency check — all with an expandable agent trajectory.
![]() |
![]() |
| Detection — the detector boxes the damage. | Assessment — severity, AUD estimate, consistency check. |
Sample vehicle photo from the public CarDD dataset.
Prerequisites: Python 3.12, AWS credentials with Amazon Bedrock model access, and a
running SageMaker detector endpoint (set its name in .env).
python -m venv .venv && source .venv/bin/activate # Windows: .\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
cp .env.example .env # set AWS_REGION, DETECTOR_ENDPOINT_NAME, BEDROCK_MODEL_IDThen, in two terminals:
python mcp-server/server.py # 1) the MCP server (5 tools)
streamlit run app/streamlit_app.py # 2) the chat interfaceconfig.py # one typed view over the environment (secrets from env only)
supervisor/ # the LangGraph brain: graph, MCP client, specialists, tracing
vision/ # annotate + schema + Bedrock reasoning (the Describer)
mcp-server/ # the MCP server exposing the five tools
memory/ # thread checkpointer + DynamoDB (dual memory)
app/ # Streamlit chat interface
- The SageMaker detector and Bedrock require your own AWS account and enabled model access.
- Secrets are read from the environment only —
.envis git-ignored; never commit real credentials.
MIT — see LICENSE.

