Skip to content

Commit 42f57d7

Browse files
authored
Merge pull request #101 from neo4j-contrib/cypher-improve-tool-annotations
update fastmcp version, add annotations, update changelog
2 parents 13b4d1d + 44a01eb commit 42f57d7

File tree

4 files changed

+1017
-996
lines changed

4 files changed

+1017
-996
lines changed

servers/mcp-neo4j-cypher/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* Add error indicator to tool results in the `CallToolResult` object
1313
* Add HTTP transport option
1414
* Migrate to FastMCP v2.x
15+
* Add tool annotations
1516
* Update Dockerfile for http configuration
1617

1718
## v0.2.4

servers/mcp-neo4j-cypher/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description = "A simple Neo4j MCP server"
55
readme = "README.md"
66
requires-python = ">=3.10"
77
dependencies = [
8-
"fastmcp>=2.0.0",
8+
"fastmcp>=2.2.7",
99
"neo4j>=5.26.0",
1010
"pydantic>=2.10.1",
1111
]

servers/mcp-neo4j-cypher/src/mcp_neo4j_cypher/server.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from fastmcp.exceptions import ToolError
77
from fastmcp.tools.tool import ToolResult, TextContent
88
from fastmcp.server import FastMCP
9+
from mcp.types import ToolAnnotations
910
from neo4j import (
1011
AsyncDriver,
1112
AsyncGraphDatabase,
@@ -51,7 +52,14 @@ def create_mcp_server(neo4j_driver: AsyncDriver, database: str = "neo4j", namesp
5152

5253
namespace_prefix = _format_namespace(namespace)
5354

54-
@mcp.tool(name=namespace_prefix+"get_neo4j_schema")
55+
@mcp.tool(name=namespace_prefix+"get_neo4j_schema",
56+
annotations=ToolAnnotations(title="Get Neo4j Schema",
57+
readOnlyHint=True,
58+
destructiveHint=False,
59+
idempotentHint=True,
60+
openWorldHint=True
61+
)
62+
)
5563
async def get_neo4j_schema() -> list[ToolResult]:
5664
"""List all node, their attributes and their relationships to other nodes in the neo4j database.
5765
If this fails with a message that includes "Neo.ClientError.Procedure.ProcedureNotFound"
@@ -143,7 +151,13 @@ def clean_schema(schema: dict) -> dict:
143151
logger.error(f"Database error retrieving schema: {e}")
144152
raise ToolError(f"Error: {e}")
145153

146-
@mcp.tool(name=namespace_prefix+"read_neo4j_cypher")
154+
@mcp.tool(name=namespace_prefix+"read_neo4j_cypher",
155+
annotations=ToolAnnotations(title="Read Neo4j Cypher",
156+
readOnlyHint=True,
157+
destructiveHint=False,
158+
idempotentHint=True,
159+
openWorldHint=True
160+
))
147161
async def read_neo4j_cypher(
148162
query: str = Field(..., description="The Cypher query to execute."),
149163
params: Optional[dict[str, Any]] = Field(
@@ -167,7 +181,13 @@ async def read_neo4j_cypher(
167181
logger.error(f"Database error executing query: {e}\n{query}\n{params}")
168182
raise ToolError(f"Error: {e}\n{query}\n{params}")
169183

170-
@mcp.tool(name=namespace_prefix+"write_neo4j_cypher")
184+
@mcp.tool(name=namespace_prefix+"write_neo4j_cypher",
185+
annotations=ToolAnnotations(title="Write Neo4j Cypher",
186+
readOnlyHint=False,
187+
destructiveHint=True,
188+
idempotentHint=False,
189+
openWorldHint=True
190+
))
171191
async def write_neo4j_cypher(
172192
query: str = Field(..., description="The Cypher query to execute."),
173193
params: Optional[dict[str, Any]] = Field(

0 commit comments

Comments
 (0)