Skip to content

Latest commit

 

History

History
227 lines (177 loc) · 9.3 KB

File metadata and controls

227 lines (177 loc) · 9.3 KB

MCP Server

NREL-shift includes a Model Context Protocol (MCP) server that exposes the full framework to LLM-based agents. The server provides 33 tools, 3 resource templates, and 3 prompt templates that enable AI assistants to build synthetic distribution feeder models interactively.

Installation

Install the MCP optional dependencies:

pip install -e ".[mcp]"

Running the Server

# Via console script
shift-mcp-server

# Via Python module
python -m shift.mcp_server

The server uses stdio transport by default.

Claude Desktop Configuration

Add the following to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "nrel-shift": {
      "command": "shift-mcp-server"
    }
  }
}

Architecture

src/shift/mcp_server/
├── __init__.py
├── __main__.py          # Entry point
├── server.py            # FastMCP instance, lifespan, registration
├── config.py            # ServerConfig (Pydantic model)
├── state.py             # AppContext — in-memory session state
├── serializers.py       # JSON serialization helpers
├── tools/
│   ├── data_acquisition/
│   │   ├── parcels.py       # fetch_parcels, fetch_parcels_in_polygon
│   │   ├── roads.py         # fetch_road_network
│   │   └── clustering.py    # cluster_parcels
│   ├── graph/
│   │   ├── management.py    # create_graph, delete_graph, list_graphs
│   │   ├── nodes.py         # add_node, remove_node, get_node
│   │   ├── edges.py         # add_edge, remove_edge, get_edge
│   │   ├── query.py         # query_graph
│   │   └── builder.py       # build_graph_from_groups
│   ├── mapper/
│   │   ├── phase.py         # configure_phase_mapper, get_phase_mapping
│   │   ├── voltage.py       # configure_voltage_mapper, get_voltage_mapping
│   │   └── equipment.py     # configure_equipment_mapper, get_equipment_mapping
│   ├── system/
│   │   ├── builder.py       # build_system, get_system_summary, list_systems
│   │   └── export.py        # export_system_json
│   ├── utilities/
│   │   ├── geo.py           # distance_between_points, polygon_from_points
│   │   ├── network.py       # create_mesh_network, split_edges
│   │   └── nearest.py       # find_nearest_points
│   └── documentation/
│       ├── search.py        # search_docs
│       └── read.py          # list_docs, read_doc
├── resources/
│   └── docs.py              # shift://docs, shift://docs/{name}, shift://graphs
└── prompts/
    └── workflows.py         # build_feeder_from_location, inspect_network, explore_api

Session State

The server is stateful — graphs, mappers, and systems are held in memory for the duration of a session via the AppContext dataclass. Each tool receives the context through FastMCP's lifespan mechanism.

Key state containers:

Container Type Contents
graphs dict[str, DistributionGraph] In-memory distribution graphs
phase_mappers dict[str, BalancedPhaseMapper] Phase mapper instances
voltage_mappers dict[str, TransformerVoltageMapper] Voltage mapper instances
equipment_mappers dict[str, EdgeEquipmentMapper] Equipment mapper instances
systems dict[str, DistributionSystem] Built distribution systems
docs_index dict[str, str] Indexed documentation content

Tools Reference

Data Acquisition (3 tools)

Tool Description
fetch_parcels Fetch building parcels from OpenStreetMap for a given location
fetch_parcels_in_polygon Fetch building parcels within a polygon boundary
fetch_road_network Fetch the road network from OpenStreetMap around a location

Graph Management (8 tools)

Tool Description
create_graph Create a new empty distribution graph
delete_graph Delete a distribution graph and its associated mappers
list_graphs List all distribution graphs in the current session
add_node Add a node to a distribution graph
remove_node Remove a node from a distribution graph
get_node Get details of a specific node
add_edge Add an edge (line or transformer) to a distribution graph
remove_edge Remove an edge from a distribution graph
get_edge Get details of a specific edge
query_graph Query information about a distribution graph (summary, nodes, edges, vsource, dfs_tree)
build_graph_from_groups Build a complete distribution graph from parcel groups using the PRSG algorithm

Mappers (6 tools)

Tool Description
configure_phase_mapper Configure balanced phase mapping for a distribution graph
get_phase_mapping Get phase assignments (nodes, assets, or transformers)
configure_voltage_mapper Configure voltage mapping for a distribution graph
get_voltage_mapping Get voltage assignments for all nodes
configure_equipment_mapper Configure equipment mapping using an equipment catalog
get_equipment_mapping Get equipment assignments for all edges

System (3 tools)

Tool Description
build_system Build a complete distribution system from a configured graph
get_system_summary Get a summary of a built distribution system
list_systems List all built distribution systems in the current session
export_system_json Export a distribution system to JSON format

Utilities (5 tools)

Tool Description
cluster_parcels Cluster geographic points into groups using K-means
distance_between_points Calculate geodesic distance between two points
polygon_from_points Create a polygon boundary from a set of points
create_mesh_network Create a regular 2D mesh/grid network
split_edges Split long edges into shorter segments
find_nearest_points Find the nearest target point for each source point

Documentation (3 tools)

Tool Description
list_docs List all available documentation files
search_docs Search across all documentation for a keyword or phrase
read_doc Read a specific documentation file, optionally by section

Resource Templates

URI Description
shift://docs List all indexed documentation files
shift://docs/{doc_name} Read a specific documentation file by name
shift://graphs List all in-memory distribution graphs

Prompt Templates

Prompt Description
build_feeder_from_location Guides through the full pipeline: fetch → cluster → build graph → map phases → map voltages → map equipment → build system → export
inspect_network Inspect an existing distribution graph and summarize its topology
explore_api Explore the NREL-shift API documentation on a given topic

Configuration

The server loads configuration from a ServerConfig Pydantic model. Defaults can be overridden by placing a shift_mcp_config.yaml file in the working directory.

Setting Default Description
server_name "nrel-shift" Server display name
server_version "0.1.0" Server version
default_search_distance_m 500.0 Default parcel/road search radius (meters)
max_search_distance_m 5000.0 Maximum allowed search radius (meters)
default_cluster_count 5 Default number of K-means clusters
docs_path "" Override path to documentation directory
log_level "INFO" Logging level

Example Workflow

A typical agent-driven workflow:

User: Build a small distribution feeder for Golden, CO

Agent:
1. fetch_parcels(location="Golden, CO", distance_meters=300)
   → 24 parcels found

2. cluster_parcels(points=[...], num_clusters=6)
   → 6 groups created

3. build_graph_from_groups(groups=[...], source_longitude=-105.22, source_latitude=39.75)
   → graph "graph-a1b2" created with 31 nodes, 30 edges

4. configure_phase_mapper(graph_id="graph-a1b2", transformer_configs=[...])
   → phase mapper configured

5. configure_voltage_mapper(graph_id="graph-a1b2", transformer_voltages=[...])
   → voltage mapper configured

6. configure_equipment_mapper(graph_id="graph-a1b2", catalog_path="...")
   → equipment mapper configured

7. build_system(system_name="golden_feeder", graph_id="graph-a1b2")
   → system built

8. export_system_json(system_name="golden_feeder", output_path="./golden_feeder.json")
   → exported to ./golden_feeder.json

Known Limitations

  • Pydantic version conflict: grid-data-models==2.2.1 pins pydantic~=2.10, while mcp[cli] may require pydantic>=2.12. You may need to relax the pin or install in a separate environment.
  • Network-dependent tools: fetch_parcels, fetch_parcels_in_polygon, and fetch_road_network require internet access to query OpenStreetMap.
  • Single session: The stdio transport serves one client at a time. For multi-client scenarios, wrap with a proxy or use the SSE transport.