agentsumo-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@agentsumo-mcpSimulate a road closure on Elm Street during peak hours."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
AgentSUMO
An Agentic Framework for Interactive Simulation Scenario Generation in SUMO via Large Language Models
Documentation · Installation · Tools · Schema · Tutorials
Overview
AgentSUMO lets non-expert stakeholders design, execute, and analyze SUMO traffic simulations through natural-language interaction. The Planner Agent translates abstract policy questions into executable simulation plans, drives them via the Model Context Protocol (MCP), and surfaces results through a web dashboard.
Conversational scenario design — describe a policy question, get a runnable simulation
Policy experiments — road closures, lane reductions, signal optimization, demand changes
Cross-scenario analysis — SQL-based comparison across runs, with auto-generated HTML reports
Web dashboard — geospatial visualization, time-series charts, and trip replay
Related MCP server: SUMO-MCP-Server
Demo
Web interface: conversational planning panel, scenario list, and live simulation status.
Geospatial visualization: per-edge metrics, congestion overlays, and trip replay on the 2.5D basemap.
Architecture
User (natural language)
|
v
Planner Agent (Claude LLM, Interactive Planning Protocol)
|
+--> AgentSUMO MCP Client --> AgentSUMO MCP Server (PyPI: agentsumo-mcp) --> SUMO
|
+--> SQLite MCP Client --> SQLite MCP Server (Anthropic, open source) --> simulations.db
|
+--> Filesystem MCP Client --> Filesystem MCP Server (Anthropic, open source) --> additional XML filesThe reasoning layer (Planner Agent) lives in this repository. The execution layer (agentsumo-mcp) is published to PyPI and installed automatically as a dependency.
Tool Layer
The AgentSUMO MCP Server exposes 26 tools grouped into five capability categories that follow the simulation workflow. Full reference at agentsumo.readthedocs.io/.../tools.
Category | Purpose | Representative tools |
Scenario Generation | Build a baseline SUMO simulation: OSM → network → trips → routes → run |
|
Policy Experimentation | Apply infrastructure, demand, and signal-control interventions |
|
Result Analysis | Convert SUMO XML output to SQLite and render HTML reports |
|
Visualization | Render networks, highlighted edges, and per-edge metric heatmaps |
|
Utility Functions | Network statistics, routing, road-name ↔ edge-id resolution, OD-coordinate validation, web-search grounding |
|
Installation
Requirements
Python 3.10 or later
SUMO 1.24 or later (locally installed, with
SUMO_HOMEset)Anthropic Claude API key (bring-your-own-key)
Mapbox access token (used by the web map renderer)
1. Install SUMO
macOS
brew install sumoOr download the installer from the Eclipse SUMO downloads page.
Windows — Download the installer from the Eclipse SUMO downloads page.
Linux (Ubuntu/Debian)
sudo add-apt-repository ppa:sumo/stable
sudo apt-get update
sudo apt-get install sumo sumo-tools sumo-doc2. Set up the Python environment
Install uv:
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"Clone the repository, create a virtual environment, and install AgentSUMO:
git clone https://github.com/mw-jeong/AgentSUMO
cd AgentSUMO
# Create a Python 3.12 venv
uv venv --python 3.12
# Activate the venv
source .venv/bin/activate # macOS / Linux
# .venv\Scripts\activate # Windows
# Install AgentSUMO and all dependencies
# (this also pulls agentsumo-mcp from PyPI as a dependency)
uv pip install -e .3. Configure environment variables
AgentSUMO reads API keys and the SUMO path from environment variables. The easiest way is a .env file at the project root:
cp .env.example .envOpen .env in your editor and fill in:
ANTHROPIC_API_KEY (required) — Claude API key that drives the Planner Agent. Get one at the Anthropic Console.
ANTHROPIC_API_KEY=sk-ant-api03-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMAPBOX_TOKEN (required for the web UI) — used to render the basemap. Get one at the Mapbox access tokens page.
MAPBOX_TOKEN=pk.eyJ1IjoixxxxxxxxxxxxxxxxxxSUMO_HOME (required) — absolute path to your local SUMO installation. The directory must contain bin/sumo (or bin/sumo.exe on Windows).
# macOS (Homebrew)
SUMO_HOME=/opt/homebrew/share/sumo
# macOS (Eclipse SUMO installer)
SUMO_HOME=/Library/Frameworks/EclipseSUMO.framework/Versions/<version>/EclipseSUMO # e.g. 1.24.0; use the directory name installed under Versions/
# Windows
SUMO_HOME=C:\Program Files (x86)\Eclipse\Sumo
# Linux
SUMO_HOME=/usr/share/sumoAGENTSUMO_MCP_OUTPUT_BASE (optional) — override the base directory where the MCP server writes simulation outputs (networks, trips, results). Defaults to the current working directory.
AGENTSUMO_MCP_OUTPUT_BASE=/path/to/your/output/dir4. Run
# Web interface (opens at http://localhost:8000)
python web.py
# CLI mode
python chat.py
# Clean up simulation outputs
python clean.pyProject Structure
AgentSUMO/
├── agentsumo/
│ ├── agent/ # Planner Agent (Claude orchestrator + prompts)
│ ├── client/ # MCP clients (AgentSUMO, SQLite, Filesystem)
│ └── core/ # Configuration
├── agentsumo_mcp/ # AgentSUMO MCP Server source (also published to PyPI)
│ └── defaults/ # Packaged fixtures (e.g., vehicle_types.add.xml)
├── packaging/mcp/ # PyPI build configuration for agentsumo-mcp
├── web/ # Web interface (FastAPI + Jinja2 templates)
├── docs/ # Sphinx documentation source
├── tests/ # Unit tests
├── assets/ # README images
├── output/ # Runtime artifacts (auto-populated; 8 categories tracked
│ # via .gitkeep — simulations/, networks/, trips/,
│ # analysis/, reports/, uploads/, visualizations/, additional/)
├── chat.py # CLI entry point
├── web.py # Web server entry point
└── .env.example # Environment variable templateUse the MCP Server Standalone
The AgentSUMO MCP Server can be used independently from this framework with any MCP-compatible LLM client (Claude Desktop, OpenAI tool clients, Gemini, local LLMs):
pip install agentsumo-mcpOr via uvx without installing:
uvx agentsumo-mcpThe server is registered in the official MCP Registry under io.github.mw-jeong/agentsumo-mcp.
Troubleshooting
SUMO path error — Verify SUMO_HOME in your .env. The directory must contain bin/sumo (or bin/sumo.exe on Windows).
API key error — Verify ANTHROPIC_API_KEY in your .env is set to a valid Claude API key. The Planner Agent will refuse to start without it.
Dependency error — Re-resolve dependencies:
uv pip install -e . --upgradeLegacy token files (deprecated, scheduled for removal in 0.2.0) — AgentSUMO still falls back to claude_api.txt and mapbox_token.txt at the project root when the corresponding environment variables are missing, but those code paths now emit a DeprecationWarning at import time. Use the .env workflow for new installations.
Documentation
Full documentation lives at agentsumo.readthedocs.io.
Installation — SUMO, Python 3.10+, environment setup
Tools — reference for all MCP tools
Schema —
simulations.dbER diagram and column referenceTutorials — walkthroughs of the paper case studies
Citation
If you use AgentSUMO in academic work, please cite:
@article{jeong2025agentsumo,
title = {AgentSUMO: An Agentic Framework for Interactive Simulation Scenario Generation in SUMO via Large Language Models},
author = {Jeong, Minwoo and Chang, Jeeyun and Yoon, Yoonjin},
journal = {arXiv preprint arXiv:2511.06804},
year = {2025},
url = {https://arxiv.org/abs/2511.06804}
}License
MIT. See LICENSE.
Developed at
Available Tools
26 toolsanalyze_road_details_toolA
Analyze detailed road information (lanes, speed limits, length, etc.).
This tool provides comprehensive analysis of road segments including:
- Number of lanes per segment
- Speed limits (km/h)
- Road length and width
- Statistical summary (averages, min/max)
USE CASES:
1. "Show lane count and speed limit for the 500m segment of Teheran-ro near Gangnam Station"
2. "Analyze current road state to compare before and after policy application"
3. "Road capacity analysis (lane count x length)"
Args:
net_file: Network file path
target_road_name: Road name (e.g., "테헤란로", "Teheran-ro")
reference_location: Reference point (e.g., "강남역", "Gangnam Station")
radius_km: Radius in km (e.g., 0.5 for 500m)
include_lane_details: Whether to include per-lane information
Returns:
Dict with detailed road analysis including:
- segments: List of segment details
- statistics: Overall statistics (avg lanes, speed, length)
- summary: Human-readable summary
- filtering: Location filtering info (if applied)
EXAMPLE:
analyze_road_details_tool(
net_file="gangnam_station.net.xml",
target_road_name="테헤란로",
reference_location="강남역",
radius_km=0.5
)
-> Returns: Detailed analysis of Teheran-ro segments within 500m of Gangnam Station
Inputs: net_file (required), target_road_name (required), radius_km, reference_location, +1 more.
edge_edit_toolA
Delete specific road segments from the network file.
⚠️🚨 CRITICAL: After using this tool, you MUST regenerate trips and routes!
Route files contain explicit edge lists - if those edges are deleted, the route file becomes INVALID!
Workflow: edge_edit → trip_generate → route_generate → sumo_runner (REQUIRED!)
🌟 REALISTIC USAGE: Specify reference_location + radius_km for partial road closure!
Three modes (priority order):
1. edge_ids: Delete exact edges (most precise, but requires knowing edge IDs)
2. target_road_name + reference_location + radius_km: Delete road segments near a location (REALISTIC!)
3. target_road_name only: Delete entire road (extreme scenario, use with caution!)
Examples:
# REALISTIC: Block 300m of Teheran-ro near Gangnam Station (construction scenario)
edge_edit_tool(
net_file="gangnam_station.net.xml",
target_road_name="테헤란로",
reference_location="강남역",
radius_km=0.3
)
# Then: trip_generate → sumo_runner (MUST regenerate trip!)
# EXTREME: Block entire Teheran-ro (unrealistic!)
edge_edit_tool(
net_file="gangnam_station.net.xml",
target_road_name="테헤란로"
)
# Then: trip_generate → sumo_runner (MUST regenerate trip!)
Args:
net_file: Network file path
route_file: Route file path (optional, but will be invalidated after edge deletion)
output_dir: Output directory for results
target_road_name: Road name to delete from network (e.g., '테헤란로')
edge_ids: Specific edge IDs to delete (list, optional)
reference_location: Reference point for partial deletion (str, optional, e.g., "강남역")
radius_km: Radius in km around reference (float, optional, e.g., 0.3)
Returns:
Dict with status, net_file, and requires_reroute=True (indicating trip regeneration needed)
Inputs: net_file (required), edge_ids, radius_km, output_dir, +3 more.
flow_generation_toolA
Generate a SUMO flow from source to destination.
Two ways to specify locations:
1. Place names (source/dest) — uses geocoding to find coordinates
2. Direct coordinates (source_lat/lon, dest_lat/lon) — skips geocoding.
Use this when coordinates are already known (e.g., from map O/D selection).
Two ways to specify vehicle count (exactly one required):
1. vehs_per_hour — rate-based generation (SUMO <flow vehsPerHour="N">)
2. number — total vehicle count over [begin,end] (SUMO <flow number="N">)
Safety parameters applied: departLane="free", departPos="random_free", departSpeed="random"
IMPORTANT: When calling multiple times for multi-OD scenarios, pass the previous call's
route_file output as the next call's route_file input to accumulate all flows in one file.
Args:
route_file: Route file path (pass previous output for chained calls)
net_file: Network file path
source: Source location place name (e.g., "Madison Square Garden")
dest: Destination location place name (e.g., "Lincoln Tunnel")
begin: Start time in seconds (default: 0.0)
end: End time in seconds (default: 3600.0)
vehs_per_hour: Vehicles per hour — mutually exclusive with number
number: Total vehicle count — mutually exclusive with vehs_per_hour
flow_id: Flow ID (auto-generated if None)
output_dir: Output directory for results
use_geocoding: Use geocoding for place name resolution (default: True)
search_radius: Search radius in km for nearest edge (default: 0.3)
source_lat: Source latitude (WGS84) — use with source_lon for coordinate mode
source_lon: Source longitude (WGS84) — use with source_lat for coordinate mode
dest_lat: Destination latitude (WGS84) — use with dest_lon for coordinate mode
dest_lon: Destination longitude (WGS84) — use with dest_lat for coordinate mode
Examples:
Place name mode (geocoding):
flow_generation_tool(route_file="r.rou.xml", net_file="n.net.xml",
source="Madison Square Garden", dest="Lincoln Tunnel",
begin=0, end=1800, vehs_per_hour=260)
Coordinate mode (from map selection):
flow_generation_tool(route_file="r.rou.xml", net_file="n.net.xml",
source_lat=40.7505, source_lon=-73.9934,
dest_lat=40.7580, dest_lon=-73.9855,
begin=0, end=3600, number=200)
Inputs: net_file (required), route_file (required), end, dest, +12 more.
get_edge_ids_from_road_name_toolA
Convert road name to SUMO edge IDs using edge.getName().
IMPORTANT: Use this when user asks questions with road names (e.g., "What is the density of Teheran-ro?")
This tool maps human-readable road names to SUMO's technical edge IDs,
enabling SQL queries based on road names.
Args:
road_name: Road name (e.g., "테헤란로", "강남대로", "9th Avenue")
net_file: Network file path used in simulation.
When working with DB data, get this from:
SELECT net_file FROM simulations WHERE simulation_id = '<your_sim_id>'
Returns:
List[str]: List of edge IDs matching the road name
Example workflow:
1. User asks: "What is the density of Teheran-ro?"
2. Get net_file from DB (if using DB data):
read_query("SELECT net_file FROM simulations WHERE simulation_id = 'baseline'")
→ "/path/to/network.net.xml"
3. Convert road name to edge IDs:
get_edge_ids_from_road_name_tool(
road_name="테헤란로",
net_file="/path/to/network.net.xml" # Use actual path from step 2
)
→ ["375049565#11", "375049565#12", "375049565#13", ...]
4. Use in SQL query:
read_query("SELECT AVG(density) FROM edge_metrics WHERE edge_id IN ('375049565#11', '375049565#12', ...)")
5. Present results with road name (not edge IDs)
Note:
- Returns all edge segments for the given road name
- Raises ValueError if road name not found
Inputs: net_file (required), road_name (required).
get_road_names_toolA
Convert SUMO edge IDs to actual road names using edge.getName().
IMPORTANT: Use this after congestion analysis to show human-readable road names!
This tool maps SUMO's technical edge IDs to real-world street names,
making analysis results much more understandable and actionable.
Args:
edge_ids: List of SUMO edge IDs to convert (e.g., ["194926855#1", "420901920#0"])
net_file: Network file path used in simulation.
When working with DB data, get this from:
SELECT net_file FROM simulations WHERE simulation_id = '<your_sim_id>'
Returns:
Dict mapping edge_id → road_name
Example workflow:
1. SQL query for Top 10 density:
read_query("SELECT edge_id, avg_density FROM edge_metrics ORDER BY avg_density DESC LIMIT 10")
→ ["194926855#1", "1030139836#1", ...]
2. Get net_file from DB (if using DB data):
read_query("SELECT net_file FROM simulations WHERE simulation_id = 'baseline'")
→ "/path/to/network.net.xml"
3. Convert to road names:
get_road_names_tool(
edge_ids=["194926855#1", "1030139836#1", ...],
net_file="/path/to/network.net.xml" # Use actual path from step 2 or user-provided
)
→ {"194926855#1": "9th Avenue", "1030139836#1": "Broadway", ...}
4. Present results:
"Top 10 Congested Roads:
1. 9th Avenue: 800 veh/km
2. Broadway: 731 veh/km
..."
Note:
- Returns "Unnamed Road" if road name not set in network
Inputs: edge_ids (required), net_file (required).
net_convertA
[Step 2/5] Convert OSM data to SUMO network format (.net.xml).
Converts the raw .osm file from osm_extract() into a SUMO-compatible
road network using netconvert. Applies road type filtering and UTM projection.
Previous step: osm_extract() to get .osm file and bbox.
Next step: trip_generate() to create traffic demand on this network.
=== PARAMETERS ===
- osm_file (REQUIRED): Path to .osm file (from osm_extract result)
- city_en: English name for output file naming (auto-derived from osm_file if omitted)
- bbox: Bounding box [west, south, east, north] for boundary trimming.
Pass the bbox from osm_extract result to trim roads at area boundaries.
If omitted, roads may extend beyond the intended area.
=== RETURNS ===
- net_file: Path to generated .net.xml file (pass to trip_generate and sumo_runner)
Inputs: osm_file (required), bbox, city_en, output_dir. Returns: result
network_summary_toolA
Get a comprehensive summary of a SUMO network.
Use when user asks about the network, its size, or what roads are included.
Returns edge count, junction count, total road length, bounding box, and road name list.
Args:
net_file: Path to the SUMO network file (.net.xml)
Returns:
Dict with network statistics and road names
Inputs: net_file (required).
osm_extractA
[Step 1/5] Extract OpenStreetMap (OSM) road network data for a given area.
This is the FIRST step in the simulation pipeline. It downloads or extracts
raw OSM data (.osm file) for the specified geographic area.
Next step: Use net_convert() to convert the .osm file to SUMO .net.xml format.
=== AREA SPECIFICATION (priority order) ===
1. bbox: Direct coordinates [west, south, east, north]
Example: [127.015, 37.490, 127.040, 37.506]
2. od_data_file: Auto-compute bbox from OD CSV coordinate columns
(use column_mapping if columns are not named O_lon, O_lat, D_lon, D_lat)
3. zone_shp_file: Auto-compute bbox from shapefile geometry bounds
4. city + radius: Geocode city name and use radius in KILOMETERS (not meters!)
Example: city="Gangnam Station", radius=1.5
=== PARAMETERS ===
- city_en (REQUIRED): English name for file naming. Example: "gangnam", "manhattan_midtown"
- bbox: [west, south, east, north] bounding box coordinates
- city: City/location name for geocoding (e.g., "강남역", "Times Square")
- radius: Radius in km (used with city parameter)
- od_data_file: Path to OD CSV file (bbox auto-computed from coordinate ranges)
- zone_shp_file: Path to zone shapefile (bbox auto-computed from geometry)
- column_mapping: Column name mapping for non-standard OD CSV files.
Keys are standard names, values are actual column names in the CSV.
Example: {"O_lon": "pickup_lng", "O_lat": "pickup_lat", "D_lon": "dropoff_lng", "D_lat": "dropoff_lat"}
=== PIPELINE CONTEXT ===
RandomOD: osm_extract(bbox/city+radius) → net_convert → trip_generate → route_generate → sumo_runner
RealOD-coord: osm_extract(od_data_file, column_mapping) → net_convert → trip_generate → route_generate → sumo_runner
RealOD-zone: osm_extract(zone_shp_file) → net_convert → trip_generate → route_generate → sumo_runner
=== RETURNS ===
- osm_file: Path to extracted .osm file (pass to net_convert)
- bbox: Computed bounding box (pass to net_convert for boundary trimming)
- tag: File naming tag derived from city_en
Inputs: city_en (required), bbox, city, radius, +4 more. Returns: result
reduce_lanes_toolA
Reduce lanes on road segments with two modes.
✅ Trip file can be reused - edges still exist, only lane count changed.
Workflow: reduce_lanes → sumo_runner (reuse existing trip file)
**MODE 1: Relative Reduction (RECOMMENDED for most policies)**
- reduce_by: Reduce N lanes from each segment
- Example: reduce_by=1 → 5→4, 3→2, 2→1, 1→1 (balanced reduction)
**MODE 2: Absolute Reduction (for special cases)**
- remain_lanes: Set all segments to N lanes
- Example: remain_lanes=1 → 5→1, 3→1, 2→1, 1→1 (extreme reduction)
REALISTIC USAGE: Use reference_location + radius_km for localized lane reduction!
Examples:
# BALANCED POLICY: Reduce 1 lane from each segment
reduce_lanes_tool(
net_file="gangnam_station.net.xml",
target_road_name="테헤란로",
reference_location="강남역",
radius_km=0.5,
reduce_by=1 # Each segment: 5→4, 3→2, 2→1, 1→1
)
# Then: sumo_runner (reuse trip file - no trip_generate needed!)
# EXTREME POLICY: Set all segments to 1 lane
reduce_lanes_tool(
net_file="gangnam_station.net.xml",
target_road_name="테헤란로",
reference_location="강남역",
radius_km=0.5,
remain_lanes=1 # All segments: 5→1, 3→1, 2→1, 1→1
)
# Then: sumo_runner (reuse trip file - no trip_generate needed!)
Args:
net_file: Network file path
route_file: Route file path (optional, can be reused after this tool)
output_dir: Output directory for results
target_road_name: Road name to reduce lanes (e.g., '테헤란로')
edge_ids: Specific edge IDs (optional)
reference_location: Reference point (optional, e.g., "강남역")
radius_km: Radius in km (optional, e.g., 0.5)
reduce_by: Number of lanes to reduce from each segment (RECOMMENDED!)
remain_lanes: Number of lanes to remain (ABSOLUTE - use with caution)
Inputs: net_file (required), edge_ids, radius_km, reduce_by, +5 more.
route_analysis_toolA
Analyze the optimal route between two locations in the network.
Accepts place names (e.g., "강남역", "Gangnam Station") or road names (e.g., "테헤란로").
TWO ROUTING MODES:
1. "distance" (default): Shortest path by edge length. Works without simulation data.
2. "traveltime": Optimal path using actual simulation results (edgedata XML) as edge weights.
Requires weight_file (edgedata XML from a previous simulation).
Can also use other attributes: "density", "CO2_abs", etc.
Use cases:
- "What is the shortest path from Gangnam Station to Samseong Station?" -> routing_mode="distance"
- "What is the optimal path based on actual travel time?" -> routing_mode="traveltime", weight_file=edgedata.xml
- "What is the lowest-CO2 path?" -> routing_mode="traveltime", weight_attribute="CO2_abs"
- "How does the path change after a road closure?" -> compare_net_file + compare_weight_file
In web mode, use [SHOW_ROUTE:edges|color|net_file_name] marker to visualize the result.
Always include net_file_name from the result so routes render on the correct network.
Args:
net_file: Network file path
origin: Origin location (place name, landmark, or road name)
destination: Destination location (place name, landmark, or road name)
routing_mode: "distance" (default, edge length) or "traveltime" (simulation-weighted)
weight_file: Edgedata XML file for weighted routing (required when routing_mode="traveltime").
Use the netstate/edgedata file from simulation output.
weight_attribute: Attribute to use as edge weight (default: "traveltime").
Other options: "density", "CO2_abs", "fuel_abs", etc.
compare_net_file: Optional second network for before/after route comparison
compare_weight_file: Optional edgedata for the comparison network
Returns:
Dict with route edges, distance, time, road names.
If comparison provided, includes both routes and diff.
Inputs: origin (required), net_file (required), destination (required), weight_file, +4 more.
route_generateA
[Step 4/5] Generate routes from trips using SUMO's duarouter.
Assigns shortest-path routes to each trip based on the road network.
Converts trips.xml → routes.rou.xml which is required for simulation.
Previous step: trip_generate() to get .trips.xml file.
Next step: sumo_runner() to run the simulation with net_file and route_file.
=== PARAMETERS ===
- net_file (REQUIRED): Path to SUMO network file (.net.xml, from net_convert)
- trip_file (REQUIRED): Path to trip file (.trips.xml, from trip_generate)
=== RETURNS ===
- route_file: Path to generated .rou.xml file (pass to sumo_runner)
Inputs: net_file (required), trip_file (required), output_dir. Returns: result
simulation_report_toolA
Generate a comprehensive HTML simulation analysis report from SQLite database.
This is the FINAL deliverable of a simulation analysis session.
It summarizes ALL scenarios in the database with KPIs, comparisons, congestion analysis, and emissions.
The report is a standalone dark-themed HTML file that can be:
- Viewed in the web interface (click from file tree)
- Opened in any browser
- Shared as a file
IMPORTANT — Before calling this tool:
1. Query the database (read_query) to understand the simulation results
2. Write an executive_summary (1-2 paragraphs, English, professional tone) that covers:
- Context: what area was studied and what problem was investigated
- Key findings: most significant results from scenario comparison
- Risks/concerns: any metrics that worsened or areas of concern
- Recommendation: what action should urban stakeholders take based on the analysis
Focus on insights useful for urban decision-makers (policymakers, planners, city officials).
Do NOT list raw numbers — interpret them.
Args:
db_path: Path to SQLite database file
executive_summary: LLM-generated executive summary for urban stakeholders (English, 1-2 paragraphs)
output_dir: Output directory for report files
Returns:
Dict with report_file path and metadata
Inputs: db_path (required), output_dir, executive_summary.
speed_limit_edit_toolA
Modify speed limits on specific road segments (supports partial application).
✅ Trip file can be reused - edges still exist, only speed limit changed.
Workflow: speed_limit_edit → sumo_runner (reuse existing trip file)
REALISTIC USAGE: Use reference_location + radius_km for localized speed limit changes!
Examples:
# REALISTIC: Reduce speed to 40km/h on 500m of Teheran-ro near Gangnam Station
speed_limit_edit_tool(
net_file="gangnam_station.net.xml",
target_road_name="테헤란로",
reference_location="강남역",
radius_km=0.5,
new_speed_kmph=40.0
)
# Then: sumo_runner (reuse trip file - no trip_generate needed!)
Args:
net_file: Network file path
route_file: Route file path (optional, can be reused after this tool)
output_dir: Output directory for results
target_road_name: Road name (e.g., '테헤란로')
edge_ids: Specific edge IDs (optional)
reference_location: Reference point (optional, e.g., "강남역")
radius_km: Radius in km (optional, e.g., 0.5)
new_speed_kmph: New speed limit in km/h (e.g., 40.0)
Inputs: net_file (required), edge_ids, radius_km, output_dir, +4 more.
sumo_runnerA
[Step 5/5] Run SUMO traffic simulation using TraCI.
Executes the simulation with the generated network and routes.
Captures vehicle position frames for post-simulation replay visualization.
Previous step: route_generate() to get .rou.xml file.
=== PARAMETERS ===
- net_file (REQUIRED): SUMO network file (.net.xml, from net_convert)
- route_file: Route file (.rou.xml, from route_generate) — preferred over trip_file
- trip_file: Trip file (.trips.xml) — use only if route_file is unavailable
- duration: Simulation duration in seconds (default: 3600 = 1 hour)
- additional_files: List of additional XML files (e.g., traffic light programs)
- policy_type: Set to "baseline" to exclude additional files
=== RETURNS ===
- output_files: List of result file paths [tripinfo, edgedata, edgedata_emission]
- summary_xml: Path to summary.xml file. ALWAYS pass this to xml_to_sqlite_tool(summary_xml=...) for dashboard time-series charts.
- replay_file: JSON file for web visualization replay
- simulation_time: Wall-clock execution time in seconds
Inputs: net_file (required), duration, trip_file, output_dir, +3 more.
tls_adaptation_toolB
Run SUMO tlsCycleAdaptation.py to optimize traffic light cycles and generate an additional XML file.
Args:
net_file: Network file path (tag will be extracted from filename)
route_file: Route file path
output_dir: Output directory for results
Inputs: net_file (required), route_file (required), output_dir.
tls_offset_toolC
Run SUMO tlsCoordinator.py to optimize traffic light offsets and generate an additional XML file.
Args:
net_file: Network file path (tag will be extracted from filename)
route_file: Route file path
output_dir: Output directory for results
Inputs: net_file (required), route_file (required), output_dir.
trip_generateA
[Step 3/5] Generate trip demand (trips.xml) for SUMO simulation.
Creates origin-destination trip definitions. This tool ONLY generates trips —
route assignment is done separately by route_generate().
Previous step: net_convert() to get .net.xml file.
Next step: route_generate() to assign routes to trips.
=== THREE MODES ===
1. RandomOD — Random trip generation:
- trip_type: "RandomOD"
- traffic_condition (REQUIRED): "light" | "medium" | "heavy"
* light: ~20% of edge count (rural, off-peak)
* medium: ~80% of edge count (typical urban)
* heavy: ~150% of edge count (rush hour, dense urban)
2. RealOD-coordinate — Real OD from coordinate CSV:
- trip_type: "RealOD", od_type: "coordinate"
- od_data_file: Path to CSV file
- Default columns: O_lon, O_lat, D_lon, D_lat, O_time_relative
- Use column_mapping if your CSV has different column names
3. RealOD-zone — Real OD from zone CSV + shapefile:
- trip_type: "RealOD", od_type: "zone"
- od_data_file: Path to OD CSV file
- zone_shp_file: Path to zone shapefile (.shp)
- Default columns: h3_lv9_O, h3_lv9_D, O_time_relative
- Default shapefile ID column: h3_indx
- Use column_mapping to override any of these
=== COLUMN MAPPING ===
For non-standard CSV files, provide column_mapping to map standard names to actual column names.
Coordinate mode mapping keys:
"O_lon", "O_lat", "D_lon", "D_lat", "O_time_relative"
Zone mode mapping keys:
"zone_O", "zone_D", "O_time_relative", "zone_id_column"
Example: {"O_lon": "pickup_lng", "O_lat": "pickup_lat", "D_lon": "dropoff_lng", "D_lat": "dropoff_lat", "O_time_relative": "start_sec"}
=== RETURNS ===
- trip_file: Path to generated .trips.xml file (pass to route_generate)
- trip_count: Number of trips generated
Inputs: net_file (required), trip_type (required), od_type, output_dir, +4 more. Returns: result
validate_od_coordinates_toolA
Validate a list of coordinates against the SUMO network.
Use this BEFORE generating flows to check which coordinates are within the network
and find the nearest edges. Essential for agentic OD planning — lets you verify
destinations are reachable before proposing them to the user.
Args:
net_file: SUMO network file path (.net.xml)
coordinates: List of coordinate dicts, each with:
- lat (float): Latitude (WGS84)
- lon (float): Longitude (WGS84)
- label (str, optional): Human-readable label (e.g., "Lincoln Tunnel")
search_radius: Search radius in km for nearest edge (default: 0.5)
Returns:
Dict with:
- network_bbox: [min_lon, min_lat, max_lon, max_lat]
- results: List of validation results per coordinate:
- label, lat, lon
- in_network: bool
- nearest_edge: edge ID (or null)
- distance_m: distance to nearest edge in meters (or null)
- status: "ok" | "out_of_network" | "no_edge_found"
Example:
validate_od_coordinates_tool(
net_file="manhattan.net.xml",
coordinates=[
{"lat": 40.7505, "lon": -73.9934, "label": "MSG"},
{"lat": 40.7425, "lon": -74.0099, "label": "Holland Tunnel"},
{"lat": 40.7060, "lon": -73.9969, "label": "Brooklyn Bridge"}
]
)
Inputs: net_file (required), coordinates (required), search_radius.
vehicle_generation_toolA
Add vehicles from source to destination with optimal path calculation.
SUPPORTS TWO MODES:
1. Road Name Mode:
- Use exact road names (e.g., '테헤란로', '강남대로')
- Set use_geocoding=False (default)
2. Location Mode (Recommended):
- Use any location name or place (e.g., '강남역', '코엑스', 'Gangnam Station, Seoul')
- Uses geocoding to find coordinates, then finds nearest edges
- Set use_geocoding=True
- Automatically validates if location is within network bounds
IMPORTANT NOTES:
- Location Mode validates coordinates against network bounds (1km buffer)
- If location is outside network, you'll get a clear error with network bbox info
- Search radius is 300m by default (sufficient for most cases)
Args:
route_file: Route file path
net_file: Network file path
source_location: Source location (road name OR place name)
destination_location: Destination location (road name OR place name)
vehicle_id: Vehicle ID prefix (default: "genveh_0")
depart_time: Departure time in seconds (default: 0.0)
depart_time_range: Departure time range [min, max] in seconds (optional)
vehicle_count: Number of vehicles to generate (default: 1)
output_dir: Output directory for results
use_geocoding: If True, use location-based mode with geocoding (default: False)
search_radius: Search radius in km for nearest edge (default: 0.3 = 300m)
Examples:
Road name mode:
vehicle_generation_tool(
route_file="routes.rou.xml",
net_file="gangnam.net.xml",
source_location="테헤란로",
destination_location="강남대로",
use_geocoding=False
)
Location mode (RECOMMENDED):
vehicle_generation_tool(
route_file="routes.rou.xml",
net_file="gangnam.net.xml",
source_location="강남역",
destination_location="코엑스",
use_geocoding=True,
vehicle_count=20
)
Inputs: net_file (required), route_file (required), source_location (required), destination_location (required), +7 more.
vehicle_type_edit_toolC
Reassign vehicle types in the route file according to the electric_ratio.
Args:
route_file: Route file path
electric_ratio: Ratio of electric vehicles (0.0 to 1.0)
output_dir: Output directory for results
Inputs: route_file (required), electric_ratio (required), output_dir.
visualize_edgedata_toolA
🎨 Visualize SUMO edgedata with flexible scaling modes for comparison.
⚠️ IMPORTANT: Only use when user EXPLICITLY requests heatmap/visualization!
- User says "show heatmap", "visualize density", "show congestion map" → Use this
- User asks "which road is congested?" -> Do NOT use; answer with text from SQL query
**SCALE MODES:**
1. **'auto'** (default): Dynamic scale from current file
- Best for: Single simulation analysis
- Scale: Optimized for current data range
2. **'unified'**: Consistent scale across multiple files
- Best for: Policy comparison (before/after)
- Requires: comparison_files parameter
- Example: Compare baseline vs policy A vs policy B
3. **'fixed'**: User-defined fixed scale
- Best for: Standardized reports, academic papers
- Requires: min_value and max_value parameters
- Example: Always use [0, 100] for all simulations
**USE CASES:**
# Single simulation analysis (auto scale)
visualize_edgedata_tool(..., scale_mode="auto")
→ Optimized color contrast for this simulation
# Policy comparison (unified scale)
visualize_edgedata_tool(
edgedata_file="after.xml",
scale_mode="unified",
comparison_files=["before.xml"]
)
→ Same colors mean same values across both
# Standardized scale (fixed)
visualize_edgedata_tool(..., scale_mode="fixed", min_value=0, max_value=100)
→ All simulations use [0, 100] scale
Args:
net_file: Path to the SUMO network file (.net.xml)
edgedata_file: Path to the SUMO edgeData output file (.xml)
attribute: Attribute to visualize (e.g., 'density', 'speed', 'CO2_abs')
output_dir: Output directory for visualization files
scale_mode: Scale mode ('auto' | 'unified' | 'fixed')
comparison_files: List of files for unified scale (for 'unified' mode)
min_value: Minimum value for fixed scale (for 'fixed' mode)
max_value: Maximum value for fixed scale (for 'fixed' mode)
Inputs: net_file (required), edgedata_file (required), attribute, max_value, +4 more.
visualize_edge_toolA
Visualize a SUMO network file with selected edges highlighted and save as PNG image.
Only use when user EXPLICITLY requests edge visualization!
- User says "show edge details", "visualize this road" → Use this
- User asks "which road is congested?" → Do NOT use, answer with text
Args:
net_file: Path to the SUMO network file (.net.xml)
road_name: Name of the road to highlight
output_dir: Output directory for visualization files
Inputs: net_file (required), road_name (required), output_dir.
visualize_net_toolA
Visualize a SUMO network file and save as PNG image.
⚠️ IMPORTANT: Only use when user EXPLICITLY requests visualization!
- User says "show network map", "visualize network" → Use this
- User asks about simulation results → Do NOT use, answer with text
Args:
net_file: Path to the SUMO network file (.net.xml)
output_dir: Output directory for visualization files
Inputs: net_file (required), output_dir.
visualize_policy_target_toolA
Visualize policy target area using SUMO's built-in visualization.
Only use when user EXPLICITLY requests to preview policy area!
- User says "show me which roads will be affected" → Use this
- User just wants to apply policy → Do NOT use, proceed with policy tool
This tool helps visualize which road segments will be affected by a policy
before actually applying it. Essential for confirming policy target area!
VISUALIZATION:
- Shows ONLY the selected road segments within the specified radius
- Uses SUMO's standard plot_net_selection.py for consistent styling
- Clean, focused view of the policy target area
USE CASES:
1. "Show me which part of 테헤란로 near 강남역 within 300m will be affected"
2. "Visualize policy target before deleting road segments"
3. "Preview lane reduction area before applying"
REALISTIC WORKFLOW:
Step 1: Use this tool to visualize policy area
Step 2: Confirm the target area is correct
Step 3: Apply policy using edge_edit_tool/reduce_lanes_tool/speed_limit_edit_tool
Args:
net_file: Network file path
target_road_name: Road name (e.g., "테헤란로", "Teheran-ro")
reference_location: Reference point (e.g., "강남역", "Gangnam Station")
radius_km: Radius in km (e.g., 0.3 for 300m)
output_dir: Output directory
Returns:
PNG file showing selected road segments only
EXAMPLE:
visualize_policy_target_tool(
net_file="gangnam_station.net.xml",
target_road_name="테헤란로",
reference_location="강남역 교차로",
radius_km=0.3
)
-> Shows: Only the 300m segment of Teheran-ro near Gangnam Station (selected segments)
Inputs: net_file (required), target_road_name (required), radius_km, output_dir, +1 more.
web_search_toolA
Search the web using DuckDuckGo. Use this to look up real-world information
that helps with simulation scenario design.
Useful for:
- Venue/facility capacity (e.g., "Madison Square Garden capacity")
- Geographic/infrastructure info (e.g., "bridges connecting Manhattan to Brooklyn")
- Traffic patterns and event schedules
- Road/highway specifications
- Any factual information needed to set realistic simulation parameters
Args:
query: Search query string. Be specific for better results.
max_results: Number of results to return (default: 5, max: 10)
Returns:
List of search results, each with title, url, and snippet.
Inputs: query (required), max_results.
xml_to_sqlite_toolA
Convert SUMO XML results to SQLite database for advanced SQL-based analysis.
IMPORTANT: This enables detailed queries that summary statistics cannot answer:
- Top N queries (e.g., "What are the top 10 roads by density?")
- Specific edge analysis (e.g., "What is the congestion level at the Gangnam Station intersection?")
- Comparative analysis (e.g., "How did density change before and after the policy?")
- Temporal analysis (e.g., "How does speed vary across times of day?")
- Road-level aggregation (e.g., "What is the average congestion across all of Teheran-ro?")
DATABASE SCHEMA (IMPORTANT):
- simulations: (simulation_id, created_at, vehicle_count, net_file, route_file, description)
- edge_info: (simulation_id, edge_id, road_name, length, num_lanes, speed_limit)
* Network topology from .net.xml — enables road-level analysis
* road_name: Human-readable street name (e.g., "테헤란로", "9th Avenue")
* length: Edge length in meters
* num_lanes: Number of lanes
* speed_limit: Speed limit in km/h
- vehicle_info: (simulation_id, vehicle_id, vehicle_type, fuel_type, origin_edge, destination_edge, origin_road, destination_road)
* Per-vehicle metadata from tripinfo + network — enables OD and fleet analysis
* vehicle_type: SUMO vType (e.g., "passenger", "truck")
* fuel_type: Classified from emissionClass — "gasoline", "diesel", "electric", "unknown"
* origin_edge / destination_edge: First/last edge IDs
* origin_road / destination_road: Human-readable road names (from edge_info)
- trips: (simulation_id, trip_id, duration, routeLength, waitingTime, timeLoss, depart, arrival, ...)
- edge_metrics: (simulation_id, edge_id, interval_begin, interval_end, speed, density, waitingTime,
timeLoss, occupancy, entered, left, ...)
* PRIMARY KEY: (simulation_id, edge_id, interval_begin)
- network_state: (simulation_id, time, running, halting, waiting, meanSpeed, meanSpeedRelative, ...)
* Network-wide time-series from summary.xml — 1 row per simulation second
* Enables temporal analysis: congestion onset, performance curves, before/after comparison
* PRIMARY KEY: (simulation_id, time)
KEY: Table name is 'edge_metrics', NOT 'edgedata'!
=== ROAD-LEVEL ANALYSIS WITH edge_info ===
For road-level congestion analysis (instead of edge-level), JOIN edge_info:
-- Road-level weighted density (RECOMMENDED for congestion ranking)
SELECT ei.road_name,
ROUND(SUM(em.density * ei.length) / SUM(ei.length), 2) AS weighted_density,
ROUND(SUM(ei.length), 1) AS total_length_m
FROM edge_metrics em
JOIN edge_info ei ON em.simulation_id = ei.simulation_id AND em.edge_id = ei.edge_id
WHERE em.simulation_id = '1_baseline' AND ei.road_name IS NOT NULL
GROUP BY ei.road_name
ORDER BY weighted_density DESC LIMIT 10;
-- Filter out micro-segments (< 10m)
WHERE ei.length > 10
-- Query by road name (NO need for get_edge_ids_from_road_name_tool!)
WHERE ei.road_name = '테헤란로'
DESIGN: Single unified DB with simulation_id for comparative studies
- Same network's simulations → Same DB file
- Different simulations → Different simulation_ids in same DB
- Enables SQL JOIN for before/after comparison
Args:
tripinfo_xml: Path to tripinfo XML file
edgedata_xml: Path to edgedata XML file
edgedata_emission_xml: Path to edgedata emission XML file
output_dir: Output directory for database (default: output/analysis)
simulation_id: REQUIRED — NEVER leave as None!
Format: "{N}_{scenario_name}" where N is the sequential number.
- Check current simulations in context to determine N.
- Use short, descriptive English names.
- Examples: "1_baseline", "2_road_closure_teheran", "3_lane_reduction_gangnam",
"4_tls_optimize_seocho", "5_speed_limit_gangnam"
net_file: Path to network (.net.xml) file used in this simulation
route_file: Path to route (.rou.xml) file used in this simulation
description: REQUIRED — NEVER leave as None!
Human-readable English description of the scenario.
Displayed in the UI for scenario comparison.
Always describe WHAT was changed and WHERE.
Examples:
- "Baseline simulation (Gangnam Station 1km)"
- "Road closure on Teheran-ro near Gangnam Station (500m)"
- "Lane reduction on Gangnam-daero (3 to 2 lanes)"
- "Signal timing optimization at Seocho-daero intersection"
- "Speed limit reduced to 30km/h on Teheran-ro"
summary_xml: Path to summary XML file from sumo_runner result's top-level "summary_xml" field.
IMPORTANT: Always provide this! Without it, dashboard time-series charts will be empty.
Returns:
Dict with db_file, simulation_id, and metadata
Examples:
# After sumo_runner returns result with metadata.absolute_summary:
xml_to_sqlite_tool(
tripinfo_xml="gangnam_tripinfo.xml",
edgedata_xml="gangnam_edgedata.xml",
edgedata_emission_xml="gangnam_emission.xml",
simulation_id="1_baseline",
description="Baseline simulation (Gangnam Station 1km)",
summary_xml="/path/to/gangnam_summary.xml"
)
Inputs: edgedata_xml (required), tripinfo_xml (required), edgedata_emission_xml (required), net_file, +5 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
26 tool updates
v0.1.0- First observed
analyze_road_details_tool - First observed
edge_edit_tool - First observed
flow_generation_tool - First observed
get_edge_ids_from_road_name_tool - First observed
get_road_names_tool - First observed
net_convert - First observed
network_summary_tool - First observed
osm_extract - First observed
reduce_lanes_tool - First observed
route_analysis_tool - First observed
route_generate - First observed
simulation_report_tool - First observed
speed_limit_edit_tool - First observed
sumo_runner - First observed
tls_adaptation_tool - First observed
tls_offset_tool - First observed
trip_generate - First observed
validate_od_coordinates_tool - First observed
vehicle_generation_tool - First observed
vehicle_type_edit_tool - First observed
visualize_edge_tool - First observed
visualize_edgedata_tool - First observed
visualize_net_tool - First observed
visualize_policy_target_tool - First observed
web_search_tool - First observed
xml_to_sqlite_tool
TDQS
Scored across 26 tools
Most tools have distinct purposes, especially the pipeline steps (osm_extract, net_convert, etc.) and editing tools (edge_edit_tool, reduce_lanes_tool). However, multiple visualization tools (visualize_net_tool, visualize_edge_tool, visualize_policy_target_tool, visualize_edgedata_tool) and two vehicle generation tools (vehicle_generation_tool, flow_generation_tool) could cause some confusion despite clear usage instructions.
The naming is mostly snake_case, but there is inconsistency: core pipeline tools omit the '_tool' suffix (e.g., net_convert, trip_generate) while many utility and editing tools include it (e.g., edge_edit_tool, xml_to_sqlite_tool). This mix of naming conventions slightly reduces predictability.
With 26 tools, the server is quite extensive for a single domain. While each tool has a clear role, the count feels high for an MCP server, potentially overwhelming agents. A more focused set (e.g., 15-20 tools) might be more manageable.
The tool set covers the entire simulation workflow: data extraction, network conversion, demand generation (with multiple modes), routing, simulation execution, network editing (edges, lanes, speed, TLS), vehicle type editing, analysis (route, road details, SQL database), visualization, reporting, and web search. There are no obvious gaps for the stated purpose of traffic simulation with SUMO.
Maintenance
Related MCP Connectors
Conversational what-if simulation: build, diagnose and compare Petri-net models; CC0 catalog.
Simulation, evaluation and monitoring for voice agents.
Deterministic reasoning stack for AI agents: simulate, decide & compute, plus cross-domain tools.
Build and run team decision simulations for training and assessment from a chat description.
1
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceConnects LLMs to Eclipse SUMO traffic simulation, enabling AI agents to automate traffic network generation, demand modeling, signal optimization, simulation execution, and real-time TraCI control through natural language.59MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with Eclipse SUMO traffic simulations, automating tasks from data acquisition to signal optimization.8MIT
- AlicenseAqualityDmaintenanceEnables natural language-driven creation and execution of autonomous-vehicle scenarios in the CARLA simulator, with validated primitives and replay support.71MIT
- FlicenseNot gradedqualityAmaintenanceEnables natural language interaction with OpenStudio building energy simulation, allowing creation, querying, and modification of models, running EnergyPlus simulations, and analyzing results.58-