Skip to content

Commit 94c5e12

Browse files
authored
Merge pull request #64 from neo4j-contrib/data-modeling-remove-nvl-viz
* remove nvl viz * shorten tool names
2 parents 2637695 + 59ecf05 commit 94c5e12

File tree

6 files changed

+7
-108
lines changed

6 files changed

+7
-108
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@ Thumbs.db
4747
__pycache__
4848
servers/mcp-neo4j-data-modeling/test.ipynb
4949
servers/mcp-neo4j-data-modeling/src/mcp_neo4j_data_modeling/temp.html
50+
mcp.json

servers/mcp-neo4j-data-modeling/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
## Next
22

33
### Fixed
4+
* Shorten tool names to comply with Cursor name length restrictions
45

56
### Changed
7+
* Removed NVL visualization due to compatibility issues
68

79
### Added
810
* Code generation tools for ingestion queries
911
* Resource that explains the recommended process of ingesting data into Neo4j
12+
* Mermaid visualization configuration generation
1013

1114
## v0.1.0
1215

servers/mcp-neo4j-data-modeling/pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ readme = "README.md"
66
requires-python = ">=3.10"
77
dependencies = [
88
"mcp[cli]>=1.6.0",
9-
"neo4j-viz>=0.3.1",
109
"pydantic>=2.10.1",
1110
]
1211

servers/mcp-neo4j-data-modeling/src/mcp_neo4j_data_modeling/data_model.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from collections import Counter
33
from typing import Any
44

5-
import neo4j_viz as nvl
65
from pydantic import BaseModel, Field, ValidationInfo, field_validator
76

87
NODE_COLOR_PALETTE = [
@@ -156,16 +155,6 @@ def all_properties_dict(self) -> dict[str, str]:
156155
props.update({self.key_property.name: f"{self.key_property.type} | KEY"})
157156
return props
158157

159-
def to_nvl(self) -> nvl.Node:
160-
"Convert the node to a Neo4j Visualization Graph Node."
161-
return nvl.Node(
162-
id=self.label,
163-
caption=self.label,
164-
size=20,
165-
caption_size=1,
166-
properties=self.all_properties_dict,
167-
)
168-
169158
def get_mermaid_config_str(self) -> str:
170159
"Get the Mermaid configuration string for the node."
171160
props = [f"<br/>{self.key_property.name}: {self.key_property.type} | KEY"]
@@ -303,15 +292,6 @@ def all_properties_dict(self) -> dict[str, str]:
303292
props.update({self.key_property.name: f"{self.key_property.type} | KEY"})
304293
return props
305294

306-
def to_nvl(self) -> nvl.Relationship:
307-
"Convert the relationship to a Neo4j Visualization Graph Relationship."
308-
return nvl.Relationship(
309-
source=self.start_node_label,
310-
target=self.end_node_label,
311-
caption=self.type,
312-
properties=self.all_properties_dict,
313-
)
314-
315295
def get_mermaid_config_str(self) -> str:
316296
"Get the Mermaid configuration string for the relationship."
317297
props = (
@@ -511,13 +491,6 @@ def remove_relationship(
511491
except ValueError:
512492
pass
513493

514-
def to_nvl(self) -> nvl.VisualizationGraph:
515-
"Convert the data model to a Neo4j Visualization Graph."
516-
return nvl.VisualizationGraph(
517-
nodes=[n.to_nvl() for n in self.nodes],
518-
relationships=[r.to_nvl() for r in self.relationships],
519-
)
520-
521494
def _generate_mermaid_config_styling_str(self) -> str:
522495
"Generate the Mermaid configuration string for the data model."
523496
node_color_config = ""

servers/mcp-neo4j-data-modeling/src/mcp_neo4j_data_modeling/server.py

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import logging
2-
import os
3-
import webbrowser
42
from typing import Any, Literal
53

64
from mcp.server.fastmcp import FastMCP
@@ -20,9 +18,7 @@
2018
def create_mcp_server() -> FastMCP:
2119
"""Create an MCP server instance for data modeling."""
2220

23-
mcp: FastMCP = FastMCP(
24-
"mcp-neo4j-data-modeling", dependencies=["pydantic", "webbrowser"]
25-
)
21+
mcp: FastMCP = FastMCP("mcp-neo4j-data-modeling", dependencies=["pydantic"])
2622

2723
@mcp.resource("resource://schema/node")
2824
def node_schema() -> dict[str, Any]:
@@ -107,35 +103,6 @@ def validate_data_model(
107103
logger.error(f"Validation error: {e}")
108104
raise ValueError(f"Validation error: {e}")
109105

110-
@mcp.tool()
111-
def visualize_data_model_in_browser(data_model: DataModel) -> None:
112-
"Open an interactive graph visualization in the default web browser. Validates the data model before opening the visualization. Warning: May not be useable in some environments such as Docker and Claude Desktop."
113-
logger.info("Validating the data model.")
114-
try:
115-
dm_validated = DataModel.model_validate(data_model, strict=True)
116-
except ValidationError as e:
117-
logger.error(f"Validation error: {e}")
118-
raise ValueError(f"Validation error: {e}")
119-
120-
def open_html_in_browser(html_content, filename="temp.html"):
121-
"""Opens an HTML string in the default web browser.
122-
123-
Args:
124-
html_content: The HTML content as a string.
125-
filename: The name of the temporary HTML file.
126-
"""
127-
with open(filename, "w") as f:
128-
f.write(html_content)
129-
130-
# Construct the file URL
131-
file_url = "file://" + os.path.realpath(filename)
132-
webbrowser.open_new_tab(file_url)
133-
134-
logger.info(
135-
"Opening an interactive graph visualization in the default web browser."
136-
)
137-
open_html_in_browser(dm_validated.to_nvl().render().data)
138-
139106
@mcp.tool()
140107
def load_from_arrows_json(arrows_data_model_dict: dict[str, Any]) -> DataModel:
141108
"Load a data model from the Arrows web application format. Returns a data model as a JSON string."
@@ -160,7 +127,7 @@ def get_mermaid_config_str(data_model: DataModel) -> str:
160127
return dm_validated.get_mermaid_config_str()
161128

162129
@mcp.tool()
163-
def get_node_cypher_ingest_query_for_many_records(
130+
def get_node_cypher_ingest_query(
164131
node: Node = Field(description="The node to get the Cypher query for."),
165132
) -> str:
166133
"""
@@ -174,7 +141,7 @@ def get_node_cypher_ingest_query_for_many_records(
174141
return node.get_cypher_ingest_query_for_many_records()
175142

176143
@mcp.tool()
177-
def get_relationship_cypher_ingest_query_for_many_records(
144+
def get_relationship_cypher_ingest_query(
178145
data_model: DataModel = Field(
179146
description="The data model snippet that contains the relationship, start node and end node."
180147
),

servers/mcp-neo4j-data-modeling/uv.lock

Lines changed: 0 additions & 44 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)