@jayjex/sensormesh-mcp
v0.1.0
Published
MCP server for the SensorMesh open sensor data commons: list devices, query readings (free 10-row window), per-sensor stats. Calls the SensorMesh HTTP API, no keys needed.
Maintainers
Readme
sensormesh-mcp
MCP server for the SensorMesh open sensor data commons. SensorMesh publishes IoT readings (air quality, temperature, noise) in an open catalog with stable schemas. Cities usually lock this kind of data behind a vendor portal; SensorMesh puts it behind a plain HTTP API instead. This server connects an MCP client to that API, so your LLM session can list the mesh and pull readings directly.
Three tools, all free, no API key:
sensor_list— devices, sites, sensor types, row counts, time coverage, sha256 of the backing data file.sensor_query— a filtered window of readings, up to 10 rows per call. Filter by device, site, sensor type, anomaly flag, or time range. JSON or CSV.sensor_stats— per-sensor min/mean/max and anomaly flag counts, with the same filters.
The 10-row cap is the API's free preview window. The same API also exposes /v1/readings with full pagination over x402 (USDC on Base, $0.001/call) for HTTP clients — this MCP package stays on the free endpoints, so there are no keys, wallets, or secrets anywhere in it.
Install
Node 18+. Nothing to configure if you want the public reference instance:
{
"mcpServers": {
"sensormesh": {
"command": "npx",
"args": ["-y", "@jayjex/sensormesh-mcp"]
}
}
}To point at your own SensorMesh API instance (the server from sensormesh, mcp/api.js), set one env var:
{
"mcpServers": {
"sensormesh": {
"command": "npx",
"args": ["-y", "@jayjex/sensormesh-mcp"],
"env": { "SENSORMESH_API_URL": "http://localhost:8793" }
}
}
}Example
sensor_query with { "site": "riverside-park", "sensor": "air_quality", "limit": 3 }:
{
"sha256": "022b54f909529cc80faed065f16e70824cb46c4c26e6efc61bfeb1be501a1197",
"total_matched": 144,
"returned": 3,
"filters": { "site": "riverside-park", "sensor": "air_quality" },
"rows": [
{ "timestamp": "2026-09-08T00:00:00Z", "device_id": "sm-004", "site": "riverside-park",
"sensor_type": "air_quality", "value": 9, "unit": "ug/m3", "anomaly": "" }
]
}total_matched tells you how many rows the filter hits; page through them with the paid HTTP endpoint, or regenerate the full dataset yourself — the sha256 pins the exact file the API serves.
Bad filter values fail fast: sensor_query rejects an unknown site or sensor with an error listing the valid ones, instead of returning zero rows and leaving you guessing.
Development
npm install
node test/fixtures.test.mjs # helpers against recorded API payloads
SENSORMESH_API_URL=http://127.0.0.1:8793 node test/smoke.mjs # live MCP round tripThe test fixtures are real responses captured from a running SensorMesh API: a 9-device inventory and a filtered preview (144 matches, 10-row window).
Related
- jayjex/sensormesh — the commons itself: device simulator, sample data, dashboard, metered HTTP API.
- jayjex/pdfcheck-mcp — PDF page-tree QA server, same stdio pattern.
MIT license.
