Connect StreetLight Data to ChatGPT: Analyze mobility & zone sets
Learn how to connect StreetLight Data to ChatGPT using a managed MCP server. Automate mobility analysis, zone set creation, and SATC metrics retrieval.
If you need to connect StreetLight Data to ChatGPT to automate mobility analysis, query SATC metrics, or manage geographic zone sets, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between ChatGPT's tool calls and StreetLight Data's complex spatial APIs. You can either build and maintain this infrastructure yourself, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL.
If your team uses Claude instead, check out our guide on connecting StreetLight Data to Claude, or explore our broader architectural overview on connecting StreetLight Data to AI Agents.
Giving a Large Language Model (LLM) read and write access to a sprawling geospatial analytics ecosystem like StreetLight Data is a massive engineering challenge. You have to map highly nested GeoJSON schemas to MCP tool definitions, handle asynchronous analysis job polling, and strictly manage query quotas. Every time StreetLight updates a parameter requirement or deprecates a metric field, you have to update your custom server code, redeploy, and test the integration.
This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for StreetLight Data, connect it natively to ChatGPT, and execute complex transportation data workflows using natural language.
The Engineering Reality of the StreetLight Data API
A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against StreetLight Data's APIs—or maintaining custom connectors for 100+ other platforms—is painful.
You aren't just integrating a standard REST CRUD application. StreetLight Data is a heavy analytics engine dealing with massive spatial constraints, asynchronous processing, and strict data quotas. If you decide to build a custom MCP server for StreetLight Data, you own the entire API lifecycle. Here are the specific integration challenges that break standard assumptions when working with StreetLight:
Spatial Data Complexity and Mutual Exclusivity
StreetLight API endpoints have highly specific validation rules that LLMs struggle with natively. For example, when creating a zone set, the API requires spatial definitions. However, zones (polygons) and osm_ids (OpenStreetMap segments) are mutually exclusive parameters. If an LLM attempts to pass both, or formats a GeoJSON LineString incorrectly for a SATC metric query, the API will reject the request. Your MCP server must enforce strict JSON Schema definitions that explicitly guide the LLM away from these collisions.
Asynchronous Analysis Pipelines
Unlike retrieving a standard user record, running a mobility analysis in StreetLight takes time. You don't just call a run endpoint and get results back in a millisecond. You must first create the analysis (POST), store the resulting analysis_uuid, periodically poll the status endpoint until the queue finishes, and finally query a separate metrics endpoint to download a large CSV or Zip file. If your MCP server doesn't break these down into distinct, composable tools, the LLM will timeout waiting for the initial HTTP request to finish.
Strict Quotas and Rate Limit Passthrough
StreetLight Data enforces strict API quotas based on your subscription tier—specifically for SATC segment queries and analysis runs. If your AI agent gets stuck in a loop and triggers an HTTP 429 Too Many Requests error, you need exact visibility into the limits.
Note on Rate Limits: Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream StreetLight Data API returns an HTTP 429, Truto passes that error directly back to the caller. Truto normalizes the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF spec. The caller (your MCP client framework) is strictly responsible for implementing exponential backoff.
The Managed MCP Approach
Instead of forcing your engineering team to build authentication state machines, poll loops, and pagination logic, Truto acts as a managed MCP provider.
When a customer connects their StreetLight Data account, Truto automatically derives a complete set of MCP tools from the API documentation and your environment's resource schemas. These tools are served dynamically over a single, authenticated JSON-RPC 2.0 endpoint. Truto flattens the input namespaces, injecting instructions directly into the LLM context to ensure parameters like pagination cursors and mutually exclusive geometries are handled correctly.
Step-by-Step: Creating a StreetLight Data MCP Server
Once you have linked a StreetLight Data account in Truto, you need to generate an MCP server URL. Each MCP server is scoped to a single integrated account and encoded with a cryptographic token.
You can generate this server either via the Truto UI or programmatically via the API.
Method 1: Via the Truto UI
- Log in to your Truto dashboard and navigate to Integrated Accounts.
- Select your connected StreetLight Data account.
- Click on the MCP Servers tab.
- Click Create MCP Server.
- Select your desired configuration (e.g., allow all tools, or restrict to read-only methods).
- Click Save and copy the generated MCP server URL.
Method 2: Via the Truto API
For teams building programmatic AI workflows, you can generate the MCP server programmatically. The API will validate your configuration, generate a secure token, and return a ready-to-use URL.
Make a POST request to /integrated-account/:id/mcp:
curl -X POST https://api.truto.one/integrated-account/<integrated_account_id>/mcp \
-H "Authorization: Bearer YOUR_TRUTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "StreetLight Mobility Assistant",
"config": {
"methods": ["read", "write", "custom"]
}
}'The response returns the server URL containing your secure token:
{
"id": "mcp_abc123",
"name": "StreetLight Mobility Assistant",
"url": "https://api.truto.one/mcp/tkn_789xyz..."
}Step-by-Step: Connecting the Server to ChatGPT
Once you have your Truto MCP server URL, you must connect it to your ChatGPT interface or your local AI agent framework.
Method 1: Via the ChatGPT UI
If you are using ChatGPT Enterprise, Pro, or Plus with Developer Mode enabled:
- Open ChatGPT and navigate to Settings → Apps → Advanced settings.
- Enable Developer mode.
- Under MCP servers / Custom connectors, click Add new server.
- Enter a descriptive name (e.g., "StreetLight Data (Truto)").
- Paste the Truto MCP URL into the Server URL field.
- Click Save. ChatGPT will immediately perform an MCP handshake, load the StreetLight Data tool schemas, and make them available in your session.
Method 2: Via Manual Config File (Local Agents)
If you are building custom agents or using a local MCP client (like Cursor or Claude Desktop), you can configure the server using the standard SSE transport mechanism.
Add the following configuration to your MCP settings JSON file:
{
"mcpServers": {
"streetlight_data": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sse",
"https://api.truto.one/mcp/tkn_789xyz..."
]
}
}
}StreetLight Data Hero Tools
Truto exposes dozens of StreetLight Data endpoints as tools, but some provide significantly more leverage for AI agents. Here are the core "hero tools" your ChatGPT agent will use to automate spatial analysis.
create_a_street_light_data_zone_set
This tool allows the LLM to dynamically create geographic boundaries for origin-destination matrices. The LLM must supply either a set of raw zones or a list of osm_ids, but the schema validation strictly prevents both.
"Create a new zone set named 'Downtown Seattle Transit Corridor'. Here are the 15 OpenStreetMap segment IDs that make up the bounding box. Create the set and return the new zone_set_uuid."
create_a_street_light_data_analysis
This is the workhorse tool. It instructs StreetLight to queue up a new mobility analysis using existing zone sets. The LLM handles the complex payload construction mapping travel modes to specific zone arrays.
"Launch a new Origin-Destination analysis for passenger vehicles. Use the 'Downtown Seattle Transit Corridor' zone set UUID I just created for both the origin and destination. Set the analysis type to OD and return the tracking UUID."
list_all_street_light_data_analyses
Because StreetLight analyses take time to process on their backend servers, the LLM needs a way to check status. This tool allows the agent to poll the status of one or more queued analysis runs.
"Check the status of analysis UUID 12345-abcde. Is the run completed, or is it still in the queue? If it is completed, tell me what metrics are available to download."
list_all_street_light_data_analysis_metrics_by_uuid
Once an analysis job is marked as complete, this tool allows ChatGPT to actually fetch the results. Depending on the size, it returns the raw CSV metric lines directly in the context window.
"The analysis finished. Download the 'Zone_Activity' metrics for UUID 12345-abcde. Summarize the peak traffic hours based on the CSV data returned."
list_all_street_light_data_satc_metrics
For quick traffic counts that don't require a full Origin-Destination matrix, the Segment Analysis Traffic Counts (SATC) tool is vital. It allows the agent to pass a geometry payload and instantly retrieve historical traffic volumes. Note: This tool hits segment quotas directly.
"I need the SATC traffic metrics for this specific GeoJSON linestring representing Main Street. Give me the average weekday volume for passenger vehicles over the last month."
street_light_data_osm_ids_search
Often, users don't know the exact OpenStreetMap IDs for a road. This tool allows the LLM to pass a geometric bounding box to StreetLight and retrieve all valid OSM segments inside it, bridging the gap between raw coordinates and routable segments.
"Search for all available StreetLight OSM segments within this GeoJSON polygon. Filter the results and list just the primary road classification segments with their IDs."
To view the complete inventory of available StreetLight Data tools and their exact JSON schemas, visit the StreetLight Data integration page.
Workflows in Action
Connecting StreetLight Data to ChatGPT is about moving from single API calls to complex, multi-step geographic orchestrations. Here is how specific personas use these tools in the real world.
Scenario 1: The Urban Planner Assessing Corridor Congestion
An urban planner needs to launch an Origin-Destination analysis for a proposed transit corridor, but they don't want to click through the complex InSight web interface to build the zones manually.
"Search for OSM IDs within this coordinate bounding box. Filter out the residential streets. Use the remaining arterial OSM IDs to create a new zone set called 'Main St Corridor'. Finally, launch a new Origin-Destination analysis for trucks using that zone set."
How the agent executes this:
street_light_data_osm_ids_search: The agent searches the provided bounding box and retrieves a list of OSM segment IDs, filtering out the residential tags.create_a_street_light_data_zone_set: The agent passes the filtered array of IDs into the zone creation endpoint and captures the returnedzone_set_uuid.create_a_street_light_data_analysis: Using the new UUID, the agent submits the analysis job to StreetLight's servers, explicitly setting the travel mode to trucks.
sequenceDiagram
participant User as User
participant ChatGPT as "ChatGPT (MCP Client)"
participant Truto as "Truto MCP Server"
participant Upstream as "StreetLight Data API"
User->>ChatGPT: "Find OSM segments, build zone set, run analysis"
ChatGPT->>Truto: Call street_light_data_osm_ids_search(geometry)
Truto->>Upstream: POST /osm/search
Upstream-->>Truto: Returns array of OSM IDs
Truto-->>ChatGPT: Parsed JSON IDs
ChatGPT->>Truto: Call create_a_street_light_data_zone_set(osm_ids)
Truto->>Upstream: POST /zonesets
Upstream-->>Truto: Returns zone_set_uuid
Truto-->>ChatGPT: New zone set confirmation
ChatGPT->>Truto: Call create_a_street_light_data_analysis(uuid)
Truto->>Upstream: POST /analyses
Upstream-->>Truto: Returns analysis job tracking UUID
Truto-->>ChatGPT: Job queued confirmation
ChatGPT-->>User: "I've queued the truck OD analysis. Tracking ID is xyz123."Scenario 2: The Traffic Engineer Polling and Extracting Metrics
A traffic engineer wants to review the results of an analysis that was queued the previous night, without logging into a dashboard or downloading CSVs manually.
"Check the status of my analysis UUID 99988-vwxyz. If it's done, pull the Zone Activity metrics and tell me which zone had the highest volume during the AM peak period."
How the agent executes this:
list_all_street_light_data_analyses: The agent queries the status endpoint. If the response indicatescompleted, it proceeds.list_all_street_light_data_analysis_metrics_by_uuid: The agent requests the raw metrics file. Truto handles the proxying and returns the text payload to the context window.- Local processing: ChatGPT reads the CSV rows directly in the prompt context and calculates the highest volume for the AM peak day part.
flowchart TD
A["list_all_street_light_data_analyses<br>(Check Job Status)"] --> B{Status?}
B -->|Queued| C["Wait / Inform User"]
B -->|Completed| D["list_all_street_light_data_analysis_metrics_by_uuid<br>(Download Metrics)"]
D --> E["LLM parses CSV text<br>Summarizes peak data"]Security and Access Control
When exposing powerful geospatial analytics tools to an LLM, strict governance is essential. Truto provides four mechanisms to secure your StreetLight Data MCP servers:
- Method Filtering: By defining
config.methods: ["read"]during server creation, you can ensure the LLM can only query existing metrics and statuses, strictly preventing it from creating expensive new analyses or burning segment quotas by accident. - Tag Filtering: Limit the server to specific domains of the StreetLight API. Passing
tags: ["zones"]restricts the available tools to zone set management only. - Extra Authentication (
require_api_token_auth): By default, possessing the MCP server URL grants access. By setting this flag to true, Truto forces the MCP client to also pass a valid Truto API token via a Bearer header—preventing execution if the URL leaks. - Automatic Expiry (
expires_at): For temporary workflows, you can set a hard TTL on the MCP server. When the timestamp is reached, Truto automatically purges the routing credentials from the distributed KV store, instantly revoking the LLM's access to StreetLight Data.
Stop writing custom poll loops and GeoJSON validation logic just to get your LLM to talk to StreetLight Data. By leveraging Truto’s dynamically generated MCP servers, your engineering team can move straight to building intelligent transportation agents, leaving the API maintenance, schema mapping, and auth refresh complexity to the infrastructure layer.
FAQ
- How does ChatGPT authenticate with the StreetLight Data API?
- ChatGPT authenticates using a secure Model Context Protocol (MCP) server URL generated by Truto. The server URL securely stores your StreetLight Data account credentials, meaning ChatGPT only needs the URL to execute operations.
- How do I handle StreetLight Data API rate limits with AI agents?
- Truto passes upstream HTTP 429 errors directly to the caller and normalizes the rate limit data into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). Truto does not retry or throttle requests; your client framework is responsible for exponential backoff.
- Can I restrict ChatGPT to only read StreetLight Data metrics?
- Yes. When creating the MCP server in Truto, you can pass a configuration filter like `methods: ["read"]`. This ensures the generated MCP server only exposes read-only tools, preventing the LLM from triggering expensive analysis jobs.