GrafeoDB MCP server demonstrates solid tool design with well-structured definitions across 13 tools. All tools have clear, purpose-driven descriptions (average ~250 chars) that explain both WHAT the tool does and WHEN/WHY to use it, notably including explicit DO NOT USE guidance to help LLMs avoid confusion. All tools include complete JSON Schema input definitions with typed parameters. However, there are three consistent gaps: (1) No output schema documentation visible, tools return results but the response structure is not formally specified, (2) No tool annotations (readOnlyHint/destructiveHint/idempotentHint) despite clear read/write semantics, (3) Limited parameter validation guidance (e.g., no explicit min/max for numeric top_k, no regex patterns for string enums). Error handling is minimal, no recovery guidance or actionable error messages visible. The server design prioritizes graph algorithm correctness and CRUD clarity over LLM-optimized ergonomics. This is a competent foundation but falls short of production A-grade by missing structured output contracts and semantic hints that enable more robust agent planning.
Bulk-create nodes and edges from JSON arrays in a single call. Use this tool when: you need to import many nodes and edges at once, e.g. loading a dataset, building a graph from structured data, or ingesting extracted entities in bulk. Do NOT use for: creating a single node or edge (use create_node / create_edge), or updating existing data (use update_node / update_edge). Nodes are created first, then edges. Edges can reference nodes created in this batch using "@index" notation (e.g. "@0" refers to the first node in the nodes array). Note: this operation is not atomic. If an error occurs partway through, already-created nodes/edges remain in the graph.
Compute betweenness centrality for all nodes (Brandes' algorithm). Betweenness centrality measures how often a node lies on the shortest path between other node pairs. High-betweenness nodes are "bridges" that connect different parts of the graph. Use this tool when: you want to find bridge or bottleneck nodes. Do NOT use this for: finding the most linked-to nodes (use pagerank) or finding communities (use louvain).
Find connected components (treating the graph as undirected). A connected component is a maximal set of nodes such that every pair is reachable from every other by following edges in either direction. Use this tool when: you want to know how many disconnected subgraphs exist, or which nodes belong to the same component. Do NOT use this for: finding dense sub-communities (use louvain).
Create a directed edge (relationship) between two existing nodes. Use this tool when: you need to connect two nodes with a typed relationship. Do NOT use this for: creating nodes (use create_node) or querying relationships (use execute_gql).
No output schema documentation. All 13 tools lack documented return types and field structures. LLMs cannot plan downstream tool calls or extract results without knowing what fields to expect.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear semantic distinctions. 9 tools marked READ_ONLY (e.g., pagerank, dijkstra, get_node) and 4 marked WRITE (batch_import, create_node, create_edge, execute_gql) would benefit from protocol-level hints to guide agent safety and retry logic.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 63 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 14 | - | v1 |
Create a new node in the graph with the given labels and properties. Use this tool when: you need to add a single new entity to the graph. Do NOT use this for: bulk inserts (use execute_gql with INSERT/CREATE statements) or creating relationships (use create_edge).
Find the shortest weighted path between two nodes (Dijkstra's algorithm). Returns the total distance and the sequence of nodes along the path. Use this tool when: you need the shortest or cheapest path between two known nodes. Do NOT use this for: discovering important nodes (use pagerank) or finding similar content (use vector_search).
Execute a GQL query against the graph database. GQL (Graph Query Language) is the ISO/IEC standard query language. Use MATCH patterns to find nodes and relationships, INSERT to add data, and RETURN to project results. Cypher syntax (e.g. CREATE) is automatically normalized to GQL (INSERT), so queries written in Cypher style will generally work as-is. Use this tool when: you need to run a custom query — complex filters, multi-hop traversals, aggregations, or mutations beyond what the CRUD tools (create_node, create_edge) provide. Do NOT use this for: simple node lookups (use get_node), label browsing (use search_nodes_by_label), or one-hop exploration (use get_neighbors).
Get neighboring nodes connected to a given node. This is the primary tool for graph traversal. Use it to explore the neighborhood of a known node. Returns connected nodes with the edges that link them. Use this tool when: you have a node ID and want to see what it connects to. Do NOT use this for: finding nodes by property (use search_nodes_by_label) or running complex multi-hop queries (use execute_gql).
Get a single node by its ID. Returns the node's labels and all properties, or a not-found message. Use this tool when: you have a specific node ID and need its details. Do NOT use this for: searching nodes by label or property (use search_nodes_by_label or execute_gql).
Get an overview of the graph database: counts, labels, edge types, and schema. Use this tool when: you need to understand what data is in the graph before writing queries, or to verify the database state after mutations. Do NOT use this for: retrieving specific node/edge data (use get_node, search_nodes_by_label, or execute_gql).
Detect communities using the Louvain modularity-optimization algorithm. Groups densely-connected nodes into communities. Higher resolution values produce more (smaller) communities; lower values produce fewer (larger) communities. Use this tool when: you want to discover clusters or groups in the graph. Do NOT use this for: finding paths (use dijkstra) or ranking nodes (use pagerank).
Run PageRank and return the top-k most important nodes. PageRank assigns every node a score proportional to how many (and how important) other nodes link to it. Higher scores mean more connected / influential nodes. Use this tool when: you want to find the most important or central nodes in the graph based on link structure. Do NOT use this for: finding similar nodes by content (use vector_search) or for finding shortest paths (use dijkstra).
Find nodes that have a specific label. Returns node IDs and their properties, paginated by limit/offset. Use this tool when: you want to list or browse nodes of a certain type (e.g. all Person nodes, all Company nodes). Do NOT use this for: getting a single node by ID (use get_node), or complex filtered queries (use execute_gql).
Parameters lack validation constraints. Numeric fields (top_k, limit, offset, max_iterations, tolerance, damping, resolution, normalized flag) have no min/max bounds, no enums for string choices (e.g., direction: 'outgoing'|'incoming'|'both'). Unbounded parameters invite hallucinated or absurd values from LLMs.
connected_components and graph_info have empty input schemas (no parameters but schema still needs explicit documentation). This is correct for parameterless tools but lacks clarity on what they return and their purpose in agent workflows.
No error handling or recovery guidance. Tools provide no examples of failure modes, error messages, or corrective actions. E.g., if execute_gql receives invalid GQL syntax or dijkstra finds no path, how does the LLM recover?
batch_import allows non-atomic operations ('already-created nodes/edges remain in the graph' if error occurs). No confirmation step or dry-run mode for bulk write operations, increasing risk of partial data corruption in agent workflows.
Result pagination not fully specified. search_nodes_by_label accepts limit/offset but does not document total count or next_cursor in response. Pagination guidance is missing, agents cannot reliably iterate through large result sets.