66from fastmcp .exceptions import ToolError
77from fastmcp .tools .tool import ToolResult , TextContent
88from fastmcp .server import FastMCP
9+ from mcp .types import ToolAnnotations
910from 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