Vibe-kodad applikation för att prata med en LLM om data i en Neo4J-databas som innehåller SCBs resgitermetadata
  • Java 97%
  • Shell 3%
Find a file
2026-05-10 15:41:57 +02:00
cli Switch to langchain4j 2026-05-10 15:41:33 +02:00
.gitignore Fixes showing responses 2026-05-09 15:04:07 +02:00
AGENTS.md Switch to langchain4j 2026-05-10 15:41:33 +02:00
Idéer.md Initial commit 2026-05-08 21:42:02 +02:00
pom.xml Switch to langchain4j 2026-05-10 15:41:33 +02:00
README.md Switch to langchain4j 2026-05-10 15:41:33 +02:00
start-native.sh Switch to langchain4j 2026-05-10 15:41:33 +02:00
start.sh Switch to langchain4j 2026-05-10 15:41:33 +02:00

LMStudio Neo4j Chat

A terminal chat application that lets you have a natural-language conversation with an LLM running in LMStudio about data stored in a Neo4j graph database.

The model can query the database autonomously using Cypher — you just ask questions in plain language and the model figures out what to look up.

┌─ LMStudio Chat ────────────────────────────────────────────┐
│ Connected. Schema loaded. Type your question. Ctrl+Q quit. │
│                                                            │
│ You: Which actors appeared in more than 5 movies?          │
│                                                            │
│ [tool] MATCH (a:Person)-[:ACTED_IN]->(m:Movie)             │
│        RETURN a.name, count(m) AS movies                   │
│        ORDER BY movies DESC LIMIT 10                       │
│        name          | movies                              │
│        ---------------------                               │
│        Tom Hanks     | 12                                  │
│        ...                                                 │
│                                                            │
│ AI:  Based on the data, Tom Hanks leads with 12 movies...  │
│                                                            │
├────────────────────────────────────────────────────────────┤
│ > _                                                        │
└────────────────────────────────────────────────────────────┘

How it works

  1. On startup, the app connects to Neo4j and automatically discovers the graph schema (node labels, relationship types, and property keys). This schema is injected as the model's system prompt so it understands the database structure upfront.

  2. When you ask a question, the model decides whether it needs to query the database. If it does, it generates a Cypher query, the app executes it against Neo4j, and the results are fed back to the model. This tool-calling loop repeats until the model has enough information to give you a final answer.

  3. Tool calls are shown inline in the chat (in yellow) so you can see exactly what queries the model ran and what came back.

Prerequisites

  • LMStudio running locally (or on another host on your LAN) with a model loaded and the server started
  • Neo4j database (local or remote) with data to explore
  • Java 25 or later

Building

mvn package -DskipTests

Running

The easiest way is the included launch script, which builds the project and starts the app:

./start.sh --model qwen2.5-7b-instruct \
           --neo4j-url bolt://localhost:7687 \
           --neo4j-password secret

Or run the JAR directly after mvn package -DskipTests:

java -cp "cli/target/cli-1.0.0-SNAPSHOT.jar:lmstudio/target/lmstudio-1.0.0-SNAPSHOT.jar:cli/target/lib/*" \
  se.mejsla.llm.Main \
  --model qwen2.5-7b-instruct \
  --neo4j-url bolt://localhost:7687 \
  --neo4j-password secret

--neo4j-password accepts the value on the command line or, if omitted, prompts securely without echo.

All options

Option Default Description
--url http://localhost:1234 LMStudio server URL
--token (empty) LMStudio API token (leave blank if auth is disabled)
--model (required) Model identifier as shown in LMStudio
--neo4j-url (required) Bolt URL, e.g. bolt://192.168.1.10:7687
--neo4j-user neo4j Neo4j username
--neo4j-password (required) Neo4j password (prompted if not given on command line)
--timeout 600 LMStudio request timeout in seconds

Controls

Key Action
Enter Submit message
Ctrl+Q Quit
/quit Quit (typed command)

Native image (optional)

Compiling to a native executable removes the JVM dependency and makes the app start in under a second.

Prerequisites

Install GraalVM JDK 25 (must match the project's Java 25 --release setting):

sdk install java 25-graalce   # via SDKMAN
native-image --version        # verify

Make sure JAVA_HOME points to the GraalVM JDK before running Maven.

First-time setup: capture reflection metadata

The native image build needs a one-time tracing run to record which classes are loaded reflectively (Lanterna terminal detection, Jackson SPI, etc.).

Build the JARs first, then run the app with the tracing agent attached:

mvn package -DskipTests

java \
  -agentlib:native-image-agent=config-output-dir=cli/src/main/resources/META-INF/native-image/se.mejsla.llm/cli \
  -cp "cli/target/cli-1.0.0-SNAPSHOT.jar:lmstudio/target/lmstudio-1.0.0-SNAPSHOT.jar:cli/target/lib/*" \
  se.mejsla.llm.Main \
  --model <model> --neo4j-url bolt://localhost:7687 --neo4j-password <pw>

Ask at least one question that triggers a tool call, then Ctrl+Q. The agent writes config files into cli/src/main/resources/META-INF/native-image/se.mejsla.llm/cli/. Commit those files — you only need to redo this step if dependencies change significantly.

Build

mvn package -DskipTests -Pnative -pl cli

Output: cli/target/lmstudio-chat (expect 25 minutes build time).

Running the native binary

./cli/target/lmstudio-chat \
  --model qwen2.5-7b-instruct \
  --neo4j-url bolt://localhost:7687 \
  --neo4j-password secret

Or use the launch script, which builds and runs in one step:

./start-native.sh --model qwen2.5-7b-instruct \
                  --neo4j-url bolt://localhost:7687 \
                  --neo4j-password secret

Troubleshooting

If the build fails with a ClassNotFoundException or NoSuchMethodException at runtime, the error message names the missing class. Add it to cli/src/main/resources/META-INF/native-image/se.mejsla.llm/cli/reflect-config.json and rebuild.

If the build fails with a Netty class-initialization error, add this to the <buildArgs> in cli/pom.xml:

<buildArg>--initialize-at-run-time=io.netty</buildArg>

Why a custom LLM client?

This project uses a hand-rolled HTTP client (lmstudio module) rather than a library like LangChain4j. The reason is JPMS: every major Java LLM/OpenAI client library (LangChain4j, the official openai-java SDK, simple-openai, Spring AI) either has no module-info.java or has split-package violations that break the Java module system. LangChain4j specifically has a documented split-package issue (#1066) that prevents it from being used on the module path at all.

The custom client only depends on java.net.http (JDK built-in) and Jackson, both of which work cleanly with JPMS. It will be replaced once an upstream library resolves its module-system compatibility.

Tips

  • Models with strong tool-calling support work best: Qwen 2.5, Llama 3.1/3.2, Mistral.
  • The model sees up to 50 rows per query result. For large result sets, ask follow-up questions to narrow down.
  • If the schema discovery produces an unhelpful system prompt (e.g. your database has hundreds of labels), you can prime the model by asking "describe the schema" as your first message.