Continuing the GenAI-with-a-GeoSpatial-twist thread I started a while back. Back then, I had a language model reason about geospatial logic. This time, I wanted it to actually do the work—on my open project, inside my running ArcGIS Pro session, while I watch.
The result is ProCowork, an experimental native ArcGIS Pro add-in that embeds the Claude Code engine in a dockable chat panel. I can ask it to list layers, add and calculate fields, select features, run a buffer, or write a more specialized ArcPy script. Claude generates the code, the add-in runs it against the live project, and the code and results come back into the same panel.
For example, I can type:
- “List the layers in the current map.”
- “Add a DOUBLE field POP_DEN to Parcels and set it to POP / AREASQMI.”
- “Select parcels where POP_DEN > 5000 and zoom to them.”
- “Buffer Roads by 100 meters and add the result to the map.”
The panel is useful, but the interesting part is not the chat UI. It is getting an external AI coding agent safely and reliably close enough to a live ArcGIS Pro project to be useful.
The constraint that shaped the design
arcpy.mp.ArcGISProject("CURRENT") only resolves inside ArcGIS Pro's
own Python execution context on the foreground geoprocessing thread. Claude Code,
however, runs as a headless child process. If it starts Python outside Pro, that
process can work with datasets on disk, but it cannot see the open project as
CURRENT.
My first design kept a long-running Python daemon inside Pro. It worked, and then it
went stale in the ways long-running bridges tend to go stale. So I flipped the
ownership around. A persistent C# bridge now lives inside ArcGIS Pro for the whole
session. For each request it either uses the ArcGIS Pro .NET SDK directly or launches
one fresh foreground ArcPy geoprocessing tool. The tool resolves
CURRENT, performs the operation, returns JSON, and goes away. There is no
Python daemon left behind to outlive its host.
ProCowork panel (WPF, inside ArcGIS Pro)
-> Claude Code (headless child process)
-> MCP over HTTP on 127.0.0.1:<ephemeral-port>
-> C# BridgeService (inside ArcGIS Pro)
-> .NET SDK on the CIM thread
-> or one fresh RunScript.pyt call
-> live project, map, and data
MCP is the small door into the live map
The bridge exposes 14 tools through the
Model Context Protocol (MCP). There
are focused tools such as list_layers, get_field_list,
feature_count, select_by_attribute,
add_field, and run_geoprocessing. The centerpiece is
run_python_current(code), which gives Claude a general ArcPy path when
the curated tools are not enough.
Inspection calls and lightweight map interactions use the .NET SDK on Pro's CIM thread, without ArcPy. Data updates and arbitrary Python go through the fresh geoprocessing call. Those calls are serialized behind a semaphore because geoprocessing does not appreciate re-entrancy. Request and response data travel as geoprocessing string parameters, so there is no file-polling spool between C# and Python.
Everything stays local except the normal Claude model traffic. The MCP server binds
only to loopback, chooses an ephemeral port at startup, and requires a new bearer
token for the session. The add-in writes those details into a generated
.mcp.json and starts Claude Code in streaming JSON mode. It can use the
user's existing Claude Code login, an OAuth token, or an Anthropic API key; stored
secrets are protected with Windows DPAPI.
There is also a very practical UI detail. Claude answers in Markdown, while ArcGIS Pro hosts a native WPF interface. ProCowork converts the Markdown with Markdig and renders headings, code, lists, links, and real tables using themed WPF controls. Tool calls can be shown or hidden, but I like keeping them visible: if an agent is changing my map, I want to see the code it ran.
A word of caution
By default, ProCowork runs in what I call YOLO mode. Generated code executes on the open project without an approval prompt. That immediacy is the point, and it is also exactly as dangerous as it sounds. ArcPy can edit or delete real data. The bundled instructions tell Claude to inspect fields first, use edit sessions, create backups before destructive operations, and report affected row counts. Those are useful working rules; they are not a security boundary.
So this is an MVP and an experiment, not an Esri product or a supported Esri solution. It currently requires Windows, ArcGIS Pro 3.7, the ArcGIS Pro SDK for .NET, and Claude Code. Keep backups and do not point it at the only copy of important data. The architecture can support an approval step, but the proper approval card is still future work.
What excites me here is not only that an LLM can write ArcPy. We already knew that. It is that a small, local bridge can give an agent useful context from a live desktop GIS, let it act through the correct execution path, and return the evidence to the same place where the request started.
The source code, build instructions, architecture notes, and current limitations are available in the ProCowork repository. The next step is the one I would want before using it on serious work: a clear review-and-approve experience for generated operations.
More to come :-)
No comments:
Post a Comment