Installation#
Requirements#
Python 3.11 or later. On Python 3.10,
pip installinstalls 0.2.0 of each server instead, without an error, and these pages do not describe it.uv(recommended), whoseuvxruns a server straight from PyPI without installing itFor the Cypher and memory servers, a running AgensGraph 2.17 or later. The driver refuses an older server at connect;
SHOW agversiontells you which you have. The data-modeling server needs no database.A database role that is not a superuser and not a member of
pg_execute_server_program(see Database role)
The servers are built on fastmcp 3.x and pydantic, and talk to AgensGraph through the
agensgraph-python 2.0 driver, which runs on
psycopg 3. The Cypher and memory servers also pull in psycopg[binary,pool].
Install#
The servers are released on PyPI as four distributions, all at 0.3.1:
Distribution |
Command it installs |
Needs a database |
|---|---|---|
|
|
Yes |
|
|
Yes |
|
|
No |
|
(none; the shared core, installed automatically) |
— |
Run with uvx. An MCP client normally launches a server itself, and uvx fetches and
runs it in a throwaway environment, so nothing needs installing first:
uvx mcp-agensgraph-cypher
uvx mcp-agensgraph-memory
uvx mcp-agensgraph-data-modeling
Install into an environment when you host a server yourself, for example over HTTP.
Install one server by name, or all three through the agensgraph-ai umbrella package:
pip install mcp-agensgraph-cypher
pip install "agensgraph-ai[mcp]" # the cypher, memory and data-modeling servers
Each server distribution puts its command on your PATH. The [mcp] extra installs the three
servers and nothing else; there is no Python module to import from it.
Exact token counting (optional)#
A Cypher read response is bounded by a token budget. Without a tokenizer the server
estimates a response’s size from its bytes. The tokens extra of the shared core installs
tiktoken so the count is exact:
pip install "mcp-agensgraph-common[tokens]"
uvx --with "mcp-agensgraph-common[tokens]" mcp-agensgraph-cypher
It is an extra because loading a tokenizer fetches the model’s encoding file over the network the first time.
From source#
To work on the servers themselves, clone the repository and set up a server with uv
(this also installs the common core it depends on):
git clone https://github.com/skaiworldwide-oss/agensgraph-ai.git
cd agensgraph-ai/mcp-agensgraph/servers/mcp-agensgraph-cypher
uv sync
uv run mcp-agensgraph-cypher --transport stdio
Database role#
A server refuses to start as a role that can run a command on the database host, that
is, a superuser or a member of pg_execute_server_program. COPY ... TO PROGRAM is not
stopped by a read-only transaction, so connected as such a role the read-only tools would not
be a boundary. Starting one anyway fails with:
RuntimeError: This role can run a command on the server's host, through COPY ... TO PROGRAM,
which a read-only transaction does not stop -- so the read tools would not be a boundary.
Connect as a role that is neither a superuser nor a member of pg_execute_server_program,
or pass --allow-server-programs to accept it.
Create an ordinary role for the servers instead. At startup the Cypher server (unless it is
read-only) and the memory server create their graph if it is missing, which needs the
CREATE privilege on the database. They do this before the role check, so a refused start
as a superuser can leave that graph behind.
CREATE ROLE mcp LOGIN PASSWORD 'mcp'; -- choose your own password
GRANT CREATE ON DATABASE mydb TO mcp;
A graph the role creates is its own, so it can read and write it with no further grants.
To point a read-only Cypher server at a graph another role owns, grant read access to that graph’s schema, which has the graph’s name:
CREATE ROLE mcp_ro LOGIN PASSWORD 'mcp_ro';
GRANT USAGE ON SCHEMA mygraph TO mcp_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA mygraph TO mcp_ro;
GRANT SELECT ON ALL TABLES covers only the labels that exist when it runs. For labels
created later, have the graph’s owner also run:
ALTER DEFAULT PRIVILEGES IN SCHEMA mygraph GRANT SELECT ON TABLES TO mcp_ro;
If CONNECT on the database has been revoked from PUBLIC, grant it to the role as well.
Label names are case-sensitive to the servers; see
Usage for labels created unquoted.
Passing --allow-server-programs (or AGENSGRAPH_ALLOW_SERVER_PROGRAMS=true) lets a server
start as a privileged role anyway. It logs a warning, and the read-only tools are then not a
boundary.
Connection configuration#
The Cypher and memory servers read their AgensGraph connection from environment variables or the matching CLI flags. A flag wins over its variable. The canonical names, with the legacy aliases still accepted, are:
Variable |
Legacy alias |
CLI flag |
Default |
Meaning |
|---|---|---|---|---|
|
|
|
|
Connection URL |
|
— |
|
|
Database user |
|
— |
|
(unset) |
Database password |
|
|
|
|
Database name |
|
|
|
|
Graph name |
The URL is a libpq connection URL, so settings it carries, such as ?sslmode=require, reach
the connection. The user, password and database are layered on top of it. Because the user
and database default to agens, a user or database written in the URL is replaced by those
defaults: set AGENSGRAPH_USERNAME and AGENSGRAPH_DATABASE (or the flags) explicitly. A
password in the URL is kept when AGENSGRAPH_PASSWORD is unset.
The password has no default. Left unset, nothing is sent, and libpq resolves it the way it
resolves everything else: PGPASSWORD, .pgpass, PGSERVICE, or an authentication method
that needs no password. Prefer the environment variable or .pgpass to --password, since a
password on the command line is visible to every process on the machine through ps.
Transports and server knobs#
All three servers share these:
Variable |
CLI flag |
Default |
Meaning |
|---|---|---|---|
|
|
|
|
|
|
(none) |
Prefix added to every tool name ( |
|
|
|
HTTP/SSE bind host |
|
|
|
HTTP/SSE port |
|
|
|
HTTP/SSE path |
|
|
(none) |
Comma-separated CORS origins |
|
|
|
Allowed hosts (DNS-rebinding protection) |
The host, port and path apply only to http and sse.
Warning
The HTTP and SSE transports have no authentication. Anything that can reach the port can
call every tool the server exposes, with its database credentials. Keep the loopback default,
and put something that authenticates in front of a server you expose. stdio, which is what
Claude Desktop uses, is not reachable by another process.
Safety flags#
CLI flag |
Variable |
Default |
Server |
Effect |
|---|---|---|---|---|
|
|
|
cypher |
No write tool |
|
|
|
cypher |
Graph DDL through the write tool |
|
|
|
cypher, memory |
Accepts a privileged role |
|
|
|
memory |
Serves a graph it did not make |
What each flag does when set:
--read-only: the server does not register the write tool, and does not create the graph at startup.--allow-graph-ddl: the write tool may change a graph’s shape: create or drop graphs, labels, indexes and constraints.--allow-server-programs: the server starts even as a superuser or a member ofpg_execute_server_program.--adopt-existing-graph: the server serves a graph that already holds aMemorylabel this server did not make.
A boolean variable takes true or false. Whatever the flags, the Cypher tools take one
graph statement at a time. A second statement after a semicolon, SQL behind EXPLAIN, and SQL
that begins with a word Cypher also uses (such as CREATE TABLE or INSERT INTO) are refused.
--adopt-existing-graph exists because the memory server, at startup, merges entities that
share a name and moves relationships onto its own labels. It stops rather than do that to a
graph it did not make. Once adopted, the graph is marked as the server’s own, and later starts
do not ask again.
Cypher server read controls#
Variable |
CLI flag |
Default |
Meaning |
|---|---|---|---|
|
|
|
Statement timeout in seconds |
|
|
|
Token budget for a read response |
|
— |
|
Default rows per read page |
|
— |
|
Ceiling on page size (larger requests are clamped) |
|
— |
|
Nodes sampled per label when inferring property types |
|
— |
|
Connections the pool holds (Cypher server only) |
|
— |
|
Connections the pool may open (Cypher server only) |
AGENSGRAPH_READ_TIMEOUT: the timeout applies to every statement on the connection, writes included. It also setslock_timeoutandidle_in_transaction_session_timeout. It must be more than 0; a non-numeric variable falls back to 30 with a warning (the flag rejects it).AGENSGRAPH_RESPONSE_TOKEN_LIMIT: whole rows are dropped to fit the budget.0turns it off.
The memory server adds AGENSGRAPH_MEMORY_LIMIT (default 1000, at most 1000), the
default limit of read_graph and search_memories (entities returned) and of
find_memories_by_name (names looked up). Its statement timeout is fixed at 30 seconds, and
its pool at 4 to 16 connections; it does not read AGENSGRAPH_POOL_*.
Use with Claude Desktop#
Claude Desktop is MCP’s native client. Add the servers to its
claude_desktop_config.json (on macOS,
~/Library/Application Support/Claude/claude_desktop_config.json; use the equivalent config
directory on Linux/Windows). Each entry launches the released package with uvx:
{
"mcpServers": {
"agensgraph-cypher": {
"command": "uvx",
"args": ["mcp-agensgraph-cypher", "--transport", "stdio"],
"env": {
"AGENSGRAPH_URL": "postgresql://localhost:5432",
"AGENSGRAPH_USERNAME": "<your-username>",
"AGENSGRAPH_PASSWORD": "<your-password>",
"AGENSGRAPH_DATABASE": "<dbname>",
"AGENSGRAPH_GRAPHNAME": "<graphname>"
}
},
"agensgraph-memory": {
"command": "uvx",
"args": ["mcp-agensgraph-memory", "--transport", "stdio"],
"env": {
"AGENSGRAPH_URL": "postgresql://localhost:5432",
"AGENSGRAPH_USERNAME": "<your-username>",
"AGENSGRAPH_PASSWORD": "<your-password>",
"AGENSGRAPH_DATABASE": "<dbname>",
"AGENSGRAPH_GRAPHNAME": "memory"
}
},
"agensgraph-data-modeling": {
"command": "uvx",
"args": ["mcp-agensgraph-data-modeling", "--transport", "stdio"]
}
}
}
The user must be a role like the one in Database role. Claude Desktop needs
to find uvx; if it does not, give its full path as command. Add --read-only,
--allow-graph-ddl and the other flags to args as needed.
Restart Claude Desktop and the three servers’ tools will appear. To run several Cypher servers
against different graphs, give each one a distinct AGENSGRAPH_NAMESPACE (or --namespace)
so their tool names don’t collide:
{
"mcpServers": {
"graph1-agensgraph": {
"command": "uvx",
"args": ["mcp-agensgraph-cypher", "--namespace", "graph1"],
"env": {
"AGENSGRAPH_URL": "postgresql://localhost:5432",
"AGENSGRAPH_USERNAME": "<your-username>",
"AGENSGRAPH_PASSWORD": "<your-password>",
"AGENSGRAPH_DATABASE": "<dbname>",
"AGENSGRAPH_GRAPHNAME": "graph1"
}
},
"graph2-agensgraph": {
"command": "uvx",
"args": ["mcp-agensgraph-cypher", "--namespace", "graph2"],
"env": {
"AGENSGRAPH_URL": "postgresql://localhost:5432",
"AGENSGRAPH_USERNAME": "<your-username>",
"AGENSGRAPH_PASSWORD": "<your-password>",
"AGENSGRAPH_DATABASE": "<dbname>",
"AGENSGRAPH_GRAPHNAME": "graph2"
}
}
}
}
The first server’s tools are then graph1-read_agensgraph_cypher and so on.
To validate a server without Claude, use the MCP Inspector. Pass the connection with -e,
or the server connects with the defaults (agens, a superuser on a packaged install) and
refuses to start:
npx @modelcontextprotocol/inspector \
-e AGENSGRAPH_USERNAME=mcp -e AGENSGRAPH_PASSWORD=<your-password> \
-e AGENSGRAPH_DATABASE=mydb -e AGENSGRAPH_GRAPHNAME=mygraph \
-- uvx mcp-agensgraph-cypher --transport stdio
See Usage for the tools each server exposes.