Skip to content

Commit bb9939b

Browse files
committed
support projection directionality as param in path algos
1 parent e1ed4bd commit bb9939b

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

mcp_server/src/mcp_server_neo4j_gds/path_algorithm_handlers.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010

1111
class DijkstraShortestPathHandler(AlgorithmHandler):
1212
def find_shortest_path(
13-
self, start_node: str, end_node: str, node_identifier_property: str, **kwargs
13+
self,
14+
start_node: str,
15+
end_node: str,
16+
node_identifier_property: str,
17+
undirected: bool = False,
18+
**kwargs,
1419
):
1520
query = f"""
1621
MATCH (start)
@@ -30,7 +35,7 @@ def find_shortest_path(
3035
start_node_id = int(df["start_id"].iloc[0])
3136
end_node_id = int(df["end_id"].iloc[0])
3237

33-
with projected_graph(self.gds) as G:
38+
with projected_graph(self.gds, undirected=undirected) as G:
3439
# If any optional parameter is not None, use that parameter
3540
args = locals()
3641
params = {k: v for k, v in kwargs.items() if v is not None}
@@ -72,13 +77,18 @@ def execute(self, arguments: Dict[str, Any]) -> Any:
7277
arguments.get("start_node"),
7378
arguments.get("end_node"),
7479
arguments.get("nodeIdentifierProperty"),
80+
undirected=arguments.get("undirected", False),
7581
relationshipWeightProperty=arguments.get("relationship_property"),
7682
)
7783

7884

7985
class DeltaSteppingShortestPathHandler(AlgorithmHandler):
8086
def delta_stepping_shortest_path(
81-
self, source_node: str, node_identifier_property: str, **kwargs
87+
self,
88+
source_node: str,
89+
node_identifier_property: str,
90+
undirected: bool = False,
91+
**kwargs,
8292
):
8393
query = f"""
8494
MATCH (source)
@@ -93,7 +103,7 @@ def delta_stepping_shortest_path(
93103

94104
source_node_id = int(df["source_id"].iloc[0])
95105

96-
with projected_graph(self.gds) as G:
106+
with projected_graph(self.gds, undirected=undirected) as G:
97107
# If any optional parameter is not None, use that parameter
98108
params = {k: v for k, v in kwargs.items() if v is not None}
99109
logger.info(f"Delta-Stepping shortest path parameters: {params}")
@@ -153,14 +163,19 @@ def execute(self, arguments: Dict[str, Any]) -> Any:
153163
return self.delta_stepping_shortest_path(
154164
arguments.get("sourceNode"),
155165
arguments.get("nodeIdentifierProperty"),
166+
undirected=arguments.get("undirected", False),
156167
delta=arguments.get("delta"),
157168
relationshipWeightProperty=arguments.get("relationshipWeightProperty"),
158169
)
159170

160171

161172
class DijkstraSingleSourceShortestPathHandler(AlgorithmHandler):
162173
def dijkstra_single_source_shortest_path(
163-
self, source_node: str, node_identifier_property: str, **kwargs
174+
self,
175+
source_node: str,
176+
node_identifier_property: str,
177+
undirected: bool = False,
178+
**kwargs,
164179
):
165180
query = f"""
166181
MATCH (source)
@@ -175,7 +190,7 @@ def dijkstra_single_source_shortest_path(
175190

176191
source_node_id = int(df["source_id"].iloc[0])
177192

178-
with projected_graph(self.gds) as G:
193+
with projected_graph(self.gds, undirected=undirected) as G:
179194
# If any optional parameter is not None, use that parameter
180195
params = {k: v for k, v in kwargs.items() if v is not None}
181196
logger.info(f"Dijkstra single-source shortest path parameters: {params}")
@@ -234,6 +249,7 @@ def execute(self, arguments: Dict[str, Any]) -> Any:
234249
return self.dijkstra_single_source_shortest_path(
235250
arguments.get("sourceNode"),
236251
arguments.get("nodeIdentifierProperty"),
252+
undirected=arguments.get("undirected", False),
237253
relationshipWeightProperty=arguments.get("relationshipWeightProperty"),
238254
)
239255

@@ -244,6 +260,7 @@ def a_star_shortest_path(
244260
source_node: str,
245261
target_node: str,
246262
node_identifier_property: str,
263+
undirected: bool = False,
247264
**kwargs,
248265
):
249266
query = f"""
@@ -264,7 +281,7 @@ def a_star_shortest_path(
264281
source_node_id = int(df["source_id"].iloc[0])
265282
target_node_id = int(df["target_id"].iloc[0])
266283

267-
with projected_graph(self.gds) as G:
284+
with projected_graph(self.gds, undirected=undirected) as G:
268285
# If any optional parameter is not None, use that parameter
269286
params = {k: v for k, v in kwargs.items() if v is not None}
270287
logger.info(f"A* shortest path parameters: {params}")
@@ -305,6 +322,7 @@ def execute(self, arguments: Dict[str, Any]) -> Any:
305322
arguments.get("sourceNode"),
306323
arguments.get("targetNode"),
307324
arguments.get("nodeIdentifierProperty"),
325+
undirected=arguments.get("undirected", False),
308326
latitudeProperty=arguments.get("latitudeProperty"),
309327
longitudeProperty=arguments.get("longitudeProperty"),
310328
relationshipWeightProperty=arguments.get("relationshipWeightProperty"),

mcp_server/src/mcp_server_neo4j_gds/path_algorithm_specs.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
"type": "string",
2424
"description": "Property of the relationship to use for path finding",
2525
},
26+
"undirected": {
27+
"type": "boolean",
28+
"description": "Whether to treat the graph as undirected or not. Default is false (directed).",
29+
},
2630
},
2731
"required": ["start_node", "end_node", "nodeIdentifierProperty"],
2832
},
@@ -53,6 +57,10 @@
5357
"type": "string",
5458
"description": "Name of the relationship property to use as weights. If unspecified, the algorithm runs unweighted.",
5559
},
60+
"undirected": {
61+
"type": "boolean",
62+
"description": "Whether to treat the graph as undirected or not. Default is false (directed).",
63+
},
5664
},
5765
"required": ["sourceNode", "nodeIdentifierProperty"],
5866
},
@@ -78,6 +86,10 @@
7886
"type": "string",
7987
"description": "Name of the relationship property to use as weights. If unspecified, the algorithm runs unweighted.",
8088
},
89+
"undirected": {
90+
"type": "boolean",
91+
"description": "Whether to treat the graph as undirected or not. Default is false (directed).",
92+
},
8193
},
8294
"required": ["sourceNode", "nodeIdentifierProperty"],
8395
},
@@ -121,6 +133,10 @@
121133
"type": "string",
122134
"description": "Name of the relationship property to use as weights. If unspecified, the algorithm runs unweighted.",
123135
},
136+
"undirected": {
137+
"type": "boolean",
138+
"description": "Whether to treat the graph as undirected or not. Default is false (directed).",
139+
},
124140
},
125141
"required": [
126142
"sourceNode",

0 commit comments

Comments
 (0)