6
6
from fastmcp .exceptions import ToolError
7
7
from fastmcp .tools .tool import ToolResult , TextContent
8
8
from fastmcp .server import FastMCP
9
+ from mcp .types import ToolAnnotations
9
10
from neo4j import (
10
11
AsyncDriver ,
11
12
AsyncGraphDatabase ,
@@ -51,7 +52,14 @@ def create_mcp_server(neo4j_driver: AsyncDriver, database: str = "neo4j", namesp
51
52
52
53
namespace_prefix = _format_namespace (namespace )
53
54
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
+ )
55
63
async def get_neo4j_schema () -> list [ToolResult ]:
56
64
"""List all node, their attributes and their relationships to other nodes in the neo4j database.
57
65
If this fails with a message that includes "Neo.ClientError.Procedure.ProcedureNotFound"
@@ -143,7 +151,13 @@ def clean_schema(schema: dict) -> dict:
143
151
logger .error (f"Database error retrieving schema: { e } " )
144
152
raise ToolError (f"Error: { e } " )
145
153
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
+ ))
147
161
async def read_neo4j_cypher (
148
162
query : str = Field (..., description = "The Cypher query to execute." ),
149
163
params : Optional [dict [str , Any ]] = Field (
@@ -167,7 +181,13 @@ async def read_neo4j_cypher(
167
181
logger .error (f"Database error executing query: { e } \n { query } \n { params } " )
168
182
raise ToolError (f"Error: { e } \n { query } \n { params } " )
169
183
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
+ ))
171
191
async def write_neo4j_cypher (
172
192
query : str = Field (..., description = "The Cypher query to execute." ),
173
193
params : Optional [dict [str , Any ]] = Field (
0 commit comments