mcp-arcgis
by rajivdatta
README.md
# mcp-arcgis — ArcGIS Online (AGOL) MCP server
A [FastMCP](https://github.com/jlowin/fastmcp) server for **searching content and
querying hosted feature layers** in ArcGIS Online. It talks to the AGOL Sharing
REST and Feature Service REST APIs directly with `requests` — no heavy `arcgis`
Python package required.
**Read-only by design.** It searches items and queries features; it never adds,
updates, or deletes anything.
## Tools
**Connection / discovery**
- `whoami` — signed-in user + portal info (connectivity smoke test)
- `search_items` — search org/public content (`query`, `item_type`, `sort_field`)
- `get_item` — full portal metadata for an item id
- `get_item_data` — an item's `/data` payload (a Web Map's operational layers, an app/dashboard config); trace which feature services a map uses
- `list_layers` — layers & tables of a feature service (ids, names, geometry types)
- `describe_layer` — fields, geometry type, extent, record count for one layer
**Query**
- `query_features` — attribute/paged query → `{count, exceededTransferLimit, features}`
- `count_features` — count matching a `where` clause (cheap sizing before a pull)
- `aggregate_features` — server-side group-by statistics (SUM/AVG/COUNT/MIN/MAX/STDDEV/VAR) via `outStatistics`; no rows pulled
- `distinct_values` — distinct value combinations of one or more fields (discover categories/codes)
- `spatial_query` — query features by geometry (point/envelope/polygon), optionally buffered by a `distance`
Identify a layer to describe/query by **either** a feature-service `item_id`
(+ `layer_index`, default 0) **or** a direct `service_url` (a `.../FeatureServer`
root plus `layer_index`, or a full `.../FeatureServer/0` layer URL).
### Example
```
search_items(query="parcels", item_type="Feature Service")
list_layers(item_id="abcd1234…")
describe_layer(item_id="abcd1234…", layer_index=0)
count_features(item_id="abcd1234…", where="STATUS = 'Active'")
query_features(item_id="abcd1234…", where="ACRES > 5",
out_fields="OBJECTID,NAME,ACRES", order_by="ACRES DESC", limit=50)
# distinct values in a field, then a grouped rollup
distinct_values(item_id="abcd1234…", fields="STATUS")
aggregate_features(item_id="abcd1234…", group_by="STATUS", order_by="sum_ACRES DESC",
statistics=[{"statisticType":"count","onStatisticField":"OBJECTID",
"outStatisticFieldName":"n"},
{"statisticType":"sum","onStatisticField":"ACRES"}])
# everything within 500 m of a lat/long point
spatial_query(item_id="abcd1234…", geometry={"x":-79.38,"y":43.65},
geometry_type="esriGeometryPoint", distance=500, units="esriSRUnit_Meter")
# which feature services does a web map reference?
get_item_data(item_id="webmap-item-id…")
```
## Auth
Set `"auth"` in `config.json`:
| value | how it signs in |
|-------|-----------------|
| `user` *(default)* | Named user: `username` + password from the env var named by `password_env` (in `.env`). A token is generated against the portal and cached. |
| `api-key` | API key from the env var named by `api_key_env`. |
| `anonymous` | No sign-in; only public content/layers are reachable. |
`url` is your organization's portal (e.g. `https://yourorg.maps.arcgis.com`) or
`https://www.arcgis.com`. `max_records` caps how many features a single
`query_features` call returns (default 2000); page with `offset` for more.
No secrets live in `config.json` — only the *name* of an environment variable.
## Setup
```powershell
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
copy config.example.json config.json # edit url + username
copy .env.example .env # set ARCGIS_PASSWORD
.\.venv\Scripts\python.exe server.py # smoke test (Ctrl+C to stop)
```
## Register with an MCP client
See `examples/mcp.json` — point `command` at the venv's `python.exe` and `args`
at `server.py`, using absolute paths.
## Use with Claude Desktop
Claude Desktop reads MCP servers from `claude_desktop_config.json`
(**Settings → Developer → Edit Config**). Add this server under `mcpServers`
with absolute paths to the venv Python and `server.py`, then fully quit and
reopen Claude Desktop.
## License
MIT — see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues