Giving an AI assistant tools for ArangoDB
How I built an MCP server for inspecting and querying ArangoDB, and why tool descriptions, result limits, and database permissions matter.
This article was revised on 13 October 2026 against the local server implementation. The original project dates to December 2024.
Why I built it
I wanted an AI assistant to inspect our development database without asking me to copy collection details and query results into a conversation.
The ArangoDB MCP Server exposes database operations through the Model Context Protocol. The assistant chooses an operation and supplies its arguments. The server validates the request, calls ArangoDB, and returns the result.
That division matters. The server does not translate natural language or decide whether an answer is useful. Those jobs belong to the assistant and the person reviewing its work.
Give the assistant a way to inspect first
An assistant cannot write a useful query if it does not know the collection names or the shape of the documents. I added tools for listing collections, inspecting indexes, counting documents, and reading samples.
A sample is incomplete evidence. It can show that a field exists in some documents, but it cannot establish that every document contains that field. Returning structured data lets the assistant use the sample without the server turning it into a stronger claim.
The implementation keeps tool descriptions in src/tools.ts, argument schemas in src/types.ts, and database operations in src/handlers.ts. The protocol setup in src/index.ts connects them over standard input and output.
Separate checking a query from running it
arango_validate_query asks ArangoDB to parse AQL, its query language, without executing the query. arango_explain_query asks for an execution plan. An assistant can inspect either result before requesting data.
For example, an assistant looking for active users could submit these arguments to arango_read_query, after establishing that the collection and field exist:
{
"query": "FOR user IN users FILTER user.active == @active RETURN user",
"bindVars": { "active": true },
"limit": 20
}The response includes the returned rows, their count, the requested limit, and a hasMore flag. The flag tells the client whether unread results remain. It prevents a partial response from looking like the whole result set.
Successful calls return both JSON text and structuredContent. A client can display the text or use the structured values in its next step.
Keep result size separate from query cost
Returning twenty rows does not prove that the database only examined twenty documents. A query can scan a large collection before producing a small result.
The query tools therefore accept optional maxRuntime and memoryLimit settings, as well as a result limit. Query-plan inspection can help explain the work involved. None of those controls makes every query inexpensive.
Graph and search tools expose more specific operations, including traversal, shortest paths, and ArangoSearch queries. They give the assistant a defined operation to request without requiring every task to start with general AQL.
Describe the write boundary honestly
arango_read_query rejects write and schema-change keywords. This is a keyword check, not a complete query authorization system. The general arango_query tool and document mutation tools can still write through the configured connection.
Dropping a collection requires confirm: true. That is an input requirement. It does not establish that a person saw and approved the request in their assistant client. The server cannot promise a confirmation dialog for every destructive operation.
Database permissions remain the access boundary. Bind variables separate values from query text, but they do not make an arbitrary query harmless. I describe this project as a development tool rather than claiming that an assistant can safely operate any database.
Treat an export as a filesystem operation
The backup tool writes collection documents as JSON. That adds a second boundary beyond the database: where files can be written.
src/backupPaths.ts resolves an output directory beneath ARANGO_BACKUP_ROOT. It accepts one directory name, checks the resolved path, and rejects symlinked output directories. The writer refuses to overwrite an existing file.
Exports also have a document limit. A successful export is therefore not a guarantee that every document, index, and database setting was backed up. The feature produces JSON files for inspection or transfer. It is not a full recovery system.
What I check
The repository includes a smoke-test script that connects an MCP client to the running server and exercises database operations. It checks bounded results, rejection of writes through the read-query tool, graph operations, and exports. Separate tests cover backup paths.
These checks target the server contract. They cannot prove that an assistant will choose the right query or correctly explain its result.
The project account covers the wider implementation. The ArangoDB MCP Server repository contains the source and setup instructions.