Drivers and client libraries
============================
.. toctree::
:hidden:
ai-integrations
AgensGraph speaks the PostgreSQL wire protocol, so **any PostgreSQL driver connects to it and
can run Cypher** — a Cypher statement is just a statement as far as the protocol is
concerned. You do not need a graph-specific client to use AgensGraph.
What a driver cannot do without help is decode the graph types. A query that returns
``m.title`` hands back ``jsonb``, which every driver understands; a query that returns ``m``
hands back a ``vertex``, and ``p`` from a path pattern hands back a ``graphpath``. A stock
driver sees those as text. A driver written for AgensGraph adds the type handling, so a
vertex arrives as an object with its label, id and properties.
That gives you two ways to work:
**Use the PostgreSQL driver you already have.** Return properties rather than whole elements,
and wrap the Cypher in SQL where you want plain scalars instead of ``jsonb`` — see
:doc:`../querying/combining-sql-and-cypher`. This is the least code and the fewest
dependencies, and in any language other than Python it is the route to take.
**Use the Python driver** when you want vertices, edges and paths as native objects, or when
you are building on one of the AI integrations.
The Python driver
-----------------
`AgensGraph for Python `_
is the driver to build on. It adds the graph type handling on top of psycopg 3, and it is what
every one of the :doc:`AI integrations ` runs on. Its manual has
installation and usage.
LangChain, LlamaIndex, LightRAG, cognee and the MCP servers all sit on that driver. See
:doc:`AI and LLM integrations `.
Other languages
---------------
For Java, Node.js and Go, use a stock PostgreSQL driver — pgjdbc, node-postgres or pgx —
and read properties rather than whole elements, as above. That is the combination to build on
today.
Drivers for those three languages do exist, and each is kept here for the projects already
using it rather than as a starting point:
* `Java / JDBC `_
:bdg-secondary-line:`legacy` — a fork of pgjdbc, published as
``net.bitnine:agensgraph-jdbc:1.4.3`` in January 2023.
* `Node.js `_
:bdg-secondary-line:`legacy` — wraps node-postgres, against ``pg >= 6.1.2``. Published as
``@skaiworldwide/ag-driver`` 1.1.0 in September 2025.
* `Go `_
:bdg-secondary-line:`legacy` — built on ``lib/pq``, distributed as a Go module at tag
``v0.1.1``.
Connection and parameters
-------------------------
**Set** ``graph_path`` **on the connection.** It is per-session, so a pooled connection needs
it set each time it is handed out — or set it once for the role or the database:
.. code-block:: sql
ALTER ROLE appuser SET graph_path = moviekb;
The Python driver's ``ConnectionPool`` takes a ``graph=`` argument and sets it once on each
connection it opens, not again on each handout, so a borrower that changes ``graph_path`` and
commits passes the change on to the next borrower.
**Give Cypher parameters a type.** A parameter whose type the driver leaves unspecified is
parsed as JSON, so a plain string fails:
.. code-block:: text
ERROR: invalid input syntax for type json
DETAIL: Token "The" is invalid.
CONTEXT: JSON data, line 1: The...
Either declare the parameter's type through the driver's API, or cast it in the statement:
.. code-block:: cypher
MATCH (m:movie {title: $1::text}) RETURN m.year;
The cast is the portable form, and it costs nothing. It matters most where a value could be
read either way: without a type, ``'123'`` arrives as the *number* 123 and stops matching a
property holding the *string* ``"123"``.
The Python driver declares the type for you. From version 2.0 it sends a Python ``str`` as
``text``, so a string parameter needs no cast there. The cast is still needed where the
statement wants another type from a string, such as ``%s::date``.